mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-04-21 03:55:32 +00:00
d3d12: Implement texture swizzling and untiling
This commit is contained in:
parent
52a68875fc
commit
b5a7637b49
1 changed files with 71 additions and 1 deletions
|
@ -3,6 +3,38 @@
|
|||
#include "D3D12GSRender.h"
|
||||
// For clarity this code deals with texture but belongs to D3D12GSRender class
|
||||
|
||||
|
||||
static
|
||||
u32 LinearToSwizzleAddress(u32 x, u32 y, u32 z, u32 log2_width, u32 log2_height, u32 log2_depth)
|
||||
{
|
||||
u32 offset = 0;
|
||||
u32 shift_count = 0;
|
||||
while (log2_width | log2_height | log2_depth) {
|
||||
if (log2_width)
|
||||
{
|
||||
offset |= (x & 0x01) << shift_count;
|
||||
x >>= 1;
|
||||
++shift_count;
|
||||
--log2_width;
|
||||
}
|
||||
if (log2_height)
|
||||
{
|
||||
offset |= (y & 0x01) << shift_count;
|
||||
y >>= 1;
|
||||
++shift_count;
|
||||
--log2_height;
|
||||
}
|
||||
if (log2_depth)
|
||||
{
|
||||
offset |= (z & 0x01) << shift_count;
|
||||
z >>= 1;
|
||||
++shift_count;
|
||||
--log2_depth;
|
||||
}
|
||||
}
|
||||
return offset;
|
||||
}
|
||||
|
||||
static D3D12_COMPARISON_FUNC ComparisonFunc[] =
|
||||
{
|
||||
D3D12_COMPARISON_FUNC_NEVER,
|
||||
|
@ -65,6 +97,7 @@ size_t D3D12GSRender::UploadTextures()
|
|||
DXGI_FORMAT dxgiFormat;
|
||||
size_t pixelSize;
|
||||
int format = m_textures[i].GetFormat() & ~(CELL_GCM_TEXTURE_LN | CELL_GCM_TEXTURE_UN);
|
||||
bool is_swizzled = !(m_textures[i].GetFormat() & CELL_GCM_TEXTURE_LN);
|
||||
switch (format)
|
||||
{
|
||||
case CELL_GCM_TEXTURE_A1R5G5B5:
|
||||
|
@ -125,7 +158,26 @@ size_t D3D12GSRender::UploadTextures()
|
|||
rowPitch = (rowPitch + 255) & ~255;
|
||||
// Upload with correct rowpitch
|
||||
for (unsigned row = 0; row < m_textures[i].GetHeight(); row++)
|
||||
{
|
||||
if (is_swizzled)
|
||||
{
|
||||
u32 *src, *dst;
|
||||
u32 log2width, log2height;
|
||||
|
||||
src = (u32*)pixels;
|
||||
dst = (u32*)textureData;
|
||||
|
||||
log2width = (u32)(logf(m_textures[i].GetWidth()) / logf(2.f));
|
||||
log2height = (u32)(logf(m_textures[i].GetHeight()) / logf(2.f));
|
||||
|
||||
for (int j = 0; j < m_textures[i].GetWidth(); j++)
|
||||
{
|
||||
dst[(row * rowPitch) + j] = src[LinearToSwizzleAddress(j, i, 0, log2width, log2height, 0)];
|
||||
}
|
||||
}
|
||||
else
|
||||
streamToBuffer((char*)textureData + row * rowPitch, (char*)pixels + row * m_textures[i].m_pitch, m_textures[i].m_pitch);
|
||||
}
|
||||
Texture->Unmap(0, nullptr);
|
||||
|
||||
check(m_device->CreatePlacedResource(
|
||||
|
@ -167,7 +219,25 @@ size_t D3D12GSRender::UploadTextures()
|
|||
srvDesc.ViewDimension = D3D12_SRV_DIMENSION_TEXTURE2D;
|
||||
srvDesc.Format = dxgiFormat;
|
||||
srvDesc.Texture2D.MipLevels = 1;
|
||||
srvDesc.Shader4ComponentMapping = D3D12_ENCODE_SHADER_4_COMPONENT_MAPPING(D3D12_SHADER_COMPONENT_MAPPING_FROM_MEMORY_COMPONENT_1, D3D12_SHADER_COMPONENT_MAPPING_FROM_MEMORY_COMPONENT_2, D3D12_SHADER_COMPONENT_MAPPING_FROM_MEMORY_COMPONENT_3, D3D12_SHADER_COMPONENT_MAPPING_FROM_MEMORY_COMPONENT_0);
|
||||
static const int RemapValue[4] =
|
||||
{
|
||||
D3D12_SHADER_COMPONENT_MAPPING_FROM_MEMORY_COMPONENT_1,
|
||||
D3D12_SHADER_COMPONENT_MAPPING_FROM_MEMORY_COMPONENT_2,
|
||||
D3D12_SHADER_COMPONENT_MAPPING_FROM_MEMORY_COMPONENT_3,
|
||||
D3D12_SHADER_COMPONENT_MAPPING_FROM_MEMORY_COMPONENT_0
|
||||
};
|
||||
if (format != CELL_GCM_TEXTURE_B8 && format != CELL_GCM_TEXTURE_X16 && format != CELL_GCM_TEXTURE_X32_FLOAT)
|
||||
{
|
||||
u8 remap_a = m_textures[i].GetRemap() & 0x3;
|
||||
u8 remap_r = (m_textures[i].GetRemap() >> 2) & 0x3;
|
||||
u8 remap_g = (m_textures[i].GetRemap() >> 4) & 0x3;
|
||||
u8 remap_b = (m_textures[i].GetRemap() >> 6) & 0x3;
|
||||
|
||||
srvDesc.Shader4ComponentMapping = D3D12_ENCODE_SHADER_4_COMPONENT_MAPPING(RemapValue[remap_a], RemapValue[remap_r], RemapValue[remap_g], RemapValue[remap_b]);
|
||||
}
|
||||
else
|
||||
srvDesc.Shader4ComponentMapping = D3D12_ENCODE_SHADER_4_COMPONENT_MAPPING(RemapValue[0], RemapValue[1], RemapValue[2], RemapValue[3]);
|
||||
|
||||
D3D12_CPU_DESCRIPTOR_HANDLE Handle = m_perFrameStorage.m_textureDescriptorsHeap->GetCPUDescriptorHandleForHeapStart();
|
||||
Handle.ptr += (m_perFrameStorage.m_currentTextureIndex + usedTexture) * m_device->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV);
|
||||
m_device->CreateShaderResourceView(vramTexture, &srvDesc, Handle);
|
||||
|
|
Loading…
Add table
Reference in a new issue