mirror of
https://github.com/skyline-emu/skyline.git
synced 2025-01-09 00:30:41 +01:00
Rework formats to support passing through guest swizzle values
Almost every Maxwell format now directly corresponds to a Vulkan format. This allows formats to be passed through and the swizzle used directly from guest (with some extra swizzle handling for edge cases) thus saving the need to explicitly support each swizzle combination which is adds a lot of code bloat. The format header is additionally reordered with line breaks to separate formats by their bits-per-block.
This commit is contained in:
parent
6f17d1351f
commit
011de98940
@ -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<u32>(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<u32>(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 <bool ConvGR, bool SwapBR>
|
||||
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<u32>(swizzle));
|
||||
}
|
||||
}};
|
||||
|
||||
return vk::ComponentMapping{
|
||||
.r = convertComponentSwizzle(format.swizzleX),
|
||||
.g = convertComponentSwizzle(format.swizzleY),
|
||||
.b = convertComponentSwizzle(format.swizzleZ),
|
||||
.a = convertComponentSwizzle(format.swizzleW)
|
||||
};
|
||||
}
|
||||
|
||||
std::shared_ptr<TextureView> 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<true, false>(textureControl.formatWord);
|
||||
else if (guest.format->swapRedBlue)
|
||||
guest.swizzle = ConvertTicSwizzleMapping<false, true>(textureControl.formatWord);
|
||||
else
|
||||
guest.swizzle = ConvertTicSwizzleMapping<false, false>(textureControl.formatWord);
|
||||
|
||||
constexpr size_t CubeFaceCount{6}; //!< The amount of faces of a cube
|
||||
|
||||
guest.baseArrayLayer = static_cast<u16>(textureControl.BaseLayer());
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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() {}
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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,
|
||||
|
Loading…
Reference in New Issue
Block a user