From 3ff8075151299c906d0ab2ca261615ff418f89e1 Mon Sep 17 00:00:00 2001 From: Billy Laws Date: Mon, 10 Jan 2022 20:45:54 +0000 Subject: [PATCH] Move vertex and RT format conv to macros and fill them fully in Makes the format conversions easier to read and shorter, and adds in some new formats needed to complete the RT table properly. --- .../gpu/interconnect/graphics_context.h | 258 ++++++++---------- app/src/main/cpp/skyline/gpu/texture/format.h | 6 +- .../skyline/soc/gm20b/engines/maxwell/types.h | 44 ++- 3 files changed, 157 insertions(+), 151 deletions(-) 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 df89c4c6..40728238 100644 --- a/app/src/main/cpp/skyline/gpu/interconnect/graphics_context.h +++ b/app/src/main/cpp/skyline/gpu/interconnect/graphics_context.h @@ -160,67 +160,83 @@ namespace skyline::gpu::interconnect { void SetColorRenderTargetFormat(size_t index, maxwell3d::ColorRenderTarget::Format format) { auto &renderTarget{colorRenderTargets.at(index)}; renderTarget.guest.format = [&]() -> texture::Format { - using MaxwellColorRtFormat = maxwell3d::ColorRenderTarget::Format; + #define FORMAT_CASE(maxwellFmt, skFmt, type) \ + case maxwell3d::ColorRenderTarget::Format::maxwellFmt ## type: \ + return format::skFmt ## type + + #define FORMAT_SAME_CASE(fmt, type) FORMAT_CASE(fmt, fmt, type) + + #define FORMAT_INT_CASE(maxwellFmt, skFmt) \ + FORMAT_CASE(maxwellFmt, skFmt, Sint); \ + FORMAT_CASE(maxwellFmt, skFmt, Uint) + + #define FORMAT_SAME_INT_CASE(fmt) FORMAT_INT_CASE(fmt, fmt) + + #define FORMAT_INT_FLOAT_CASE(maxwellFmt, skFmt) \ + FORMAT_INT_CASE(maxwellFmt, skFmt); \ + FORMAT_CASE(maxwellFmt, skFmt, Float) + + #define FORMAT_SAME_INT_FLOAT_CASE(fmt) FORMAT_INT_FLOAT_CASE(fmt, fmt) + + #define FORMAT_NORM_CASE(maxwellFmt, skFmt) \ + FORMAT_CASE(maxwellFmt, skFmt, Snorm); \ + FORMAT_CASE(maxwellFmt, skFmt, Unorm) + + #define FORMAT_NORM_INT_CASE(maxwellFmt, skFmt) \ + FORMAT_NORM_CASE(maxwellFmt, skFmt); \ + FORMAT_INT_CASE(maxwellFmt, skFmt) + + #define FORMAT_SAME_NORM_INT_CASE(fmt) FORMAT_NORM_INT_CASE(fmt, fmt) + + #define FORMAT_NORM_INT_SRGB_CASE(maxwellFmt, skFmt) \ + FORMAT_NORM_INT_CASE(maxwellFmt, skFmt); \ + FORMAT_CASE(maxwellFmt, skFmt, Srgb) + + #define FORMAT_NORM_INT_FLOAT_CASE(maxwellFmt, skFmt) \ + FORMAT_NORM_INT_CASE(maxwellFmt, skFmt); \ + FORMAT_CASE(maxwellFmt, skFmt, Float) + + #define FORMAT_SAME_NORM_INT_FLOAT_CASE(fmt) FORMAT_NORM_INT_FLOAT_CASE(fmt, fmt) + switch (format) { - case MaxwellColorRtFormat::None: - return {}; - case MaxwellColorRtFormat::R32B32G32A32Float: - return format::R32B32G32A32Float; - case MaxwellColorRtFormat::R16G16B16A16Unorm: - return format::R16G16B16A16Unorm; - case MaxwellColorRtFormat::R16G16B16A16Snorm: - return format::R16G16B16A16Snorm; - case MaxwellColorRtFormat::R16G16B16A16Sint: - return format::R16G16B16A16Sint; - case MaxwellColorRtFormat::R16G16B16A16Uint: - return format::R16G16B16A16Uint; - case MaxwellColorRtFormat::R16G16B16A16Float: - return format::R16G16B16A16Float; - case MaxwellColorRtFormat::B8G8R8A8Unorm: - return format::B8G8R8A8Unorm; - case MaxwellColorRtFormat::B8G8R8A8Srgb: - return format::B8G8R8A8Srgb; - case MaxwellColorRtFormat::A2B10G10R10Unorm: - return format::A2B10G10R10Unorm; - case MaxwellColorRtFormat::R8G8B8A8Unorm: - return format::R8G8B8A8Unorm; - case MaxwellColorRtFormat::A8B8G8R8Srgb: - return format::A8B8G8R8Srgb; - case MaxwellColorRtFormat::A8B8G8R8Snorm: - return format::A8B8G8R8Snorm; - case MaxwellColorRtFormat::R16G16Unorm: - return format::R16G16Unorm; - case MaxwellColorRtFormat::R16G16Snorm: - return format::R16G16Snorm; - case MaxwellColorRtFormat::R16G16Sint: - return format::R16G16Sint; - case MaxwellColorRtFormat::R16G16Uint: - return format::R16G16Uint; - case MaxwellColorRtFormat::R16G16Float: - return format::R16G16Float; - case MaxwellColorRtFormat::B10G11R11Float: - return format::B10G11R11Float; - case MaxwellColorRtFormat::R32Float: - return format::R32Float; - case MaxwellColorRtFormat::R8G8Unorm: - return format::R8G8Unorm; - case MaxwellColorRtFormat::R8G8Snorm: - return format::R8G8Snorm; - case MaxwellColorRtFormat::R16Unorm: - return format::R16Unorm; - case MaxwellColorRtFormat::R16Float: - return format::R16Float; - case MaxwellColorRtFormat::R8Unorm: - return format::R8Unorm; - case MaxwellColorRtFormat::R8Snorm: - return format::R8Snorm; - case MaxwellColorRtFormat::R8Sint: - return format::R8Sint; - case MaxwellColorRtFormat::R8Uint: - return format::R8Uint; + FORMAT_SAME_NORM_INT_CASE(R8); + FORMAT_SAME_NORM_INT_FLOAT_CASE(R16); + FORMAT_SAME_NORM_INT_CASE(R8G8); + FORMAT_SAME_CASE(B5G6R5, Unorm); + FORMAT_SAME_CASE(B5G5R5A1, Unorm); + FORMAT_SAME_INT_FLOAT_CASE(R32); + 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); + /* Not supported by VK + FORMAT_SAME_CASE(R10G10B10A2, Unorm); + FORMAT_SAME_CASE(R10G10B10A2, Uint);*/ + FORMAT_SAME_INT_CASE(R32G32); + FORMAT_SAME_CASE(R32G32, Float); + FORMAT_SAME_CASE(R16G16B16A16, Float); + FORMAT_NORM_INT_FLOAT_CASE(R16G16B16X16, R16G16B16A16); + FORMAT_SAME_CASE(R32G32B32A32, Float); + FORMAT_INT_FLOAT_CASE(R32G32B32X32, R32G32B32A32); + default: throw exception("Cannot translate the supplied color RT format: 0x{:X}", static_cast(format)); } + + #undef FORMAT_CASE + #undef FORMAT_SAME_CASE + #undef FORMAT_INT_CASE + #undef FORMAT_SAME_INT_CASE + #undef FORMAT_INT_FLOAT_CASE + #undef FORMAT_SAME_INT_FLOAT_CASE + #undef FORMAT_NORM_CASE + #undef FORMAT_NORM_INT_CASE + #undef FORMAT_SAME_NORM_INT_CASE + #undef FORMAT_NORM_INT_SRGB_CASE + #undef FORMAT_NORM_INT_FLOAT_CASE + #undef FORMAT_SAME_NORM_INT_FLOAT_CASE }(); if (renderTarget.guest.tileConfig.mode == texture::TileMode::Linear && renderTarget.guest.format) @@ -234,6 +250,8 @@ namespace skyline::gpu::interconnect { depthRenderTarget.guest.format = [&]() -> texture::Format { using MaxwellDepthRtFormat = maxwell3d::DepthRtFormat; switch (format) { + case MaxwellDepthRtFormat::D32Float: + return format::D32Float; case MaxwellDepthRtFormat::S8D24Unorm: return format::S8D24Unorm; default: @@ -1431,102 +1449,54 @@ namespace skyline::gpu::interconnect { if (size == Size::e0 || type == Type::None) return vk::Format::eUndefined; + #define FORMAT_CASE(size, type, vkType, vkFormat, ...) \ + case Size::size | Type::type: \ + return vk::Format::vkFormat ## vkType ##__VA_ARGS__ + + #define FORMAT_INT_CASE(size, vkFormat, ...) \ + FORMAT_CASE(size, Uint, Uint, vkFormat, ##__VA_ARGS__); \ + FORMAT_CASE(size, Sint, Sint, vkFormat, ##__VA_ARGS__); + + #define FORMAT_INT_FLOAT_CASE(size, vkFormat, ...) \ + FORMAT_INT_CASE(size, vkFormat, ##__VA_ARGS__); \ + FORMAT_CASE(size, Float, Sfloat, vkFormat, ##__VA_ARGS__); + + #define FORMAT_NORM_INT_SCALED_CASE(size, vkFormat, ...) \ + FORMAT_INT_CASE(size, vkFormat, ##__VA_ARGS__); \ + FORMAT_CASE(size, Unorm, Unorm, vkFormat, ##__VA_ARGS__); \ + FORMAT_CASE(size, Snorm, Unorm, vkFormat, ##__VA_ARGS__); \ + FORMAT_CASE(size, Uscaled, Uscaled, vkFormat, ##__VA_ARGS__); \ + FORMAT_CASE(size, Sscaled, Sscaled, vkFormat, ##__VA_ARGS__) + + #define FORMAT_NORM_INT_SCALED_FLOAT_CASE(size, vkFormat) \ + FORMAT_NORM_INT_SCALED_CASE(size, vkFormat); \ + FORMAT_CASE(size, Float, Sfloat, vkFormat) + switch (size | type) { // @fmt:off /* 8-bit components */ - - case Size::e1x8 | Type::Unorm: return vk::Format::eR8Unorm; - case Size::e1x8 | Type::Snorm: return vk::Format::eR8Snorm; - case Size::e1x8 | Type::Uint: return vk::Format::eR8Uint; - case Size::e1x8 | Type::Sint: return vk::Format::eR8Sint; - case Size::e1x8 | Type::Uscaled: return vk::Format::eR8Uscaled; - case Size::e1x8 | Type::Sscaled: return vk::Format::eR8Sscaled; - - case Size::e2x8 | Type::Unorm: return vk::Format::eR8G8Unorm; - case Size::e2x8 | Type::Snorm: return vk::Format::eR8G8Snorm; - case Size::e2x8 | Type::Uint: return vk::Format::eR8G8Uint; - case Size::e2x8 | Type::Sint: return vk::Format::eR8G8Sint; - case Size::e2x8 | Type::Uscaled: return vk::Format::eR8G8Uscaled; - case Size::e2x8 | Type::Sscaled: return vk::Format::eR8G8Sscaled; - - case Size::e3x8 | Type::Unorm: return vk::Format::eR8G8B8Unorm; - case Size::e3x8 | Type::Snorm: return vk::Format::eR8G8B8Snorm; - case Size::e3x8 | Type::Uint: return vk::Format::eR8G8B8Uint; - case Size::e3x8 | Type::Sint: return vk::Format::eR8G8B8Sint; - case Size::e3x8 | Type::Uscaled: return vk::Format::eR8G8B8Uscaled; - case Size::e3x8 | Type::Sscaled: return vk::Format::eR8G8B8Sscaled; - - case Size::e4x8 | Type::Unorm: return vk::Format::eR8G8B8A8Unorm; - case Size::e4x8 | Type::Snorm: return vk::Format::eR8G8B8A8Snorm; - case Size::e4x8 | Type::Uint: return vk::Format::eR8G8B8A8Uint; - case Size::e4x8 | Type::Sint: return vk::Format::eR8G8B8A8Sint; - case Size::e4x8 | Type::Uscaled: return vk::Format::eR8G8B8A8Uscaled; - case Size::e4x8 | Type::Sscaled: return vk::Format::eR8G8B8A8Sscaled; + FORMAT_NORM_INT_SCALED_CASE(e1x8, eR8); + FORMAT_NORM_INT_SCALED_CASE(e2x8, eR8G8); + FORMAT_NORM_INT_SCALED_CASE(e3x8, eR8G8B8); + FORMAT_NORM_INT_SCALED_CASE(e4x8, eR8G8B8A8); /* 16-bit components */ - - case Size::e1x16 | Type::Unorm: return vk::Format::eR16Unorm; - case Size::e1x16 | Type::Snorm: return vk::Format::eR16Snorm; - case Size::e1x16 | Type::Uint: return vk::Format::eR16Uint; - case Size::e1x16 | Type::Sint: return vk::Format::eR16Sint; - case Size::e1x16 | Type::Uscaled: return vk::Format::eR16Uscaled; - case Size::e1x16 | Type::Sscaled: return vk::Format::eR16Sscaled; - case Size::e1x16 | Type::Float: return vk::Format::eR16Sfloat; - - case Size::e2x16 | Type::Unorm: return vk::Format::eR16G16Unorm; - case Size::e2x16 | Type::Snorm: return vk::Format::eR16G16Snorm; - case Size::e2x16 | Type::Uint: return vk::Format::eR16G16Uint; - case Size::e2x16 | Type::Sint: return vk::Format::eR16G16Sint; - case Size::e2x16 | Type::Uscaled: return vk::Format::eR16G16Uscaled; - case Size::e2x16 | Type::Sscaled: return vk::Format::eR16G16Sscaled; - case Size::e2x16 | Type::Float: return vk::Format::eR16G16Sfloat; - - case Size::e3x16 | Type::Unorm: return vk::Format::eR16G16B16Unorm; - case Size::e3x16 | Type::Snorm: return vk::Format::eR16G16B16Snorm; - case Size::e3x16 | Type::Uint: return vk::Format::eR16G16B16Uint; - case Size::e3x16 | Type::Sint: return vk::Format::eR16G16B16Sint; - case Size::e3x16 | Type::Uscaled: return vk::Format::eR16G16B16Uscaled; - case Size::e3x16 | Type::Sscaled: return vk::Format::eR16G16B16Sscaled; - case Size::e3x16 | Type::Float: return vk::Format::eR16G16B16Sfloat; - - case Size::e4x16 | Type::Unorm: return vk::Format::eR16G16B16A16Unorm; - case Size::e4x16 | Type::Snorm: return vk::Format::eR16G16B16A16Snorm; - case Size::e4x16 | Type::Uint: return vk::Format::eR16G16B16A16Uint; - case Size::e4x16 | Type::Sint: return vk::Format::eR16G16B16A16Sint; - case Size::e4x16 | Type::Uscaled: return vk::Format::eR16G16B16A16Uscaled; - case Size::e4x16 | Type::Sscaled: return vk::Format::eR16G16B16A16Sscaled; - case Size::e4x16 | Type::Float: return vk::Format::eR16G16B16A16Sfloat; + FORMAT_NORM_INT_SCALED_FLOAT_CASE(e1x16, eR16); + FORMAT_NORM_INT_SCALED_FLOAT_CASE(e2x16, eR16G16); + FORMAT_NORM_INT_SCALED_FLOAT_CASE(e3x16, eR16G16B16); + FORMAT_NORM_INT_SCALED_FLOAT_CASE(e4x16, eR16G16B16A16); /* 32-bit components */ - - case Size::e1x32 | Type::Uint: return vk::Format::eR32Uint; - case Size::e1x32 | Type::Sint: return vk::Format::eR32Sint; - case Size::e1x32 | Type::Float: return vk::Format::eR32Sfloat; - - case Size::e2x32 | Type::Uint: return vk::Format::eR32G32Uint; - case Size::e2x32 | Type::Sint: return vk::Format::eR32G32Sint; - case Size::e2x32 | Type::Float: return vk::Format::eR32G32Sfloat; - - case Size::e3x32 | Type::Uint: return vk::Format::eR32G32B32Uint; - case Size::e3x32 | Type::Sint: return vk::Format::eR32G32B32Sint; - case Size::e3x32 | Type::Float: return vk::Format::eR32G32B32Sfloat; - - case Size::e4x32 | Type::Uint: return vk::Format::eR32G32B32A32Uint; - case Size::e4x32 | Type::Sint: return vk::Format::eR32G32B32A32Sint; - case Size::e4x32 | Type::Float: return vk::Format::eR32G32B32A32Sfloat; + FORMAT_INT_FLOAT_CASE(e1x32, eR32); + FORMAT_INT_FLOAT_CASE(e2x32, eR32G32); + FORMAT_INT_FLOAT_CASE(e3x32, eR32G32B32); + FORMAT_INT_FLOAT_CASE(e4x32, eR32G32B32A32); /* 10-bit RGB, 2-bit A */ - - case Size::e10_10_10_2 | Type::Unorm: return vk::Format::eA2R10G10B10UnormPack32; - case Size::e10_10_10_2 | Type::Snorm: return vk::Format::eA2R10G10B10SnormPack32; - case Size::e10_10_10_2 | Type::Uint: return vk::Format::eA2R10G10B10UintPack32; - case Size::e10_10_10_2 | Type::Sint: return vk::Format::eA2R10G10B10SintPack32; - case Size::e10_10_10_2 | Type::Uscaled: return vk::Format::eA2R10G10B10UscaledPack32; - case Size::e10_10_10_2 | Type::Sscaled: return vk::Format::eA2R10G10B10SscaledPack32; + FORMAT_NORM_INT_SCALED_CASE(e10_10_10_2, eA2B10G10R10, Pack32); /* Unknown */ - case 0x12F: return vk::Format::eUndefined; // Issued by Maxwell3D::InitializeRegisters() // @fmt:on @@ -1534,6 +1504,12 @@ namespace skyline::gpu::interconnect { default: throw exception("Unimplemented Maxwell3D Vertex Buffer Format: {} | {}", maxwell3d::VertexAttribute::ToString(size), maxwell3d::VertexAttribute::ToString(type)); } + + #undef FORMAT_CASE + #undef FORMAT_INT_CASE + #undef FORMAT_INT_FLOAT_CASE + #undef FORMAT_NORM_INT_SCALED_CASE + #undef FORMAT_NORM_INT_SCALED_FLOAT_CASE } void SetVertexAttributeState(u32 index, maxwell3d::VertexAttribute attribute) { diff --git a/app/src/main/cpp/skyline/gpu/texture/format.h b/app/src/main/cpp/skyline/gpu/texture/format.h index 6ea3311c..e3adf24f 100644 --- a/app/src/main/cpp/skyline/gpu/texture/format.h +++ b/app/src/main/cpp/skyline/gpu/texture/format.h @@ -61,6 +61,8 @@ namespace skyline::gpu::format { 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_INT_FLOAT(R32, 32, eR32); FORMAT_NORM_INT_FLOAT(R16G16, 32, eR16G16); FORMAT(B10G11R11Float, 32, eB10G11R11UfloatPack32); @@ -72,9 +74,11 @@ namespace skyline::gpu::format { .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_SUFF_NORM_INT_SRGB(A8B8G8R8, 32, eA8B8G8R8, Pack32); + 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, 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 8dbcec4f..23f48940 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 @@ -69,33 +69,59 @@ namespace skyline::soc::gm20b::engine::maxwell3d::type { enum class Format : u32 { None = 0x0, - R32B32G32A32Float = 0xC0, - R16G16B16A16Unorm = 0xC6, - R16G16B16A16Snorm = 0xC7, - R16G16B16A16Sint = 0xC8, - R16G16B16A16Uint = 0xC9, + R32G32B32A32Float = 0xC0, + R32G32B32A32Sint = 0xC1, + R32G32B32A32Uint = 0xC2, + R32G32B32X32Float = 0xC3, + R32G32B32X32Sint = 0xC4, + R32G32B32X32Uint = 0xC5, + R16G16B16X16Unorm = 0xC6, + R16G16B16X16Snorm = 0xC7, + R16G16B16X16Sint = 0xC8, + R16G16B16X16Uint = 0xC9, R16G16B16A16Float = 0xCA, + R32G32Float = 0xCB, + R32G32Sint = 0xCC, + R32G32Uint = 0xCD, + R16G16B16X16Float = 0xCE, B8G8R8A8Unorm = 0xCF, B8G8R8A8Srgb = 0xD0, - A2B10G10R10Unorm = 0xD1, + R10G10B10A2Unorm = 0xD1, + R10G10B10A2Uint = 0xD2, R8G8B8A8Unorm = 0xD5, - A8B8G8R8Srgb = 0xD6, - A8B8G8R8Snorm = 0xD7, + R8G8B8A8Srgb = 0xD6, + R8G8B8X8Snorm = 0xD7, + R8G8B8X8Sint = 0xD8, + R8G8B8X8Uint = 0xD9, R16G16Unorm = 0xDA, R16G16Snorm = 0xDB, R16G16Sint = 0xDC, R16G16Uint = 0xDD, R16G16Float = 0xDE, - B10G11R11Float = 0xE0, + R11G11B10Float = 0xE0, + R32Sint = 0xE3, + R32Uint = 0xE4, R32Float = 0xE5, + B8G8R8X8Unorm = 0xE6, + B8G8R8X8Srgb = 0xE7, + B5G6R5Unorm = 0xE8, + B5G5R5A1Unorm = 0xE9, R8G8Unorm = 0xEA, R8G8Snorm = 0xEB, + R8G8Sint = 0xEC, + R8G8Uint = 0xED, R16Unorm = 0xEE, + R16Snorm = 0xEF, + R16Sint = 0xF0, + R16Uint = 0xF1, R16Float = 0xF2, R8Unorm = 0xF3, R8Snorm = 0xF4, R8Sint = 0xF5, R8Uint = 0xF6, + B5G5R5X1Unorm = 0xF8, + R8G8B8X8Unorm = 0xF9, + R8G8B8X8Srgb = 0xFA } format; RenderTargetTileMode tileMode;