[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] = {
// k_1_REVERSE
{DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, LoadMode::kUnknown,
DXGI_FORMAT_UNKNOWN, LoadMode::kUnknown, false, DXGI_FORMAT_UNKNOWN,
LoadMode::kUnknown, xenos::XE_GPU_TEXTURE_SWIZZLE_RRRR},
{DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, kLoadShaderIndexUnknown,
DXGI_FORMAT_UNKNOWN, kLoadShaderIndexUnknown, false, DXGI_FORMAT_UNKNOWN,
kLoadShaderIndexUnknown, xenos::XE_GPU_TEXTURE_SWIZZLE_RRRR},
// k_1
{DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, LoadMode::kUnknown,
DXGI_FORMAT_UNKNOWN, LoadMode::kUnknown, false, DXGI_FORMAT_UNKNOWN,
LoadMode::kUnknown, xenos::XE_GPU_TEXTURE_SWIZZLE_RRRR},
{DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, kLoadShaderIndexUnknown,
DXGI_FORMAT_UNKNOWN, kLoadShaderIndexUnknown, false, DXGI_FORMAT_UNKNOWN,
kLoadShaderIndexUnknown, xenos::XE_GPU_TEXTURE_SWIZZLE_RRRR},
// k_8
{DXGI_FORMAT_R8_TYPELESS, DXGI_FORMAT_R8_UNORM, LoadMode::k8bpb,
DXGI_FORMAT_R8_SNORM, LoadMode::kUnknown, false, DXGI_FORMAT_UNKNOWN,
LoadMode::kUnknown, xenos::XE_GPU_TEXTURE_SWIZZLE_RRRR},
{DXGI_FORMAT_R8_TYPELESS, DXGI_FORMAT_R8_UNORM, kLoadShaderIndex8bpb,
DXGI_FORMAT_R8_SNORM, kLoadShaderIndexUnknown, false, DXGI_FORMAT_UNKNOWN,
kLoadShaderIndexUnknown, xenos::XE_GPU_TEXTURE_SWIZZLE_RRRR},
// k_1_5_5_5
// Red and blue swapped in the load shader for simplicity.
{DXGI_FORMAT_B5G5R5A1_UNORM, DXGI_FORMAT_B5G5R5A1_UNORM,
LoadMode::kR5G5B5A1ToB5G5R5A1, DXGI_FORMAT_UNKNOWN, LoadMode::kUnknown,
false, DXGI_FORMAT_UNKNOWN, LoadMode::kUnknown,
xenos::XE_GPU_TEXTURE_SWIZZLE_RGBA},
kLoadShaderIndexR5G5B5A1ToB5G5R5A1, DXGI_FORMAT_UNKNOWN,
kLoadShaderIndexUnknown, false, DXGI_FORMAT_UNKNOWN,
kLoadShaderIndexUnknown, xenos::XE_GPU_TEXTURE_SWIZZLE_RGBA},
// k_5_6_5
// Red and blue swapped in the load shader for simplicity.
{DXGI_FORMAT_B5G6R5_UNORM, DXGI_FORMAT_B5G6R5_UNORM,
LoadMode::kR5G6B5ToB5G6R5, DXGI_FORMAT_UNKNOWN, LoadMode::kUnknown, false,
DXGI_FORMAT_UNKNOWN, LoadMode::kUnknown,
xenos::XE_GPU_TEXTURE_SWIZZLE_RGBB},
kLoadShaderIndexR5G6B5ToB5G6R5, DXGI_FORMAT_UNKNOWN,
kLoadShaderIndexUnknown, false, DXGI_FORMAT_UNKNOWN,
kLoadShaderIndexUnknown, xenos::XE_GPU_TEXTURE_SWIZZLE_RGBB},
// k_6_5_5
// On the host, green bits in blue, blue bits in green.
{DXGI_FORMAT_B5G6R5_UNORM, DXGI_FORMAT_B5G6R5_UNORM,
LoadMode::kR5G5B6ToB5G6R5WithRBGASwizzle, DXGI_FORMAT_UNKNOWN,
LoadMode::kUnknown, false, DXGI_FORMAT_UNKNOWN, LoadMode::kUnknown,
XE_GPU_MAKE_TEXTURE_SWIZZLE(R, B, G, G)},
kLoadShaderIndexR5G5B6ToB5G6R5WithRBGASwizzle, DXGI_FORMAT_UNKNOWN,
kLoadShaderIndexUnknown, false, DXGI_FORMAT_UNKNOWN,
kLoadShaderIndexUnknown, XE_GPU_MAKE_TEXTURE_SWIZZLE(R, B, G, G)},
// k_8_8_8_8
{DXGI_FORMAT_R8G8B8A8_TYPELESS, DXGI_FORMAT_R8G8B8A8_UNORM,
LoadMode::k32bpb, DXGI_FORMAT_R8G8B8A8_SNORM, LoadMode::kUnknown, false,
DXGI_FORMAT_UNKNOWN, LoadMode::kUnknown,
kLoadShaderIndex32bpb, DXGI_FORMAT_R8G8B8A8_SNORM, kLoadShaderIndexUnknown,
false, DXGI_FORMAT_UNKNOWN, kLoadShaderIndexUnknown,
xenos::XE_GPU_TEXTURE_SWIZZLE_RGBA},
// k_2_10_10_10
{DXGI_FORMAT_R10G10B10A2_TYPELESS, DXGI_FORMAT_R10G10B10A2_UNORM,
LoadMode::k32bpb, DXGI_FORMAT_UNKNOWN, LoadMode::kUnknown, false,
DXGI_FORMAT_UNKNOWN, LoadMode::kUnknown,
kLoadShaderIndex32bpb, DXGI_FORMAT_UNKNOWN, kLoadShaderIndexUnknown, false,
DXGI_FORMAT_UNKNOWN, kLoadShaderIndexUnknown,
xenos::XE_GPU_TEXTURE_SWIZZLE_RGBA},
// k_8_A
{DXGI_FORMAT_R8_TYPELESS, DXGI_FORMAT_R8_UNORM, LoadMode::k8bpb,
DXGI_FORMAT_R8_SNORM, LoadMode::kUnknown, false, DXGI_FORMAT_UNKNOWN,
LoadMode::kUnknown, xenos::XE_GPU_TEXTURE_SWIZZLE_RRRR},
{DXGI_FORMAT_R8_TYPELESS, DXGI_FORMAT_R8_UNORM, kLoadShaderIndex8bpb,
DXGI_FORMAT_R8_SNORM, kLoadShaderIndexUnknown, false, DXGI_FORMAT_UNKNOWN,
kLoadShaderIndexUnknown, xenos::XE_GPU_TEXTURE_SWIZZLE_RRRR},
// k_8_B
{DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, LoadMode::kUnknown,
DXGI_FORMAT_UNKNOWN, LoadMode::kUnknown, false, DXGI_FORMAT_UNKNOWN,
LoadMode::kUnknown, xenos::XE_GPU_TEXTURE_SWIZZLE_RRRR},
{DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, kLoadShaderIndexUnknown,
DXGI_FORMAT_UNKNOWN, kLoadShaderIndexUnknown, false, DXGI_FORMAT_UNKNOWN,
kLoadShaderIndexUnknown, xenos::XE_GPU_TEXTURE_SWIZZLE_RRRR},
// k_8_8
{DXGI_FORMAT_R8G8_TYPELESS, DXGI_FORMAT_R8G8_UNORM, LoadMode::k16bpb,
DXGI_FORMAT_R8G8_SNORM, LoadMode::kUnknown, false, DXGI_FORMAT_UNKNOWN,
LoadMode::kUnknown, xenos::XE_GPU_TEXTURE_SWIZZLE_RGGG},
{DXGI_FORMAT_R8G8_TYPELESS, DXGI_FORMAT_R8G8_UNORM, kLoadShaderIndex16bpb,
DXGI_FORMAT_R8G8_SNORM, kLoadShaderIndexUnknown, false,
DXGI_FORMAT_UNKNOWN, kLoadShaderIndexUnknown,
xenos::XE_GPU_TEXTURE_SWIZZLE_RGGG},
// k_Cr_Y1_Cb_Y0_REP
// Red and blue swapped in the load shader for simplicity.
// 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).
{DXGI_FORMAT_G8R8_G8B8_UNORM, DXGI_FORMAT_G8R8_G8B8_UNORM,
LoadMode::kGBGR8ToGRGB8, DXGI_FORMAT_UNKNOWN, LoadMode::kUnknown, true,
DXGI_FORMAT_R8G8B8A8_UNORM, LoadMode::kGBGR8ToRGB8,
kLoadShaderIndexGBGR8ToGRGB8, DXGI_FORMAT_UNKNOWN, kLoadShaderIndexUnknown,
true, DXGI_FORMAT_R8G8B8A8_UNORM, kLoadShaderIndexGBGR8ToRGB8,
xenos::XE_GPU_TEXTURE_SWIZZLE_RGBB},
// k_Y1_Cr_Y0_Cb_REP
// Red and blue swapped in the load shader for simplicity.
// 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).
{DXGI_FORMAT_R8G8_B8G8_UNORM, DXGI_FORMAT_R8G8_B8G8_UNORM,
LoadMode::kBGRG8ToRGBG8, DXGI_FORMAT_UNKNOWN, LoadMode::kUnknown, true,
DXGI_FORMAT_R8G8B8A8_UNORM, LoadMode::kBGRG8ToRGB8,
kLoadShaderIndexBGRG8ToRGBG8, DXGI_FORMAT_UNKNOWN, kLoadShaderIndexUnknown,
true, DXGI_FORMAT_R8G8B8A8_UNORM, kLoadShaderIndexBGRG8ToRGB8,
xenos::XE_GPU_TEXTURE_SWIZZLE_RGBB},
// k_16_16_EDRAM
// Not usable as a texture, also has -32...32 range.
{DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, LoadMode::kUnknown,
DXGI_FORMAT_UNKNOWN, LoadMode::kUnknown, false, DXGI_FORMAT_UNKNOWN,
LoadMode::kUnknown, xenos::XE_GPU_TEXTURE_SWIZZLE_RGGG},
{DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, kLoadShaderIndexUnknown,
DXGI_FORMAT_UNKNOWN, kLoadShaderIndexUnknown, false, DXGI_FORMAT_UNKNOWN,
kLoadShaderIndexUnknown, xenos::XE_GPU_TEXTURE_SWIZZLE_RGGG},
// k_8_8_8_8_A
{DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, LoadMode::kUnknown,
DXGI_FORMAT_UNKNOWN, LoadMode::kUnknown, false, DXGI_FORMAT_UNKNOWN,
LoadMode::kUnknown, xenos::XE_GPU_TEXTURE_SWIZZLE_RGBA},
{DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, kLoadShaderIndexUnknown,
DXGI_FORMAT_UNKNOWN, kLoadShaderIndexUnknown, false, DXGI_FORMAT_UNKNOWN,
kLoadShaderIndexUnknown, xenos::XE_GPU_TEXTURE_SWIZZLE_RGBA},
// k_4_4_4_4
// Red and blue swapped in the load shader for simplicity.
{DXGI_FORMAT_B4G4R4A4_UNORM, DXGI_FORMAT_B4G4R4A4_UNORM,
LoadMode::kR4G4B4A4ToB4G4R4A4, DXGI_FORMAT_UNKNOWN, LoadMode::kUnknown,
false, DXGI_FORMAT_UNKNOWN, LoadMode::kUnknown,
kLoadShaderIndexRGBA4ToBGRA4, DXGI_FORMAT_UNKNOWN, kLoadShaderIndexUnknown,
false, DXGI_FORMAT_UNKNOWN, kLoadShaderIndexUnknown,
xenos::XE_GPU_TEXTURE_SWIZZLE_RGBA},
// k_10_11_11
{DXGI_FORMAT_R16G16B16A16_TYPELESS, DXGI_FORMAT_R16G16B16A16_UNORM,
LoadMode::kR11G11B10ToRGBA16, DXGI_FORMAT_R16G16B16A16_SNORM,
LoadMode::kR11G11B10ToRGBA16SNorm, false, DXGI_FORMAT_UNKNOWN,
LoadMode::kUnknown, xenos::XE_GPU_TEXTURE_SWIZZLE_RGBB},
kLoadShaderIndexR11G11B10ToRGBA16, DXGI_FORMAT_R16G16B16A16_SNORM,
kLoadShaderIndexR11G11B10ToRGBA16SNorm, false, DXGI_FORMAT_UNKNOWN,
kLoadShaderIndexUnknown, xenos::XE_GPU_TEXTURE_SWIZZLE_RGBB},
// k_11_11_10
{DXGI_FORMAT_R16G16B16A16_TYPELESS, DXGI_FORMAT_R16G16B16A16_UNORM,
LoadMode::kR10G11B11ToRGBA16, DXGI_FORMAT_R16G16B16A16_SNORM,
LoadMode::kR10G11B11ToRGBA16SNorm, false, DXGI_FORMAT_UNKNOWN,
LoadMode::kUnknown, xenos::XE_GPU_TEXTURE_SWIZZLE_RGBB},
kLoadShaderIndexR10G11B11ToRGBA16, DXGI_FORMAT_R16G16B16A16_SNORM,
kLoadShaderIndexR10G11B11ToRGBA16SNorm, false, DXGI_FORMAT_UNKNOWN,
kLoadShaderIndexUnknown, xenos::XE_GPU_TEXTURE_SWIZZLE_RGBB},
// k_DXT1
{DXGI_FORMAT_BC1_UNORM, DXGI_FORMAT_BC1_UNORM, LoadMode::k64bpb,
DXGI_FORMAT_UNKNOWN, LoadMode::kUnknown, true, DXGI_FORMAT_R8G8B8A8_UNORM,
LoadMode::kDXT1ToRGBA8, xenos::XE_GPU_TEXTURE_SWIZZLE_RGBA},
{DXGI_FORMAT_BC1_UNORM, DXGI_FORMAT_BC1_UNORM, kLoadShaderIndex64bpb,
DXGI_FORMAT_UNKNOWN, kLoadShaderIndexUnknown, true,
DXGI_FORMAT_R8G8B8A8_UNORM, kLoadShaderIndexDXT1ToRGBA8,
xenos::XE_GPU_TEXTURE_SWIZZLE_RGBA},
// k_DXT2_3
{DXGI_FORMAT_BC2_UNORM, DXGI_FORMAT_BC2_UNORM, LoadMode::k128bpb,
DXGI_FORMAT_UNKNOWN, LoadMode::kUnknown, true, DXGI_FORMAT_R8G8B8A8_UNORM,
LoadMode::kDXT3ToRGBA8, xenos::XE_GPU_TEXTURE_SWIZZLE_RGBA},
{DXGI_FORMAT_BC2_UNORM, DXGI_FORMAT_BC2_UNORM, kLoadShaderIndex128bpb,
DXGI_FORMAT_UNKNOWN, kLoadShaderIndexUnknown, true,
DXGI_FORMAT_R8G8B8A8_UNORM, kLoadShaderIndexDXT3ToRGBA8,
xenos::XE_GPU_TEXTURE_SWIZZLE_RGBA},
// k_DXT4_5
{DXGI_FORMAT_BC3_UNORM, DXGI_FORMAT_BC3_UNORM, LoadMode::k128bpb,
DXGI_FORMAT_UNKNOWN, LoadMode::kUnknown, true, DXGI_FORMAT_R8G8B8A8_UNORM,
LoadMode::kDXT5ToRGBA8, xenos::XE_GPU_TEXTURE_SWIZZLE_RGBA},
{DXGI_FORMAT_BC3_UNORM, DXGI_FORMAT_BC3_UNORM, kLoadShaderIndex128bpb,
DXGI_FORMAT_UNKNOWN, kLoadShaderIndexUnknown, true,
DXGI_FORMAT_R8G8B8A8_UNORM, kLoadShaderIndexDXT5ToRGBA8,
xenos::XE_GPU_TEXTURE_SWIZZLE_RGBA},
// k_16_16_16_16_EDRAM
// Not usable as a texture, also has -32...32 range.
{DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, LoadMode::kUnknown,
DXGI_FORMAT_UNKNOWN, LoadMode::kUnknown, false, DXGI_FORMAT_UNKNOWN,
LoadMode::kUnknown, xenos::XE_GPU_TEXTURE_SWIZZLE_RGBA},
{DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, kLoadShaderIndexUnknown,
DXGI_FORMAT_UNKNOWN, kLoadShaderIndexUnknown, false, DXGI_FORMAT_UNKNOWN,
kLoadShaderIndexUnknown, xenos::XE_GPU_TEXTURE_SWIZZLE_RGBA},
// R32_FLOAT for depth because shaders would require an additional SRV to
// sample stencil, which we don't provide.
// k_24_8
{DXGI_FORMAT_R32_FLOAT, DXGI_FORMAT_R32_FLOAT, LoadMode::kDepthUnorm,
DXGI_FORMAT_R32_FLOAT, LoadMode::kUnknown, false, DXGI_FORMAT_UNKNOWN,
LoadMode::kUnknown, xenos::XE_GPU_TEXTURE_SWIZZLE_RRRR},
{DXGI_FORMAT_R32_FLOAT, DXGI_FORMAT_R32_FLOAT, kLoadShaderIndexDepthUnorm,
DXGI_FORMAT_R32_FLOAT, kLoadShaderIndexUnknown, false, DXGI_FORMAT_UNKNOWN,
kLoadShaderIndexUnknown, xenos::XE_GPU_TEXTURE_SWIZZLE_RRRR},
// k_24_8_FLOAT
{DXGI_FORMAT_R32_FLOAT, DXGI_FORMAT_R32_FLOAT, LoadMode::kDepthFloat,
DXGI_FORMAT_R32_FLOAT, LoadMode::kUnknown, false, DXGI_FORMAT_UNKNOWN,
LoadMode::kUnknown, xenos::XE_GPU_TEXTURE_SWIZZLE_RRRR},
{DXGI_FORMAT_R32_FLOAT, DXGI_FORMAT_R32_FLOAT, kLoadShaderIndexDepthFloat,
DXGI_FORMAT_R32_FLOAT, kLoadShaderIndexUnknown, false, DXGI_FORMAT_UNKNOWN,
kLoadShaderIndexUnknown, xenos::XE_GPU_TEXTURE_SWIZZLE_RRRR},
// k_16
{DXGI_FORMAT_R16_TYPELESS, DXGI_FORMAT_R16_UNORM, LoadMode::k16bpb,
DXGI_FORMAT_R16_SNORM, LoadMode::kUnknown, false, DXGI_FORMAT_UNKNOWN,
LoadMode::kUnknown, xenos::XE_GPU_TEXTURE_SWIZZLE_RRRR},
{DXGI_FORMAT_R16_TYPELESS, DXGI_FORMAT_R16_UNORM, kLoadShaderIndex16bpb,
DXGI_FORMAT_R16_SNORM, kLoadShaderIndexUnknown, false, DXGI_FORMAT_UNKNOWN,
kLoadShaderIndexUnknown, xenos::XE_GPU_TEXTURE_SWIZZLE_RRRR},
// k_16_16
{DXGI_FORMAT_R16G16_TYPELESS, DXGI_FORMAT_R16G16_UNORM, LoadMode::k32bpb,
DXGI_FORMAT_R16G16_SNORM, LoadMode::kUnknown, false, DXGI_FORMAT_UNKNOWN,
LoadMode::kUnknown, xenos::XE_GPU_TEXTURE_SWIZZLE_RGGG},
{DXGI_FORMAT_R16G16_TYPELESS, DXGI_FORMAT_R16G16_UNORM,
kLoadShaderIndex32bpb, DXGI_FORMAT_R16G16_SNORM, kLoadShaderIndexUnknown,
false, DXGI_FORMAT_UNKNOWN, kLoadShaderIndexUnknown,
xenos::XE_GPU_TEXTURE_SWIZZLE_RGGG},
// k_16_16_16_16
{DXGI_FORMAT_R16G16B16A16_TYPELESS, DXGI_FORMAT_R16G16B16A16_UNORM,
LoadMode::k64bpb, DXGI_FORMAT_R16G16B16A16_SNORM, LoadMode::kUnknown,
false, DXGI_FORMAT_UNKNOWN, LoadMode::kUnknown,
xenos::XE_GPU_TEXTURE_SWIZZLE_RGBA},
kLoadShaderIndex64bpb, DXGI_FORMAT_R16G16B16A16_SNORM,
kLoadShaderIndexUnknown, false, DXGI_FORMAT_UNKNOWN,
kLoadShaderIndexUnknown, xenos::XE_GPU_TEXTURE_SWIZZLE_RGBA},
// k_16_EXPAND
{DXGI_FORMAT_R16_FLOAT, DXGI_FORMAT_R16_FLOAT, LoadMode::k16bpb,
DXGI_FORMAT_R16_FLOAT, LoadMode::kUnknown, false, DXGI_FORMAT_UNKNOWN,
LoadMode::kUnknown, xenos::XE_GPU_TEXTURE_SWIZZLE_RRRR},
{DXGI_FORMAT_R16_FLOAT, DXGI_FORMAT_R16_FLOAT, kLoadShaderIndex16bpb,
DXGI_FORMAT_R16_FLOAT, kLoadShaderIndexUnknown, false, DXGI_FORMAT_UNKNOWN,
kLoadShaderIndexUnknown, xenos::XE_GPU_TEXTURE_SWIZZLE_RRRR},
// k_16_16_EXPAND
{DXGI_FORMAT_R16G16_FLOAT, DXGI_FORMAT_R16G16_FLOAT, LoadMode::k32bpb,
DXGI_FORMAT_R16G16_FLOAT, LoadMode::kUnknown, false, DXGI_FORMAT_UNKNOWN,
LoadMode::kUnknown, xenos::XE_GPU_TEXTURE_SWIZZLE_RGGG},
{DXGI_FORMAT_R16G16_FLOAT, DXGI_FORMAT_R16G16_FLOAT, kLoadShaderIndex32bpb,
DXGI_FORMAT_R16G16_FLOAT, kLoadShaderIndexUnknown, false,
DXGI_FORMAT_UNKNOWN, kLoadShaderIndexUnknown,
xenos::XE_GPU_TEXTURE_SWIZZLE_RGGG},
// k_16_16_16_16_EXPAND
{DXGI_FORMAT_R16G16B16A16_FLOAT, DXGI_FORMAT_R16G16B16A16_FLOAT,
LoadMode::k64bpb, DXGI_FORMAT_R16G16B16A16_FLOAT, LoadMode::kUnknown,
false, DXGI_FORMAT_UNKNOWN, LoadMode::kUnknown,
xenos::XE_GPU_TEXTURE_SWIZZLE_RGBA},
kLoadShaderIndex64bpb, DXGI_FORMAT_R16G16B16A16_FLOAT,
kLoadShaderIndexUnknown, false, DXGI_FORMAT_UNKNOWN,
kLoadShaderIndexUnknown, xenos::XE_GPU_TEXTURE_SWIZZLE_RGBA},
// k_16_FLOAT
{DXGI_FORMAT_R16_FLOAT, DXGI_FORMAT_R16_FLOAT, LoadMode::k16bpb,
DXGI_FORMAT_R16_FLOAT, LoadMode::kUnknown, false, DXGI_FORMAT_UNKNOWN,
LoadMode::kUnknown, xenos::XE_GPU_TEXTURE_SWIZZLE_RRRR},
{DXGI_FORMAT_R16_FLOAT, DXGI_FORMAT_R16_FLOAT, kLoadShaderIndex16bpb,
DXGI_FORMAT_R16_FLOAT, kLoadShaderIndexUnknown, false, DXGI_FORMAT_UNKNOWN,
kLoadShaderIndexUnknown, xenos::XE_GPU_TEXTURE_SWIZZLE_RRRR},
// k_16_16_FLOAT
{DXGI_FORMAT_R16G16_FLOAT, DXGI_FORMAT_R16G16_FLOAT, LoadMode::k32bpb,
DXGI_FORMAT_R16G16_FLOAT, LoadMode::kUnknown, false, DXGI_FORMAT_UNKNOWN,
LoadMode::kUnknown, xenos::XE_GPU_TEXTURE_SWIZZLE_RGGG},
{DXGI_FORMAT_R16G16_FLOAT, DXGI_FORMAT_R16G16_FLOAT, kLoadShaderIndex32bpb,
DXGI_FORMAT_R16G16_FLOAT, kLoadShaderIndexUnknown, false,
DXGI_FORMAT_UNKNOWN, kLoadShaderIndexUnknown,
xenos::XE_GPU_TEXTURE_SWIZZLE_RGGG},
// k_16_16_16_16_FLOAT
{DXGI_FORMAT_R16G16B16A16_FLOAT, DXGI_FORMAT_R16G16B16A16_FLOAT,
LoadMode::k64bpb, DXGI_FORMAT_R16G16B16A16_FLOAT, LoadMode::kUnknown,
false, DXGI_FORMAT_UNKNOWN, LoadMode::kUnknown,
xenos::XE_GPU_TEXTURE_SWIZZLE_RGBA},
kLoadShaderIndex64bpb, DXGI_FORMAT_R16G16B16A16_FLOAT,
kLoadShaderIndexUnknown, false, DXGI_FORMAT_UNKNOWN,
kLoadShaderIndexUnknown, xenos::XE_GPU_TEXTURE_SWIZZLE_RGBA},
// k_32
{DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, LoadMode::kUnknown,
DXGI_FORMAT_UNKNOWN, LoadMode::kUnknown, false, DXGI_FORMAT_UNKNOWN,
LoadMode::kUnknown, xenos::XE_GPU_TEXTURE_SWIZZLE_RRRR},
{DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, kLoadShaderIndexUnknown,
DXGI_FORMAT_UNKNOWN, kLoadShaderIndexUnknown, false, DXGI_FORMAT_UNKNOWN,
kLoadShaderIndexUnknown, xenos::XE_GPU_TEXTURE_SWIZZLE_RRRR},
// k_32_32
{DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, LoadMode::kUnknown,
DXGI_FORMAT_UNKNOWN, LoadMode::kUnknown, false, DXGI_FORMAT_UNKNOWN,
LoadMode::kUnknown, xenos::XE_GPU_TEXTURE_SWIZZLE_RGGG},
{DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, kLoadShaderIndexUnknown,
DXGI_FORMAT_UNKNOWN, kLoadShaderIndexUnknown, false, DXGI_FORMAT_UNKNOWN,
kLoadShaderIndexUnknown, xenos::XE_GPU_TEXTURE_SWIZZLE_RGGG},
// k_32_32_32_32
{DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, LoadMode::kUnknown,
DXGI_FORMAT_UNKNOWN, LoadMode::kUnknown, false, DXGI_FORMAT_UNKNOWN,
LoadMode::kUnknown, xenos::XE_GPU_TEXTURE_SWIZZLE_RGBA},
{DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, kLoadShaderIndexUnknown,
DXGI_FORMAT_UNKNOWN, kLoadShaderIndexUnknown, false, DXGI_FORMAT_UNKNOWN,
kLoadShaderIndexUnknown, xenos::XE_GPU_TEXTURE_SWIZZLE_RGBA},
// k_32_FLOAT
{DXGI_FORMAT_R32_FLOAT, DXGI_FORMAT_R32_FLOAT, LoadMode::k32bpb,
DXGI_FORMAT_R32_FLOAT, LoadMode::kUnknown, false, DXGI_FORMAT_UNKNOWN,
LoadMode::kUnknown, xenos::XE_GPU_TEXTURE_SWIZZLE_RRRR},
{DXGI_FORMAT_R32_FLOAT, DXGI_FORMAT_R32_FLOAT, kLoadShaderIndex32bpb,
DXGI_FORMAT_R32_FLOAT, kLoadShaderIndexUnknown, false, DXGI_FORMAT_UNKNOWN,
kLoadShaderIndexUnknown, xenos::XE_GPU_TEXTURE_SWIZZLE_RRRR},
// k_32_32_FLOAT
{DXGI_FORMAT_R32G32_FLOAT, DXGI_FORMAT_R32G32_FLOAT, LoadMode::k64bpb,
DXGI_FORMAT_R32G32_FLOAT, LoadMode::kUnknown, false, DXGI_FORMAT_UNKNOWN,
LoadMode::kUnknown, xenos::XE_GPU_TEXTURE_SWIZZLE_RGGG},
{DXGI_FORMAT_R32G32_FLOAT, DXGI_FORMAT_R32G32_FLOAT, kLoadShaderIndex64bpb,
DXGI_FORMAT_R32G32_FLOAT, kLoadShaderIndexUnknown, false,
DXGI_FORMAT_UNKNOWN, kLoadShaderIndexUnknown,
xenos::XE_GPU_TEXTURE_SWIZZLE_RGGG},
// k_32_32_32_32_FLOAT
{DXGI_FORMAT_R32G32B32A32_FLOAT, DXGI_FORMAT_R32G32B32A32_FLOAT,
LoadMode::k128bpb, DXGI_FORMAT_R32G32B32A32_FLOAT, LoadMode::kUnknown,
false, DXGI_FORMAT_UNKNOWN, LoadMode::kUnknown,
xenos::XE_GPU_TEXTURE_SWIZZLE_RGBA},
kLoadShaderIndex128bpb, DXGI_FORMAT_R32G32B32A32_FLOAT,
kLoadShaderIndexUnknown, false, DXGI_FORMAT_UNKNOWN,
kLoadShaderIndexUnknown, xenos::XE_GPU_TEXTURE_SWIZZLE_RGBA},
// k_32_AS_8
{DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, LoadMode::kUnknown,
DXGI_FORMAT_UNKNOWN, LoadMode::kUnknown, false, DXGI_FORMAT_UNKNOWN,
LoadMode::kUnknown, xenos::XE_GPU_TEXTURE_SWIZZLE_RRRR},
{DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, kLoadShaderIndexUnknown,
DXGI_FORMAT_UNKNOWN, kLoadShaderIndexUnknown, false, DXGI_FORMAT_UNKNOWN,
kLoadShaderIndexUnknown, xenos::XE_GPU_TEXTURE_SWIZZLE_RRRR},
// k_32_AS_8_8
{DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, LoadMode::kUnknown,
DXGI_FORMAT_UNKNOWN, LoadMode::kUnknown, false, DXGI_FORMAT_UNKNOWN,
LoadMode::kUnknown, xenos::XE_GPU_TEXTURE_SWIZZLE_RGGG},
{DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, kLoadShaderIndexUnknown,
DXGI_FORMAT_UNKNOWN, kLoadShaderIndexUnknown, false, DXGI_FORMAT_UNKNOWN,
kLoadShaderIndexUnknown, xenos::XE_GPU_TEXTURE_SWIZZLE_RGGG},
// k_16_MPEG
{DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, LoadMode::kUnknown,
DXGI_FORMAT_UNKNOWN, LoadMode::kUnknown, false, DXGI_FORMAT_UNKNOWN,
LoadMode::kUnknown, xenos::XE_GPU_TEXTURE_SWIZZLE_RRRR},
{DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, kLoadShaderIndexUnknown,
DXGI_FORMAT_UNKNOWN, kLoadShaderIndexUnknown, false, DXGI_FORMAT_UNKNOWN,
kLoadShaderIndexUnknown, xenos::XE_GPU_TEXTURE_SWIZZLE_RRRR},
// k_16_16_MPEG
{DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, LoadMode::kUnknown,
DXGI_FORMAT_UNKNOWN, LoadMode::kUnknown, false, DXGI_FORMAT_UNKNOWN,
LoadMode::kUnknown, xenos::XE_GPU_TEXTURE_SWIZZLE_RGGG},
{DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, kLoadShaderIndexUnknown,
DXGI_FORMAT_UNKNOWN, kLoadShaderIndexUnknown, false, DXGI_FORMAT_UNKNOWN,
kLoadShaderIndexUnknown, xenos::XE_GPU_TEXTURE_SWIZZLE_RGGG},
// k_8_INTERLACED
{DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, LoadMode::kUnknown,
DXGI_FORMAT_UNKNOWN, LoadMode::kUnknown, false, DXGI_FORMAT_UNKNOWN,
LoadMode::kUnknown, xenos::XE_GPU_TEXTURE_SWIZZLE_RRRR},
{DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, kLoadShaderIndexUnknown,
DXGI_FORMAT_UNKNOWN, kLoadShaderIndexUnknown, false, DXGI_FORMAT_UNKNOWN,
kLoadShaderIndexUnknown, xenos::XE_GPU_TEXTURE_SWIZZLE_RRRR},
// k_32_AS_8_INTERLACED
{DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, LoadMode::kUnknown,
DXGI_FORMAT_UNKNOWN, LoadMode::kUnknown, false, DXGI_FORMAT_UNKNOWN,
LoadMode::kUnknown, xenos::XE_GPU_TEXTURE_SWIZZLE_RRRR},
{DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, kLoadShaderIndexUnknown,
DXGI_FORMAT_UNKNOWN, kLoadShaderIndexUnknown, false, DXGI_FORMAT_UNKNOWN,
kLoadShaderIndexUnknown, xenos::XE_GPU_TEXTURE_SWIZZLE_RRRR},
// k_32_AS_8_8_INTERLACED
{DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, LoadMode::kUnknown,
DXGI_FORMAT_UNKNOWN, LoadMode::kUnknown, false, DXGI_FORMAT_UNKNOWN,
LoadMode::kUnknown, xenos::XE_GPU_TEXTURE_SWIZZLE_RGGG},
{DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, kLoadShaderIndexUnknown,
DXGI_FORMAT_UNKNOWN, kLoadShaderIndexUnknown, false, DXGI_FORMAT_UNKNOWN,
kLoadShaderIndexUnknown, xenos::XE_GPU_TEXTURE_SWIZZLE_RGGG},
// k_16_INTERLACED
{DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, LoadMode::kUnknown,
DXGI_FORMAT_UNKNOWN, LoadMode::kUnknown, false, DXGI_FORMAT_UNKNOWN,
LoadMode::kUnknown, xenos::XE_GPU_TEXTURE_SWIZZLE_RRRR},
{DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, kLoadShaderIndexUnknown,
DXGI_FORMAT_UNKNOWN, kLoadShaderIndexUnknown, false, DXGI_FORMAT_UNKNOWN,
kLoadShaderIndexUnknown, xenos::XE_GPU_TEXTURE_SWIZZLE_RRRR},
// k_16_MPEG_INTERLACED
{DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, LoadMode::kUnknown,
DXGI_FORMAT_UNKNOWN, LoadMode::kUnknown, false, DXGI_FORMAT_UNKNOWN,
LoadMode::kUnknown, xenos::XE_GPU_TEXTURE_SWIZZLE_RRRR},
{DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, kLoadShaderIndexUnknown,
DXGI_FORMAT_UNKNOWN, kLoadShaderIndexUnknown, false, DXGI_FORMAT_UNKNOWN,
kLoadShaderIndexUnknown, xenos::XE_GPU_TEXTURE_SWIZZLE_RRRR},
// k_16_16_MPEG_INTERLACED
{DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, LoadMode::kUnknown,
DXGI_FORMAT_UNKNOWN, LoadMode::kUnknown, false, DXGI_FORMAT_UNKNOWN,
LoadMode::kUnknown, xenos::XE_GPU_TEXTURE_SWIZZLE_RGGG},
{DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, kLoadShaderIndexUnknown,
DXGI_FORMAT_UNKNOWN, kLoadShaderIndexUnknown, false, DXGI_FORMAT_UNKNOWN,
kLoadShaderIndexUnknown, xenos::XE_GPU_TEXTURE_SWIZZLE_RGGG},
// k_DXN
{DXGI_FORMAT_BC5_UNORM, DXGI_FORMAT_BC5_UNORM, LoadMode::k128bpb,
DXGI_FORMAT_UNKNOWN, LoadMode::kUnknown, true, DXGI_FORMAT_R8G8_UNORM,
LoadMode::kDXNToRG8, xenos::XE_GPU_TEXTURE_SWIZZLE_RGGG},
{DXGI_FORMAT_BC5_UNORM, DXGI_FORMAT_BC5_UNORM, kLoadShaderIndex128bpb,
DXGI_FORMAT_UNKNOWN, kLoadShaderIndexUnknown, true, DXGI_FORMAT_R8G8_UNORM,
kLoadShaderIndexDXNToRG8, xenos::XE_GPU_TEXTURE_SWIZZLE_RGGG},
// k_8_8_8_8_AS_16_16_16_16
{DXGI_FORMAT_R8G8B8A8_TYPELESS, DXGI_FORMAT_R8G8B8A8_UNORM,
LoadMode::k32bpb, DXGI_FORMAT_R8G8B8A8_SNORM, LoadMode::kUnknown, false,
DXGI_FORMAT_UNKNOWN, LoadMode::kUnknown,
kLoadShaderIndex32bpb, DXGI_FORMAT_R8G8B8A8_SNORM, kLoadShaderIndexUnknown,
false, DXGI_FORMAT_UNKNOWN, kLoadShaderIndexUnknown,
xenos::XE_GPU_TEXTURE_SWIZZLE_RGBA},
// k_DXT1_AS_16_16_16_16
{DXGI_FORMAT_BC1_UNORM, DXGI_FORMAT_BC1_UNORM, LoadMode::k64bpb,
DXGI_FORMAT_UNKNOWN, LoadMode::kUnknown, true, DXGI_FORMAT_R8G8B8A8_UNORM,
LoadMode::kDXT1ToRGBA8, xenos::XE_GPU_TEXTURE_SWIZZLE_RGBA},
{DXGI_FORMAT_BC1_UNORM, DXGI_FORMAT_BC1_UNORM, kLoadShaderIndex64bpb,
DXGI_FORMAT_UNKNOWN, kLoadShaderIndexUnknown, true,
DXGI_FORMAT_R8G8B8A8_UNORM, kLoadShaderIndexDXT1ToRGBA8,
xenos::XE_GPU_TEXTURE_SWIZZLE_RGBA},
// k_DXT2_3_AS_16_16_16_16
{DXGI_FORMAT_BC2_UNORM, DXGI_FORMAT_BC2_UNORM, LoadMode::k128bpb,
DXGI_FORMAT_UNKNOWN, LoadMode::kUnknown, true, DXGI_FORMAT_R8G8B8A8_UNORM,
LoadMode::kDXT3ToRGBA8, xenos::XE_GPU_TEXTURE_SWIZZLE_RGBA},
{DXGI_FORMAT_BC2_UNORM, DXGI_FORMAT_BC2_UNORM, kLoadShaderIndex128bpb,
DXGI_FORMAT_UNKNOWN, kLoadShaderIndexUnknown, true,
DXGI_FORMAT_R8G8B8A8_UNORM, kLoadShaderIndexDXT3ToRGBA8,
xenos::XE_GPU_TEXTURE_SWIZZLE_RGBA},
// k_DXT4_5_AS_16_16_16_16
{DXGI_FORMAT_BC3_UNORM, DXGI_FORMAT_BC3_UNORM, LoadMode::k128bpb,
DXGI_FORMAT_UNKNOWN, LoadMode::kUnknown, true, DXGI_FORMAT_R8G8B8A8_UNORM,
LoadMode::kDXT5ToRGBA8, xenos::XE_GPU_TEXTURE_SWIZZLE_RGBA},
{DXGI_FORMAT_BC3_UNORM, DXGI_FORMAT_BC3_UNORM, kLoadShaderIndex128bpb,
DXGI_FORMAT_UNKNOWN, kLoadShaderIndexUnknown, true,
DXGI_FORMAT_R8G8B8A8_UNORM, kLoadShaderIndexDXT5ToRGBA8,
xenos::XE_GPU_TEXTURE_SWIZZLE_RGBA},
// k_2_10_10_10_AS_16_16_16_16
{DXGI_FORMAT_R10G10B10A2_UNORM, DXGI_FORMAT_R10G10B10A2_UNORM,
LoadMode::k32bpb, DXGI_FORMAT_UNKNOWN, LoadMode::kUnknown, false,
DXGI_FORMAT_UNKNOWN, LoadMode::kUnknown,
kLoadShaderIndex32bpb, DXGI_FORMAT_UNKNOWN, kLoadShaderIndexUnknown, false,
DXGI_FORMAT_UNKNOWN, kLoadShaderIndexUnknown,
xenos::XE_GPU_TEXTURE_SWIZZLE_RGBA},
// k_10_11_11_AS_16_16_16_16
{DXGI_FORMAT_R16G16B16A16_TYPELESS, DXGI_FORMAT_R16G16B16A16_UNORM,
LoadMode::kR11G11B10ToRGBA16, DXGI_FORMAT_R16G16B16A16_SNORM,
LoadMode::kR11G11B10ToRGBA16SNorm, false, DXGI_FORMAT_UNKNOWN,
LoadMode::kUnknown, xenos::XE_GPU_TEXTURE_SWIZZLE_RGBB},
kLoadShaderIndexR11G11B10ToRGBA16, DXGI_FORMAT_R16G16B16A16_SNORM,
kLoadShaderIndexR11G11B10ToRGBA16SNorm, false, DXGI_FORMAT_UNKNOWN,
kLoadShaderIndexUnknown, xenos::XE_GPU_TEXTURE_SWIZZLE_RGBB},
// k_11_11_10_AS_16_16_16_16
{DXGI_FORMAT_R16G16B16A16_TYPELESS, DXGI_FORMAT_R16G16B16A16_UNORM,
LoadMode::kR10G11B11ToRGBA16, DXGI_FORMAT_R16G16B16A16_SNORM,
LoadMode::kR10G11B11ToRGBA16SNorm, false, DXGI_FORMAT_UNKNOWN,
LoadMode::kUnknown, xenos::XE_GPU_TEXTURE_SWIZZLE_RGBB},
kLoadShaderIndexR10G11B11ToRGBA16, DXGI_FORMAT_R16G16B16A16_SNORM,
kLoadShaderIndexR10G11B11ToRGBA16SNorm, false, DXGI_FORMAT_UNKNOWN,
kLoadShaderIndexUnknown, xenos::XE_GPU_TEXTURE_SWIZZLE_RGBB},
// k_32_32_32_FLOAT
{DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, LoadMode::kUnknown,
DXGI_FORMAT_UNKNOWN, LoadMode::kUnknown, false, DXGI_FORMAT_UNKNOWN,
LoadMode::kUnknown, xenos::XE_GPU_TEXTURE_SWIZZLE_RGBB},
{DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, kLoadShaderIndexUnknown,
DXGI_FORMAT_UNKNOWN, kLoadShaderIndexUnknown, false, DXGI_FORMAT_UNKNOWN,
kLoadShaderIndexUnknown, xenos::XE_GPU_TEXTURE_SWIZZLE_RGBB},
// k_DXT3A
// R8_UNORM has the same size as BC2, but doesn't have the 4x4 size
// alignment requirement.
{DXGI_FORMAT_R8_UNORM, DXGI_FORMAT_R8_UNORM, LoadMode::kDXT3A,
DXGI_FORMAT_UNKNOWN, LoadMode::kUnknown, false, DXGI_FORMAT_UNKNOWN,
LoadMode::kUnknown, xenos::XE_GPU_TEXTURE_SWIZZLE_RRRR},
{DXGI_FORMAT_R8_UNORM, DXGI_FORMAT_R8_UNORM, kLoadShaderIndexDXT3A,
DXGI_FORMAT_UNKNOWN, kLoadShaderIndexUnknown, false, DXGI_FORMAT_UNKNOWN,
kLoadShaderIndexUnknown, xenos::XE_GPU_TEXTURE_SWIZZLE_RRRR},
// k_DXT5A
{DXGI_FORMAT_BC4_UNORM, DXGI_FORMAT_BC4_UNORM, LoadMode::k64bpb,
DXGI_FORMAT_UNKNOWN, LoadMode::kUnknown, true, DXGI_FORMAT_R8_UNORM,
LoadMode::kDXT5AToR8, xenos::XE_GPU_TEXTURE_SWIZZLE_RRRR},
{DXGI_FORMAT_BC4_UNORM, DXGI_FORMAT_BC4_UNORM, kLoadShaderIndex64bpb,
DXGI_FORMAT_UNKNOWN, kLoadShaderIndexUnknown, true, DXGI_FORMAT_R8_UNORM,
kLoadShaderIndexDXT5AToR8, xenos::XE_GPU_TEXTURE_SWIZZLE_RRRR},
// k_CTX1
{DXGI_FORMAT_R8G8_UNORM, DXGI_FORMAT_R8G8_UNORM, LoadMode::kCTX1,
DXGI_FORMAT_UNKNOWN, LoadMode::kUnknown, false, DXGI_FORMAT_UNKNOWN,
LoadMode::kUnknown, xenos::XE_GPU_TEXTURE_SWIZZLE_RGGG},
{DXGI_FORMAT_R8G8_UNORM, DXGI_FORMAT_R8G8_UNORM, kLoadShaderIndexCTX1,
DXGI_FORMAT_UNKNOWN, kLoadShaderIndexUnknown, false, DXGI_FORMAT_UNKNOWN,
kLoadShaderIndexUnknown, xenos::XE_GPU_TEXTURE_SWIZZLE_RGGG},
// k_DXT3A_AS_1_1_1_1
{DXGI_FORMAT_B4G4R4A4_UNORM, DXGI_FORMAT_B4G4R4A4_UNORM,
LoadMode::kDXT3AAs1111ToBGRA4, DXGI_FORMAT_UNKNOWN, LoadMode::kUnknown,
false, DXGI_FORMAT_UNKNOWN, LoadMode::kUnknown,
xenos::XE_GPU_TEXTURE_SWIZZLE_RGBA},
kLoadShaderIndexDXT3AAs1111ToBGRA4, DXGI_FORMAT_UNKNOWN,
kLoadShaderIndexUnknown, false, DXGI_FORMAT_UNKNOWN,
kLoadShaderIndexUnknown, xenos::XE_GPU_TEXTURE_SWIZZLE_RGBA},
// k_8_8_8_8_GAMMA_EDRAM
// Not usable as a texture.
{DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, LoadMode::kUnknown,
DXGI_FORMAT_UNKNOWN, LoadMode::kUnknown, false, DXGI_FORMAT_UNKNOWN,
LoadMode::kUnknown, xenos::XE_GPU_TEXTURE_SWIZZLE_RGBA},
{DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, kLoadShaderIndexUnknown,
DXGI_FORMAT_UNKNOWN, kLoadShaderIndexUnknown, false, DXGI_FORMAT_UNKNOWN,
kLoadShaderIndexUnknown, xenos::XE_GPU_TEXTURE_SWIZZLE_RGBA},
// k_2_10_10_10_FLOAT_EDRAM
// Not usable as a texture.
{DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, LoadMode::kUnknown,
DXGI_FORMAT_UNKNOWN, LoadMode::kUnknown, false, DXGI_FORMAT_UNKNOWN,
LoadMode::kUnknown, 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},
{DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, kLoadShaderIndexUnknown,
DXGI_FORMAT_UNKNOWN, kLoadShaderIndexUnknown, false, DXGI_FORMAT_UNKNOWN,
kLoadShaderIndexUnknown, xenos::XE_GPU_TEXTURE_SWIZZLE_RGBA},
};
D3D12TextureCache::D3D12TextureCache(const RegisterFile& register_file,
@ -551,31 +476,176 @@ bool D3D12TextureCache::Initialize() {
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.
for (uint32_t i = 0; i < uint32_t(LoadMode::kCount); ++i) {
const LoadModeInfo& load_mode_info = load_mode_info_[i];
for (size_t i = 0; i < kLoadShaderCount; ++i) {
const D3D12_SHADER_BYTECODE& current_load_shader_code = load_shader_code[i];
if (!current_load_shader_code.pShaderBytecode) {
continue;
}
*(load_pipelines_[i].ReleaseAndGetAddressOf()) =
ui::d3d12::util::CreateComputePipeline(device, load_mode_info.shader,
load_mode_info.shader_size,
load_root_signature_.Get());
ui::d3d12::util::CreateComputePipeline(
device, current_load_shader_code.pShaderBytecode,
current_load_shader_code.BytecodeLength,
load_root_signature_.Get());
if (!load_pipelines_[i]) {
XELOGE(
"D3D12TextureCache: Failed to create the texture loading pipeline "
"for mode {}",
"for shader {}",
i);
return false;
}
if (IsDrawResolutionScaled() && load_mode_info.shader_scaled) {
*(load_pipelines_scaled_[i].ReleaseAndGetAddressOf()) =
ui::d3d12::util::CreateComputePipeline(
device, load_mode_info.shader_scaled,
load_mode_info.shader_scaled_size, load_root_signature_.Get());
if (!load_pipelines_scaled_[i]) {
XELOGE(
"D3D12TextureCache: Failed to create the resolution-scaled texture "
"loading pipeline for mode {}",
i);
return false;
if (IsDrawResolutionScaled()) {
const D3D12_SHADER_BYTECODE& current_load_shader_code_scaled =
load_shader_code_scaled[i];
if (current_load_shader_code_scaled.pShaderBytecode) {
*(load_pipelines_scaled_[i].ReleaseAndGetAddressOf()) =
ui::d3d12::util::CreateComputePipeline(
device, current_load_shader_code_scaled.pShaderBytecode,
current_load_shader_code_scaled.BytecodeLength,
load_root_signature_.Get());
if (!load_pipelines_scaled_[i]) {
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,
unsupported_features & kUnsupportedResourceBit ? " resource" : "",
unsupported_features & kUnsupportedUnormBit ? " unorm" : "",
unsupported_features & kUnsupportedSnormBit ? " snorm" : "");
unsupported_features & kUnsupportedUnormBit ? " unsigned" : "",
unsupported_features & kUnsupportedSnormBit ? " signed" : "");
unsupported_format_features_used_[i] = 0;
}
}
@ -1383,28 +1453,29 @@ bool D3D12TextureCache::IsDecompressionNeeded(xenos::TextureFormat format,
(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)];
if (key.signed_separate) {
return host_format.load_mode_snorm;
return host_format.load_shader_signed;
}
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 {
const HostFormat& host_format = host_formats_[uint32_t(key.format)];
return host_format.load_mode_snorm != LoadMode::kUnknown &&
host_format.load_mode_snorm != host_format.load_mode;
return host_format.load_shader_signed != kLoadShaderIndexUnknown &&
host_format.load_shader_signed != host_format.load_shader;
}
bool D3D12TextureCache::IsScaledResolveSupportedForFormat(
TextureKey key) const {
LoadMode load_mode = GetLoadMode(key);
return load_mode != LoadMode::kUnknown &&
load_pipelines_scaled_[uint32_t(load_mode)] != nullptr;
LoadShaderIndex load_shader = GetLoadShaderIndex(key);
return load_shader != kLoadShaderIndexUnknown &&
load_pipelines_scaled_[load_shader] != nullptr;
}
uint32_t D3D12TextureCache::GetHostFormatSwizzle(TextureKey key) const {
@ -1502,19 +1573,18 @@ bool D3D12TextureCache::LoadTextureDataFromResidentMemoryImpl(Texture& texture,
ID3D12Device* device = command_processor_.GetD3D12Provider().GetDevice();
// Get the pipeline.
LoadMode load_mode = GetLoadMode(texture_key);
if (load_mode == LoadMode::kUnknown) {
LoadShaderIndex load_shader = GetLoadShaderIndex(texture_key);
if (load_shader == kLoadShaderIndexUnknown) {
return false;
}
bool texture_resolution_scaled = texture_key.scaled_resolve;
ID3D12PipelineState* pipeline =
texture_resolution_scaled
? load_pipelines_scaled_[uint32_t(load_mode)].Get()
: load_pipelines_[uint32_t(load_mode)].Get();
texture_resolution_scaled ? load_pipelines_scaled_[load_shader].Get()
: load_pipelines_[load_shader].Get();
if (pipeline == nullptr) {
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.
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_height = host_block_compressed ? block_height : 1;
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) {
// Decompressing guest blocks.
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 /
host_block_width,
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));
host_slice_size_base = xe::align(
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 /
host_block_width,
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));
UINT64 host_slice_sizes_mip = xe::align(
UINT64(host_slice_layout_mip.Footprint.RowPitch) *
@ -1693,8 +1763,8 @@ bool D3D12TextureCache::LoadTextureDataFromResidentMemoryImpl(Texture& texture,
descriptors_allocated[descriptor_write_index++];
ui::d3d12::util::CreateBufferTypedUAV(
device, descriptor_dest.first, copy_buffer,
ui::d3d12::util::GetUintPow2DXGIFormat(load_mode_info.uav_bpe_log2),
uint32_t(copy_buffer_size) >> load_mode_info.uav_bpe_log2);
ui::d3d12::util::GetUintPow2DXGIFormat(load_shader_info.dest_bpe_log2),
uint32_t(copy_buffer_size) >> load_shader_info.dest_bpe_log2);
command_list.D3DSetComputeRootDescriptorTable(2, descriptor_dest.second);
// 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,
@ -1707,13 +1777,13 @@ bool D3D12TextureCache::LoadTextureDataFromResidentMemoryImpl(Texture& texture,
if (bindless_resources_used_) {
descriptor_unscaled_source =
command_processor_.GetSharedMemoryUintPow2BindlessSRVHandlePair(
load_mode_info.srv_bpe_log2);
load_shader_info.source_bpe_log2);
} else {
assert_true(descriptor_write_index < descriptor_count);
descriptor_unscaled_source =
descriptors_allocated[descriptor_write_index++];
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(
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.
bool scaled_mips_source_set_up = false;
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;
++loop_level) {
bool is_base = loop_level == 0;
@ -1776,8 +1846,8 @@ bool D3D12TextureCache::LoadTextureDataFromResidentMemoryImpl(Texture& texture,
assert_true(descriptor_write_index < descriptor_count);
ui::d3d12::util::DescriptorCpuGpuHandlePair descriptor_scaled_source =
descriptors_allocated[descriptor_write_index++];
CreateCurrentScaledResolveRangeUintPow2SRV(descriptor_scaled_source.first,
load_mode_info.srv_bpe_log2);
CreateCurrentScaledResolveRangeUintPow2SRV(
descriptor_scaled_source.first, load_shader_info.source_bpe_log2);
command_list.D3DSetComputeRootDescriptorTable(
1, descriptor_scaled_source.second);
if (!is_base) {
@ -2003,7 +2073,7 @@ uint32_t D3D12TextureCache::FindOrCreateTextureDescriptor(
if (is_signed) {
// Not supporting signed compressed textures - hopefully DXN and DXT5A are
// 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 {
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 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 {
// Format info for the regular case.
// DXGI format (typeless when different signedness or number representation
// is used) for the texture resource.
DXGI_FORMAT dxgi_format_resource;
// DXGI format for unsigned normalized or unsigned/signed float SRV.
DXGI_FORMAT dxgi_format_unorm;
// The regular load mode, used when special modes (like signed-specific or
// decompressing) aren't needed.
LoadMode load_mode;
DXGI_FORMAT dxgi_format_unsigned;
// The regular load shader, used when special load shaders (like
// signed-specific or decompressing) aren't needed.
LoadShaderIndex load_shader;
// 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,
// this is the load mode for the signed version. Otherwise the regular
// load_mode will be used for the signed version, and a single copy will be
// created if both unsigned and signed are used.
LoadMode load_mode_snorm;
// this is the load shader for the signed version. Otherwise the regular
// load_shader will be used for the signed version, and a single copy will
// be created if both unsigned and signed are used.
LoadShaderIndex load_shader_signed;
// 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
@ -276,7 +214,7 @@ class D3D12TextureCache final : public TextureCache {
// supports unsigned normalized formats - let's hope GPUSIGN_SIGNED was not
// used for DXN and DXT5A.
DXGI_FORMAT dxgi_format_uncompressed;
LoadMode decompress_mode;
LoadShaderIndex load_shader_decompress;
// Mapping of Xenos swizzle components to DXGI format components.
uint32_t swizzle;
@ -440,13 +378,13 @@ class D3D12TextureCache final : public TextureCache {
const HostFormat& host_format = host_formats_[uint32_t(format)];
return IsDecompressionNeeded(format, width, height)
? host_format.dxgi_format_uncompressed
: host_format.dxgi_format_unorm;
: host_format.dxgi_format_unsigned;
}
static DXGI_FORMAT GetDXGIUnormFormat(TextureKey key) {
return GetDXGIUnormFormat(key.format, key.GetWidth(), key.GetHeight());
}
static LoadMode GetLoadMode(TextureKey key);
static LoadShaderIndex GetLoadShaderIndex(TextureKey key);
static constexpr bool AreDimensionsCompatible(
xenos::FetchOpDimension binding_dimension,
@ -528,14 +466,11 @@ class D3D12TextureCache final : public TextureCache {
D3D12CommandProcessor& command_processor_;
bool bindless_resources_used_;
static const LoadModeInfo load_mode_info_[];
Microsoft::WRL::ComPtr<ID3D12RootSignature> load_root_signature_;
std::array<Microsoft::WRL::ComPtr<ID3D12PipelineState>,
size_t(LoadMode::kCount)>
std::array<Microsoft::WRL::ComPtr<ID3D12PipelineState>, kLoadShaderCount>
load_pipelines_;
// Load pipelines for resolution-scaled resolve targets.
std::array<Microsoft::WRL::ComPtr<ID3D12PipelineState>,
size_t(LoadMode::kCount)>
std::array<Microsoft::WRL::ComPtr<ID3D12PipelineState>, kLoadShaderCount>
load_pipelines_scaled_;
std::vector<SRVDescriptorCachePage> srv_descriptor_cache_;

View File

@ -73,6 +73,80 @@ DEFINE_uint32(
namespace xe {
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,
SharedMemory& shared_memory,
uint32_t draw_resolution_scale_x,

View File

@ -395,6 +395,69 @@ class TextureCache {
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 =
uint8_t(xenos::TextureSign::kUnsigned) * uint8_t(0b01010101);
@ -472,6 +535,11 @@ class TextureCache {
// should be made.
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);
// 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
@ -527,6 +595,8 @@ class TextureCache {
uint32_t draw_resolution_scale_x_;
uint32_t draw_resolution_scale_y_;
static const LoadShaderInfo load_shader_info_[kLoadShaderCount];
xe::global_critical_region global_critical_region_;
// 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