Use macros for defining texture formats and their conversions

Avoids the need to repeat all the possible component types for each texture format while also making them simpler to add and easier to read.
This commit is contained in:
Billy Laws 2022-01-09 17:43:39 +00:00 committed by PixelyIon
parent a9d4e6bb1a
commit 68f31c3688
2 changed files with 135 additions and 42 deletions

View File

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

View File

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