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:
Billy Laws 2022-01-25 23:01:43 +00:00 committed by PixelyIon
parent 6f17d1351f
commit 011de98940
6 changed files with 195 additions and 186 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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