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.
This commit is contained in:
Billy Laws 2022-01-10 20:45:54 +00:00 committed by PixelyIon
parent 8f0db18624
commit 3ff8075151
3 changed files with 157 additions and 151 deletions

View File

@ -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<u32>(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) {

View File

@ -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,

View File

@ -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;