[GPU] Move texture load shader info to common

This commit is contained in:
Triang3l 2022-05-24 22:24:33 +03:00
parent c1f15c86a3
commit 75c185e759
4 changed files with 546 additions and 397 deletions

View File

@ -80,386 +80,311 @@ namespace shaders {
const D3D12TextureCache::HostFormat D3D12TextureCache::host_formats_[64] = { const D3D12TextureCache::HostFormat D3D12TextureCache::host_formats_[64] = {
// k_1_REVERSE // k_1_REVERSE
{DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, LoadMode::kUnknown, {DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, kLoadShaderIndexUnknown,
DXGI_FORMAT_UNKNOWN, LoadMode::kUnknown, false, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, kLoadShaderIndexUnknown, false, DXGI_FORMAT_UNKNOWN,
LoadMode::kUnknown, xenos::XE_GPU_TEXTURE_SWIZZLE_RRRR}, kLoadShaderIndexUnknown, xenos::XE_GPU_TEXTURE_SWIZZLE_RRRR},
// k_1 // k_1
{DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, LoadMode::kUnknown, {DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, kLoadShaderIndexUnknown,
DXGI_FORMAT_UNKNOWN, LoadMode::kUnknown, false, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, kLoadShaderIndexUnknown, false, DXGI_FORMAT_UNKNOWN,
LoadMode::kUnknown, xenos::XE_GPU_TEXTURE_SWIZZLE_RRRR}, kLoadShaderIndexUnknown, xenos::XE_GPU_TEXTURE_SWIZZLE_RRRR},
// k_8 // k_8
{DXGI_FORMAT_R8_TYPELESS, DXGI_FORMAT_R8_UNORM, LoadMode::k8bpb, {DXGI_FORMAT_R8_TYPELESS, DXGI_FORMAT_R8_UNORM, kLoadShaderIndex8bpb,
DXGI_FORMAT_R8_SNORM, LoadMode::kUnknown, false, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_R8_SNORM, kLoadShaderIndexUnknown, false, DXGI_FORMAT_UNKNOWN,
LoadMode::kUnknown, xenos::XE_GPU_TEXTURE_SWIZZLE_RRRR}, kLoadShaderIndexUnknown, xenos::XE_GPU_TEXTURE_SWIZZLE_RRRR},
// k_1_5_5_5 // k_1_5_5_5
// Red and blue swapped in the load shader for simplicity. // Red and blue swapped in the load shader for simplicity.
{DXGI_FORMAT_B5G5R5A1_UNORM, DXGI_FORMAT_B5G5R5A1_UNORM, {DXGI_FORMAT_B5G5R5A1_UNORM, DXGI_FORMAT_B5G5R5A1_UNORM,
LoadMode::kR5G5B5A1ToB5G5R5A1, DXGI_FORMAT_UNKNOWN, LoadMode::kUnknown, kLoadShaderIndexR5G5B5A1ToB5G5R5A1, DXGI_FORMAT_UNKNOWN,
false, DXGI_FORMAT_UNKNOWN, LoadMode::kUnknown, kLoadShaderIndexUnknown, false, DXGI_FORMAT_UNKNOWN,
xenos::XE_GPU_TEXTURE_SWIZZLE_RGBA}, kLoadShaderIndexUnknown, xenos::XE_GPU_TEXTURE_SWIZZLE_RGBA},
// k_5_6_5 // k_5_6_5
// Red and blue swapped in the load shader for simplicity. // Red and blue swapped in the load shader for simplicity.
{DXGI_FORMAT_B5G6R5_UNORM, DXGI_FORMAT_B5G6R5_UNORM, {DXGI_FORMAT_B5G6R5_UNORM, DXGI_FORMAT_B5G6R5_UNORM,
LoadMode::kR5G6B5ToB5G6R5, DXGI_FORMAT_UNKNOWN, LoadMode::kUnknown, false, kLoadShaderIndexR5G6B5ToB5G6R5, DXGI_FORMAT_UNKNOWN,
DXGI_FORMAT_UNKNOWN, LoadMode::kUnknown, kLoadShaderIndexUnknown, false, DXGI_FORMAT_UNKNOWN,
xenos::XE_GPU_TEXTURE_SWIZZLE_RGBB}, kLoadShaderIndexUnknown, xenos::XE_GPU_TEXTURE_SWIZZLE_RGBB},
// k_6_5_5 // k_6_5_5
// On the host, green bits in blue, blue bits in green. // On the host, green bits in blue, blue bits in green.
{DXGI_FORMAT_B5G6R5_UNORM, DXGI_FORMAT_B5G6R5_UNORM, {DXGI_FORMAT_B5G6R5_UNORM, DXGI_FORMAT_B5G6R5_UNORM,
LoadMode::kR5G5B6ToB5G6R5WithRBGASwizzle, DXGI_FORMAT_UNKNOWN, kLoadShaderIndexR5G5B6ToB5G6R5WithRBGASwizzle, DXGI_FORMAT_UNKNOWN,
LoadMode::kUnknown, false, DXGI_FORMAT_UNKNOWN, LoadMode::kUnknown, kLoadShaderIndexUnknown, false, DXGI_FORMAT_UNKNOWN,
XE_GPU_MAKE_TEXTURE_SWIZZLE(R, B, G, G)}, kLoadShaderIndexUnknown, XE_GPU_MAKE_TEXTURE_SWIZZLE(R, B, G, G)},
// k_8_8_8_8 // k_8_8_8_8
{DXGI_FORMAT_R8G8B8A8_TYPELESS, DXGI_FORMAT_R8G8B8A8_UNORM, {DXGI_FORMAT_R8G8B8A8_TYPELESS, DXGI_FORMAT_R8G8B8A8_UNORM,
LoadMode::k32bpb, DXGI_FORMAT_R8G8B8A8_SNORM, LoadMode::kUnknown, false, kLoadShaderIndex32bpb, DXGI_FORMAT_R8G8B8A8_SNORM, kLoadShaderIndexUnknown,
DXGI_FORMAT_UNKNOWN, LoadMode::kUnknown, false, DXGI_FORMAT_UNKNOWN, kLoadShaderIndexUnknown,
xenos::XE_GPU_TEXTURE_SWIZZLE_RGBA}, xenos::XE_GPU_TEXTURE_SWIZZLE_RGBA},
// k_2_10_10_10 // k_2_10_10_10
{DXGI_FORMAT_R10G10B10A2_TYPELESS, DXGI_FORMAT_R10G10B10A2_UNORM, {DXGI_FORMAT_R10G10B10A2_TYPELESS, DXGI_FORMAT_R10G10B10A2_UNORM,
LoadMode::k32bpb, DXGI_FORMAT_UNKNOWN, LoadMode::kUnknown, false, kLoadShaderIndex32bpb, DXGI_FORMAT_UNKNOWN, kLoadShaderIndexUnknown, false,
DXGI_FORMAT_UNKNOWN, LoadMode::kUnknown, DXGI_FORMAT_UNKNOWN, kLoadShaderIndexUnknown,
xenos::XE_GPU_TEXTURE_SWIZZLE_RGBA}, xenos::XE_GPU_TEXTURE_SWIZZLE_RGBA},
// k_8_A // k_8_A
{DXGI_FORMAT_R8_TYPELESS, DXGI_FORMAT_R8_UNORM, LoadMode::k8bpb, {DXGI_FORMAT_R8_TYPELESS, DXGI_FORMAT_R8_UNORM, kLoadShaderIndex8bpb,
DXGI_FORMAT_R8_SNORM, LoadMode::kUnknown, false, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_R8_SNORM, kLoadShaderIndexUnknown, false, DXGI_FORMAT_UNKNOWN,
LoadMode::kUnknown, xenos::XE_GPU_TEXTURE_SWIZZLE_RRRR}, kLoadShaderIndexUnknown, xenos::XE_GPU_TEXTURE_SWIZZLE_RRRR},
// k_8_B // k_8_B
{DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, LoadMode::kUnknown, {DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, kLoadShaderIndexUnknown,
DXGI_FORMAT_UNKNOWN, LoadMode::kUnknown, false, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, kLoadShaderIndexUnknown, false, DXGI_FORMAT_UNKNOWN,
LoadMode::kUnknown, xenos::XE_GPU_TEXTURE_SWIZZLE_RRRR}, kLoadShaderIndexUnknown, xenos::XE_GPU_TEXTURE_SWIZZLE_RRRR},
// k_8_8 // k_8_8
{DXGI_FORMAT_R8G8_TYPELESS, DXGI_FORMAT_R8G8_UNORM, LoadMode::k16bpb, {DXGI_FORMAT_R8G8_TYPELESS, DXGI_FORMAT_R8G8_UNORM, kLoadShaderIndex16bpb,
DXGI_FORMAT_R8G8_SNORM, LoadMode::kUnknown, false, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_R8G8_SNORM, kLoadShaderIndexUnknown, false,
LoadMode::kUnknown, xenos::XE_GPU_TEXTURE_SWIZZLE_RGGG}, DXGI_FORMAT_UNKNOWN, kLoadShaderIndexUnknown,
xenos::XE_GPU_TEXTURE_SWIZZLE_RGGG},
// k_Cr_Y1_Cb_Y0_REP // k_Cr_Y1_Cb_Y0_REP
// Red and blue swapped in the load shader for simplicity. // Red and blue swapped in the load shader for simplicity.
// TODO(Triang3l): The DXGI_FORMAT_R8G8B8A8_U/SNORM conversion is usable for // TODO(Triang3l): The DXGI_FORMAT_R8G8B8A8_U/SNORM conversion is usable for
// the signed version, separate unsigned and signed load modes completely // the signed version, separate unsigned and signed load shaders completely
// (as one doesn't need decompression for this format, while another does). // (as one doesn't need decompression for this format, while another does).
{DXGI_FORMAT_G8R8_G8B8_UNORM, DXGI_FORMAT_G8R8_G8B8_UNORM, {DXGI_FORMAT_G8R8_G8B8_UNORM, DXGI_FORMAT_G8R8_G8B8_UNORM,
LoadMode::kGBGR8ToGRGB8, DXGI_FORMAT_UNKNOWN, LoadMode::kUnknown, true, kLoadShaderIndexGBGR8ToGRGB8, DXGI_FORMAT_UNKNOWN, kLoadShaderIndexUnknown,
DXGI_FORMAT_R8G8B8A8_UNORM, LoadMode::kGBGR8ToRGB8, true, DXGI_FORMAT_R8G8B8A8_UNORM, kLoadShaderIndexGBGR8ToRGB8,
xenos::XE_GPU_TEXTURE_SWIZZLE_RGBB}, xenos::XE_GPU_TEXTURE_SWIZZLE_RGBB},
// k_Y1_Cr_Y0_Cb_REP // k_Y1_Cr_Y0_Cb_REP
// Red and blue swapped in the load shader for simplicity. // Red and blue swapped in the load shader for simplicity.
// TODO(Triang3l): The DXGI_FORMAT_R8G8B8A8_U/SNORM conversion is usable for // TODO(Triang3l): The DXGI_FORMAT_R8G8B8A8_U/SNORM conversion is usable for
// the signed version, separate unsigned and signed load modes completely // the signed version, separate unsigned and signed load shaders completely
// (as one doesn't need decompression for this format, while another does). // (as one doesn't need decompression for this format, while another does).
{DXGI_FORMAT_R8G8_B8G8_UNORM, DXGI_FORMAT_R8G8_B8G8_UNORM, {DXGI_FORMAT_R8G8_B8G8_UNORM, DXGI_FORMAT_R8G8_B8G8_UNORM,
LoadMode::kBGRG8ToRGBG8, DXGI_FORMAT_UNKNOWN, LoadMode::kUnknown, true, kLoadShaderIndexBGRG8ToRGBG8, DXGI_FORMAT_UNKNOWN, kLoadShaderIndexUnknown,
DXGI_FORMAT_R8G8B8A8_UNORM, LoadMode::kBGRG8ToRGB8, true, DXGI_FORMAT_R8G8B8A8_UNORM, kLoadShaderIndexBGRG8ToRGB8,
xenos::XE_GPU_TEXTURE_SWIZZLE_RGBB}, xenos::XE_GPU_TEXTURE_SWIZZLE_RGBB},
// k_16_16_EDRAM // k_16_16_EDRAM
// Not usable as a texture, also has -32...32 range. // Not usable as a texture, also has -32...32 range.
{DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, LoadMode::kUnknown, {DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, kLoadShaderIndexUnknown,
DXGI_FORMAT_UNKNOWN, LoadMode::kUnknown, false, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, kLoadShaderIndexUnknown, false, DXGI_FORMAT_UNKNOWN,
LoadMode::kUnknown, xenos::XE_GPU_TEXTURE_SWIZZLE_RGGG}, kLoadShaderIndexUnknown, xenos::XE_GPU_TEXTURE_SWIZZLE_RGGG},
// k_8_8_8_8_A // k_8_8_8_8_A
{DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, LoadMode::kUnknown, {DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, kLoadShaderIndexUnknown,
DXGI_FORMAT_UNKNOWN, LoadMode::kUnknown, false, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, kLoadShaderIndexUnknown, false, DXGI_FORMAT_UNKNOWN,
LoadMode::kUnknown, xenos::XE_GPU_TEXTURE_SWIZZLE_RGBA}, kLoadShaderIndexUnknown, xenos::XE_GPU_TEXTURE_SWIZZLE_RGBA},
// k_4_4_4_4 // k_4_4_4_4
// Red and blue swapped in the load shader for simplicity. // Red and blue swapped in the load shader for simplicity.
{DXGI_FORMAT_B4G4R4A4_UNORM, DXGI_FORMAT_B4G4R4A4_UNORM, {DXGI_FORMAT_B4G4R4A4_UNORM, DXGI_FORMAT_B4G4R4A4_UNORM,
LoadMode::kR4G4B4A4ToB4G4R4A4, DXGI_FORMAT_UNKNOWN, LoadMode::kUnknown, kLoadShaderIndexRGBA4ToBGRA4, DXGI_FORMAT_UNKNOWN, kLoadShaderIndexUnknown,
false, DXGI_FORMAT_UNKNOWN, LoadMode::kUnknown, false, DXGI_FORMAT_UNKNOWN, kLoadShaderIndexUnknown,
xenos::XE_GPU_TEXTURE_SWIZZLE_RGBA}, xenos::XE_GPU_TEXTURE_SWIZZLE_RGBA},
// k_10_11_11 // k_10_11_11
{DXGI_FORMAT_R16G16B16A16_TYPELESS, DXGI_FORMAT_R16G16B16A16_UNORM, {DXGI_FORMAT_R16G16B16A16_TYPELESS, DXGI_FORMAT_R16G16B16A16_UNORM,
LoadMode::kR11G11B10ToRGBA16, DXGI_FORMAT_R16G16B16A16_SNORM, kLoadShaderIndexR11G11B10ToRGBA16, DXGI_FORMAT_R16G16B16A16_SNORM,
LoadMode::kR11G11B10ToRGBA16SNorm, false, DXGI_FORMAT_UNKNOWN, kLoadShaderIndexR11G11B10ToRGBA16SNorm, false, DXGI_FORMAT_UNKNOWN,
LoadMode::kUnknown, xenos::XE_GPU_TEXTURE_SWIZZLE_RGBB}, kLoadShaderIndexUnknown, xenos::XE_GPU_TEXTURE_SWIZZLE_RGBB},
// k_11_11_10 // k_11_11_10
{DXGI_FORMAT_R16G16B16A16_TYPELESS, DXGI_FORMAT_R16G16B16A16_UNORM, {DXGI_FORMAT_R16G16B16A16_TYPELESS, DXGI_FORMAT_R16G16B16A16_UNORM,
LoadMode::kR10G11B11ToRGBA16, DXGI_FORMAT_R16G16B16A16_SNORM, kLoadShaderIndexR10G11B11ToRGBA16, DXGI_FORMAT_R16G16B16A16_SNORM,
LoadMode::kR10G11B11ToRGBA16SNorm, false, DXGI_FORMAT_UNKNOWN, kLoadShaderIndexR10G11B11ToRGBA16SNorm, false, DXGI_FORMAT_UNKNOWN,
LoadMode::kUnknown, xenos::XE_GPU_TEXTURE_SWIZZLE_RGBB}, kLoadShaderIndexUnknown, xenos::XE_GPU_TEXTURE_SWIZZLE_RGBB},
// k_DXT1 // k_DXT1
{DXGI_FORMAT_BC1_UNORM, DXGI_FORMAT_BC1_UNORM, LoadMode::k64bpb, {DXGI_FORMAT_BC1_UNORM, DXGI_FORMAT_BC1_UNORM, kLoadShaderIndex64bpb,
DXGI_FORMAT_UNKNOWN, LoadMode::kUnknown, true, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_UNKNOWN, kLoadShaderIndexUnknown, true,
LoadMode::kDXT1ToRGBA8, xenos::XE_GPU_TEXTURE_SWIZZLE_RGBA}, DXGI_FORMAT_R8G8B8A8_UNORM, kLoadShaderIndexDXT1ToRGBA8,
xenos::XE_GPU_TEXTURE_SWIZZLE_RGBA},
// k_DXT2_3 // k_DXT2_3
{DXGI_FORMAT_BC2_UNORM, DXGI_FORMAT_BC2_UNORM, LoadMode::k128bpb, {DXGI_FORMAT_BC2_UNORM, DXGI_FORMAT_BC2_UNORM, kLoadShaderIndex128bpb,
DXGI_FORMAT_UNKNOWN, LoadMode::kUnknown, true, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_UNKNOWN, kLoadShaderIndexUnknown, true,
LoadMode::kDXT3ToRGBA8, xenos::XE_GPU_TEXTURE_SWIZZLE_RGBA}, DXGI_FORMAT_R8G8B8A8_UNORM, kLoadShaderIndexDXT3ToRGBA8,
xenos::XE_GPU_TEXTURE_SWIZZLE_RGBA},
// k_DXT4_5 // k_DXT4_5
{DXGI_FORMAT_BC3_UNORM, DXGI_FORMAT_BC3_UNORM, LoadMode::k128bpb, {DXGI_FORMAT_BC3_UNORM, DXGI_FORMAT_BC3_UNORM, kLoadShaderIndex128bpb,
DXGI_FORMAT_UNKNOWN, LoadMode::kUnknown, true, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_UNKNOWN, kLoadShaderIndexUnknown, true,
LoadMode::kDXT5ToRGBA8, xenos::XE_GPU_TEXTURE_SWIZZLE_RGBA}, DXGI_FORMAT_R8G8B8A8_UNORM, kLoadShaderIndexDXT5ToRGBA8,
xenos::XE_GPU_TEXTURE_SWIZZLE_RGBA},
// k_16_16_16_16_EDRAM // k_16_16_16_16_EDRAM
// Not usable as a texture, also has -32...32 range. // Not usable as a texture, also has -32...32 range.
{DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, LoadMode::kUnknown, {DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, kLoadShaderIndexUnknown,
DXGI_FORMAT_UNKNOWN, LoadMode::kUnknown, false, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, kLoadShaderIndexUnknown, false, DXGI_FORMAT_UNKNOWN,
LoadMode::kUnknown, xenos::XE_GPU_TEXTURE_SWIZZLE_RGBA}, kLoadShaderIndexUnknown, xenos::XE_GPU_TEXTURE_SWIZZLE_RGBA},
// R32_FLOAT for depth because shaders would require an additional SRV to // R32_FLOAT for depth because shaders would require an additional SRV to
// sample stencil, which we don't provide. // sample stencil, which we don't provide.
// k_24_8 // k_24_8
{DXGI_FORMAT_R32_FLOAT, DXGI_FORMAT_R32_FLOAT, LoadMode::kDepthUnorm, {DXGI_FORMAT_R32_FLOAT, DXGI_FORMAT_R32_FLOAT, kLoadShaderIndexDepthUnorm,
DXGI_FORMAT_R32_FLOAT, LoadMode::kUnknown, false, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_R32_FLOAT, kLoadShaderIndexUnknown, false, DXGI_FORMAT_UNKNOWN,
LoadMode::kUnknown, xenos::XE_GPU_TEXTURE_SWIZZLE_RRRR}, kLoadShaderIndexUnknown, xenos::XE_GPU_TEXTURE_SWIZZLE_RRRR},
// k_24_8_FLOAT // k_24_8_FLOAT
{DXGI_FORMAT_R32_FLOAT, DXGI_FORMAT_R32_FLOAT, LoadMode::kDepthFloat, {DXGI_FORMAT_R32_FLOAT, DXGI_FORMAT_R32_FLOAT, kLoadShaderIndexDepthFloat,
DXGI_FORMAT_R32_FLOAT, LoadMode::kUnknown, false, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_R32_FLOAT, kLoadShaderIndexUnknown, false, DXGI_FORMAT_UNKNOWN,
LoadMode::kUnknown, xenos::XE_GPU_TEXTURE_SWIZZLE_RRRR}, kLoadShaderIndexUnknown, xenos::XE_GPU_TEXTURE_SWIZZLE_RRRR},
// k_16 // k_16
{DXGI_FORMAT_R16_TYPELESS, DXGI_FORMAT_R16_UNORM, LoadMode::k16bpb, {DXGI_FORMAT_R16_TYPELESS, DXGI_FORMAT_R16_UNORM, kLoadShaderIndex16bpb,
DXGI_FORMAT_R16_SNORM, LoadMode::kUnknown, false, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_R16_SNORM, kLoadShaderIndexUnknown, false, DXGI_FORMAT_UNKNOWN,
LoadMode::kUnknown, xenos::XE_GPU_TEXTURE_SWIZZLE_RRRR}, kLoadShaderIndexUnknown, xenos::XE_GPU_TEXTURE_SWIZZLE_RRRR},
// k_16_16 // k_16_16
{DXGI_FORMAT_R16G16_TYPELESS, DXGI_FORMAT_R16G16_UNORM, LoadMode::k32bpb, {DXGI_FORMAT_R16G16_TYPELESS, DXGI_FORMAT_R16G16_UNORM,
DXGI_FORMAT_R16G16_SNORM, LoadMode::kUnknown, false, DXGI_FORMAT_UNKNOWN, kLoadShaderIndex32bpb, DXGI_FORMAT_R16G16_SNORM, kLoadShaderIndexUnknown,
LoadMode::kUnknown, xenos::XE_GPU_TEXTURE_SWIZZLE_RGGG}, false, DXGI_FORMAT_UNKNOWN, kLoadShaderIndexUnknown,
xenos::XE_GPU_TEXTURE_SWIZZLE_RGGG},
// k_16_16_16_16 // k_16_16_16_16
{DXGI_FORMAT_R16G16B16A16_TYPELESS, DXGI_FORMAT_R16G16B16A16_UNORM, {DXGI_FORMAT_R16G16B16A16_TYPELESS, DXGI_FORMAT_R16G16B16A16_UNORM,
LoadMode::k64bpb, DXGI_FORMAT_R16G16B16A16_SNORM, LoadMode::kUnknown, kLoadShaderIndex64bpb, DXGI_FORMAT_R16G16B16A16_SNORM,
false, DXGI_FORMAT_UNKNOWN, LoadMode::kUnknown, kLoadShaderIndexUnknown, false, DXGI_FORMAT_UNKNOWN,
xenos::XE_GPU_TEXTURE_SWIZZLE_RGBA}, kLoadShaderIndexUnknown, xenos::XE_GPU_TEXTURE_SWIZZLE_RGBA},
// k_16_EXPAND // k_16_EXPAND
{DXGI_FORMAT_R16_FLOAT, DXGI_FORMAT_R16_FLOAT, LoadMode::k16bpb, {DXGI_FORMAT_R16_FLOAT, DXGI_FORMAT_R16_FLOAT, kLoadShaderIndex16bpb,
DXGI_FORMAT_R16_FLOAT, LoadMode::kUnknown, false, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_R16_FLOAT, kLoadShaderIndexUnknown, false, DXGI_FORMAT_UNKNOWN,
LoadMode::kUnknown, xenos::XE_GPU_TEXTURE_SWIZZLE_RRRR}, kLoadShaderIndexUnknown, xenos::XE_GPU_TEXTURE_SWIZZLE_RRRR},
// k_16_16_EXPAND // k_16_16_EXPAND
{DXGI_FORMAT_R16G16_FLOAT, DXGI_FORMAT_R16G16_FLOAT, LoadMode::k32bpb, {DXGI_FORMAT_R16G16_FLOAT, DXGI_FORMAT_R16G16_FLOAT, kLoadShaderIndex32bpb,
DXGI_FORMAT_R16G16_FLOAT, LoadMode::kUnknown, false, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_R16G16_FLOAT, kLoadShaderIndexUnknown, false,
LoadMode::kUnknown, xenos::XE_GPU_TEXTURE_SWIZZLE_RGGG}, DXGI_FORMAT_UNKNOWN, kLoadShaderIndexUnknown,
xenos::XE_GPU_TEXTURE_SWIZZLE_RGGG},
// k_16_16_16_16_EXPAND // k_16_16_16_16_EXPAND
{DXGI_FORMAT_R16G16B16A16_FLOAT, DXGI_FORMAT_R16G16B16A16_FLOAT, {DXGI_FORMAT_R16G16B16A16_FLOAT, DXGI_FORMAT_R16G16B16A16_FLOAT,
LoadMode::k64bpb, DXGI_FORMAT_R16G16B16A16_FLOAT, LoadMode::kUnknown, kLoadShaderIndex64bpb, DXGI_FORMAT_R16G16B16A16_FLOAT,
false, DXGI_FORMAT_UNKNOWN, LoadMode::kUnknown, kLoadShaderIndexUnknown, false, DXGI_FORMAT_UNKNOWN,
xenos::XE_GPU_TEXTURE_SWIZZLE_RGBA}, kLoadShaderIndexUnknown, xenos::XE_GPU_TEXTURE_SWIZZLE_RGBA},
// k_16_FLOAT // k_16_FLOAT
{DXGI_FORMAT_R16_FLOAT, DXGI_FORMAT_R16_FLOAT, LoadMode::k16bpb, {DXGI_FORMAT_R16_FLOAT, DXGI_FORMAT_R16_FLOAT, kLoadShaderIndex16bpb,
DXGI_FORMAT_R16_FLOAT, LoadMode::kUnknown, false, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_R16_FLOAT, kLoadShaderIndexUnknown, false, DXGI_FORMAT_UNKNOWN,
LoadMode::kUnknown, xenos::XE_GPU_TEXTURE_SWIZZLE_RRRR}, kLoadShaderIndexUnknown, xenos::XE_GPU_TEXTURE_SWIZZLE_RRRR},
// k_16_16_FLOAT // k_16_16_FLOAT
{DXGI_FORMAT_R16G16_FLOAT, DXGI_FORMAT_R16G16_FLOAT, LoadMode::k32bpb, {DXGI_FORMAT_R16G16_FLOAT, DXGI_FORMAT_R16G16_FLOAT, kLoadShaderIndex32bpb,
DXGI_FORMAT_R16G16_FLOAT, LoadMode::kUnknown, false, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_R16G16_FLOAT, kLoadShaderIndexUnknown, false,
LoadMode::kUnknown, xenos::XE_GPU_TEXTURE_SWIZZLE_RGGG}, DXGI_FORMAT_UNKNOWN, kLoadShaderIndexUnknown,
xenos::XE_GPU_TEXTURE_SWIZZLE_RGGG},
// k_16_16_16_16_FLOAT // k_16_16_16_16_FLOAT
{DXGI_FORMAT_R16G16B16A16_FLOAT, DXGI_FORMAT_R16G16B16A16_FLOAT, {DXGI_FORMAT_R16G16B16A16_FLOAT, DXGI_FORMAT_R16G16B16A16_FLOAT,
LoadMode::k64bpb, DXGI_FORMAT_R16G16B16A16_FLOAT, LoadMode::kUnknown, kLoadShaderIndex64bpb, DXGI_FORMAT_R16G16B16A16_FLOAT,
false, DXGI_FORMAT_UNKNOWN, LoadMode::kUnknown, kLoadShaderIndexUnknown, false, DXGI_FORMAT_UNKNOWN,
xenos::XE_GPU_TEXTURE_SWIZZLE_RGBA}, kLoadShaderIndexUnknown, xenos::XE_GPU_TEXTURE_SWIZZLE_RGBA},
// k_32 // k_32
{DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, LoadMode::kUnknown, {DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, kLoadShaderIndexUnknown,
DXGI_FORMAT_UNKNOWN, LoadMode::kUnknown, false, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, kLoadShaderIndexUnknown, false, DXGI_FORMAT_UNKNOWN,
LoadMode::kUnknown, xenos::XE_GPU_TEXTURE_SWIZZLE_RRRR}, kLoadShaderIndexUnknown, xenos::XE_GPU_TEXTURE_SWIZZLE_RRRR},
// k_32_32 // k_32_32
{DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, LoadMode::kUnknown, {DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, kLoadShaderIndexUnknown,
DXGI_FORMAT_UNKNOWN, LoadMode::kUnknown, false, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, kLoadShaderIndexUnknown, false, DXGI_FORMAT_UNKNOWN,
LoadMode::kUnknown, xenos::XE_GPU_TEXTURE_SWIZZLE_RGGG}, kLoadShaderIndexUnknown, xenos::XE_GPU_TEXTURE_SWIZZLE_RGGG},
// k_32_32_32_32 // k_32_32_32_32
{DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, LoadMode::kUnknown, {DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, kLoadShaderIndexUnknown,
DXGI_FORMAT_UNKNOWN, LoadMode::kUnknown, false, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, kLoadShaderIndexUnknown, false, DXGI_FORMAT_UNKNOWN,
LoadMode::kUnknown, xenos::XE_GPU_TEXTURE_SWIZZLE_RGBA}, kLoadShaderIndexUnknown, xenos::XE_GPU_TEXTURE_SWIZZLE_RGBA},
// k_32_FLOAT // k_32_FLOAT
{DXGI_FORMAT_R32_FLOAT, DXGI_FORMAT_R32_FLOAT, LoadMode::k32bpb, {DXGI_FORMAT_R32_FLOAT, DXGI_FORMAT_R32_FLOAT, kLoadShaderIndex32bpb,
DXGI_FORMAT_R32_FLOAT, LoadMode::kUnknown, false, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_R32_FLOAT, kLoadShaderIndexUnknown, false, DXGI_FORMAT_UNKNOWN,
LoadMode::kUnknown, xenos::XE_GPU_TEXTURE_SWIZZLE_RRRR}, kLoadShaderIndexUnknown, xenos::XE_GPU_TEXTURE_SWIZZLE_RRRR},
// k_32_32_FLOAT // k_32_32_FLOAT
{DXGI_FORMAT_R32G32_FLOAT, DXGI_FORMAT_R32G32_FLOAT, LoadMode::k64bpb, {DXGI_FORMAT_R32G32_FLOAT, DXGI_FORMAT_R32G32_FLOAT, kLoadShaderIndex64bpb,
DXGI_FORMAT_R32G32_FLOAT, LoadMode::kUnknown, false, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_R32G32_FLOAT, kLoadShaderIndexUnknown, false,
LoadMode::kUnknown, xenos::XE_GPU_TEXTURE_SWIZZLE_RGGG}, DXGI_FORMAT_UNKNOWN, kLoadShaderIndexUnknown,
xenos::XE_GPU_TEXTURE_SWIZZLE_RGGG},
// k_32_32_32_32_FLOAT // k_32_32_32_32_FLOAT
{DXGI_FORMAT_R32G32B32A32_FLOAT, DXGI_FORMAT_R32G32B32A32_FLOAT, {DXGI_FORMAT_R32G32B32A32_FLOAT, DXGI_FORMAT_R32G32B32A32_FLOAT,
LoadMode::k128bpb, DXGI_FORMAT_R32G32B32A32_FLOAT, LoadMode::kUnknown, kLoadShaderIndex128bpb, DXGI_FORMAT_R32G32B32A32_FLOAT,
false, DXGI_FORMAT_UNKNOWN, LoadMode::kUnknown, kLoadShaderIndexUnknown, false, DXGI_FORMAT_UNKNOWN,
xenos::XE_GPU_TEXTURE_SWIZZLE_RGBA}, kLoadShaderIndexUnknown, xenos::XE_GPU_TEXTURE_SWIZZLE_RGBA},
// k_32_AS_8 // k_32_AS_8
{DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, LoadMode::kUnknown, {DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, kLoadShaderIndexUnknown,
DXGI_FORMAT_UNKNOWN, LoadMode::kUnknown, false, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, kLoadShaderIndexUnknown, false, DXGI_FORMAT_UNKNOWN,
LoadMode::kUnknown, xenos::XE_GPU_TEXTURE_SWIZZLE_RRRR}, kLoadShaderIndexUnknown, xenos::XE_GPU_TEXTURE_SWIZZLE_RRRR},
// k_32_AS_8_8 // k_32_AS_8_8
{DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, LoadMode::kUnknown, {DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, kLoadShaderIndexUnknown,
DXGI_FORMAT_UNKNOWN, LoadMode::kUnknown, false, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, kLoadShaderIndexUnknown, false, DXGI_FORMAT_UNKNOWN,
LoadMode::kUnknown, xenos::XE_GPU_TEXTURE_SWIZZLE_RGGG}, kLoadShaderIndexUnknown, xenos::XE_GPU_TEXTURE_SWIZZLE_RGGG},
// k_16_MPEG // k_16_MPEG
{DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, LoadMode::kUnknown, {DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, kLoadShaderIndexUnknown,
DXGI_FORMAT_UNKNOWN, LoadMode::kUnknown, false, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, kLoadShaderIndexUnknown, false, DXGI_FORMAT_UNKNOWN,
LoadMode::kUnknown, xenos::XE_GPU_TEXTURE_SWIZZLE_RRRR}, kLoadShaderIndexUnknown, xenos::XE_GPU_TEXTURE_SWIZZLE_RRRR},
// k_16_16_MPEG // k_16_16_MPEG
{DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, LoadMode::kUnknown, {DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, kLoadShaderIndexUnknown,
DXGI_FORMAT_UNKNOWN, LoadMode::kUnknown, false, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, kLoadShaderIndexUnknown, false, DXGI_FORMAT_UNKNOWN,
LoadMode::kUnknown, xenos::XE_GPU_TEXTURE_SWIZZLE_RGGG}, kLoadShaderIndexUnknown, xenos::XE_GPU_TEXTURE_SWIZZLE_RGGG},
// k_8_INTERLACED // k_8_INTERLACED
{DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, LoadMode::kUnknown, {DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, kLoadShaderIndexUnknown,
DXGI_FORMAT_UNKNOWN, LoadMode::kUnknown, false, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, kLoadShaderIndexUnknown, false, DXGI_FORMAT_UNKNOWN,
LoadMode::kUnknown, xenos::XE_GPU_TEXTURE_SWIZZLE_RRRR}, kLoadShaderIndexUnknown, xenos::XE_GPU_TEXTURE_SWIZZLE_RRRR},
// k_32_AS_8_INTERLACED // k_32_AS_8_INTERLACED
{DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, LoadMode::kUnknown, {DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, kLoadShaderIndexUnknown,
DXGI_FORMAT_UNKNOWN, LoadMode::kUnknown, false, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, kLoadShaderIndexUnknown, false, DXGI_FORMAT_UNKNOWN,
LoadMode::kUnknown, xenos::XE_GPU_TEXTURE_SWIZZLE_RRRR}, kLoadShaderIndexUnknown, xenos::XE_GPU_TEXTURE_SWIZZLE_RRRR},
// k_32_AS_8_8_INTERLACED // k_32_AS_8_8_INTERLACED
{DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, LoadMode::kUnknown, {DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, kLoadShaderIndexUnknown,
DXGI_FORMAT_UNKNOWN, LoadMode::kUnknown, false, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, kLoadShaderIndexUnknown, false, DXGI_FORMAT_UNKNOWN,
LoadMode::kUnknown, xenos::XE_GPU_TEXTURE_SWIZZLE_RGGG}, kLoadShaderIndexUnknown, xenos::XE_GPU_TEXTURE_SWIZZLE_RGGG},
// k_16_INTERLACED // k_16_INTERLACED
{DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, LoadMode::kUnknown, {DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, kLoadShaderIndexUnknown,
DXGI_FORMAT_UNKNOWN, LoadMode::kUnknown, false, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, kLoadShaderIndexUnknown, false, DXGI_FORMAT_UNKNOWN,
LoadMode::kUnknown, xenos::XE_GPU_TEXTURE_SWIZZLE_RRRR}, kLoadShaderIndexUnknown, xenos::XE_GPU_TEXTURE_SWIZZLE_RRRR},
// k_16_MPEG_INTERLACED // k_16_MPEG_INTERLACED
{DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, LoadMode::kUnknown, {DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, kLoadShaderIndexUnknown,
DXGI_FORMAT_UNKNOWN, LoadMode::kUnknown, false, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, kLoadShaderIndexUnknown, false, DXGI_FORMAT_UNKNOWN,
LoadMode::kUnknown, xenos::XE_GPU_TEXTURE_SWIZZLE_RRRR}, kLoadShaderIndexUnknown, xenos::XE_GPU_TEXTURE_SWIZZLE_RRRR},
// k_16_16_MPEG_INTERLACED // k_16_16_MPEG_INTERLACED
{DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, LoadMode::kUnknown, {DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, kLoadShaderIndexUnknown,
DXGI_FORMAT_UNKNOWN, LoadMode::kUnknown, false, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, kLoadShaderIndexUnknown, false, DXGI_FORMAT_UNKNOWN,
LoadMode::kUnknown, xenos::XE_GPU_TEXTURE_SWIZZLE_RGGG}, kLoadShaderIndexUnknown, xenos::XE_GPU_TEXTURE_SWIZZLE_RGGG},
// k_DXN // k_DXN
{DXGI_FORMAT_BC5_UNORM, DXGI_FORMAT_BC5_UNORM, LoadMode::k128bpb, {DXGI_FORMAT_BC5_UNORM, DXGI_FORMAT_BC5_UNORM, kLoadShaderIndex128bpb,
DXGI_FORMAT_UNKNOWN, LoadMode::kUnknown, true, DXGI_FORMAT_R8G8_UNORM, DXGI_FORMAT_UNKNOWN, kLoadShaderIndexUnknown, true, DXGI_FORMAT_R8G8_UNORM,
LoadMode::kDXNToRG8, xenos::XE_GPU_TEXTURE_SWIZZLE_RGGG}, kLoadShaderIndexDXNToRG8, xenos::XE_GPU_TEXTURE_SWIZZLE_RGGG},
// k_8_8_8_8_AS_16_16_16_16 // k_8_8_8_8_AS_16_16_16_16
{DXGI_FORMAT_R8G8B8A8_TYPELESS, DXGI_FORMAT_R8G8B8A8_UNORM, {DXGI_FORMAT_R8G8B8A8_TYPELESS, DXGI_FORMAT_R8G8B8A8_UNORM,
LoadMode::k32bpb, DXGI_FORMAT_R8G8B8A8_SNORM, LoadMode::kUnknown, false, kLoadShaderIndex32bpb, DXGI_FORMAT_R8G8B8A8_SNORM, kLoadShaderIndexUnknown,
DXGI_FORMAT_UNKNOWN, LoadMode::kUnknown, false, DXGI_FORMAT_UNKNOWN, kLoadShaderIndexUnknown,
xenos::XE_GPU_TEXTURE_SWIZZLE_RGBA}, xenos::XE_GPU_TEXTURE_SWIZZLE_RGBA},
// k_DXT1_AS_16_16_16_16 // k_DXT1_AS_16_16_16_16
{DXGI_FORMAT_BC1_UNORM, DXGI_FORMAT_BC1_UNORM, LoadMode::k64bpb, {DXGI_FORMAT_BC1_UNORM, DXGI_FORMAT_BC1_UNORM, kLoadShaderIndex64bpb,
DXGI_FORMAT_UNKNOWN, LoadMode::kUnknown, true, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_UNKNOWN, kLoadShaderIndexUnknown, true,
LoadMode::kDXT1ToRGBA8, xenos::XE_GPU_TEXTURE_SWIZZLE_RGBA}, DXGI_FORMAT_R8G8B8A8_UNORM, kLoadShaderIndexDXT1ToRGBA8,
xenos::XE_GPU_TEXTURE_SWIZZLE_RGBA},
// k_DXT2_3_AS_16_16_16_16 // k_DXT2_3_AS_16_16_16_16
{DXGI_FORMAT_BC2_UNORM, DXGI_FORMAT_BC2_UNORM, LoadMode::k128bpb, {DXGI_FORMAT_BC2_UNORM, DXGI_FORMAT_BC2_UNORM, kLoadShaderIndex128bpb,
DXGI_FORMAT_UNKNOWN, LoadMode::kUnknown, true, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_UNKNOWN, kLoadShaderIndexUnknown, true,
LoadMode::kDXT3ToRGBA8, xenos::XE_GPU_TEXTURE_SWIZZLE_RGBA}, DXGI_FORMAT_R8G8B8A8_UNORM, kLoadShaderIndexDXT3ToRGBA8,
xenos::XE_GPU_TEXTURE_SWIZZLE_RGBA},
// k_DXT4_5_AS_16_16_16_16 // k_DXT4_5_AS_16_16_16_16
{DXGI_FORMAT_BC3_UNORM, DXGI_FORMAT_BC3_UNORM, LoadMode::k128bpb, {DXGI_FORMAT_BC3_UNORM, DXGI_FORMAT_BC3_UNORM, kLoadShaderIndex128bpb,
DXGI_FORMAT_UNKNOWN, LoadMode::kUnknown, true, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_UNKNOWN, kLoadShaderIndexUnknown, true,
LoadMode::kDXT5ToRGBA8, xenos::XE_GPU_TEXTURE_SWIZZLE_RGBA}, DXGI_FORMAT_R8G8B8A8_UNORM, kLoadShaderIndexDXT5ToRGBA8,
xenos::XE_GPU_TEXTURE_SWIZZLE_RGBA},
// k_2_10_10_10_AS_16_16_16_16 // k_2_10_10_10_AS_16_16_16_16
{DXGI_FORMAT_R10G10B10A2_UNORM, DXGI_FORMAT_R10G10B10A2_UNORM, {DXGI_FORMAT_R10G10B10A2_UNORM, DXGI_FORMAT_R10G10B10A2_UNORM,
LoadMode::k32bpb, DXGI_FORMAT_UNKNOWN, LoadMode::kUnknown, false, kLoadShaderIndex32bpb, DXGI_FORMAT_UNKNOWN, kLoadShaderIndexUnknown, false,
DXGI_FORMAT_UNKNOWN, LoadMode::kUnknown, DXGI_FORMAT_UNKNOWN, kLoadShaderIndexUnknown,
xenos::XE_GPU_TEXTURE_SWIZZLE_RGBA}, xenos::XE_GPU_TEXTURE_SWIZZLE_RGBA},
// k_10_11_11_AS_16_16_16_16 // k_10_11_11_AS_16_16_16_16
{DXGI_FORMAT_R16G16B16A16_TYPELESS, DXGI_FORMAT_R16G16B16A16_UNORM, {DXGI_FORMAT_R16G16B16A16_TYPELESS, DXGI_FORMAT_R16G16B16A16_UNORM,
LoadMode::kR11G11B10ToRGBA16, DXGI_FORMAT_R16G16B16A16_SNORM, kLoadShaderIndexR11G11B10ToRGBA16, DXGI_FORMAT_R16G16B16A16_SNORM,
LoadMode::kR11G11B10ToRGBA16SNorm, false, DXGI_FORMAT_UNKNOWN, kLoadShaderIndexR11G11B10ToRGBA16SNorm, false, DXGI_FORMAT_UNKNOWN,
LoadMode::kUnknown, xenos::XE_GPU_TEXTURE_SWIZZLE_RGBB}, kLoadShaderIndexUnknown, xenos::XE_GPU_TEXTURE_SWIZZLE_RGBB},
// k_11_11_10_AS_16_16_16_16 // k_11_11_10_AS_16_16_16_16
{DXGI_FORMAT_R16G16B16A16_TYPELESS, DXGI_FORMAT_R16G16B16A16_UNORM, {DXGI_FORMAT_R16G16B16A16_TYPELESS, DXGI_FORMAT_R16G16B16A16_UNORM,
LoadMode::kR10G11B11ToRGBA16, DXGI_FORMAT_R16G16B16A16_SNORM, kLoadShaderIndexR10G11B11ToRGBA16, DXGI_FORMAT_R16G16B16A16_SNORM,
LoadMode::kR10G11B11ToRGBA16SNorm, false, DXGI_FORMAT_UNKNOWN, kLoadShaderIndexR10G11B11ToRGBA16SNorm, false, DXGI_FORMAT_UNKNOWN,
LoadMode::kUnknown, xenos::XE_GPU_TEXTURE_SWIZZLE_RGBB}, kLoadShaderIndexUnknown, xenos::XE_GPU_TEXTURE_SWIZZLE_RGBB},
// k_32_32_32_FLOAT // k_32_32_32_FLOAT
{DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, LoadMode::kUnknown, {DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, kLoadShaderIndexUnknown,
DXGI_FORMAT_UNKNOWN, LoadMode::kUnknown, false, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, kLoadShaderIndexUnknown, false, DXGI_FORMAT_UNKNOWN,
LoadMode::kUnknown, xenos::XE_GPU_TEXTURE_SWIZZLE_RGBB}, kLoadShaderIndexUnknown, xenos::XE_GPU_TEXTURE_SWIZZLE_RGBB},
// k_DXT3A // k_DXT3A
// R8_UNORM has the same size as BC2, but doesn't have the 4x4 size // R8_UNORM has the same size as BC2, but doesn't have the 4x4 size
// alignment requirement. // alignment requirement.
{DXGI_FORMAT_R8_UNORM, DXGI_FORMAT_R8_UNORM, LoadMode::kDXT3A, {DXGI_FORMAT_R8_UNORM, DXGI_FORMAT_R8_UNORM, kLoadShaderIndexDXT3A,
DXGI_FORMAT_UNKNOWN, LoadMode::kUnknown, false, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, kLoadShaderIndexUnknown, false, DXGI_FORMAT_UNKNOWN,
LoadMode::kUnknown, xenos::XE_GPU_TEXTURE_SWIZZLE_RRRR}, kLoadShaderIndexUnknown, xenos::XE_GPU_TEXTURE_SWIZZLE_RRRR},
// k_DXT5A // k_DXT5A
{DXGI_FORMAT_BC4_UNORM, DXGI_FORMAT_BC4_UNORM, LoadMode::k64bpb, {DXGI_FORMAT_BC4_UNORM, DXGI_FORMAT_BC4_UNORM, kLoadShaderIndex64bpb,
DXGI_FORMAT_UNKNOWN, LoadMode::kUnknown, true, DXGI_FORMAT_R8_UNORM, DXGI_FORMAT_UNKNOWN, kLoadShaderIndexUnknown, true, DXGI_FORMAT_R8_UNORM,
LoadMode::kDXT5AToR8, xenos::XE_GPU_TEXTURE_SWIZZLE_RRRR}, kLoadShaderIndexDXT5AToR8, xenos::XE_GPU_TEXTURE_SWIZZLE_RRRR},
// k_CTX1 // k_CTX1
{DXGI_FORMAT_R8G8_UNORM, DXGI_FORMAT_R8G8_UNORM, LoadMode::kCTX1, {DXGI_FORMAT_R8G8_UNORM, DXGI_FORMAT_R8G8_UNORM, kLoadShaderIndexCTX1,
DXGI_FORMAT_UNKNOWN, LoadMode::kUnknown, false, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, kLoadShaderIndexUnknown, false, DXGI_FORMAT_UNKNOWN,
LoadMode::kUnknown, xenos::XE_GPU_TEXTURE_SWIZZLE_RGGG}, kLoadShaderIndexUnknown, xenos::XE_GPU_TEXTURE_SWIZZLE_RGGG},
// k_DXT3A_AS_1_1_1_1 // k_DXT3A_AS_1_1_1_1
{DXGI_FORMAT_B4G4R4A4_UNORM, DXGI_FORMAT_B4G4R4A4_UNORM, {DXGI_FORMAT_B4G4R4A4_UNORM, DXGI_FORMAT_B4G4R4A4_UNORM,
LoadMode::kDXT3AAs1111ToBGRA4, DXGI_FORMAT_UNKNOWN, LoadMode::kUnknown, kLoadShaderIndexDXT3AAs1111ToBGRA4, DXGI_FORMAT_UNKNOWN,
false, DXGI_FORMAT_UNKNOWN, LoadMode::kUnknown, kLoadShaderIndexUnknown, false, DXGI_FORMAT_UNKNOWN,
xenos::XE_GPU_TEXTURE_SWIZZLE_RGBA}, kLoadShaderIndexUnknown, xenos::XE_GPU_TEXTURE_SWIZZLE_RGBA},
// k_8_8_8_8_GAMMA_EDRAM // k_8_8_8_8_GAMMA_EDRAM
// Not usable as a texture. // Not usable as a texture.
{DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, LoadMode::kUnknown, {DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, kLoadShaderIndexUnknown,
DXGI_FORMAT_UNKNOWN, LoadMode::kUnknown, false, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, kLoadShaderIndexUnknown, false, DXGI_FORMAT_UNKNOWN,
LoadMode::kUnknown, xenos::XE_GPU_TEXTURE_SWIZZLE_RGBA}, kLoadShaderIndexUnknown, xenos::XE_GPU_TEXTURE_SWIZZLE_RGBA},
// k_2_10_10_10_FLOAT_EDRAM // k_2_10_10_10_FLOAT_EDRAM
// Not usable as a texture. // Not usable as a texture.
{DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, LoadMode::kUnknown, {DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, kLoadShaderIndexUnknown,
DXGI_FORMAT_UNKNOWN, LoadMode::kUnknown, false, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, kLoadShaderIndexUnknown, false, DXGI_FORMAT_UNKNOWN,
LoadMode::kUnknown, xenos::XE_GPU_TEXTURE_SWIZZLE_RGBA}, kLoadShaderIndexUnknown, xenos::XE_GPU_TEXTURE_SWIZZLE_RGBA},
};
const D3D12TextureCache::LoadModeInfo D3D12TextureCache::load_mode_info_[] = {
{shaders::texture_load_8bpb_cs, sizeof(shaders::texture_load_8bpb_cs),
shaders::texture_load_8bpb_scaled_cs,
sizeof(shaders::texture_load_8bpb_scaled_cs), 3, 4, 1, 4},
{shaders::texture_load_16bpb_cs, sizeof(shaders::texture_load_16bpb_cs),
shaders::texture_load_16bpb_scaled_cs,
sizeof(shaders::texture_load_16bpb_scaled_cs), 4, 4, 2, 4},
{shaders::texture_load_32bpb_cs, sizeof(shaders::texture_load_32bpb_cs),
shaders::texture_load_32bpb_scaled_cs,
sizeof(shaders::texture_load_32bpb_scaled_cs), 4, 4, 4, 3},
{shaders::texture_load_64bpb_cs, sizeof(shaders::texture_load_64bpb_cs),
shaders::texture_load_64bpb_scaled_cs,
sizeof(shaders::texture_load_64bpb_scaled_cs), 4, 4, 8, 2},
{shaders::texture_load_128bpb_cs, sizeof(shaders::texture_load_128bpb_cs),
shaders::texture_load_128bpb_scaled_cs,
sizeof(shaders::texture_load_128bpb_scaled_cs), 4, 4, 16, 1},
{shaders::texture_load_r5g5b5a1_b5g5r5a1_cs,
sizeof(shaders::texture_load_r5g5b5a1_b5g5r5a1_cs),
shaders::texture_load_r5g5b5a1_b5g5r5a1_scaled_cs,
sizeof(shaders::texture_load_r5g5b5a1_b5g5r5a1_scaled_cs), 4, 4, 2, 4},
{shaders::texture_load_r5g6b5_b5g6r5_cs,
sizeof(shaders::texture_load_r5g6b5_b5g6r5_cs),
shaders::texture_load_r5g6b5_b5g6r5_scaled_cs,
sizeof(shaders::texture_load_r5g6b5_b5g6r5_scaled_cs), 4, 4, 2, 4},
{shaders::texture_load_r5g5b6_b5g6r5_swizzle_rbga_cs,
sizeof(shaders::texture_load_r5g5b6_b5g6r5_swizzle_rbga_cs),
shaders::texture_load_r5g5b6_b5g6r5_swizzle_rbga_scaled_cs,
sizeof(shaders::texture_load_r5g5b6_b5g6r5_swizzle_rbga_scaled_cs), 4, 4,
2, 4},
{shaders::texture_load_r4g4b4a4_b4g4r4a4_cs,
sizeof(shaders::texture_load_r4g4b4a4_b4g4r4a4_cs),
shaders::texture_load_r4g4b4a4_b4g4r4a4_scaled_cs,
sizeof(shaders::texture_load_r4g4b4a4_b4g4r4a4_scaled_cs), 4, 4, 2, 4},
{shaders::texture_load_gbgr8_grgb8_cs,
sizeof(shaders::texture_load_gbgr8_grgb8_cs), nullptr, 0, 4, 4, 4, 3},
{shaders::texture_load_gbgr8_rgb8_cs,
sizeof(shaders::texture_load_gbgr8_rgb8_cs), nullptr, 0, 4, 4, 8, 3},
{shaders::texture_load_bgrg8_rgbg8_cs,
sizeof(shaders::texture_load_bgrg8_rgbg8_cs), nullptr, 0, 4, 4, 4, 3},
{shaders::texture_load_bgrg8_rgb8_cs,
sizeof(shaders::texture_load_bgrg8_rgb8_cs), nullptr, 0, 4, 4, 8, 3},
{shaders::texture_load_r10g11b11_rgba16_cs,
sizeof(shaders::texture_load_r10g11b11_rgba16_cs),
shaders::texture_load_r10g11b11_rgba16_scaled_cs,
sizeof(shaders::texture_load_r10g11b11_rgba16_scaled_cs), 4, 4, 8, 3},
{shaders::texture_load_r10g11b11_rgba16_snorm_cs,
sizeof(shaders::texture_load_r10g11b11_rgba16_snorm_cs),
shaders::texture_load_r10g11b11_rgba16_snorm_scaled_cs,
sizeof(shaders::texture_load_r10g11b11_rgba16_snorm_scaled_cs), 4, 4, 8,
3},
{shaders::texture_load_r11g11b10_rgba16_cs,
sizeof(shaders::texture_load_r11g11b10_rgba16_cs),
shaders::texture_load_r11g11b10_rgba16_scaled_cs,
sizeof(shaders::texture_load_r11g11b10_rgba16_scaled_cs), 4, 4, 8, 3},
{shaders::texture_load_r11g11b10_rgba16_snorm_cs,
sizeof(shaders::texture_load_r11g11b10_rgba16_snorm_cs),
shaders::texture_load_r11g11b10_rgba16_snorm_scaled_cs,
sizeof(shaders::texture_load_r11g11b10_rgba16_snorm_scaled_cs), 4, 4, 8,
3},
{shaders::texture_load_dxt1_rgba8_cs,
sizeof(shaders::texture_load_dxt1_rgba8_cs), nullptr, 0, 4, 4, 4, 2},
{shaders::texture_load_dxt3_rgba8_cs,
sizeof(shaders::texture_load_dxt3_rgba8_cs), nullptr, 0, 4, 4, 4, 1},
{shaders::texture_load_dxt5_rgba8_cs,
sizeof(shaders::texture_load_dxt5_rgba8_cs), nullptr, 0, 4, 4, 4, 1},
{shaders::texture_load_dxn_rg8_cs, sizeof(shaders::texture_load_dxn_rg8_cs),
nullptr, 0, 4, 4, 2, 1},
{shaders::texture_load_dxt3a_cs, sizeof(shaders::texture_load_dxt3a_cs),
nullptr, 0, 4, 4, 1, 2},
{shaders::texture_load_dxt3aas1111_bgra4_cs,
sizeof(shaders::texture_load_dxt3aas1111_bgra4_cs), nullptr, 0, 4, 4, 2,
2},
{shaders::texture_load_dxt5a_r8_cs,
sizeof(shaders::texture_load_dxt5a_r8_cs), nullptr, 0, 4, 4, 1, 2},
{shaders::texture_load_ctx1_cs, sizeof(shaders::texture_load_ctx1_cs),
nullptr, 0, 4, 4, 2, 2},
{shaders::texture_load_depth_unorm_cs,
sizeof(shaders::texture_load_depth_unorm_cs),
shaders::texture_load_depth_unorm_scaled_cs,
sizeof(shaders::texture_load_depth_unorm_scaled_cs), 4, 4, 4, 3},
{shaders::texture_load_depth_float_cs,
sizeof(shaders::texture_load_depth_float_cs),
shaders::texture_load_depth_float_scaled_cs,
sizeof(shaders::texture_load_depth_float_scaled_cs), 4, 4, 4, 3},
}; };
D3D12TextureCache::D3D12TextureCache(const RegisterFile& register_file, D3D12TextureCache::D3D12TextureCache(const RegisterFile& register_file,
@ -551,31 +476,176 @@ bool D3D12TextureCache::Initialize() {
return false; return false;
} }
// Specify the load shader code.
D3D12_SHADER_BYTECODE load_shader_code[kLoadShaderCount] = {};
load_shader_code[kLoadShaderIndex8bpb] = D3D12_SHADER_BYTECODE{
shaders::texture_load_8bpb_cs, sizeof(shaders::texture_load_8bpb_cs)};
load_shader_code[kLoadShaderIndex16bpb] = D3D12_SHADER_BYTECODE{
shaders::texture_load_16bpb_cs, sizeof(shaders::texture_load_16bpb_cs)};
load_shader_code[kLoadShaderIndex32bpb] = D3D12_SHADER_BYTECODE{
shaders::texture_load_32bpb_cs, sizeof(shaders::texture_load_32bpb_cs)};
load_shader_code[kLoadShaderIndex64bpb] = D3D12_SHADER_BYTECODE{
shaders::texture_load_64bpb_cs, sizeof(shaders::texture_load_64bpb_cs)};
load_shader_code[kLoadShaderIndex128bpb] = D3D12_SHADER_BYTECODE{
shaders::texture_load_128bpb_cs, sizeof(shaders::texture_load_128bpb_cs)};
load_shader_code[kLoadShaderIndexR5G5B5A1ToB5G5R5A1] =
D3D12_SHADER_BYTECODE{shaders::texture_load_r5g5b5a1_b5g5r5a1_cs,
sizeof(shaders::texture_load_r5g5b5a1_b5g5r5a1_cs)};
load_shader_code[kLoadShaderIndexR5G6B5ToB5G6R5] =
D3D12_SHADER_BYTECODE{shaders::texture_load_r5g6b5_b5g6r5_cs,
sizeof(shaders::texture_load_r5g6b5_b5g6r5_cs)};
load_shader_code[kLoadShaderIndexR5G5B6ToB5G6R5WithRBGASwizzle] =
D3D12_SHADER_BYTECODE{
shaders::texture_load_r5g5b6_b5g6r5_swizzle_rbga_cs,
sizeof(shaders::texture_load_r5g5b6_b5g6r5_swizzle_rbga_cs)};
load_shader_code[kLoadShaderIndexRGBA4ToBGRA4] =
D3D12_SHADER_BYTECODE{shaders::texture_load_r4g4b4a4_b4g4r4a4_cs,
sizeof(shaders::texture_load_r4g4b4a4_b4g4r4a4_cs)};
load_shader_code[kLoadShaderIndexGBGR8ToGRGB8] =
D3D12_SHADER_BYTECODE{shaders::texture_load_gbgr8_grgb8_cs,
sizeof(shaders::texture_load_gbgr8_grgb8_cs)};
load_shader_code[kLoadShaderIndexGBGR8ToRGB8] =
D3D12_SHADER_BYTECODE{shaders::texture_load_gbgr8_rgb8_cs,
sizeof(shaders::texture_load_gbgr8_rgb8_cs)};
load_shader_code[kLoadShaderIndexBGRG8ToRGBG8] =
D3D12_SHADER_BYTECODE{shaders::texture_load_bgrg8_rgbg8_cs,
sizeof(shaders::texture_load_bgrg8_rgbg8_cs)};
load_shader_code[kLoadShaderIndexBGRG8ToRGB8] =
D3D12_SHADER_BYTECODE{shaders::texture_load_bgrg8_rgb8_cs,
sizeof(shaders::texture_load_bgrg8_rgb8_cs)};
load_shader_code[kLoadShaderIndexR10G11B11ToRGBA16] =
D3D12_SHADER_BYTECODE{shaders::texture_load_r10g11b11_rgba16_cs,
sizeof(shaders::texture_load_r10g11b11_rgba16_cs)};
load_shader_code[kLoadShaderIndexR10G11B11ToRGBA16SNorm] =
D3D12_SHADER_BYTECODE{
shaders::texture_load_r10g11b11_rgba16_snorm_cs,
sizeof(shaders::texture_load_r10g11b11_rgba16_snorm_cs)};
load_shader_code[kLoadShaderIndexR11G11B10ToRGBA16] =
D3D12_SHADER_BYTECODE{shaders::texture_load_r11g11b10_rgba16_cs,
sizeof(shaders::texture_load_r11g11b10_rgba16_cs)};
load_shader_code[kLoadShaderIndexR11G11B10ToRGBA16SNorm] =
D3D12_SHADER_BYTECODE{
shaders::texture_load_r11g11b10_rgba16_snorm_cs,
sizeof(shaders::texture_load_r11g11b10_rgba16_snorm_cs)};
load_shader_code[kLoadShaderIndexDXT1ToRGBA8] =
D3D12_SHADER_BYTECODE{shaders::texture_load_dxt1_rgba8_cs,
sizeof(shaders::texture_load_dxt1_rgba8_cs)};
load_shader_code[kLoadShaderIndexDXT3ToRGBA8] =
D3D12_SHADER_BYTECODE{shaders::texture_load_dxt3_rgba8_cs,
sizeof(shaders::texture_load_dxt3_rgba8_cs)};
load_shader_code[kLoadShaderIndexDXT5ToRGBA8] =
D3D12_SHADER_BYTECODE{shaders::texture_load_dxt5_rgba8_cs,
sizeof(shaders::texture_load_dxt5_rgba8_cs)};
load_shader_code[kLoadShaderIndexDXNToRG8] =
D3D12_SHADER_BYTECODE{shaders::texture_load_dxn_rg8_cs,
sizeof(shaders::texture_load_dxn_rg8_cs)};
load_shader_code[kLoadShaderIndexDXT3A] = D3D12_SHADER_BYTECODE{
shaders::texture_load_dxt3a_cs, sizeof(shaders::texture_load_dxt3a_cs)};
load_shader_code[kLoadShaderIndexDXT3AAs1111ToBGRA4] =
D3D12_SHADER_BYTECODE{shaders::texture_load_dxt3aas1111_bgra4_cs,
sizeof(shaders::texture_load_dxt3aas1111_bgra4_cs)};
load_shader_code[kLoadShaderIndexDXT5AToR8] =
D3D12_SHADER_BYTECODE{shaders::texture_load_dxt5a_r8_cs,
sizeof(shaders::texture_load_dxt5a_r8_cs)};
load_shader_code[kLoadShaderIndexCTX1] = D3D12_SHADER_BYTECODE{
shaders::texture_load_ctx1_cs, sizeof(shaders::texture_load_ctx1_cs)};
load_shader_code[kLoadShaderIndexDepthUnorm] =
D3D12_SHADER_BYTECODE{shaders::texture_load_depth_unorm_cs,
sizeof(shaders::texture_load_depth_unorm_cs)};
load_shader_code[kLoadShaderIndexDepthFloat] =
D3D12_SHADER_BYTECODE{shaders::texture_load_depth_float_cs,
sizeof(shaders::texture_load_depth_float_cs)};
D3D12_SHADER_BYTECODE load_shader_code_scaled[kLoadShaderCount] = {};
if (IsDrawResolutionScaled()) {
load_shader_code_scaled[kLoadShaderIndex8bpb] =
D3D12_SHADER_BYTECODE{shaders::texture_load_8bpb_scaled_cs,
sizeof(shaders::texture_load_8bpb_scaled_cs)};
load_shader_code_scaled[kLoadShaderIndex16bpb] =
D3D12_SHADER_BYTECODE{shaders::texture_load_16bpb_scaled_cs,
sizeof(shaders::texture_load_16bpb_scaled_cs)};
load_shader_code_scaled[kLoadShaderIndex32bpb] =
D3D12_SHADER_BYTECODE{shaders::texture_load_32bpb_scaled_cs,
sizeof(shaders::texture_load_32bpb_scaled_cs)};
load_shader_code_scaled[kLoadShaderIndex64bpb] =
D3D12_SHADER_BYTECODE{shaders::texture_load_64bpb_scaled_cs,
sizeof(shaders::texture_load_64bpb_scaled_cs)};
load_shader_code_scaled[kLoadShaderIndex128bpb] =
D3D12_SHADER_BYTECODE{shaders::texture_load_128bpb_scaled_cs,
sizeof(shaders::texture_load_128bpb_scaled_cs)};
load_shader_code_scaled[kLoadShaderIndexR5G5B5A1ToB5G5R5A1] =
D3D12_SHADER_BYTECODE{
shaders::texture_load_r5g5b5a1_b5g5r5a1_scaled_cs,
sizeof(shaders::texture_load_r5g5b5a1_b5g5r5a1_scaled_cs)};
load_shader_code_scaled[kLoadShaderIndexR5G6B5ToB5G6R5] =
D3D12_SHADER_BYTECODE{
shaders::texture_load_r5g6b5_b5g6r5_scaled_cs,
sizeof(shaders::texture_load_r5g6b5_b5g6r5_scaled_cs)};
load_shader_code_scaled[kLoadShaderIndexR5G5B6ToB5G6R5WithRBGASwizzle] =
D3D12_SHADER_BYTECODE{
shaders::texture_load_r5g5b6_b5g6r5_swizzle_rbga_scaled_cs,
sizeof(shaders::texture_load_r5g5b6_b5g6r5_swizzle_rbga_scaled_cs)};
load_shader_code_scaled[kLoadShaderIndexRGBA4ToBGRA4] =
D3D12_SHADER_BYTECODE{
shaders::texture_load_r4g4b4a4_b4g4r4a4_scaled_cs,
sizeof(shaders::texture_load_r4g4b4a4_b4g4r4a4_scaled_cs)};
load_shader_code_scaled[kLoadShaderIndexR10G11B11ToRGBA16] =
D3D12_SHADER_BYTECODE{
shaders::texture_load_r10g11b11_rgba16_scaled_cs,
sizeof(shaders::texture_load_r10g11b11_rgba16_scaled_cs)};
load_shader_code_scaled[kLoadShaderIndexR10G11B11ToRGBA16SNorm] =
D3D12_SHADER_BYTECODE{
shaders::texture_load_r10g11b11_rgba16_snorm_scaled_cs,
sizeof(shaders::texture_load_r10g11b11_rgba16_snorm_scaled_cs)};
load_shader_code_scaled[kLoadShaderIndexR11G11B10ToRGBA16] =
D3D12_SHADER_BYTECODE{
shaders::texture_load_r11g11b10_rgba16_scaled_cs,
sizeof(shaders::texture_load_r11g11b10_rgba16_scaled_cs)};
load_shader_code_scaled[kLoadShaderIndexR11G11B10ToRGBA16SNorm] =
D3D12_SHADER_BYTECODE{
shaders::texture_load_r11g11b10_rgba16_snorm_scaled_cs,
sizeof(shaders::texture_load_r11g11b10_rgba16_snorm_scaled_cs)};
load_shader_code_scaled[kLoadShaderIndexDepthUnorm] = D3D12_SHADER_BYTECODE{
shaders::texture_load_depth_unorm_scaled_cs,
sizeof(shaders::texture_load_depth_unorm_scaled_cs)};
load_shader_code_scaled[kLoadShaderIndexDepthFloat] = D3D12_SHADER_BYTECODE{
shaders::texture_load_depth_float_scaled_cs,
sizeof(shaders::texture_load_depth_float_scaled_cs)};
}
// Create the loading pipelines. // Create the loading pipelines.
for (uint32_t i = 0; i < uint32_t(LoadMode::kCount); ++i) { for (size_t i = 0; i < kLoadShaderCount; ++i) {
const LoadModeInfo& load_mode_info = load_mode_info_[i]; const D3D12_SHADER_BYTECODE& current_load_shader_code = load_shader_code[i];
if (!current_load_shader_code.pShaderBytecode) {
continue;
}
*(load_pipelines_[i].ReleaseAndGetAddressOf()) = *(load_pipelines_[i].ReleaseAndGetAddressOf()) =
ui::d3d12::util::CreateComputePipeline(device, load_mode_info.shader, ui::d3d12::util::CreateComputePipeline(
load_mode_info.shader_size, device, current_load_shader_code.pShaderBytecode,
load_root_signature_.Get()); current_load_shader_code.BytecodeLength,
load_root_signature_.Get());
if (!load_pipelines_[i]) { if (!load_pipelines_[i]) {
XELOGE( XELOGE(
"D3D12TextureCache: Failed to create the texture loading pipeline " "D3D12TextureCache: Failed to create the texture loading pipeline "
"for mode {}", "for shader {}",
i); i);
return false; return false;
} }
if (IsDrawResolutionScaled() && load_mode_info.shader_scaled) { if (IsDrawResolutionScaled()) {
*(load_pipelines_scaled_[i].ReleaseAndGetAddressOf()) = const D3D12_SHADER_BYTECODE& current_load_shader_code_scaled =
ui::d3d12::util::CreateComputePipeline( load_shader_code_scaled[i];
device, load_mode_info.shader_scaled, if (current_load_shader_code_scaled.pShaderBytecode) {
load_mode_info.shader_scaled_size, load_root_signature_.Get()); *(load_pipelines_scaled_[i].ReleaseAndGetAddressOf()) =
if (!load_pipelines_scaled_[i]) { ui::d3d12::util::CreateComputePipeline(
XELOGE( device, current_load_shader_code_scaled.pShaderBytecode,
"D3D12TextureCache: Failed to create the resolution-scaled texture " current_load_shader_code_scaled.BytecodeLength,
"loading pipeline for mode {}", load_root_signature_.Get());
i); if (!load_pipelines_scaled_[i]) {
return false; XELOGE(
"D3D12TextureCache: Failed to create the resolution-scaled "
"texture loading pipeline for shader {}",
i);
return false;
}
} }
} }
} }
@ -689,8 +759,8 @@ void D3D12TextureCache::EndFrame() {
} }
XELOGE("* {}{}{}{}", FormatInfo::Get(xenos::TextureFormat(i))->name, XELOGE("* {}{}{}{}", FormatInfo::Get(xenos::TextureFormat(i))->name,
unsupported_features & kUnsupportedResourceBit ? " resource" : "", unsupported_features & kUnsupportedResourceBit ? " resource" : "",
unsupported_features & kUnsupportedUnormBit ? " unorm" : "", unsupported_features & kUnsupportedUnormBit ? " unsigned" : "",
unsupported_features & kUnsupportedSnormBit ? " snorm" : ""); unsupported_features & kUnsupportedSnormBit ? " signed" : "");
unsupported_format_features_used_[i] = 0; unsupported_format_features_used_[i] = 0;
} }
} }
@ -1383,28 +1453,29 @@ bool D3D12TextureCache::IsDecompressionNeeded(xenos::TextureFormat format,
(height & (format_info->block_height - 1)) != 0; (height & (format_info->block_height - 1)) != 0;
} }
D3D12TextureCache::LoadMode D3D12TextureCache::GetLoadMode(TextureKey key) { TextureCache::LoadShaderIndex D3D12TextureCache::GetLoadShaderIndex(
TextureKey key) {
const HostFormat& host_format = host_formats_[uint32_t(key.format)]; const HostFormat& host_format = host_formats_[uint32_t(key.format)];
if (key.signed_separate) { if (key.signed_separate) {
return host_format.load_mode_snorm; return host_format.load_shader_signed;
} }
if (IsDecompressionNeeded(key.format, key.GetWidth(), key.GetHeight())) { if (IsDecompressionNeeded(key.format, key.GetWidth(), key.GetHeight())) {
return host_format.decompress_mode; return host_format.load_shader_decompress;
} }
return host_format.load_mode; return host_format.load_shader;
} }
bool D3D12TextureCache::IsSignedVersionSeparateForFormat(TextureKey key) const { bool D3D12TextureCache::IsSignedVersionSeparateForFormat(TextureKey key) const {
const HostFormat& host_format = host_formats_[uint32_t(key.format)]; const HostFormat& host_format = host_formats_[uint32_t(key.format)];
return host_format.load_mode_snorm != LoadMode::kUnknown && return host_format.load_shader_signed != kLoadShaderIndexUnknown &&
host_format.load_mode_snorm != host_format.load_mode; host_format.load_shader_signed != host_format.load_shader;
} }
bool D3D12TextureCache::IsScaledResolveSupportedForFormat( bool D3D12TextureCache::IsScaledResolveSupportedForFormat(
TextureKey key) const { TextureKey key) const {
LoadMode load_mode = GetLoadMode(key); LoadShaderIndex load_shader = GetLoadShaderIndex(key);
return load_mode != LoadMode::kUnknown && return load_shader != kLoadShaderIndexUnknown &&
load_pipelines_scaled_[uint32_t(load_mode)] != nullptr; load_pipelines_scaled_[load_shader] != nullptr;
} }
uint32_t D3D12TextureCache::GetHostFormatSwizzle(TextureKey key) const { uint32_t D3D12TextureCache::GetHostFormatSwizzle(TextureKey key) const {
@ -1502,19 +1573,18 @@ bool D3D12TextureCache::LoadTextureDataFromResidentMemoryImpl(Texture& texture,
ID3D12Device* device = command_processor_.GetD3D12Provider().GetDevice(); ID3D12Device* device = command_processor_.GetD3D12Provider().GetDevice();
// Get the pipeline. // Get the pipeline.
LoadMode load_mode = GetLoadMode(texture_key); LoadShaderIndex load_shader = GetLoadShaderIndex(texture_key);
if (load_mode == LoadMode::kUnknown) { if (load_shader == kLoadShaderIndexUnknown) {
return false; return false;
} }
bool texture_resolution_scaled = texture_key.scaled_resolve; bool texture_resolution_scaled = texture_key.scaled_resolve;
ID3D12PipelineState* pipeline = ID3D12PipelineState* pipeline =
texture_resolution_scaled texture_resolution_scaled ? load_pipelines_scaled_[load_shader].Get()
? load_pipelines_scaled_[uint32_t(load_mode)].Get() : load_pipelines_[load_shader].Get();
: load_pipelines_[uint32_t(load_mode)].Get();
if (pipeline == nullptr) { if (pipeline == nullptr) {
return false; return false;
} }
const LoadModeInfo& load_mode_info = load_mode_info_[uint32_t(load_mode)]; const LoadShaderInfo& load_shader_info = GetLoadShaderInfo(load_shader);
// Get the guest layout. // Get the guest layout.
const texture_util::TextureGuestLayout& guest_layout = const texture_util::TextureGuestLayout& guest_layout =
@ -1549,7 +1619,7 @@ bool D3D12TextureCache::LoadTextureDataFromResidentMemoryImpl(Texture& texture,
uint32_t host_block_width = host_block_compressed ? block_width : 1; uint32_t host_block_width = host_block_compressed ? block_width : 1;
uint32_t host_block_height = host_block_compressed ? block_height : 1; uint32_t host_block_height = host_block_compressed ? block_height : 1;
uint32_t host_x_blocks_per_thread = uint32_t host_x_blocks_per_thread =
UINT32_C(1) << load_mode_info.guest_x_blocks_per_thread_log2; UINT32_C(1) << load_shader_info.guest_x_blocks_per_thread_log2;
if (!host_block_compressed) { if (!host_block_compressed) {
// Decompressing guest blocks. // Decompressing guest blocks.
host_x_blocks_per_thread *= block_width; host_x_blocks_per_thread *= block_width;
@ -1598,7 +1668,7 @@ bool D3D12TextureCache::LoadTextureDataFromResidentMemoryImpl(Texture& texture,
xe::align(xe::round_up(host_slice_layout_base.Footprint.Width / xe::align(xe::round_up(host_slice_layout_base.Footprint.Width /
host_block_width, host_block_width,
host_x_blocks_per_thread) * host_x_blocks_per_thread) *
load_mode_info.bytes_per_host_block, load_shader_info.bytes_per_host_block,
uint32_t(D3D12_TEXTURE_DATA_PITCH_ALIGNMENT)); uint32_t(D3D12_TEXTURE_DATA_PITCH_ALIGNMENT));
host_slice_size_base = xe::align( host_slice_size_base = xe::align(
UINT64(host_slice_layout_base.Footprint.RowPitch) * UINT64(host_slice_layout_base.Footprint.RowPitch) *
@ -1643,7 +1713,7 @@ bool D3D12TextureCache::LoadTextureDataFromResidentMemoryImpl(Texture& texture,
xe::align(xe::round_up(host_slice_layout_mip.Footprint.Width / xe::align(xe::round_up(host_slice_layout_mip.Footprint.Width /
host_block_width, host_block_width,
host_x_blocks_per_thread) * host_x_blocks_per_thread) *
load_mode_info.bytes_per_host_block, load_shader_info.bytes_per_host_block,
uint32_t(D3D12_TEXTURE_DATA_PITCH_ALIGNMENT)); uint32_t(D3D12_TEXTURE_DATA_PITCH_ALIGNMENT));
UINT64 host_slice_sizes_mip = xe::align( UINT64 host_slice_sizes_mip = xe::align(
UINT64(host_slice_layout_mip.Footprint.RowPitch) * UINT64(host_slice_layout_mip.Footprint.RowPitch) *
@ -1693,8 +1763,8 @@ bool D3D12TextureCache::LoadTextureDataFromResidentMemoryImpl(Texture& texture,
descriptors_allocated[descriptor_write_index++]; descriptors_allocated[descriptor_write_index++];
ui::d3d12::util::CreateBufferTypedUAV( ui::d3d12::util::CreateBufferTypedUAV(
device, descriptor_dest.first, copy_buffer, device, descriptor_dest.first, copy_buffer,
ui::d3d12::util::GetUintPow2DXGIFormat(load_mode_info.uav_bpe_log2), ui::d3d12::util::GetUintPow2DXGIFormat(load_shader_info.dest_bpe_log2),
uint32_t(copy_buffer_size) >> load_mode_info.uav_bpe_log2); uint32_t(copy_buffer_size) >> load_shader_info.dest_bpe_log2);
command_list.D3DSetComputeRootDescriptorTable(2, descriptor_dest.second); command_list.D3DSetComputeRootDescriptorTable(2, descriptor_dest.second);
// Set up the unscaled source descriptor (scaled needs two descriptors that // Set up the unscaled source descriptor (scaled needs two descriptors that
// depend on the buffer being current, so they will be set later - for mips, // depend on the buffer being current, so they will be set later - for mips,
@ -1707,13 +1777,13 @@ bool D3D12TextureCache::LoadTextureDataFromResidentMemoryImpl(Texture& texture,
if (bindless_resources_used_) { if (bindless_resources_used_) {
descriptor_unscaled_source = descriptor_unscaled_source =
command_processor_.GetSharedMemoryUintPow2BindlessSRVHandlePair( command_processor_.GetSharedMemoryUintPow2BindlessSRVHandlePair(
load_mode_info.srv_bpe_log2); load_shader_info.source_bpe_log2);
} else { } else {
assert_true(descriptor_write_index < descriptor_count); assert_true(descriptor_write_index < descriptor_count);
descriptor_unscaled_source = descriptor_unscaled_source =
descriptors_allocated[descriptor_write_index++]; descriptors_allocated[descriptor_write_index++];
d3d12_shared_memory.WriteUintPow2SRVDescriptor( d3d12_shared_memory.WriteUintPow2SRVDescriptor(
descriptor_unscaled_source.first, load_mode_info.srv_bpe_log2); descriptor_unscaled_source.first, load_shader_info.source_bpe_log2);
} }
command_list.D3DSetComputeRootDescriptorTable( command_list.D3DSetComputeRootDescriptorTable(
1, descriptor_unscaled_source.second); 1, descriptor_unscaled_source.second);
@ -1752,7 +1822,7 @@ bool D3D12TextureCache::LoadTextureDataFromResidentMemoryImpl(Texture& texture,
// address is required - which may be different for base and mips. // address is required - which may be different for base and mips.
bool scaled_mips_source_set_up = false; bool scaled_mips_source_set_up = false;
uint32_t guest_x_blocks_per_group_log2 = uint32_t guest_x_blocks_per_group_log2 =
load_mode_info.GetGuestXBlocksPerGroupLog2(); load_shader_info.GetGuestXBlocksPerGroupLog2();
for (uint32_t loop_level = loop_level_first; loop_level <= loop_level_last; for (uint32_t loop_level = loop_level_first; loop_level <= loop_level_last;
++loop_level) { ++loop_level) {
bool is_base = loop_level == 0; bool is_base = loop_level == 0;
@ -1776,8 +1846,8 @@ bool D3D12TextureCache::LoadTextureDataFromResidentMemoryImpl(Texture& texture,
assert_true(descriptor_write_index < descriptor_count); assert_true(descriptor_write_index < descriptor_count);
ui::d3d12::util::DescriptorCpuGpuHandlePair descriptor_scaled_source = ui::d3d12::util::DescriptorCpuGpuHandlePair descriptor_scaled_source =
descriptors_allocated[descriptor_write_index++]; descriptors_allocated[descriptor_write_index++];
CreateCurrentScaledResolveRangeUintPow2SRV(descriptor_scaled_source.first, CreateCurrentScaledResolveRangeUintPow2SRV(
load_mode_info.srv_bpe_log2); descriptor_scaled_source.first, load_shader_info.source_bpe_log2);
command_list.D3DSetComputeRootDescriptorTable( command_list.D3DSetComputeRootDescriptorTable(
1, descriptor_scaled_source.second); 1, descriptor_scaled_source.second);
if (!is_base) { if (!is_base) {
@ -2003,7 +2073,7 @@ uint32_t D3D12TextureCache::FindOrCreateTextureDescriptor(
if (is_signed) { if (is_signed) {
// Not supporting signed compressed textures - hopefully DXN and DXT5A are // Not supporting signed compressed textures - hopefully DXN and DXT5A are
// not used as signed. // not used as signed.
desc.Format = host_formats_[uint32_t(format)].dxgi_format_snorm; desc.Format = host_formats_[uint32_t(format)].dxgi_format_signed;
} else { } else {
desc.Format = GetDXGIUnormFormat(texture_key); desc.Format = GetDXGIUnormFormat(texture_key);
} }

View File

@ -179,85 +179,23 @@ class D3D12TextureCache final : public TextureCache {
static constexpr uint32_t kLoadGuestXThreadsPerGroupLog2 = 2; static constexpr uint32_t kLoadGuestXThreadsPerGroupLog2 = 2;
static constexpr uint32_t kLoadGuestYBlocksPerGroupLog2 = 5; static constexpr uint32_t kLoadGuestYBlocksPerGroupLog2 = 5;
enum class LoadMode {
k8bpb,
k16bpb,
k32bpb,
k64bpb,
k128bpb,
kR5G5B5A1ToB5G5R5A1,
kR5G6B5ToB5G6R5,
kR5G5B6ToB5G6R5WithRBGASwizzle,
kR4G4B4A4ToB4G4R4A4,
kGBGR8ToGRGB8,
kGBGR8ToRGB8,
kBGRG8ToRGBG8,
kBGRG8ToRGB8,
kR10G11B11ToRGBA16,
kR10G11B11ToRGBA16SNorm,
kR11G11B10ToRGBA16,
kR11G11B10ToRGBA16SNorm,
kDXT1ToRGBA8,
kDXT3ToRGBA8,
kDXT5ToRGBA8,
kDXNToRG8,
kDXT3A,
kDXT3AAs1111ToBGRA4,
kDXT5AToR8,
kCTX1,
kDepthUnorm,
kDepthFloat,
kCount,
kUnknown = kCount
};
struct LoadModeInfo {
// Shader without resolution scaling.
const void* shader;
size_t shader_size;
// Shader with resolution scaling, if available. These shaders are separate
// so the majority of the textures are not affected by the code needed for
// resolution scale support, and also to check if the format allows
// resolution scaling.
const void* shader_scaled;
size_t shader_scaled_size;
// Log2 of the sizes, in bytes, of the source (guest) SRV and the
// destination (host) UAV accessed by the copying shader, since the shader
// may copy multiple blocks per one invocation.
uint32_t srv_bpe_log2;
uint32_t uav_bpe_log2;
// Number of bytes in a host resolution-scaled block (corresponding to a
// guest block if not decompressing, or a host texel if decompressing)
// written by the shader.
uint32_t bytes_per_host_block;
// Log2 of the number of guest resolution-scaled blocks along the X axis
// loaded by a single thread shader group.
uint32_t guest_x_blocks_per_thread_log2;
uint32_t GetGuestXBlocksPerGroupLog2() const {
return kLoadGuestXThreadsPerGroupLog2 + guest_x_blocks_per_thread_log2;
}
};
struct HostFormat { struct HostFormat {
// Format info for the regular case. // Format info for the regular case.
// DXGI format (typeless when different signedness or number representation // DXGI format (typeless when different signedness or number representation
// is used) for the texture resource. // is used) for the texture resource.
DXGI_FORMAT dxgi_format_resource; DXGI_FORMAT dxgi_format_resource;
// DXGI format for unsigned normalized or unsigned/signed float SRV. // DXGI format for unsigned normalized or unsigned/signed float SRV.
DXGI_FORMAT dxgi_format_unorm; DXGI_FORMAT dxgi_format_unsigned;
// The regular load mode, used when special modes (like signed-specific or // The regular load shader, used when special load shaders (like
// decompressing) aren't needed. // signed-specific or decompressing) aren't needed.
LoadMode load_mode; LoadShaderIndex load_shader;
// DXGI format for signed normalized or unsigned/signed float SRV. // DXGI format for signed normalized or unsigned/signed float SRV.
DXGI_FORMAT dxgi_format_snorm; DXGI_FORMAT dxgi_format_signed;
// If the signed version needs a different bit representation on the host, // If the signed version needs a different bit representation on the host,
// this is the load mode for the signed version. Otherwise the regular // this is the load shader for the signed version. Otherwise the regular
// load_mode will be used for the signed version, and a single copy will be // load_shader will be used for the signed version, and a single copy will
// created if both unsigned and signed are used. // be created if both unsigned and signed are used.
LoadMode load_mode_snorm; LoadShaderIndex load_shader_signed;
// Do NOT add integer DXGI formats to this - they are not filterable, can // Do NOT add integer DXGI formats to this - they are not filterable, can
// only be read with Load, not Sample! If any game is seen using num_format // only be read with Load, not Sample! If any game is seen using num_format
@ -276,7 +214,7 @@ class D3D12TextureCache final : public TextureCache {
// supports unsigned normalized formats - let's hope GPUSIGN_SIGNED was not // supports unsigned normalized formats - let's hope GPUSIGN_SIGNED was not
// used for DXN and DXT5A. // used for DXN and DXT5A.
DXGI_FORMAT dxgi_format_uncompressed; DXGI_FORMAT dxgi_format_uncompressed;
LoadMode decompress_mode; LoadShaderIndex load_shader_decompress;
// Mapping of Xenos swizzle components to DXGI format components. // Mapping of Xenos swizzle components to DXGI format components.
uint32_t swizzle; uint32_t swizzle;
@ -440,13 +378,13 @@ class D3D12TextureCache final : public TextureCache {
const HostFormat& host_format = host_formats_[uint32_t(format)]; const HostFormat& host_format = host_formats_[uint32_t(format)];
return IsDecompressionNeeded(format, width, height) return IsDecompressionNeeded(format, width, height)
? host_format.dxgi_format_uncompressed ? host_format.dxgi_format_uncompressed
: host_format.dxgi_format_unorm; : host_format.dxgi_format_unsigned;
} }
static DXGI_FORMAT GetDXGIUnormFormat(TextureKey key) { static DXGI_FORMAT GetDXGIUnormFormat(TextureKey key) {
return GetDXGIUnormFormat(key.format, key.GetWidth(), key.GetHeight()); return GetDXGIUnormFormat(key.format, key.GetWidth(), key.GetHeight());
} }
static LoadMode GetLoadMode(TextureKey key); static LoadShaderIndex GetLoadShaderIndex(TextureKey key);
static constexpr bool AreDimensionsCompatible( static constexpr bool AreDimensionsCompatible(
xenos::FetchOpDimension binding_dimension, xenos::FetchOpDimension binding_dimension,
@ -528,14 +466,11 @@ class D3D12TextureCache final : public TextureCache {
D3D12CommandProcessor& command_processor_; D3D12CommandProcessor& command_processor_;
bool bindless_resources_used_; bool bindless_resources_used_;
static const LoadModeInfo load_mode_info_[];
Microsoft::WRL::ComPtr<ID3D12RootSignature> load_root_signature_; Microsoft::WRL::ComPtr<ID3D12RootSignature> load_root_signature_;
std::array<Microsoft::WRL::ComPtr<ID3D12PipelineState>, std::array<Microsoft::WRL::ComPtr<ID3D12PipelineState>, kLoadShaderCount>
size_t(LoadMode::kCount)>
load_pipelines_; load_pipelines_;
// Load pipelines for resolution-scaled resolve targets. // Load pipelines for resolution-scaled resolve targets.
std::array<Microsoft::WRL::ComPtr<ID3D12PipelineState>, std::array<Microsoft::WRL::ComPtr<ID3D12PipelineState>, kLoadShaderCount>
size_t(LoadMode::kCount)>
load_pipelines_scaled_; load_pipelines_scaled_;
std::vector<SRVDescriptorCachePage> srv_descriptor_cache_; std::vector<SRVDescriptorCachePage> srv_descriptor_cache_;

View File

@ -73,6 +73,80 @@ DEFINE_uint32(
namespace xe { namespace xe {
namespace gpu { namespace gpu {
const TextureCache::LoadShaderInfo
TextureCache::load_shader_info_[kLoadShaderCount] = {
// k8bpb
{3, 4, 1, 4},
// k16bpb
{4, 4, 2, 4},
// k32bpb
{4, 4, 4, 3},
// k64bpb
{4, 4, 8, 2},
// k128bpb
{4, 4, 16, 1},
// kR5G5B5A1ToB5G5R5A1
{4, 4, 2, 4},
// kR5G6B5ToB5G6R5
{4, 4, 2, 4},
// kR5G5B6ToB5G6R5WithRBGASwizzle
{4, 4, 2, 4},
// kRGBA4ToBGRA4
{4, 4, 2, 4},
// kRGBA4ToARGB4
{4, 4, 2, 4},
// kGBGR8ToGRGB8
{4, 4, 4, 3},
// kGBGR8ToRGB8
{4, 4, 8, 3},
// kBGRG8ToRGBG8
{4, 4, 4, 3},
// kBGRG8ToRGB8
{4, 4, 8, 3},
// kR10G11B11ToRGBA16
{4, 4, 8, 3},
// kR10G11B11ToRGBA16SNorm
{4, 4, 8, 3},
// kR11G11B10ToRGBA16
{4, 4, 8, 3},
// kR11G11B10ToRGBA16SNorm
{4, 4, 8, 3},
// kR16UNormToFloat
{4, 4, 2, 4},
// kR16SNormToFloat
{4, 4, 2, 4},
// kRG16UNormToFloat
{4, 4, 4, 3},
// kRG16SNormToFloat
{4, 4, 4, 3},
// kRGBA16UNormToFloat
{4, 4, 8, 2},
// kRGBA16SNormToFloat
{4, 4, 8, 2},
// kDXT1ToRGBA8
{4, 4, 4, 2},
// kDXT3ToRGBA8
{4, 4, 4, 1},
// kDXT5ToRGBA8
{4, 4, 4, 1},
// kDXNToRG8
{4, 4, 2, 1},
// kDXT3A
{4, 4, 1, 2},
// kDXT3AAs1111ToBGRA4
{4, 4, 2, 2},
// kDXT3AAs1111ToARGB4
{4, 4, 2, 2},
// kDXT5AToR8
{4, 4, 1, 2},
// kCTX1
{4, 4, 2, 2},
// kDepthUnorm
{4, 4, 4, 3},
// kDepthFloat
{4, 4, 4, 3},
};
TextureCache::TextureCache(const RegisterFile& register_file, TextureCache::TextureCache(const RegisterFile& register_file,
SharedMemory& shared_memory, SharedMemory& shared_memory,
uint32_t draw_resolution_scale_x, uint32_t draw_resolution_scale_x,

View File

@ -395,6 +395,69 @@ class TextureCache {
uint32_t height_texels; uint32_t height_texels;
}; };
static constexpr uint32_t kLoadGuestXThreadsPerGroupLog2 = 2;
static constexpr uint32_t kLoadGuestYBlocksPerGroupLog2 = 5;
enum LoadShaderIndex {
kLoadShaderIndex8bpb,
kLoadShaderIndex16bpb,
kLoadShaderIndex32bpb,
kLoadShaderIndex64bpb,
kLoadShaderIndex128bpb,
kLoadShaderIndexR5G5B5A1ToB5G5R5A1,
kLoadShaderIndexR5G6B5ToB5G6R5,
kLoadShaderIndexR5G5B6ToB5G6R5WithRBGASwizzle,
kLoadShaderIndexRGBA4ToBGRA4,
kLoadShaderIndexRGBA4ToARGB4,
kLoadShaderIndexGBGR8ToGRGB8,
kLoadShaderIndexGBGR8ToRGB8,
kLoadShaderIndexBGRG8ToRGBG8,
kLoadShaderIndexBGRG8ToRGB8,
kLoadShaderIndexR10G11B11ToRGBA16,
kLoadShaderIndexR10G11B11ToRGBA16SNorm,
kLoadShaderIndexR11G11B10ToRGBA16,
kLoadShaderIndexR11G11B10ToRGBA16SNorm,
kLoadShaderIndexR16UNormToFloat,
kLoadShaderIndexR16SNormToFloat,
kLoadShaderIndexRG16UNormToFloat,
kLoadShaderIndexRG16SNormToFloat,
kLoadShaderIndexRGBA16UNormToFloat,
kLoadShaderIndexRGBA16SNormToFloat,
kLoadShaderIndexDXT1ToRGBA8,
kLoadShaderIndexDXT3ToRGBA8,
kLoadShaderIndexDXT5ToRGBA8,
kLoadShaderIndexDXNToRG8,
kLoadShaderIndexDXT3A,
kLoadShaderIndexDXT3AAs1111ToBGRA4,
kLoadShaderIndexDXT3AAs1111ToARGB4,
kLoadShaderIndexDXT5AToR8,
kLoadShaderIndexCTX1,
kLoadShaderIndexDepthUnorm,
kLoadShaderIndexDepthFloat,
kLoadShaderCount,
kLoadShaderIndexUnknown = kLoadShaderCount,
};
struct LoadShaderInfo {
// Log2 of the sizes, in bytes, of the elements in the source (guest) and
// the destination (host) buffer bindings accessed by the copying shader,
// since the shader may copy multiple blocks per one invocation.
uint32_t source_bpe_log2;
uint32_t dest_bpe_log2;
// Number of bytes in a host resolution-scaled block (corresponding to a
// guest block if not decompressing, or a host texel if decompressing)
// written by the shader.
uint32_t bytes_per_host_block;
// Log2 of the number of guest resolution-scaled blocks along the X axis
// loaded by a single thread shader group.
uint32_t guest_x_blocks_per_thread_log2;
uint32_t GetGuestXBlocksPerGroupLog2() const {
return kLoadGuestXThreadsPerGroupLog2 + guest_x_blocks_per_thread_log2;
}
};
static constexpr uint8_t kSwizzledSignsUnsigned = static constexpr uint8_t kSwizzledSignsUnsigned =
uint8_t(xenos::TextureSign::kUnsigned) * uint8_t(0b01010101); uint8_t(xenos::TextureSign::kUnsigned) * uint8_t(0b01010101);
@ -472,6 +535,11 @@ class TextureCache {
// should be made. // should be made.
Texture* FindOrCreateTexture(TextureKey key); Texture* FindOrCreateTexture(TextureKey key);
static const LoadShaderInfo& GetLoadShaderInfo(
LoadShaderIndex load_shader_index) {
assert_true(load_shader_index < kLoadShaderCount);
return load_shader_info_[load_shader_index];
}
bool LoadTextureData(Texture& texture); bool LoadTextureData(Texture& texture);
// Writes the texture data (for base, mips or both - but not neither) from the // Writes the texture data (for base, mips or both - but not neither) from the
// shared memory or the scaled resolve memory. The shared memory management is // shared memory or the scaled resolve memory. The shared memory management is
@ -527,6 +595,8 @@ class TextureCache {
uint32_t draw_resolution_scale_x_; uint32_t draw_resolution_scale_x_;
uint32_t draw_resolution_scale_y_; uint32_t draw_resolution_scale_y_;
static const LoadShaderInfo load_shader_info_[kLoadShaderCount];
xe::global_critical_region global_critical_region_; xe::global_critical_region global_critical_region_;
// Bit vector storing whether each 4 KB physical memory page contains scaled // Bit vector storing whether each 4 KB physical memory page contains scaled
// resolve data. uint32_t rather than uint64_t because parts of it can be sent // resolve data. uint32_t rather than uint64_t because parts of it can be sent