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 694ddb23..359322c3 100644 --- a/app/src/main/cpp/skyline/gpu/interconnect/graphics_context.h +++ b/app/src/main/cpp/skyline/gpu/interconnect/graphics_context.h @@ -203,15 +203,15 @@ namespace skyline::gpu::interconnect { FORMAT_SAME_CASE(B5G6R5, Unorm); FORMAT_SAME_CASE(B5G5R5A1, Unorm); FORMAT_SAME_INT_FLOAT_CASE(R32); - FORMAT_SAME_CASE(R11G11B10, Float); + FORMAT_SAME_CASE(B10G11R11, Float); FORMAT_SAME_NORM_INT_FLOAT_CASE(R16G16); FORMAT_SAME_CASE(R8G8B8A8, Unorm); FORMAT_SAME_CASE(R8G8B8A8, Srgb); FORMAT_NORM_INT_SRGB_CASE(R8G8B8X8, R8G8B8A8); FORMAT_SAME_CASE(B8G8R8A8, Unorm); FORMAT_SAME_CASE(B8G8R8A8, Srgb); - FORMAT_SAME_CASE(A2R10G10B10, Unorm); - FORMAT_SAME_CASE(A2R10G10B10, Uint); + FORMAT_SAME_CASE(A2B10G10R10, Unorm); + FORMAT_SAME_CASE(A2B10G10R10, Uint); FORMAT_SAME_INT_CASE(R32G32); FORMAT_SAME_CASE(R32G32, Float); FORMAT_SAME_CASE(R16G16B16A16, Float); @@ -253,9 +253,11 @@ namespace skyline::gpu::interconnect { case MaxwellDepthRtFormat::D32Float: return format::D32Float; case MaxwellDepthRtFormat::S8D24Unorm: - return format::S8D24Unorm; + return format::S8UintD24Unorm; case MaxwellDepthRtFormat::D24S8Unorm: - return format::D24S8Unorm; + return format::D24UnormS8Uint; + case MaxwellDepthRtFormat::D32S8X24Float: + return format::D32FloatS8Uint; default: throw exception("Cannot translate the supplied depth RT format: 0x{:X}", static_cast(format)); } @@ -1704,55 +1706,77 @@ 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) \ + TIC::FormatWord{TIC::ImageFormat::format, \ + TIC::ImageComponent::componentR, TIC::ImageComponent::componentG, TIC::ImageComponent::componentB, TIC::ImageComponent::componentA}.Raw() // 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_ST(format, component) \ + TIC_FORMAT(format, component, component, component, component) - #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): \ + #define TIC_FORMAT_CASE(ticFormat, skFormat, componentR, componentG, componentB, componentA) \ + case TIC_FORMAT(ticFormat, componentR, componentG, componentB, componentA): \ 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): \ + #define TIC_FORMAT_CASE_ST(ticFormat, skFormat, component) \ + case TIC_FORMAT_ST(ticFormat, component): \ 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_NORM(ticFormat, skFormat) \ + TIC_FORMAT_CASE_ST(ticFormat, skFormat, Unorm); \ + TIC_FORMAT_CASE_ST(ticFormat, skFormat, Snorm) - #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_INT(ticFormat, skFormat) \ + TIC_FORMAT_CASE_ST(ticFormat, skFormat, Uint); \ + TIC_FORMAT_CASE_ST(ticFormat, skFormat, Sint) - #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(ticFormat, skFormat) \ + TIC_FORMAT_CASE_NORM(ticFormat, skFormat); \ + TIC_FORMAT_CASE_INT(ticFormat, skFormat) - #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) + #define TIC_FORMAT_CASE_NORM_INT_FLOAT(ticFormat, skFormat) \ + TIC_FORMAT_CASE_NORM_INT(ticFormat, skFormat); \ + TIC_FORMAT_CASE_ST(ticFormat, skFormat, Float) - switch (format.Raw()) { - TIC_FORMAT_CASE_NORM_INT(R8, R8R001, R, Zero, Zero, OneFloat); - 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); - TIC_FORMAT_CASE_ST(Dxt1, Bc1, Unorm, R, G, B, A); - TIC_FORMAT_CASE_ST(Dxt23, Bc2, Unorm, R, G, B, A); - TIC_FORMAT_CASE_ST(Dxt45, Bc3, Unorm, R, G, B, A); - TIC_FORMAT_CASE_ST(Dxn1, Bc4111R, Unorm, OneFloat, OneFloat, OneFloat, R); - TIC_FORMAT_CASE_ST(Dxn1, Bc4RRR1, Unorm, R, R, R, OneFloat); - TIC_FORMAT_CASE_ST(BC7U, Bc7, Unorm, R, G, B, A); - TIC_FORMAT_CASE_ST(ZF32, D32, Float, R, R, R, OneFloat); + #define TIC_FORMAT_CASE_INT_FLOAT(ticFormat, skFormat) \ + TIC_FORMAT_CASE_INT(ticFormat, skFormat); \ + TIC_FORMAT_CASE_ST(ticFormat, skFormat, Float) + + // Ignore the swizzle components of the format word + switch (format.Raw() & TextureImageControl::FormatWord::FormatColorComponentMask) { + TIC_FORMAT_CASE_NORM_INT(R8, R8); + + TIC_FORMAT_CASE_NORM_INT_FLOAT(R16, R16); + TIC_FORMAT_CASE_ST(D16, D16, Unorm); + TIC_FORMAT_CASE_NORM_INT(R8G8, R8G8); + TIC_FORMAT_CASE_ST(B5G6R5, B5G6R5, Unorm); + TIC_FORMAT_CASE_ST(A1B5G5R5, A1B5G5R5, Unorm); + + TIC_FORMAT_CASE_INT_FLOAT(R32, R32); + TIC_FORMAT_CASE_ST(D32, D32, Float); + TIC_FORMAT_CASE_NORM_INT_FLOAT(R16G16, R16G16); + TIC_FORMAT_CASE(R8G24, D24UnormS8Uint, Uint, Unorm, Unorm, Unorm); + TIC_FORMAT_CASE(S8D24, D24UnormS8Uint, Uint, Unorm, Uint, Uint); + TIC_FORMAT_CASE(S8D24, D24UnormS8Uint, Uint, Unorm, Unorm, Unorm); + TIC_FORMAT_CASE_ST(B10G11R11, B10G11R11, Float); + TIC_FORMAT_CASE_NORM_INT(A8B8G8R8, A8B8G8R8); + TIC_FORMAT_CASE_NORM_INT(A2B10G10R10, A2B10G10R10); + TIC_FORMAT_CASE_ST(E5B9G9R9, E5B9G9R9, Float); + + TIC_FORMAT_CASE_ST(BC1, BC1, Unorm); + TIC_FORMAT_CASE_NORM(BC4, BC4); + TIC_FORMAT_CASE_INT_FLOAT(R32G32, R32G32); + TIC_FORMAT_CASE(D32S8, D32FloatS8Uint, Float, Uint, Uint, Unorm); + TIC_FORMAT_CASE_NORM_INT_FLOAT(R16G16B16A16, R16G16B16A16); + + TIC_FORMAT_CASE_ST(Astc4x4, Astc4x4, Unorm); + TIC_FORMAT_CASE_ST(BC2, BC2, Unorm); + TIC_FORMAT_CASE_ST(BC3, BC3, Unorm); + TIC_FORMAT_CASE_NORM(BC5, BC5); + TIC_FORMAT_CASE(Bc6HUfloat, Bc6HUfloat, Float, Float, Float, Float); + TIC_FORMAT_CASE(Bc6HSfloat, Bc6HSfloat, Float, Float, Float, Float); + TIC_FORMAT_CASE_ST(BC7, BC7, Unorm); + TIC_FORMAT_CASE_INT_FLOAT(R32G32B32A32, R32G32B32A32); default: throw exception("Cannot translate TIC format: 0x{:X}", static_cast(format.Raw())); @@ -1768,6 +1792,40 @@ namespace skyline::gpu::interconnect { #undef TIC_FORMAT_CASE_NORM_INT_FLOAT } + /** + * @tparam ConvGR Converts all green component + * @tparam SwapBR Swaps blue and red components + */ + template + vk::ComponentMapping ConvertTicSwizzleMapping(TextureImageControl::FormatWord format) { + auto convertComponentSwizzle{[](TextureImageControl::ImageSwizzle swizzle) { + switch (swizzle) { + case TextureImageControl::ImageSwizzle::R: + return SwapBR ? vk::ComponentSwizzle::eB : vk::ComponentSwizzle::eR; + case TextureImageControl::ImageSwizzle::G: + return ConvGR ? vk::ComponentSwizzle::eR : vk::ComponentSwizzle::eG; + case TextureImageControl::ImageSwizzle::B: + return SwapBR ? vk::ComponentSwizzle::eR : vk::ComponentSwizzle::eB; + case TextureImageControl::ImageSwizzle::A: + return vk::ComponentSwizzle::eA; + case TextureImageControl::ImageSwizzle::Zero: + return vk::ComponentSwizzle::eZero; + case TextureImageControl::ImageSwizzle::OneFloat: + case TextureImageControl::ImageSwizzle::OneInt: + return vk::ComponentSwizzle::eOne; + default: + throw exception("Invalid swizzle: {:X}", static_cast(swizzle)); + } + }}; + + return vk::ComponentMapping{ + .r = convertComponentSwizzle(format.swizzleX), + .g = convertComponentSwizzle(format.swizzleY), + .b = convertComponentSwizzle(format.swizzleZ), + .a = convertComponentSwizzle(format.swizzleW) + }; + } + std::shared_ptr GetPoolTextureView(u32 index) { if (!texturePool.imageControls.valid()) { auto mappings{channelCtx.asCtx->gmmu.TranslateRange(texturePool.iova, texturePool.maximumIndex * sizeof(TextureImageControl))}; @@ -1784,6 +1842,13 @@ namespace skyline::gpu::interconnect { auto &guest{poolTexture.guest}; guest.format = ConvertTicFormat(textureControl.formatWord); + if (guest.format->IsDepthOrStencil()) // G/R are equivalent for depth/stencil + guest.swizzle = ConvertTicSwizzleMapping(textureControl.formatWord); + else if (guest.format->swapRedBlue) + guest.swizzle = ConvertTicSwizzleMapping(textureControl.formatWord); + else + guest.swizzle = ConvertTicSwizzleMapping(textureControl.formatWord); + constexpr size_t CubeFaceCount{6}; //!< The amount of faces of a cube guest.baseArrayLayer = static_cast(textureControl.BaseLayer()); diff --git a/app/src/main/cpp/skyline/gpu/interconnect/types/tic.h b/app/src/main/cpp/skyline/gpu/interconnect/types/tic.h index 69daf9cc..623557e3 100644 --- a/app/src/main/cpp/skyline/gpu/interconnect/types/tic.h +++ b/app/src/main/cpp/skyline/gpu/interconnect/types/tic.h @@ -29,23 +29,23 @@ namespace skyline::gpu::interconnect { R32B24G8 = 0x05, Etc2Rgb = 0x06, X8B8G8R8 = 0x07, - A8R8G8B8 = 0x08, + A8B8G8R8 = 0x08, A2B10G10R10 = 0x09, Etc2RgbPta = 0x0A, Etc2Rgba = 0x0B, R16G16 = 0x0C, - G8R24 = 0x0D, - G24R8 = 0x0E, + R24G8 = 0x0D, + R8G24 = 0x0E, R32 = 0x0F, - BC6hSf16 = 0x10, - BC6hUf16 = 0x11, - A4B4G4R4 = 0x12, + Bc6HSfloat = 0x10, + Bc6HUfloat = 0x11, + R4G4B4A = 0x12, A5B5G5R1 = 0x13, A1B5G5R5 = 0x14, B5G6R5 = 0x15, B6G5R5 = 0x16, - BC7U = 0x17, - G8R8 = 0x18, + BC7 = 0x17, + R8G8 = 0x18, Eac = 0x19, EacX2 = 0x1A, R16 = 0x1B, @@ -53,37 +53,37 @@ namespace skyline::gpu::interconnect { R8 = 0x1D, G4R4 = 0x1E, R1 = 0x1F, - E5B9G9R9SharedExponent = 0x20, - BF10GF11RF11 = 0x21, + E5B9G9R9 = 0x20, + B10G11R11 = 0x21, G8B8G8R8 = 0x22, B8G8R8G8 = 0x23, - Dxt1 = 0x24, - Dxt23 = 0x25, - Dxt45 = 0x26, - Dxn1 = 0x27, - Dxn2 = 0x28, - Z24S8 = 0x29, - X8Z24 = 0x2A, - S8Z24 = 0x2B, - X4V4Z24_Cov4R4V = 0x2C, - X4V4Z24_Cov8R8V = 0x2D, - V8Z24_Cov4R12V = 0x2E, - ZF32 = 0x2F, - ZF32_X24S8 = 0x30, - X8Z24_X20V4S8_Cov4R4V = 0x31, - X8Z24_X20V4S8_Cov8R8V = 0x32, - ZF32_X20V4X8_Cov4R4V = 0x33, - ZF32_X20V4X8_Cov8R8V = 0x34, - ZF32_X20V4S8_Cov4R4V = 0x35, - ZF32_X20V4S8_Cov8R8V = 0x36, - X8Z24_X16V8S8_Cov4R12V = 0x37, - ZF32_X16V8X8_Cov4R12V = 0x38, - ZF32_X16V8S8_Cov4R12V = 0x39, - Z16 = 0x3A, - V8Z24_Cov8R24V = 0x3B, - X8Z24_X16V8S8_Cov8R24V = 0x3C, - ZF32_X16V8X8_Cov8R24V = 0x3D, - ZF32_X16V8S8_Cov8R24V = 0x3E, + BC1 = 0x24, + BC2 = 0x25, + BC3 = 0x26, + BC4 = 0x27, + BC5 = 0x28, + S8D24 = 0x29, + X8D24 = 0x2A, + D24S8 = 0x2B, + X4V4D24_Cov4R4V = 0x2C, + X4V4D24_Cov8R8V = 0x2D, + V8D24_Cov4R12V = 0x2E, + D32 = 0x2F, + D32S8 = 0x30, + X8D24_X20V4S8_Cov4R4V = 0x31, + X8D24_X20V4S8_Cov8R8V = 0x32, + D32_X20V4X8_Cov4R4V = 0x33, + D32_X20V4X8_Cov8R8V = 0x34, + D32_X20V4S8_Cov4R4V = 0x35, + D32_X20V4S8_Cov8R8V = 0x36, + X8D24_X16V8S8_Cov4R12V = 0x37, + D32_X16V8X8_Cov4R12V = 0x38, + D32_X16V8S8_Cov4R12V = 0x39, + D16 = 0x3A, + V8D24_Cov8R24V = 0x3B, + X8D24_X16V8S8_Cov8R24V = 0x3C, + D32_X16V8X8_Cov8R24V = 0x3D, + D32_X16V8S8_Cov8R24V = 0x3E, Astc4x4 = 0x40, Astc5x5 = 0x41, Astc6x6 = 0x42, @@ -199,8 +199,11 @@ namespace skyline::gpu::interconnect { e16to1 = 7, }; + // 0x00 struct FormatWord { + static constexpr u32 FormatColorComponentMask{0b111'111'111'111'1111111}; //!< Mask for the format and component fields + ImageFormat format : 7; ImageComponent componentR : 3; ImageComponent componentG : 3; diff --git a/app/src/main/cpp/skyline/gpu/texture/format.h b/app/src/main/cpp/skyline/gpu/texture/format.h index 88d6e30e..2e7b6a1d 100644 --- a/app/src/main/cpp/skyline/gpu/texture/format.h +++ b/app/src/main/cpp/skyline/gpu/texture/format.h @@ -9,7 +9,6 @@ namespace skyline::gpu::format { // @fmt:off using vka = vk::ImageAspectFlagBits; - using swc = gpu::texture::SwizzleChannel; #define FORMAT(name, bitsPerBlock, format, ...) \ constexpr gpu::texture::FormatBase name{bitsPerBlock / 8, vk::Format::format, ##__VA_ARGS__} @@ -40,7 +39,6 @@ namespace skyline::gpu::format { FORMAT_SUFF_INT(name, bitsPerBlock, format, fmtSuffix, ##__VA_ARGS__); \ FORMAT_SUFF_NORM(name, bitsPerBlock, format, fmtSuffix, ##__VA_ARGS__) - #define FORMAT_NORM_INT(name, bitsPerBlock, format, ...) \ FORMAT_SUFF_NORM_INT(name, bitsPerBlock, format,, ##__VA_ARGS__) @@ -58,105 +56,85 @@ namespace skyline::gpu::format { #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 + // These are ordered according to Size -> Component Count -> R/G/B/A/E Order // Color formats FORMAT_NORM_INT_SRGB(R8, 8, eR8); - FORMAT_NORM_INT_SRGB(R8R001, 8, eR8); FORMAT_NORM_INT_FLOAT(R16, 16, eR16); FORMAT_NORM_INT_SRGB(R8G8, 16, eR8G8); FORMAT(R5G6B5Unorm, 16, eR5G6B5UnormPack16); FORMAT(B5G6R5Unorm, 16, eB5G6R5UnormPack16); FORMAT(B5G5R5A1Unorm, 16, eB5G5R5A1UnormPack16); + FORMAT(A1B5G5R5Unorm, 16, eA1R5G5B5UnormPack16, .swapRedBlue = true); + FORMAT_INT_FLOAT(R32, 32, eR32); FORMAT_NORM_INT_FLOAT(R16G16, 32, eR16G16); - FORMAT(R11G11B10Float, 32, eB10G11R11UfloatPack32, .swizzle = { - .red = swc::Blue, - .green = swc::Green, - .blue = swc::Red, - }); FORMAT(B10G11R11Float, 32, eB10G11R11UfloatPack32); FORMAT_NORM_INT_SRGB(R8G8B8A8, 32, eR8G8B8A8); - FORMAT_NORM_INT_SRGB(G8B8A8R8, 32, eB8G8R8A8, .swizzle = { - .blue = swc::Alpha, - .green = swc::Red, - .red = swc::Green, - .alpha = swc::Blue - }); FORMAT_NORM_INT_SRGB(B8G8R8A8, 32, eB8G8R8A8); FORMAT_SUFF_NORM_INT(A2B10G10R10, 32, eA2B10G10R10, Pack32); - FORMAT_SUFF_NORM_INT(A2R10G10B10, 32, eA2B10G10R10, Pack32, .swizzle = { - .blue = swc::Red, - .red = swc::Blue - }); - FORMAT_SUFF_NORM_INT_SRGB(A8B8G8R8, 32, eA8B8G8R8, Pack32); + FORMAT(E5B9G9R9Float, 32, eE5B9G9R9UfloatPack32); + FORMAT_INT_FLOAT(R32G32, 32 * 2, eR32G32); FORMAT_NORM_INT_FLOAT(R16G16B16A16, 16 * 4, eR16G16B16A16); + FORMAT_INT_FLOAT(R32G32B32A32, 32 * 4, eR32G32B32A32); - FORMAT_INT_FLOAT(R32B32G32A32, 32 * 4, eR32G32B32A32, .swizzle = { - .blue = swc::Green, - .green = swc::Blue, - }); // Compressed Colour Formats - FORMAT_SUFF_UNORM_SRGB(Bc1, 64, eBc1Rgba, Block, + FORMAT_SUFF_UNORM_SRGB(BC1, 64, eBc1Rgba, Block, .blockWidth = 4, .blockHeight = 4 ); - - FORMAT_SUFF_UNORM_SRGB(Bc2, 64, eBc2, Block, + FORMAT_SUFF_UNORM_SRGB(BC2, 64, eBc2, Block, .blockWidth = 4, .blockHeight = 4 ); - - FORMAT_SUFF_UNORM_SRGB(Bc3, 64, eBc3, Block, + FORMAT_SUFF_UNORM_SRGB(BC3, 64, eBc3, Block, .blockWidth = 4, .blockHeight = 4 ); - - FORMAT_SUFF_NORM(Bc4111R, 64, eBc4, Block, - .blockWidth = 4, - .blockHeight = 4, - .swizzle = { - .red = swc::One, - .green = swc::One, - .blue = swc::One, - .alpha = swc::Red - } - ); - - FORMAT_SUFF_NORM(Bc4RRR1, 64, eBc4, Block, - .blockWidth = 4, - .blockHeight = 4, - .swizzle = { - .red = swc::Red, - .green = swc::Red, - .blue = swc::Red, - .alpha = swc::One - } - ); - - FORMAT_SUFF_UNORM_SRGB(Bc7, 128, eBc7, Block, + FORMAT_SUFF_NORM(BC4, 64, eBc4, Block, .blockWidth = 4, - .blockHeight = 4 + .blockHeight = 4, ); FORMAT_SUFF_UNORM_SRGB(Astc4x4, 128, eAstc4x4, Block, .blockWidth = 4, .blockHeight = 4 ); + FORMAT_SUFF_NORM(BC5, 128, eBc5, Block, + .blockWidth = 4, + .blockHeight = 4, + ); + FORMAT(Bc6HUfloat, 128, eBc6HUfloatBlock, + .blockWidth = 4, + .blockHeight = 4, + ); + FORMAT(Bc6HSfloat, 128, eBc6HSfloatBlock, + .blockWidth = 4, + .blockHeight = 4, + ); + FORMAT_SUFF_UNORM_SRGB(BC7, 128, eBc7, Block, + .blockWidth = 4, + .blockHeight = 4 + ); // Depth/Stencil Formats FORMAT(D16Unorm, 16, eD16Unorm, vka::eDepth); + FORMAT(D32Float, 32, eD32Sfloat, vka::eDepth); - FORMAT(S8D24Unorm, 32, eD24UnormS8Uint, .vkAspect = { - vka::eStencil | vka::eDepth - }); // TODO: Swizzle Depth/Stencil - FORMAT(D24S8Unorm, 32, eD24UnormS8Uint, .vkAspect = { + FORMAT(D24UnormS8Uint, 32, eD24UnormS8Uint, .vkAspect = { vka::eStencil | vka::eDepth }); + FORMAT(D32FloatS8Uint, 32, eD32SfloatS8Uint, .vkAspect = { + vka::eStencil | vka::eDepth + }); + FORMAT(S8UintD24Unorm, 32, eD24UnormS8Uint, .vkAspect = { + vka::eStencil | vka::eDepth + }); // TODO: Swizzle Depth/Stencil + #undef FORMAT #undef FORMAT_SUFF_UNORM_SRGB diff --git a/app/src/main/cpp/skyline/gpu/texture/texture.h b/app/src/main/cpp/skyline/gpu/texture/texture.h index 1e568737..e901246f 100644 --- a/app/src/main/cpp/skyline/gpu/texture/texture.h +++ b/app/src/main/cpp/skyline/gpu/texture/texture.h @@ -58,48 +58,6 @@ namespace skyline::gpu { } }; - enum class SwizzleChannel : u8 { - Zero, //!< Write 0 to the channel - One, //!< Write 1 to the channel - Red, //!< Red color channel - Green, //!< Green color channel - Blue, //!< Blue color channel - Alpha, //!< Alpha channel - }; - - struct Swizzle { - SwizzleChannel red{SwizzleChannel::Red}; //!< Swizzle for the red channel - SwizzleChannel green{SwizzleChannel::Green}; //!< Swizzle for the green channel - SwizzleChannel blue{SwizzleChannel::Blue}; //!< Swizzle for the blue channel - SwizzleChannel alpha{SwizzleChannel::Alpha}; //!< Swizzle for the alpha channel - - constexpr operator vk::ComponentMapping() const { - auto swizzleConvert{[](SwizzleChannel channel) { - switch (channel) { - case SwizzleChannel::Zero: - return vk::ComponentSwizzle::eZero; - case SwizzleChannel::One: - return vk::ComponentSwizzle::eOne; - case SwizzleChannel::Red: - return vk::ComponentSwizzle::eR; - case SwizzleChannel::Green: - return vk::ComponentSwizzle::eG; - case SwizzleChannel::Blue: - return vk::ComponentSwizzle::eB; - case SwizzleChannel::Alpha: - return vk::ComponentSwizzle::eA; - } - }}; - - return vk::ComponentMapping{ - .r = swizzleConvert(red), - .g = swizzleConvert(green), - .b = swizzleConvert(blue), - .a = swizzleConvert(alpha), - }; - } - }; - /** * @note Blocks refers to the atomic unit of a compressed format (IE: The minimum amount of data that can be decompressed) */ @@ -107,9 +65,9 @@ namespace skyline::gpu { u8 bpb{}; //!< Bytes Per Block, this is used instead of bytes per pixel as that might not be a whole number for compressed formats vk::Format vkFormat{vk::Format::eUndefined}; vk::ImageAspectFlags vkAspect{vk::ImageAspectFlagBits::eColor}; - Swizzle swizzle{}; u16 blockHeight{1}; //!< The height of a block in pixels u16 blockWidth{1}; //!< The width of a block in pixels + bool swapRedBlue{}; //!< Swap the red and blue channels, ignored on depth formats constexpr bool IsCompressed() const { return (blockHeight != 1) || (blockWidth != 1); @@ -154,6 +112,10 @@ namespace skyline::gpu { constexpr bool IsCompatible(const FormatBase &other) const { return bpb == other.bpb && blockHeight == other.blockHeight && blockWidth == other.blockWidth; } + + constexpr bool IsDepthOrStencil() const { + return bool(vkAspect & (vk::ImageAspectFlagBits::eDepth | vk::ImageAspectFlagBits::eStencil)); + } }; /** @@ -262,6 +224,7 @@ namespace skyline::gpu { u16 baseArrayLayer{}; u16 layerCount{}; u32 layerStride{}; //!< An optional hint regarding the size of a single layer, it will be set to 0 when not available, GetLayerSize() should be used to retrieve this value + vk::ComponentMapping swizzle{}; //!< Component swizzle derived from format requirements and the guest supplied swizzle GuestTexture() {} diff --git a/app/src/main/cpp/skyline/gpu/texture_manager.cpp b/app/src/main/cpp/skyline/gpu/texture_manager.cpp index dca31bc2..08091518 100644 --- a/app/src/main/cpp/skyline/gpu/texture_manager.cpp +++ b/app/src/main/cpp/skyline/gpu/texture_manager.cpp @@ -51,7 +51,7 @@ namespace skyline::gpu { .aspectMask = guestTexture.format->vkAspect, .levelCount = texture->mipLevels, .layerCount = texture->layerCount, - }, guestTexture.format, guestTexture.format->swizzle); + }, guestTexture.format, guestTexture.swizzle); } } /* else if (mappingMatch) { // We've gotten a partial match with a certain subset of contiguous mappings matching, we need to check if this is a meaningful overlap @@ -82,6 +82,6 @@ namespace skyline::gpu { .aspectMask = guestTexture.format->vkAspect, .levelCount = texture->mipLevels, .layerCount = texture->layerCount, - }, guestTexture.format, guestTexture.format->swizzle); + }, guestTexture.format, guestTexture.swizzle); } } diff --git a/app/src/main/cpp/skyline/soc/gm20b/engines/maxwell/types.h b/app/src/main/cpp/skyline/soc/gm20b/engines/maxwell/types.h index 0871a6ee..b5e35b7c 100644 --- a/app/src/main/cpp/skyline/soc/gm20b/engines/maxwell/types.h +++ b/app/src/main/cpp/skyline/soc/gm20b/engines/maxwell/types.h @@ -86,8 +86,8 @@ namespace skyline::soc::gm20b::engine::maxwell3d::type { R16G16B16X16Float = 0xCE, B8G8R8A8Unorm = 0xCF, B8G8R8A8Srgb = 0xD0, - A2R10G10B10Unorm = 0xD1, - A2R10G10B10Uint = 0xD2, + A2B10G10R10Unorm = 0xD1, + A2B10G10R10Uint = 0xD2, R8G8B8A8Unorm = 0xD5, R8G8B8A8Srgb = 0xD6, R8G8B8X8Snorm = 0xD7, @@ -98,7 +98,7 @@ namespace skyline::soc::gm20b::engine::maxwell3d::type { R16G16Sint = 0xDC, R16G16Uint = 0xDD, R16G16Float = 0xDE, - R11G11B10Float = 0xE0, + B10G11R11Float = 0xE0, R32Sint = 0xE3, R32Uint = 0xE4, R32Float = 0xE5,