diff --git a/app/src/main/cpp/skyline/gpu/interconnect/graphics_context.h b/app/src/main/cpp/skyline/gpu/interconnect/graphics_context.h index 6647eedb..df89c4c6 100644 --- a/app/src/main/cpp/skyline/gpu/interconnect/graphics_context.h +++ b/app/src/main/cpp/skyline/gpu/interconnect/graphics_context.h @@ -1686,23 +1686,60 @@ namespace skyline::gpu::interconnect { private: texture::Format ConvertTicFormat(TextureImageControl::FormatWord format) { using TIC = TextureImageControl; - #define TIC_FORMAT(format, componentR, componentG, componentB, componentA, swizzleX, swizzleY, swizzleZ, swizzleW) TIC::FormatWord{TIC::ImageFormat::format, TIC::ImageComponent::componentR, TIC::ImageComponent::componentG, TIC::ImageComponent::componentB, TIC::ImageComponent::componentA, TIC::ImageSwizzle::swizzleX, TIC::ImageSwizzle::swizzleY, TIC::ImageSwizzle::swizzleZ, TIC::ImageSwizzle::swizzleW}.Raw() + #define TIC_FORMAT(format, componentR, componentG, componentB, componentA, swizzleX, swizzleY, swizzleZ, swizzleW) \ + TIC::FormatWord{TIC::ImageFormat::format, \ + TIC::ImageComponent::componentR, TIC::ImageComponent::componentG, TIC::ImageComponent::componentB, TIC::ImageComponent::componentA, \ + TIC::ImageSwizzle::swizzleX, TIC::ImageSwizzle::swizzleY, TIC::ImageSwizzle::swizzleZ, TIC::ImageSwizzle::swizzleW}.Raw() - #define TIC_FORMAT_SC(format, component, swizzleX, swizzleY, swizzleZ, swizzleW) TIC_FORMAT(format, component, component, component, component, swizzleX, swizzleY, swizzleZ, swizzleW) + // For formats where all components are of the same type + #define TIC_FORMAT_ST(format, component, swizzleX, swizzleY, swizzleZ, swizzleW) \ + TIC_FORMAT(format, component, component, component, component, swizzleX, swizzleY, swizzleZ, swizzleW) + + #define TIC_FORMAT_CASE(ticFormat, skFormat, componentR, componentG, componentB, componentA, swizzleX, swizzleY, swizzleZ, swizzleW) \ + case TIC_FORMAT(ticFormat, component, component, component, component, swizzleX, swizzleY, swizzleZ, swizzleW): \ + return format::skFormat + + #define TIC_FORMAT_CASE_ST(ticFormat, skFormat, component, swizzleX, swizzleY, swizzleZ, swizzleW) \ + case TIC_FORMAT_ST(ticFormat, component, swizzleX, swizzleY, swizzleZ, swizzleW): \ + return format::skFormat ## component + + #define TIC_FORMAT_CASE_NORM(ticFormat, skFormat, swizzleX, swizzleY, swizzleZ, swizzleW) \ + TIC_FORMAT_CASE_ST(ticFormat, skFormat, Unorm, swizzleX, swizzleY, swizzleZ, swizzleW); \ + TIC_FORMAT_CASE_ST(ticFormat, skFormat, Snorm, swizzleX, swizzleY, swizzleZ, swizzleW) + + #define TIC_FORMAT_CASE_INT(ticFormat, skFormat, swizzleX, swizzleY, swizzleZ, swizzleW) \ + TIC_FORMAT_CASE_ST(ticFormat, skFormat, Uint, swizzleX, swizzleY, swizzleZ, swizzleW); \ + TIC_FORMAT_CASE_ST(ticFormat, skFormat, Sint, swizzleX, swizzleY, swizzleZ, swizzleW) + + #define TIC_FORMAT_CASE_NORM_INT(ticFormat, skFormat, swizzleX, swizzleY, swizzleZ, swizzleW) \ + TIC_FORMAT_CASE_NORM(ticFormat, skFormat, swizzleX, swizzleY, swizzleZ, swizzleW); \ + TIC_FORMAT_CASE_INT(ticFormat, skFormat, swizzleX, swizzleY, swizzleZ, swizzleW) + + #define TIC_FORMAT_CASE_NORM_INT_FLOAT(ticFormat, skFormat, swizzleX, swizzleY, swizzleZ, swizzleW) \ + TIC_FORMAT_CASE_NORM_INT(ticFormat, skFormat, swizzleX, swizzleY, swizzleZ, swizzleW); \ + TIC_FORMAT_CASE_ST(ticFormat, skFormat, Float, swizzleX, swizzleY, swizzleZ, swizzleW) switch (format.Raw()) { - case TIC_FORMAT_SC(B5G6R5, Unorm, B, G, R, OneFloat): - return format::R5G6B5Unorm; - - case TIC_FORMAT_SC(A8R8G8B8, Unorm, R, G, B, A): - return format::A8B8G8R8Unorm; + TIC_FORMAT_CASE_ST(B5G6R5, R5G6B5, Unorm, B, G, R, OneFloat); + TIC_FORMAT_CASE_NORM_INT(A8R8G8B8, R8G8B8A8, R, G, B, A); + TIC_FORMAT_CASE_NORM_INT(A8R8G8B8, A8B8G8R8, A, R, G, B); + TIC_FORMAT_CASE_NORM_INT(A8R8G8B8, G8B8A8R8, G, B, A, R); + TIC_FORMAT_CASE_NORM_INT_FLOAT(R16G16B16A16, R16G16B16A16, R, G, B, A); + TIC_FORMAT_CASE_NORM_INT(A2B10G10R10, A2B10G10R10, R, G, B, A); + TIC_FORMAT_CASE_ST(Astc4x4, Astc4x4, Unorm, R, G, B, A); default: throw exception("Cannot translate TIC format: 0x{:X}", static_cast(format.Raw())); } - #undef TIC_FORMAT_SC #undef TIC_FORMAT + #undef TIC_FORMAT_ST + #undef TIC_FORMAT_CASE + #undef TIC_FORMAT_CASE_ST + #undef TIC_FORMAT_CASE_NORM + #undef TIC_FORMAT_CASE_INT + #undef TIC_FORMAT_CASE_NORM_INT + #undef TIC_FORMAT_CASE_NORM_INT_FLOAT } std::shared_ptr GetPoolTextureView(u32 index) { diff --git a/app/src/main/cpp/skyline/gpu/texture/format.h b/app/src/main/cpp/skyline/gpu/texture/format.h index ca11a147..6ea3311c 100644 --- a/app/src/main/cpp/skyline/gpu/texture/format.h +++ b/app/src/main/cpp/skyline/gpu/texture/format.h @@ -6,45 +6,101 @@ #include "texture.h" namespace skyline::gpu::format { - using Format = gpu::texture::FormatBase; - using vkf = vk::Format; + // @fmt:off + using vka = vk::ImageAspectFlagBits; using swc = gpu::texture::SwizzleChannel; - // Color Formats - constexpr Format R8G8B8A8Unorm{sizeof(u32), vkf::eR8G8B8A8Unorm}; - constexpr Format R5G6B5Unorm{sizeof(u16), vkf::eR5G6B5UnormPack16}; - constexpr Format A2B10G10R10Unorm{sizeof(u32), vkf::eA2B10G10R10UnormPack32}; - constexpr Format A8B8G8R8Srgb{sizeof(u32), vkf::eA8B8G8R8SrgbPack32}; - constexpr Format A8B8G8R8Unorm{sizeof(u32), vkf::eA8B8G8R8UnormPack32}; - constexpr Format A8B8G8R8Snorm{sizeof(u32), vkf::eA8B8G8R8SnormPack32}; - constexpr Format R16G16Unorm{sizeof(u32), vkf::eR16G16Unorm}; - constexpr Format R16G16Snorm{sizeof(u32), vkf::eR16G16Snorm}; - constexpr Format R16G16Sint{sizeof(u32), vkf::eR16G16Sint}; - constexpr Format R16G16Uint{sizeof(u32), vkf::eR16G16Uint}; - constexpr Format R16G16Float{sizeof(u32), vkf::eR16G16Sfloat}; - constexpr Format B10G11R11Float{sizeof(u32), vkf::eB10G11R11UfloatPack32}; - constexpr Format R32Float{sizeof(u32), vkf::eR32Sfloat}; - constexpr Format R8G8Unorm{sizeof(u16), vkf::eR8G8Unorm}; - constexpr Format R8G8Snorm{sizeof(u16), vkf::eR8G8Snorm}; - constexpr Format R16Unorm{sizeof(u16), vkf::eR16Unorm}; - constexpr Format R16Float{sizeof(u16), vkf::eR16Sfloat}; - constexpr Format R8Unorm{sizeof(u8), vkf::eR8Unorm}; - constexpr Format R8Snorm{sizeof(u8), vkf::eR8Snorm}; - constexpr Format R8Sint{sizeof(u8), vkf::eR8Sint}; - constexpr Format R8Uint{sizeof(u8), vkf::eR8Uint}; - constexpr Format R32B32G32A32Float{sizeof(u32) * 4, vkf::eR32G32B32A32Sfloat, .swizzle = { + #define FORMAT(name, bitsPerBlock, format, ...) \ + constexpr gpu::texture::FormatBase name{bitsPerBlock / 8, vk::Format::format, ##__VA_ARGS__} + + #define FORMAT_SUFF_UNORM_SRGB(name, bitsPerBlock, format, fmtSuffix, ...) \ + FORMAT(name ## Unorm, bitsPerBlock, format ## Unorm ## fmtSuffix, ##__VA_ARGS__); \ + FORMAT(name ## Srgb, bitsPerBlock, format ## Srgb ## fmtSuffix, ##__VA_ARGS__) + + #define FORMAT_SUFF_INT(name, bitsPerBlock, format, fmtSuffix, ...) \ + FORMAT(name ## Uint, bitsPerBlock, format ## Uint ## fmtSuffix, ##__VA_ARGS__); \ + FORMAT(name ## Sint, bitsPerBlock, format ## Sint ## fmtSuffix, ##__VA_ARGS__) + + #define FORMAT_INT(name, bitsPerBlock, format, ...) \ + FORMAT_SUFF_INT(name, bitsPerBlock, format,, ##__VA_ARGS__) + + #define FORMAT_SUFF_INT_FLOAT(name, bitsPerBlock, format, fmtSuffix, ...) \ + FORMAT_SUFF_INT(name, bitsPerBlock, format, fmtSuffix, ##__VA_ARGS__) ; \ + FORMAT(name ## Float, bitsPerBlock, format ## Sfloat ## fmtSuffix, ##__VA_ARGS__) + + #define FORMAT_INT_FLOAT(name, bitsPerBlock, format, ...) \ + FORMAT_SUFF_INT_FLOAT(name, bitsPerBlock, format,, ##__VA_ARGS__) + + #define FORMAT_SUFF_NORM_INT(name, bitsPerBlock, format, fmtSuffix, ...) \ + FORMAT_SUFF_INT(name, bitsPerBlock, format, fmtSuffix, ##__VA_ARGS__); \ + FORMAT(name ## Unorm, bitsPerBlock, format ## Unorm ## fmtSuffix, ##__VA_ARGS__); \ + FORMAT(name ## Snorm, bitsPerBlock, format ## Snorm ## fmtSuffix, ##__VA_ARGS__) + + #define FORMAT_NORM_INT(name, bitsPerBlock, format, ...) \ + FORMAT_SUFF_NORM_INT(name, bitsPerBlock, format,, ##__VA_ARGS__) + + #define FORMAT_SUFF_NORM_INT_SRGB(name, bitsPerBlock, format, fmtSuffix, ...) \ + FORMAT_SUFF_NORM_INT(name, bitsPerBlock, format, fmtSuffix, ##__VA_ARGS__); \ + FORMAT(name ## Srgb, bitsPerBlock, format ## Srgb ## fmtSuffix, ##__VA_ARGS__) + + #define FORMAT_NORM_INT_SRGB(name, bitsPerBlock, format, ...) \ + FORMAT_SUFF_NORM_INT_SRGB(name, bitsPerBlock, format,, ##__VA_ARGS__) + + #define FORMAT_SUFF_NORM_INT_FLOAT(name, bitsPerBlock, format, fmtSuffix, ...) \ + FORMAT_SUFF_NORM_INT(name, bitsPerBlock, format, fmtSuffix, ##__VA_ARGS__) ; \ + FORMAT(name ## Float, bitsPerBlock, format ## Sfloat ## fmtSuffix, ##__VA_ARGS__) + + #define FORMAT_NORM_INT_FLOAT(name, bitsPerBlock, format, ...) \ + FORMAT_SUFF_NORM_INT_FLOAT(name, bitsPerBlock, format,, ##__VA_ARGS__) + + // These are ordered according to Size -> Component Count -> R/G/B/A Order + + // Color formats + FORMAT_NORM_INT_SRGB(R8, 8, eR8); + FORMAT_NORM_INT_FLOAT(R16, 16, eR16); + FORMAT_NORM_INT_SRGB(R8G8, 16, eR8G8); + FORMAT(R5G6B5Unorm, 16, eR5G6B5UnormPack16); + FORMAT_INT_FLOAT(R32, 32, eR32); + FORMAT_NORM_INT_FLOAT(R16G16, 32, eR16G16); + FORMAT(B10G11R11Float, 32, eB10G11R11UfloatPack32); + FORMAT_NORM_INT_SRGB(R8G8B8A8, 32, eR8G8B8A8); + FORMAT_NORM_INT_SRGB(G8B8A8R8, 32, eB8G8R8A8, .swizzle = { .blue = swc::Green, .green = swc::Blue, - }}; - constexpr Format R16G16B16A16Unorm{sizeof(u16) * 4, vkf::eR16G16B16A16Unorm}; - constexpr Format R16G16B16A16Snorm{sizeof(u16) * 4, vkf::eR16G16B16A16Snorm}; - constexpr Format R16G16B16A16Sint{sizeof(u16) * 4, vkf::eR16G16B16A16Sint}; - constexpr Format R16G16B16A16Uint{sizeof(u16) * 4, vkf::eR16G16B16A16Uint}; - constexpr Format R16G16B16A16Float{sizeof(u16) * 4, vkf::eR16G16B16A16Sfloat}; - constexpr Format B8G8R8A8Unorm{sizeof(u32), vkf::eB8G8R8A8Unorm}; - constexpr Format B8G8R8A8Srgb{sizeof(u32), vkf::eB8G8R8A8Srgb}; + .red = swc::Alpha, + .alpha = swc::Red + }); + FORMAT_NORM_INT_SRGB(B8G8R8A8, 32, eB8G8R8A8); + FORMAT_SUFF_NORM_INT_SRGB(A8B8G8R8, 32, eA8B8G8R8, Pack32); + FORMAT_SUFF_NORM_INT(A2B10G10R10, 32, eA2B10G10R10, Pack32); + FORMAT_NORM_INT_FLOAT(R16G16B16A16, 16 * 4, eR16G16B16A16); + FORMAT_INT_FLOAT(R32B32G32A32, 32 * 4, eR32G32B32A32, .swizzle = { + .blue = swc::Green, + .green = swc::Blue, + }); + + // Compressed Colour Formats + FORMAT_SUFF_UNORM_SRGB(Astc4x4, 128, eAstc4x4, Block); // Depth/Stencil Formats - constexpr Format S8D24Unorm{sizeof(u32), vkf::eD24UnormS8Uint, vka::eStencil | vka::eDepth}; // TODO: Swizzle Depth/Stencil + FORMAT(D32Float, 32, eD32Sfloat, vka::eDepth); + FORMAT(S8D24Unorm, 32, eD24UnormS8Uint, .vkAspect = { + vka::eStencil | vka::eDepth + }); // TODO: Swizzle Depth/Stencil + + #undef FORMAT + #undef FORMAT_SUFF_UNORM_SRGB + #undef FORMAT_SUFF_INT + #undef FORMAT_INT + #undef FORMAT_SUFF_INT_FLOAT + #undef FORMAT_INT_FLOAT + #undef FORMAT_SUFF_NORM_INT + #undef FORMAT_NORM_INT + #undef FORMAT_SUFF_NORM_INT_SRGB + #undef FORMAT_NORM_INT_SRGB + #undef FORMAT_SUFF_NORM_INT_FLOAT + #undef FORMAT_NORM_INT_FLOAT + + // @fmt:on }