mirror of
https://github.com/shadps4-emu/shadPS4.git
synced 2024-12-29 11:06:07 +00:00
renderer_vulkan: Refactor surface and depth format mapping. (#1067)
* renderer_vulkan: Refactor surface and depth format mapping. * image: Convert usage to feature flags for format support checks.
This commit is contained in:
parent
cc99f52606
commit
36ef61908d
|
@ -43,6 +43,23 @@ enum class DataFormat : u32 {
|
|||
FormatBc5 = 39,
|
||||
FormatBc6 = 40,
|
||||
FormatBc7 = 41,
|
||||
FormatFmask8_1 = 47,
|
||||
FormatFmask8_2 = 48,
|
||||
FormatFmask8_4 = 49,
|
||||
FormatFmask16_1 = 50,
|
||||
FormatFmask16_2 = 51,
|
||||
FormatFmask32_2 = 52,
|
||||
FormatFmask32_4 = 53,
|
||||
FormatFmask32_8 = 54,
|
||||
FormatFmask64_4 = 55,
|
||||
FormatFmask64_8 = 56,
|
||||
Format4_4 = 57,
|
||||
Format6_5_5 = 58,
|
||||
Format1 = 59,
|
||||
Format1_Reversed = 60,
|
||||
Format32_As_8 = 61,
|
||||
Format32_As_8_8 = 62,
|
||||
Format32_As_32_32_32_32 = 63,
|
||||
};
|
||||
|
||||
enum class NumberFormat : u32 {
|
||||
|
|
|
@ -294,302 +294,336 @@ vk::BorderColor BorderColor(AmdGpu::BorderColor color) {
|
|||
}
|
||||
}
|
||||
|
||||
std::span<const vk::Format> GetAllFormats() {
|
||||
static constexpr vk::FormatFeatureFlags2 BufferRead =
|
||||
vk::FormatFeatureFlagBits2::eUniformTexelBuffer | vk::FormatFeatureFlagBits2::eVertexBuffer;
|
||||
static constexpr vk::FormatFeatureFlags2 BufferWrite =
|
||||
vk::FormatFeatureFlagBits2::eStorageTexelBuffer |
|
||||
vk::FormatFeatureFlagBits2::eStorageReadWithoutFormat |
|
||||
vk::FormatFeatureFlagBits2::eStorageWriteWithoutFormat;
|
||||
static constexpr vk::FormatFeatureFlags2 ImageRead = vk::FormatFeatureFlagBits2::eTransferSrc |
|
||||
vk::FormatFeatureFlagBits2::eTransferDst |
|
||||
vk::FormatFeatureFlagBits2::eSampledImage;
|
||||
static constexpr vk::FormatFeatureFlags2 ImageWrite =
|
||||
vk::FormatFeatureFlagBits2::eStorageImage |
|
||||
vk::FormatFeatureFlagBits2::eStorageReadWithoutFormat |
|
||||
vk::FormatFeatureFlagBits2::eStorageWriteWithoutFormat;
|
||||
static constexpr vk::FormatFeatureFlags2 Mrt = vk::FormatFeatureFlagBits2::eColorAttachment;
|
||||
|
||||
// Table 8.13 Data and Image Formats [Sea Islands Series Instruction Set Architecture]
|
||||
static constexpr vk::FormatFeatureFlags2 GetDataFormatFeatureFlags(
|
||||
const AmdGpu::DataFormat data_format) {
|
||||
switch (data_format) {
|
||||
case AmdGpu::DataFormat::FormatInvalid:
|
||||
case AmdGpu::DataFormat::Format8:
|
||||
case AmdGpu::DataFormat::Format16:
|
||||
case AmdGpu::DataFormat::Format8_8:
|
||||
case AmdGpu::DataFormat::Format32:
|
||||
case AmdGpu::DataFormat::Format16_16:
|
||||
case AmdGpu::DataFormat::Format10_11_11:
|
||||
case AmdGpu::DataFormat::Format11_11_10:
|
||||
case AmdGpu::DataFormat::Format10_10_10_2:
|
||||
case AmdGpu::DataFormat::Format2_10_10_10:
|
||||
case AmdGpu::DataFormat::Format8_8_8_8:
|
||||
case AmdGpu::DataFormat::Format32_32:
|
||||
case AmdGpu::DataFormat::Format16_16_16_16:
|
||||
case AmdGpu::DataFormat::Format32_32_32_32:
|
||||
return BufferRead | BufferWrite | ImageRead | ImageWrite | Mrt;
|
||||
case AmdGpu::DataFormat::Format32_32_32:
|
||||
return BufferRead | BufferWrite | ImageRead;
|
||||
case AmdGpu::DataFormat::Format5_6_5:
|
||||
case AmdGpu::DataFormat::Format1_5_5_5:
|
||||
case AmdGpu::DataFormat::Format5_5_5_1:
|
||||
case AmdGpu::DataFormat::Format4_4_4_4:
|
||||
return ImageRead | ImageWrite | Mrt;
|
||||
case AmdGpu::DataFormat::Format8_24:
|
||||
case AmdGpu::DataFormat::Format24_8:
|
||||
case AmdGpu::DataFormat::FormatX24_8_32:
|
||||
return ImageRead | Mrt;
|
||||
case AmdGpu::DataFormat::FormatGB_GR:
|
||||
case AmdGpu::DataFormat::FormatBG_RG:
|
||||
case AmdGpu::DataFormat::Format5_9_9_9:
|
||||
case AmdGpu::DataFormat::FormatBc1:
|
||||
case AmdGpu::DataFormat::FormatBc2:
|
||||
case AmdGpu::DataFormat::FormatBc3:
|
||||
case AmdGpu::DataFormat::FormatBc4:
|
||||
case AmdGpu::DataFormat::FormatBc5:
|
||||
case AmdGpu::DataFormat::FormatBc6:
|
||||
case AmdGpu::DataFormat::FormatBc7:
|
||||
case AmdGpu::DataFormat::Format4_4:
|
||||
case AmdGpu::DataFormat::Format6_5_5:
|
||||
case AmdGpu::DataFormat::Format1:
|
||||
case AmdGpu::DataFormat::Format1_Reversed:
|
||||
case AmdGpu::DataFormat::Format32_As_8:
|
||||
case AmdGpu::DataFormat::Format32_As_8_8:
|
||||
case AmdGpu::DataFormat::Format32_As_32_32_32_32:
|
||||
return ImageRead;
|
||||
case AmdGpu::DataFormat::FormatFmask8_1:
|
||||
case AmdGpu::DataFormat::FormatFmask8_2:
|
||||
case AmdGpu::DataFormat::FormatFmask8_4:
|
||||
case AmdGpu::DataFormat::FormatFmask16_1:
|
||||
case AmdGpu::DataFormat::FormatFmask16_2:
|
||||
case AmdGpu::DataFormat::FormatFmask32_2:
|
||||
case AmdGpu::DataFormat::FormatFmask32_4:
|
||||
case AmdGpu::DataFormat::FormatFmask32_8:
|
||||
case AmdGpu::DataFormat::FormatFmask64_4:
|
||||
case AmdGpu::DataFormat::FormatFmask64_8:
|
||||
return ImageRead | ImageWrite;
|
||||
}
|
||||
UNREACHABLE_MSG("Missing feature flags for data format {}", static_cast<u32>(data_format));
|
||||
}
|
||||
|
||||
// Table 8.13 Data and Image Formats [Sea Islands Series Instruction Set Architecture]
|
||||
static constexpr vk::FormatFeatureFlags2 GetNumberFormatFeatureFlags(
|
||||
const AmdGpu::NumberFormat number_format) {
|
||||
switch (number_format) {
|
||||
case AmdGpu::NumberFormat::Unorm:
|
||||
case AmdGpu::NumberFormat::Snorm:
|
||||
case AmdGpu::NumberFormat::Uint:
|
||||
case AmdGpu::NumberFormat::Sint:
|
||||
case AmdGpu::NumberFormat::Float:
|
||||
return BufferRead | BufferWrite | ImageRead | ImageWrite;
|
||||
case AmdGpu::NumberFormat::Uscaled:
|
||||
case AmdGpu::NumberFormat::Sscaled:
|
||||
case AmdGpu::NumberFormat::SnormNz:
|
||||
return BufferRead | ImageRead;
|
||||
case AmdGpu::NumberFormat::Srgb:
|
||||
case AmdGpu::NumberFormat::Ubnorm:
|
||||
case AmdGpu::NumberFormat::UbnromNz:
|
||||
case AmdGpu::NumberFormat::Ubint:
|
||||
case AmdGpu::NumberFormat::Ubscaled:
|
||||
return ImageRead;
|
||||
}
|
||||
UNREACHABLE_MSG("Missing feature flags for number format {}", static_cast<u32>(number_format));
|
||||
}
|
||||
|
||||
static constexpr SurfaceFormatInfo CreateSurfaceFormatInfo(const AmdGpu::DataFormat data_format,
|
||||
const AmdGpu::NumberFormat number_format,
|
||||
const vk::Format vk_format) {
|
||||
return {
|
||||
.data_format = data_format,
|
||||
.number_format = number_format,
|
||||
.vk_format = vk_format,
|
||||
.flags =
|
||||
GetDataFormatFeatureFlags(data_format) & GetNumberFormatFeatureFlags(number_format),
|
||||
};
|
||||
}
|
||||
|
||||
std::span<const SurfaceFormatInfo> SurfaceFormats() {
|
||||
static constexpr std::array formats{
|
||||
vk::Format::eA2B10G10R10SnormPack32,
|
||||
vk::Format::eA2B10G10R10UnormPack32,
|
||||
vk::Format::eA2R10G10B10UnormPack32,
|
||||
vk::Format::eB5G6R5UnormPack16,
|
||||
vk::Format::eB8G8R8A8Srgb,
|
||||
vk::Format::eB8G8R8A8Unorm,
|
||||
vk::Format::eB10G11R11UfloatPack32,
|
||||
vk::Format::eBc1RgbaSrgbBlock,
|
||||
vk::Format::eBc1RgbaUnormBlock,
|
||||
vk::Format::eBc2SrgbBlock,
|
||||
vk::Format::eBc2UnormBlock,
|
||||
vk::Format::eBc3SrgbBlock,
|
||||
vk::Format::eBc3UnormBlock,
|
||||
vk::Format::eBc4UnormBlock,
|
||||
vk::Format::eBc5UnormBlock,
|
||||
vk::Format::eBc5SnormBlock,
|
||||
vk::Format::eBc7SrgbBlock,
|
||||
vk::Format::eBc7UnormBlock,
|
||||
vk::Format::eD16Unorm,
|
||||
vk::Format::eD16UnormS8Uint,
|
||||
vk::Format::eD24UnormS8Uint,
|
||||
vk::Format::eD32Sfloat,
|
||||
vk::Format::eD32SfloatS8Uint,
|
||||
vk::Format::eR4G4B4A4UnormPack16,
|
||||
vk::Format::eR5G6B5UnormPack16,
|
||||
vk::Format::eR5G5B5A1UnormPack16,
|
||||
vk::Format::eR8G8B8A8Srgb,
|
||||
vk::Format::eR8G8B8A8Uint,
|
||||
vk::Format::eR8G8B8A8Unorm,
|
||||
vk::Format::eR8G8B8A8Snorm,
|
||||
vk::Format::eR8G8B8A8Uscaled,
|
||||
vk::Format::eR8G8Snorm,
|
||||
vk::Format::eR8G8Uint,
|
||||
vk::Format::eR8G8Unorm,
|
||||
vk::Format::eR8Sint,
|
||||
vk::Format::eR8Snorm,
|
||||
vk::Format::eR8Uint,
|
||||
vk::Format::eR8Unorm,
|
||||
vk::Format::eR8Srgb,
|
||||
vk::Format::eR16G16B16A16Sfloat,
|
||||
vk::Format::eR16G16B16A16Sint,
|
||||
vk::Format::eR16G16B16A16Snorm,
|
||||
vk::Format::eR16G16B16A16Uint,
|
||||
vk::Format::eR16G16B16A16Unorm,
|
||||
vk::Format::eR16G16Sfloat,
|
||||
vk::Format::eR16G16Sint,
|
||||
vk::Format::eR16G16Snorm,
|
||||
vk::Format::eR16Sfloat,
|
||||
vk::Format::eR16Uint,
|
||||
vk::Format::eR16Unorm,
|
||||
vk::Format::eR32G32B32A32Sfloat,
|
||||
vk::Format::eR32G32B32A32Sint,
|
||||
vk::Format::eR32G32B32A32Uint,
|
||||
vk::Format::eR32G32B32Sfloat,
|
||||
vk::Format::eR32G32B32Uint,
|
||||
vk::Format::eR32G32Sfloat,
|
||||
vk::Format::eR32G32Uint,
|
||||
vk::Format::eR32Sfloat,
|
||||
vk::Format::eR32Sint,
|
||||
vk::Format::eR32Uint,
|
||||
vk::Format::eBc6HUfloatBlock,
|
||||
vk::Format::eBc6HSfloatBlock,
|
||||
vk::Format::eR16G16Unorm,
|
||||
vk::Format::eR16G16B16A16Sscaled,
|
||||
vk::Format::eR16G16Sscaled,
|
||||
vk::Format::eE5B9G9R9UfloatPack32,
|
||||
// Invalid
|
||||
CreateSurfaceFormatInfo(AmdGpu::DataFormat::FormatInvalid, AmdGpu::NumberFormat::Unorm,
|
||||
vk::Format::eUndefined),
|
||||
CreateSurfaceFormatInfo(AmdGpu::DataFormat::FormatInvalid, AmdGpu::NumberFormat::Snorm,
|
||||
vk::Format::eUndefined),
|
||||
CreateSurfaceFormatInfo(AmdGpu::DataFormat::FormatInvalid, AmdGpu::NumberFormat::Uscaled,
|
||||
vk::Format::eUndefined),
|
||||
CreateSurfaceFormatInfo(AmdGpu::DataFormat::FormatInvalid, AmdGpu::NumberFormat::Sscaled,
|
||||
vk::Format::eUndefined),
|
||||
CreateSurfaceFormatInfo(AmdGpu::DataFormat::FormatInvalid, AmdGpu::NumberFormat::Uint,
|
||||
vk::Format::eUndefined),
|
||||
CreateSurfaceFormatInfo(AmdGpu::DataFormat::FormatInvalid, AmdGpu::NumberFormat::Sint,
|
||||
vk::Format::eUndefined),
|
||||
CreateSurfaceFormatInfo(AmdGpu::DataFormat::FormatInvalid, AmdGpu::NumberFormat::SnormNz,
|
||||
vk::Format::eUndefined),
|
||||
CreateSurfaceFormatInfo(AmdGpu::DataFormat::FormatInvalid, AmdGpu::NumberFormat::Float,
|
||||
vk::Format::eUndefined),
|
||||
CreateSurfaceFormatInfo(AmdGpu::DataFormat::FormatInvalid, AmdGpu::NumberFormat::Srgb,
|
||||
vk::Format::eUndefined),
|
||||
CreateSurfaceFormatInfo(AmdGpu::DataFormat::FormatInvalid, AmdGpu::NumberFormat::Ubnorm,
|
||||
vk::Format::eUndefined),
|
||||
CreateSurfaceFormatInfo(AmdGpu::DataFormat::FormatInvalid, AmdGpu::NumberFormat::UbnromNz,
|
||||
vk::Format::eUndefined),
|
||||
CreateSurfaceFormatInfo(AmdGpu::DataFormat::FormatInvalid, AmdGpu::NumberFormat::Ubint,
|
||||
vk::Format::eUndefined),
|
||||
CreateSurfaceFormatInfo(AmdGpu::DataFormat::FormatInvalid, AmdGpu::NumberFormat::Ubscaled,
|
||||
vk::Format::eUndefined),
|
||||
// 8
|
||||
CreateSurfaceFormatInfo(AmdGpu::DataFormat::Format8, AmdGpu::NumberFormat::Unorm,
|
||||
vk::Format::eR8Unorm),
|
||||
CreateSurfaceFormatInfo(AmdGpu::DataFormat::Format8, AmdGpu::NumberFormat::Snorm,
|
||||
vk::Format::eR8Snorm),
|
||||
CreateSurfaceFormatInfo(AmdGpu::DataFormat::Format8, AmdGpu::NumberFormat::Uint,
|
||||
vk::Format::eR8Uint),
|
||||
CreateSurfaceFormatInfo(AmdGpu::DataFormat::Format8, AmdGpu::NumberFormat::Sint,
|
||||
vk::Format::eR8Sint),
|
||||
CreateSurfaceFormatInfo(AmdGpu::DataFormat::Format8, AmdGpu::NumberFormat::Srgb,
|
||||
vk::Format::eR8Srgb),
|
||||
// 16
|
||||
CreateSurfaceFormatInfo(AmdGpu::DataFormat::Format16, AmdGpu::NumberFormat::Unorm,
|
||||
vk::Format::eR16Unorm),
|
||||
CreateSurfaceFormatInfo(AmdGpu::DataFormat::Format16, AmdGpu::NumberFormat::Snorm,
|
||||
vk::Format::eR16Snorm),
|
||||
CreateSurfaceFormatInfo(AmdGpu::DataFormat::Format16, AmdGpu::NumberFormat::Uint,
|
||||
vk::Format::eR16Uint),
|
||||
CreateSurfaceFormatInfo(AmdGpu::DataFormat::Format16, AmdGpu::NumberFormat::Sint,
|
||||
vk::Format::eR16Sint),
|
||||
CreateSurfaceFormatInfo(AmdGpu::DataFormat::Format16, AmdGpu::NumberFormat::Float,
|
||||
vk::Format::eR16Sfloat),
|
||||
// 8_8
|
||||
CreateSurfaceFormatInfo(AmdGpu::DataFormat::Format8_8, AmdGpu::NumberFormat::Unorm,
|
||||
vk::Format::eR8G8Unorm),
|
||||
CreateSurfaceFormatInfo(AmdGpu::DataFormat::Format8_8, AmdGpu::NumberFormat::Snorm,
|
||||
vk::Format::eR8G8Snorm),
|
||||
CreateSurfaceFormatInfo(AmdGpu::DataFormat::Format8_8, AmdGpu::NumberFormat::Uint,
|
||||
vk::Format::eR8G8Uint),
|
||||
CreateSurfaceFormatInfo(AmdGpu::DataFormat::Format8_8, AmdGpu::NumberFormat::Sint,
|
||||
vk::Format::eR8G8Sint),
|
||||
CreateSurfaceFormatInfo(AmdGpu::DataFormat::Format8_8, AmdGpu::NumberFormat::Srgb,
|
||||
vk::Format::eR8G8Srgb),
|
||||
// 32
|
||||
CreateSurfaceFormatInfo(AmdGpu::DataFormat::Format32, AmdGpu::NumberFormat::Uint,
|
||||
vk::Format::eR32Uint),
|
||||
CreateSurfaceFormatInfo(AmdGpu::DataFormat::Format32, AmdGpu::NumberFormat::Sint,
|
||||
vk::Format::eR32Sint),
|
||||
CreateSurfaceFormatInfo(AmdGpu::DataFormat::Format32, AmdGpu::NumberFormat::Float,
|
||||
vk::Format::eR32Sfloat),
|
||||
// 16_16
|
||||
CreateSurfaceFormatInfo(AmdGpu::DataFormat::Format16_16, AmdGpu::NumberFormat::Unorm,
|
||||
vk::Format::eR16G16Unorm),
|
||||
CreateSurfaceFormatInfo(AmdGpu::DataFormat::Format16_16, AmdGpu::NumberFormat::Snorm,
|
||||
vk::Format::eR16G16Snorm),
|
||||
CreateSurfaceFormatInfo(AmdGpu::DataFormat::Format16_16, AmdGpu::NumberFormat::Uscaled,
|
||||
vk::Format::eR16G16Uscaled),
|
||||
CreateSurfaceFormatInfo(AmdGpu::DataFormat::Format16_16, AmdGpu::NumberFormat::Sscaled,
|
||||
vk::Format::eR16G16Sscaled),
|
||||
CreateSurfaceFormatInfo(AmdGpu::DataFormat::Format16_16, AmdGpu::NumberFormat::Uint,
|
||||
vk::Format::eR16G16Uint),
|
||||
CreateSurfaceFormatInfo(AmdGpu::DataFormat::Format16_16, AmdGpu::NumberFormat::Sint,
|
||||
vk::Format::eR16G16Sint),
|
||||
CreateSurfaceFormatInfo(AmdGpu::DataFormat::Format16_16, AmdGpu::NumberFormat::Float,
|
||||
vk::Format::eR16G16Sfloat),
|
||||
// 10_11_11
|
||||
CreateSurfaceFormatInfo(AmdGpu::DataFormat::Format10_11_11, AmdGpu::NumberFormat::Float,
|
||||
vk::Format::eB10G11R11UfloatPack32),
|
||||
// 11_11_10
|
||||
CreateSurfaceFormatInfo(AmdGpu::DataFormat::Format11_11_10, AmdGpu::NumberFormat::Float,
|
||||
vk::Format::eB10G11R11UfloatPack32),
|
||||
// 10_10_10_2
|
||||
// 2_10_10_10
|
||||
CreateSurfaceFormatInfo(AmdGpu::DataFormat::Format2_10_10_10, AmdGpu::NumberFormat::Unorm,
|
||||
vk::Format::eA2B10G10R10UnormPack32),
|
||||
CreateSurfaceFormatInfo(AmdGpu::DataFormat::Format2_10_10_10, AmdGpu::NumberFormat::Snorm,
|
||||
vk::Format::eA2B10G10R10SnormPack32),
|
||||
// 8_8_8_8
|
||||
CreateSurfaceFormatInfo(AmdGpu::DataFormat::Format8_8_8_8, AmdGpu::NumberFormat::Unorm,
|
||||
vk::Format::eR8G8B8A8Unorm),
|
||||
CreateSurfaceFormatInfo(AmdGpu::DataFormat::Format8_8_8_8, AmdGpu::NumberFormat::Snorm,
|
||||
vk::Format::eR8G8B8A8Snorm),
|
||||
CreateSurfaceFormatInfo(AmdGpu::DataFormat::Format8_8_8_8, AmdGpu::NumberFormat::Uscaled,
|
||||
vk::Format::eR8G8B8A8Uscaled),
|
||||
CreateSurfaceFormatInfo(AmdGpu::DataFormat::Format8_8_8_8, AmdGpu::NumberFormat::Sscaled,
|
||||
vk::Format::eR8G8B8A8Sscaled),
|
||||
CreateSurfaceFormatInfo(AmdGpu::DataFormat::Format8_8_8_8, AmdGpu::NumberFormat::Uint,
|
||||
vk::Format::eR8G8B8A8Uint),
|
||||
CreateSurfaceFormatInfo(AmdGpu::DataFormat::Format8_8_8_8, AmdGpu::NumberFormat::Sint,
|
||||
vk::Format::eR8G8B8A8Sint),
|
||||
CreateSurfaceFormatInfo(AmdGpu::DataFormat::Format8_8_8_8, AmdGpu::NumberFormat::Srgb,
|
||||
vk::Format::eR8G8B8A8Srgb),
|
||||
// 32_32
|
||||
CreateSurfaceFormatInfo(AmdGpu::DataFormat::Format32_32, AmdGpu::NumberFormat::Uint,
|
||||
vk::Format::eR32G32Uint),
|
||||
CreateSurfaceFormatInfo(AmdGpu::DataFormat::Format32_32, AmdGpu::NumberFormat::Sint,
|
||||
vk::Format::eR32G32Sint),
|
||||
CreateSurfaceFormatInfo(AmdGpu::DataFormat::Format32_32, AmdGpu::NumberFormat::Float,
|
||||
vk::Format::eR32G32Sfloat),
|
||||
// 16_16_16_16
|
||||
CreateSurfaceFormatInfo(AmdGpu::DataFormat::Format16_16_16_16, AmdGpu::NumberFormat::Unorm,
|
||||
vk::Format::eR16G16B16A16Unorm),
|
||||
CreateSurfaceFormatInfo(AmdGpu::DataFormat::Format16_16_16_16, AmdGpu::NumberFormat::Snorm,
|
||||
vk::Format::eR16G16B16A16Snorm),
|
||||
CreateSurfaceFormatInfo(AmdGpu::DataFormat::Format16_16_16_16,
|
||||
AmdGpu::NumberFormat::Uscaled, vk::Format::eR16G16B16A16Uscaled),
|
||||
CreateSurfaceFormatInfo(AmdGpu::DataFormat::Format16_16_16_16,
|
||||
AmdGpu::NumberFormat::Sscaled, vk::Format::eR16G16B16A16Sscaled),
|
||||
CreateSurfaceFormatInfo(AmdGpu::DataFormat::Format16_16_16_16, AmdGpu::NumberFormat::Uint,
|
||||
vk::Format::eR16G16B16A16Uint),
|
||||
CreateSurfaceFormatInfo(AmdGpu::DataFormat::Format16_16_16_16, AmdGpu::NumberFormat::Sint,
|
||||
vk::Format::eR16G16B16A16Sint),
|
||||
CreateSurfaceFormatInfo(AmdGpu::DataFormat::Format16_16_16_16,
|
||||
AmdGpu::NumberFormat::SnormNz, vk::Format::eR16G16B16A16Snorm),
|
||||
CreateSurfaceFormatInfo(AmdGpu::DataFormat::Format16_16_16_16, AmdGpu::NumberFormat::Float,
|
||||
vk::Format::eR16G16B16A16Sfloat),
|
||||
// 32_32_32
|
||||
CreateSurfaceFormatInfo(AmdGpu::DataFormat::Format32_32_32, AmdGpu::NumberFormat::Uint,
|
||||
vk::Format::eR32G32B32Uint),
|
||||
CreateSurfaceFormatInfo(AmdGpu::DataFormat::Format32_32_32, AmdGpu::NumberFormat::Sint,
|
||||
vk::Format::eR32G32B32Sint),
|
||||
CreateSurfaceFormatInfo(AmdGpu::DataFormat::Format32_32_32, AmdGpu::NumberFormat::Float,
|
||||
vk::Format::eR32G32B32Sfloat),
|
||||
// 32_32_32_32
|
||||
CreateSurfaceFormatInfo(AmdGpu::DataFormat::Format32_32_32_32, AmdGpu::NumberFormat::Uint,
|
||||
vk::Format::eR32G32B32A32Uint),
|
||||
CreateSurfaceFormatInfo(AmdGpu::DataFormat::Format32_32_32_32, AmdGpu::NumberFormat::Sint,
|
||||
vk::Format::eR32G32B32A32Sint),
|
||||
CreateSurfaceFormatInfo(AmdGpu::DataFormat::Format32_32_32_32, AmdGpu::NumberFormat::Float,
|
||||
vk::Format::eR32G32B32A32Sfloat),
|
||||
// 5_6_5
|
||||
CreateSurfaceFormatInfo(AmdGpu::DataFormat::Format5_6_5, AmdGpu::NumberFormat::Unorm,
|
||||
vk::Format::eB5G6R5UnormPack16),
|
||||
// 1_5_5_5
|
||||
CreateSurfaceFormatInfo(AmdGpu::DataFormat::Format1_5_5_5, AmdGpu::NumberFormat::Unorm,
|
||||
vk::Format::eR5G5B5A1UnormPack16),
|
||||
// 5_5_5_1
|
||||
// 4_4_4_4
|
||||
CreateSurfaceFormatInfo(AmdGpu::DataFormat::Format4_4_4_4, AmdGpu::NumberFormat::Unorm,
|
||||
vk::Format::eR4G4B4A4UnormPack16),
|
||||
// 8_24
|
||||
// 24_8
|
||||
// X24_8_32
|
||||
// GB_GR
|
||||
// BG_RG
|
||||
// 5_9_9_9
|
||||
CreateSurfaceFormatInfo(AmdGpu::DataFormat::Format5_9_9_9, AmdGpu::NumberFormat::Float,
|
||||
vk::Format::eE5B9G9R9UfloatPack32),
|
||||
// BC1
|
||||
CreateSurfaceFormatInfo(AmdGpu::DataFormat::FormatBc1, AmdGpu::NumberFormat::Unorm,
|
||||
vk::Format::eBc1RgbaUnormBlock),
|
||||
CreateSurfaceFormatInfo(AmdGpu::DataFormat::FormatBc1, AmdGpu::NumberFormat::Srgb,
|
||||
vk::Format::eBc1RgbaSrgbBlock),
|
||||
// BC2
|
||||
CreateSurfaceFormatInfo(AmdGpu::DataFormat::FormatBc2, AmdGpu::NumberFormat::Unorm,
|
||||
vk::Format::eBc2UnormBlock),
|
||||
CreateSurfaceFormatInfo(AmdGpu::DataFormat::FormatBc2, AmdGpu::NumberFormat::Srgb,
|
||||
vk::Format::eBc2SrgbBlock),
|
||||
// BC3
|
||||
CreateSurfaceFormatInfo(AmdGpu::DataFormat::FormatBc3, AmdGpu::NumberFormat::Unorm,
|
||||
vk::Format::eBc3UnormBlock),
|
||||
CreateSurfaceFormatInfo(AmdGpu::DataFormat::FormatBc3, AmdGpu::NumberFormat::Srgb,
|
||||
vk::Format::eBc3SrgbBlock),
|
||||
// BC4
|
||||
CreateSurfaceFormatInfo(AmdGpu::DataFormat::FormatBc4, AmdGpu::NumberFormat::Unorm,
|
||||
vk::Format::eBc4UnormBlock),
|
||||
CreateSurfaceFormatInfo(AmdGpu::DataFormat::FormatBc4, AmdGpu::NumberFormat::Snorm,
|
||||
vk::Format::eBc4SnormBlock),
|
||||
// BC5
|
||||
CreateSurfaceFormatInfo(AmdGpu::DataFormat::FormatBc5, AmdGpu::NumberFormat::Unorm,
|
||||
vk::Format::eBc5UnormBlock),
|
||||
CreateSurfaceFormatInfo(AmdGpu::DataFormat::FormatBc5, AmdGpu::NumberFormat::Snorm,
|
||||
vk::Format::eBc5SnormBlock),
|
||||
// BC6
|
||||
CreateSurfaceFormatInfo(AmdGpu::DataFormat::FormatBc6, AmdGpu::NumberFormat::Unorm,
|
||||
vk::Format::eBc6HUfloatBlock),
|
||||
CreateSurfaceFormatInfo(AmdGpu::DataFormat::FormatBc6, AmdGpu::NumberFormat::Snorm,
|
||||
vk::Format::eBc6HSfloatBlock),
|
||||
// BC7
|
||||
CreateSurfaceFormatInfo(AmdGpu::DataFormat::FormatBc7, AmdGpu::NumberFormat::Unorm,
|
||||
vk::Format::eBc7UnormBlock),
|
||||
CreateSurfaceFormatInfo(AmdGpu::DataFormat::FormatBc7, AmdGpu::NumberFormat::Srgb,
|
||||
vk::Format::eBc7SrgbBlock),
|
||||
};
|
||||
return formats;
|
||||
}
|
||||
|
||||
vk::Format SurfaceFormat(AmdGpu::DataFormat data_format, AmdGpu::NumberFormat num_format) {
|
||||
|
||||
if (data_format == AmdGpu::DataFormat::Format32_32_32_32 &&
|
||||
num_format == AmdGpu::NumberFormat::Float) {
|
||||
return vk::Format::eR32G32B32A32Sfloat;
|
||||
}
|
||||
if (data_format == AmdGpu::DataFormat::Format32_32_32 &&
|
||||
num_format == AmdGpu::NumberFormat::Uint) {
|
||||
return vk::Format::eR32G32B32Uint;
|
||||
}
|
||||
if (data_format == AmdGpu::DataFormat::Format8_8_8_8 &&
|
||||
num_format == AmdGpu::NumberFormat::Unorm) {
|
||||
return vk::Format::eR8G8B8A8Unorm;
|
||||
}
|
||||
if (data_format == AmdGpu::DataFormat::Format8_8_8_8 &&
|
||||
num_format == AmdGpu::NumberFormat::Srgb) {
|
||||
return vk::Format::eR8G8B8A8Srgb;
|
||||
}
|
||||
if (data_format == AmdGpu::DataFormat::Format32_32_32 &&
|
||||
num_format == AmdGpu::NumberFormat::Float) {
|
||||
return vk::Format::eR32G32B32Sfloat;
|
||||
}
|
||||
if (data_format == AmdGpu::DataFormat::Format32_32 &&
|
||||
num_format == AmdGpu::NumberFormat::Float) {
|
||||
return vk::Format::eR32G32Sfloat;
|
||||
}
|
||||
if (data_format == AmdGpu::DataFormat::Format5_6_5 &&
|
||||
num_format == AmdGpu::NumberFormat::Unorm) {
|
||||
return vk::Format::eB5G6R5UnormPack16;
|
||||
}
|
||||
if (data_format == AmdGpu::DataFormat::Format1_5_5_5 &&
|
||||
num_format == AmdGpu::NumberFormat::Unorm) {
|
||||
return vk::Format::eR5G5B5A1UnormPack16;
|
||||
}
|
||||
if (data_format == AmdGpu::DataFormat::Format8 && num_format == AmdGpu::NumberFormat::Unorm) {
|
||||
return vk::Format::eR8Unorm;
|
||||
}
|
||||
if (data_format == AmdGpu::DataFormat::FormatBc3 && num_format == AmdGpu::NumberFormat::Srgb) {
|
||||
return vk::Format::eBc3SrgbBlock;
|
||||
}
|
||||
if (data_format == AmdGpu::DataFormat::FormatBc3 && num_format == AmdGpu::NumberFormat::Unorm) {
|
||||
return vk::Format::eBc3UnormBlock;
|
||||
}
|
||||
if (data_format == AmdGpu::DataFormat::FormatBc4 && num_format == AmdGpu::NumberFormat::Unorm) {
|
||||
return vk::Format::eBc4UnormBlock;
|
||||
}
|
||||
if (data_format == AmdGpu::DataFormat::FormatBc5 && num_format == AmdGpu::NumberFormat::Unorm) {
|
||||
return vk::Format::eBc5UnormBlock;
|
||||
}
|
||||
if (data_format == AmdGpu::DataFormat::FormatBc5 && num_format == AmdGpu::NumberFormat::Snorm) {
|
||||
return vk::Format::eBc5SnormBlock;
|
||||
}
|
||||
if (data_format == AmdGpu::DataFormat::Format16_16_16_16 &&
|
||||
num_format == AmdGpu::NumberFormat::Sint) {
|
||||
return vk::Format::eR16G16B16A16Sint;
|
||||
}
|
||||
if (data_format == AmdGpu::DataFormat::Format16_16_16_16 &&
|
||||
num_format == AmdGpu::NumberFormat::Sscaled) {
|
||||
return vk::Format::eR16G16B16A16Sscaled;
|
||||
}
|
||||
if (data_format == AmdGpu::DataFormat::Format16_16 &&
|
||||
num_format == AmdGpu::NumberFormat::Float) {
|
||||
return vk::Format::eR16G16Sfloat;
|
||||
}
|
||||
if (data_format == AmdGpu::DataFormat::Format16_16 &&
|
||||
num_format == AmdGpu::NumberFormat::Unorm) {
|
||||
return vk::Format::eR16G16Unorm;
|
||||
}
|
||||
if (data_format == AmdGpu::DataFormat::Format2_10_10_10 &&
|
||||
num_format == AmdGpu::NumberFormat::Unorm) {
|
||||
return vk::Format::eA2B10G10R10UnormPack32;
|
||||
}
|
||||
if (data_format == AmdGpu::DataFormat::Format2_10_10_10 &&
|
||||
num_format == AmdGpu::NumberFormat::Snorm) {
|
||||
return vk::Format::eA2B10G10R10SnormPack32;
|
||||
}
|
||||
if (data_format == AmdGpu::DataFormat::FormatBc7 && num_format == AmdGpu::NumberFormat::Srgb) {
|
||||
return vk::Format::eBc7SrgbBlock;
|
||||
}
|
||||
if (data_format == AmdGpu::DataFormat::FormatBc1 && num_format == AmdGpu::NumberFormat::Unorm) {
|
||||
return vk::Format::eBc1RgbaUnormBlock;
|
||||
}
|
||||
if (data_format == AmdGpu::DataFormat::Format8_8_8_8 &&
|
||||
num_format == AmdGpu::NumberFormat::Uint) {
|
||||
return vk::Format::eR8G8B8A8Uint;
|
||||
}
|
||||
if (data_format == AmdGpu::DataFormat::Format16 && num_format == AmdGpu::NumberFormat::Float) {
|
||||
return vk::Format::eR16Sfloat;
|
||||
}
|
||||
if (data_format == AmdGpu::DataFormat::Format32 && num_format == AmdGpu::NumberFormat::Float) {
|
||||
return vk::Format::eR32Sfloat;
|
||||
}
|
||||
if (data_format == AmdGpu::DataFormat::Format16_16_16_16 &&
|
||||
num_format == AmdGpu::NumberFormat::Float) {
|
||||
return vk::Format::eR16G16B16A16Sfloat;
|
||||
}
|
||||
if (data_format == AmdGpu::DataFormat::Format32 && num_format == AmdGpu::NumberFormat::Uint) {
|
||||
return vk::Format::eR32Uint;
|
||||
}
|
||||
if (data_format == AmdGpu::DataFormat::Format32 && num_format == AmdGpu::NumberFormat::Sint) {
|
||||
return vk::Format::eR32Sint;
|
||||
}
|
||||
if (data_format == AmdGpu::DataFormat::Format8_8 && num_format == AmdGpu::NumberFormat::Unorm) {
|
||||
return vk::Format::eR8G8Unorm;
|
||||
}
|
||||
if (data_format == AmdGpu::DataFormat::Format8_8 && num_format == AmdGpu::NumberFormat::Uint) {
|
||||
return vk::Format::eR8G8Uint;
|
||||
}
|
||||
if (data_format == AmdGpu::DataFormat::Format8_8 && num_format == AmdGpu::NumberFormat::Snorm) {
|
||||
return vk::Format::eR8G8Snorm;
|
||||
}
|
||||
if (data_format == AmdGpu::DataFormat::FormatBc7 && num_format == AmdGpu::NumberFormat::Unorm) {
|
||||
return vk::Format::eBc7UnormBlock;
|
||||
}
|
||||
if (data_format == AmdGpu::DataFormat::FormatBc2 && num_format == AmdGpu::NumberFormat::Srgb) {
|
||||
return vk::Format::eBc2SrgbBlock;
|
||||
}
|
||||
if (data_format == AmdGpu::DataFormat::FormatBc2 && num_format == AmdGpu::NumberFormat::Unorm) {
|
||||
return vk::Format::eBc2UnormBlock;
|
||||
}
|
||||
if (data_format == AmdGpu::DataFormat::Format16_16 &&
|
||||
num_format == AmdGpu::NumberFormat::Snorm) {
|
||||
return vk::Format::eR16G16Snorm;
|
||||
}
|
||||
if (data_format == AmdGpu::DataFormat::Format10_11_11 &&
|
||||
num_format == AmdGpu::NumberFormat::Float) {
|
||||
return vk::Format::eB10G11R11UfloatPack32;
|
||||
}
|
||||
if (data_format == AmdGpu::DataFormat::Format16_16 &&
|
||||
num_format == AmdGpu::NumberFormat::Float) {
|
||||
return vk::Format::eR16G16Sfloat;
|
||||
}
|
||||
if (data_format == AmdGpu::DataFormat::Format16_16_16_16 &&
|
||||
num_format == AmdGpu::NumberFormat::Snorm) {
|
||||
return vk::Format::eR16G16B16A16Snorm;
|
||||
}
|
||||
if (data_format == AmdGpu::DataFormat::Format32_32 &&
|
||||
num_format == AmdGpu::NumberFormat::Uint) {
|
||||
return vk::Format::eR32G32Uint;
|
||||
}
|
||||
if (data_format == AmdGpu::DataFormat::Format4_4_4_4 &&
|
||||
num_format == AmdGpu::NumberFormat::Unorm) {
|
||||
return vk::Format::eR4G4B4A4UnormPack16;
|
||||
}
|
||||
if (data_format == AmdGpu::DataFormat::Format16_16_16_16 &&
|
||||
num_format == AmdGpu::NumberFormat::Uint) {
|
||||
return vk::Format::eR16G16B16A16Uint;
|
||||
}
|
||||
if (data_format == AmdGpu::DataFormat::Format32_32_32_32 &&
|
||||
num_format == AmdGpu::NumberFormat::Uint) {
|
||||
return vk::Format::eR32G32B32A32Uint;
|
||||
}
|
||||
if (data_format == AmdGpu::DataFormat::Format32_32_32_32 &&
|
||||
num_format == AmdGpu::NumberFormat::Sint) {
|
||||
return vk::Format::eR32G32B32A32Sint;
|
||||
}
|
||||
if (data_format == AmdGpu::DataFormat::Format8 && num_format == AmdGpu::NumberFormat::Sint) {
|
||||
return vk::Format::eR8Sint;
|
||||
}
|
||||
if (data_format == AmdGpu::DataFormat::FormatBc1 && num_format == AmdGpu::NumberFormat::Srgb) {
|
||||
return vk::Format::eBc1RgbaSrgbBlock;
|
||||
}
|
||||
if (data_format == AmdGpu::DataFormat::Format16_16 &&
|
||||
num_format == AmdGpu::NumberFormat::Sint) {
|
||||
return vk::Format::eR16G16Sint;
|
||||
}
|
||||
if (data_format == AmdGpu::DataFormat::Format16_16 &&
|
||||
num_format == AmdGpu::NumberFormat::Sscaled) {
|
||||
return vk::Format::eR16G16Sscaled;
|
||||
}
|
||||
if (data_format == AmdGpu::DataFormat::Format8_8_8_8 &&
|
||||
num_format == AmdGpu::NumberFormat::Uscaled) {
|
||||
return vk::Format::eR8G8B8A8Uscaled;
|
||||
}
|
||||
if (data_format == AmdGpu::DataFormat::Format16 && num_format == AmdGpu::NumberFormat::Unorm) {
|
||||
return vk::Format::eR16Unorm;
|
||||
}
|
||||
if (data_format == AmdGpu::DataFormat::Format16_16_16_16 &&
|
||||
num_format == AmdGpu::NumberFormat::Unorm) {
|
||||
return vk::Format::eR16G16B16A16Unorm;
|
||||
}
|
||||
if (data_format == AmdGpu::DataFormat::Format16_16 &&
|
||||
num_format == AmdGpu::NumberFormat::Uint) {
|
||||
return vk::Format::eR16G16Uint;
|
||||
}
|
||||
if (data_format == AmdGpu::DataFormat::Format8 && num_format == AmdGpu::NumberFormat::Uint) {
|
||||
return vk::Format::eR8Uint;
|
||||
}
|
||||
if (data_format == AmdGpu::DataFormat::Format16_16_16_16 &&
|
||||
num_format == AmdGpu::NumberFormat::SnormNz) {
|
||||
return vk::Format::eR16G16B16A16Snorm;
|
||||
}
|
||||
if (data_format == AmdGpu::DataFormat::Format8_8_8_8 &&
|
||||
num_format == AmdGpu::NumberFormat::Snorm) {
|
||||
return vk::Format::eR8G8B8A8Snorm;
|
||||
}
|
||||
if (data_format == AmdGpu::DataFormat::FormatBc6 && num_format == AmdGpu::NumberFormat::Unorm) {
|
||||
return vk::Format::eBc6HUfloatBlock;
|
||||
}
|
||||
if (data_format == AmdGpu::DataFormat::FormatBc6 && num_format == AmdGpu::NumberFormat::Snorm) {
|
||||
return vk::Format::eBc6HSfloatBlock;
|
||||
}
|
||||
if (data_format == AmdGpu::DataFormat::Format8_8_8_8 &&
|
||||
num_format == AmdGpu::NumberFormat::Sint) {
|
||||
return vk::Format::eR8G8B8A8Sint;
|
||||
}
|
||||
if (data_format == AmdGpu::DataFormat::Format8 && num_format == AmdGpu::NumberFormat::Srgb) {
|
||||
return vk::Format::eR8Srgb;
|
||||
}
|
||||
if (data_format == AmdGpu::DataFormat::Format11_11_10 &&
|
||||
num_format == AmdGpu::NumberFormat::Float) {
|
||||
return vk::Format::eB10G11R11UfloatPack32;
|
||||
}
|
||||
if (data_format == AmdGpu::DataFormat::Format16 && num_format == AmdGpu::NumberFormat::Uint) {
|
||||
return vk::Format::eR16Uint;
|
||||
}
|
||||
if (data_format == AmdGpu::DataFormat::Format5_9_9_9 &&
|
||||
num_format == AmdGpu::NumberFormat::Float) {
|
||||
return vk::Format::eE5B9G9R9UfloatPack32;
|
||||
}
|
||||
if (data_format == AmdGpu::DataFormat::Format8 && num_format == AmdGpu::NumberFormat::Snorm) {
|
||||
return vk::Format::eR8Snorm;
|
||||
}
|
||||
UNREACHABLE_MSG("Unknown data_format={} and num_format={}", u32(data_format), u32(num_format));
|
||||
const auto& formats = SurfaceFormats();
|
||||
const auto format =
|
||||
std::find_if(formats.begin(), formats.end(), [&](const SurfaceFormatInfo& format_info) {
|
||||
return format_info.data_format == data_format &&
|
||||
format_info.number_format == num_format;
|
||||
});
|
||||
ASSERT_MSG(format != formats.end(), "Unknown data_format={} and num_format={}",
|
||||
static_cast<u32>(data_format), static_cast<u32>(num_format));
|
||||
return format->vk_format;
|
||||
}
|
||||
|
||||
vk::Format AdjustColorBufferFormat(vk::Format base_format,
|
||||
|
@ -636,30 +670,45 @@ vk::Format AdjustColorBufferFormat(vk::Format base_format,
|
|||
return base_format;
|
||||
}
|
||||
|
||||
vk::Format DepthFormat(DepthBuffer::ZFormat z_format, DepthBuffer::StencilFormat stencil_format) {
|
||||
static constexpr DepthFormatInfo CreateDepthFormatInfo(
|
||||
const DepthBuffer::ZFormat z_format, const DepthBuffer::StencilFormat stencil_format,
|
||||
const vk::Format vk_format) {
|
||||
return {
|
||||
.z_format = z_format,
|
||||
.stencil_format = stencil_format,
|
||||
.vk_format = vk_format,
|
||||
.flags = vk::FormatFeatureFlagBits2::eDepthStencilAttachment,
|
||||
};
|
||||
}
|
||||
|
||||
std::span<const DepthFormatInfo> DepthFormats() {
|
||||
using ZFormat = DepthBuffer::ZFormat;
|
||||
using StencilFormat = DepthBuffer::StencilFormat;
|
||||
static constexpr std::array formats{
|
||||
// Invalid
|
||||
CreateDepthFormatInfo(ZFormat::Invalid, StencilFormat::Invalid, vk::Format::eUndefined),
|
||||
CreateDepthFormatInfo(ZFormat::Invalid, StencilFormat::Stencil8,
|
||||
vk::Format::eD32SfloatS8Uint),
|
||||
// 16
|
||||
CreateDepthFormatInfo(ZFormat::Z16, StencilFormat::Invalid, vk::Format::eD16Unorm),
|
||||
CreateDepthFormatInfo(ZFormat::Z16, StencilFormat::Stencil8, vk::Format::eD16UnormS8Uint),
|
||||
// 32_Float
|
||||
CreateDepthFormatInfo(ZFormat::Z32Float, StencilFormat::Invalid, vk::Format::eD32Sfloat),
|
||||
CreateDepthFormatInfo(ZFormat::Z32Float, StencilFormat::Stencil8,
|
||||
vk::Format::eD32SfloatS8Uint),
|
||||
};
|
||||
return formats;
|
||||
}
|
||||
|
||||
if (z_format == ZFormat::Z32Float && stencil_format == StencilFormat::Stencil8) {
|
||||
return vk::Format::eD32SfloatS8Uint;
|
||||
}
|
||||
if (z_format == ZFormat::Z32Float && stencil_format == StencilFormat::Invalid) {
|
||||
return vk::Format::eD32Sfloat;
|
||||
}
|
||||
if (z_format == ZFormat::Z16 && stencil_format == StencilFormat::Invalid) {
|
||||
return vk::Format::eD16Unorm;
|
||||
}
|
||||
if (z_format == ZFormat::Z16 && stencil_format == StencilFormat::Stencil8) {
|
||||
return vk::Format::eD16UnormS8Uint;
|
||||
}
|
||||
if (z_format == ZFormat::Invalid && stencil_format == StencilFormat::Stencil8) {
|
||||
return vk::Format::eD32SfloatS8Uint;
|
||||
}
|
||||
if (z_format == ZFormat::Invalid && stencil_format == StencilFormat::Invalid) {
|
||||
return vk::Format::eUndefined;
|
||||
}
|
||||
UNREACHABLE_MSG("Unsupported depth/stencil format. depth = {} stencil = {}",
|
||||
magic_enum::enum_name(z_format), magic_enum::enum_name(stencil_format));
|
||||
vk::Format DepthFormat(DepthBuffer::ZFormat z_format, DepthBuffer::StencilFormat stencil_format) {
|
||||
const auto& formats = DepthFormats();
|
||||
const auto format =
|
||||
std::find_if(formats.begin(), formats.end(), [&](const DepthFormatInfo& format_info) {
|
||||
return format_info.z_format == z_format && format_info.stencil_format == stencil_format;
|
||||
});
|
||||
ASSERT_MSG(format != formats.end(), "Unknown z_format={} and stencil_format={}",
|
||||
static_cast<u32>(z_format), static_cast<u32>(stencil_format));
|
||||
return format->vk_format;
|
||||
}
|
||||
|
||||
void EmitQuadToTriangleListIndices(u8* out_ptr, u32 num_vertices) {
|
||||
|
|
|
@ -40,13 +40,27 @@ vk::SamplerMipmapMode MipFilter(AmdGpu::MipFilter filter);
|
|||
|
||||
vk::BorderColor BorderColor(AmdGpu::BorderColor color);
|
||||
|
||||
std::span<const vk::Format> GetAllFormats();
|
||||
struct SurfaceFormatInfo {
|
||||
AmdGpu::DataFormat data_format;
|
||||
AmdGpu::NumberFormat number_format;
|
||||
vk::Format vk_format;
|
||||
vk::FormatFeatureFlags2 flags;
|
||||
};
|
||||
std::span<const SurfaceFormatInfo> SurfaceFormats();
|
||||
|
||||
vk::Format SurfaceFormat(AmdGpu::DataFormat data_format, AmdGpu::NumberFormat num_format);
|
||||
|
||||
vk::Format AdjustColorBufferFormat(vk::Format base_format,
|
||||
Liverpool::ColorBuffer::SwapMode comp_swap, bool is_vo_surface);
|
||||
|
||||
struct DepthFormatInfo {
|
||||
Liverpool::DepthBuffer::ZFormat z_format;
|
||||
Liverpool::DepthBuffer::StencilFormat stencil_format;
|
||||
vk::Format vk_format;
|
||||
vk::FormatFeatureFlags2 flags;
|
||||
};
|
||||
std::span<const DepthFormatInfo> DepthFormats();
|
||||
|
||||
vk::Format DepthFormat(Liverpool::DepthBuffer::ZFormat z_format,
|
||||
Liverpool::DepthBuffer::StencilFormat stencil_format);
|
||||
|
||||
|
|
|
@ -33,16 +33,41 @@ std::vector<std::string> GetSupportedExtensions(vk::PhysicalDevice physical) {
|
|||
return supported_extensions;
|
||||
}
|
||||
|
||||
vk::FormatProperties3 GetFormatProperties(vk::PhysicalDevice physical, vk::Format format) {
|
||||
vk::FormatProperties3 properties3{};
|
||||
vk::FormatProperties2 properties2 = {
|
||||
.pNext = &properties3,
|
||||
};
|
||||
physical.getFormatProperties2(format, &properties2);
|
||||
return properties3;
|
||||
}
|
||||
|
||||
std::unordered_map<vk::Format, vk::FormatProperties3> GetFormatProperties(
|
||||
vk::PhysicalDevice physical) {
|
||||
std::unordered_map<vk::Format, vk::FormatProperties3> format_properties;
|
||||
for (const auto& format : LiverpoolToVK::GetAllFormats()) {
|
||||
vk::FormatProperties3 properties3{};
|
||||
vk::FormatProperties2 properties2 = {
|
||||
.pNext = &properties3,
|
||||
};
|
||||
physical.getFormatProperties2(format, &properties2);
|
||||
format_properties.emplace(format, properties3);
|
||||
for (const auto& format_info : LiverpoolToVK::SurfaceFormats()) {
|
||||
const auto format = format_info.vk_format;
|
||||
if (!format_properties.contains(format)) {
|
||||
format_properties.emplace(format, GetFormatProperties(physical, format));
|
||||
}
|
||||
}
|
||||
for (const auto& format_info : LiverpoolToVK::DepthFormats()) {
|
||||
const auto format = format_info.vk_format;
|
||||
if (!format_properties.contains(format)) {
|
||||
format_properties.emplace(format, GetFormatProperties(physical, format));
|
||||
}
|
||||
}
|
||||
// Other miscellaneous formats, e.g. for color buffers, swizzles, or compatibility
|
||||
static constexpr std::array misc_formats = {
|
||||
vk::Format::eA2R10G10B10UnormPack32, vk::Format::eA8B8G8R8UnormPack32,
|
||||
vk::Format::eA8B8G8R8SrgbPack32, vk::Format::eB8G8R8A8Unorm,
|
||||
vk::Format::eB8G8R8A8Srgb, vk::Format::eR5G6B5UnormPack16,
|
||||
vk::Format::eD24UnormS8Uint,
|
||||
};
|
||||
for (const auto& format : misc_formats) {
|
||||
if (!format_properties.contains(format)) {
|
||||
format_properties.emplace(format, GetFormatProperties(physical, format));
|
||||
}
|
||||
}
|
||||
return format_properties;
|
||||
}
|
||||
|
@ -125,22 +150,23 @@ Instance::Instance(Frontend::WindowSDL& window, s32 physical_device_index,
|
|||
CollectToolingInfo();
|
||||
|
||||
// Check and log format support details.
|
||||
for (const auto& key : format_properties | std::views::keys) {
|
||||
const auto format = key;
|
||||
if (!IsImageFormatSupported(format)) {
|
||||
const auto alternative = GetAlternativeFormat(format);
|
||||
if (IsImageFormatSupported(alternative)) {
|
||||
LOG_WARNING(Render_Vulkan,
|
||||
"Format {} is not supported for images, falling back to {}.",
|
||||
vk::to_string(format), vk::to_string(alternative));
|
||||
} else if (IsVertexFormatSupported(format)) {
|
||||
LOG_WARNING(Render_Vulkan, "Format {} is only supported for vertex buffers.",
|
||||
vk::to_string(format));
|
||||
} else {
|
||||
LOG_ERROR(Render_Vulkan,
|
||||
"Format {} is not supported and no suitable alternative is supported.",
|
||||
vk::to_string(format));
|
||||
}
|
||||
for (const auto& format : LiverpoolToVK::SurfaceFormats()) {
|
||||
if (!IsFormatSupported(GetSupportedFormat(format.vk_format, format.flags), format.flags)) {
|
||||
LOG_WARNING(Render_Vulkan,
|
||||
"Surface format data_format={}, number_format={} is not fully supported "
|
||||
"(vk_format={}, requested flags={})",
|
||||
static_cast<u32>(format.data_format),
|
||||
static_cast<u32>(format.number_format), vk::to_string(format.vk_format),
|
||||
vk::to_string(format.flags));
|
||||
}
|
||||
}
|
||||
for (const auto& format : LiverpoolToVK::DepthFormats()) {
|
||||
if (!IsFormatSupported(GetSupportedFormat(format.vk_format, format.flags), format.flags)) {
|
||||
LOG_WARNING(Render_Vulkan,
|
||||
"Depth format z_format={}, stencil_format={} is not fully supported "
|
||||
"(vk_format={}, requested flags={})",
|
||||
static_cast<u32>(format.z_format), static_cast<u32>(format.stencil_format),
|
||||
vk::to_string(format.vk_format), vk::to_string(format.flags));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -496,7 +522,8 @@ void Instance::CollectToolingInfo() {
|
|||
}
|
||||
}
|
||||
|
||||
bool Instance::IsImageFormatSupported(const vk::Format format) const {
|
||||
bool Instance::IsFormatSupported(const vk::Format format,
|
||||
const vk::FormatFeatureFlags2 flags) const {
|
||||
if (format == vk::Format::eUndefined) [[unlikely]] {
|
||||
return true;
|
||||
}
|
||||
|
@ -506,49 +533,36 @@ bool Instance::IsImageFormatSupported(const vk::Format format) const {
|
|||
UNIMPLEMENTED_MSG("Properties of format {} have not been queried.", vk::to_string(format));
|
||||
}
|
||||
|
||||
constexpr vk::FormatFeatureFlags2 optimal_flags = vk::FormatFeatureFlagBits2::eTransferSrc |
|
||||
vk::FormatFeatureFlagBits2::eTransferDst |
|
||||
vk::FormatFeatureFlagBits2::eSampledImage;
|
||||
return (it->second.optimalTilingFeatures & optimal_flags) == optimal_flags;
|
||||
return ((it->second.optimalTilingFeatures | it->second.bufferFeatures) & flags) == flags;
|
||||
}
|
||||
|
||||
bool Instance::IsVertexFormatSupported(const vk::Format format) const {
|
||||
if (format == vk::Format::eUndefined) [[unlikely]] {
|
||||
return true;
|
||||
}
|
||||
|
||||
const auto it = format_properties.find(format);
|
||||
if (it == format_properties.end()) {
|
||||
UNIMPLEMENTED_MSG("Properties of format {} have not been queried.", vk::to_string(format));
|
||||
}
|
||||
|
||||
constexpr vk::FormatFeatureFlags2 optimal_flags = vk::FormatFeatureFlagBits2::eVertexBuffer;
|
||||
return (it->second.bufferFeatures & optimal_flags) == optimal_flags;
|
||||
}
|
||||
|
||||
vk::Format Instance::GetAlternativeFormat(const vk::Format format) const {
|
||||
if (format == vk::Format::eB5G6R5UnormPack16) {
|
||||
static vk::Format GetAlternativeFormat(const vk::Format format) {
|
||||
switch (format) {
|
||||
case vk::Format::eB5G6R5UnormPack16:
|
||||
return vk::Format::eR5G6B5UnormPack16;
|
||||
} else if (format == vk::Format::eD16UnormS8Uint) {
|
||||
case vk::Format::eD16UnormS8Uint:
|
||||
return vk::Format::eD24UnormS8Uint;
|
||||
default:
|
||||
return format;
|
||||
}
|
||||
return format;
|
||||
}
|
||||
|
||||
vk::Format Instance::GetSupportedFormat(const vk::Format format) const {
|
||||
if (IsImageFormatSupported(format)) [[likely]] {
|
||||
vk::Format Instance::GetSupportedFormat(const vk::Format format,
|
||||
const vk::FormatFeatureFlags2 flags) const {
|
||||
if (IsFormatSupported(format, flags)) [[likely]] {
|
||||
return format;
|
||||
}
|
||||
const vk::Format alternative = GetAlternativeFormat(format);
|
||||
if (IsImageFormatSupported(alternative)) [[likely]] {
|
||||
if (IsFormatSupported(alternative, flags)) [[likely]] {
|
||||
return alternative;
|
||||
}
|
||||
return format;
|
||||
}
|
||||
|
||||
vk::ComponentMapping Instance::GetSupportedComponentSwizzle(vk::Format format,
|
||||
vk::ComponentMapping swizzle) const {
|
||||
if (IsImageFormatSupported(format)) [[likely]] {
|
||||
vk::ComponentMapping Instance::GetSupportedComponentSwizzle(
|
||||
const vk::Format format, const vk::ComponentMapping swizzle,
|
||||
const vk::FormatFeatureFlags2 flags) const {
|
||||
if (IsFormatSupported(format, flags)) [[likely]] {
|
||||
return swizzle;
|
||||
}
|
||||
|
||||
|
|
|
@ -30,11 +30,12 @@ public:
|
|||
std::string GetDriverVersionName();
|
||||
|
||||
/// Gets a compatibility format if the format is not supported.
|
||||
[[nodiscard]] vk::Format GetSupportedFormat(vk::Format format) const;
|
||||
[[nodiscard]] vk::Format GetSupportedFormat(vk::Format format,
|
||||
vk::FormatFeatureFlags2 flags) const;
|
||||
|
||||
/// Re-orders a component swizzle for format compatibility, if needed.
|
||||
[[nodiscard]] vk::ComponentMapping GetSupportedComponentSwizzle(
|
||||
vk::Format format, vk::ComponentMapping swizzle) const;
|
||||
vk::Format format, vk::ComponentMapping swizzle, vk::FormatFeatureFlags2 flags) const;
|
||||
|
||||
/// Returns the Vulkan instance
|
||||
vk::Instance GetInstance() const {
|
||||
|
@ -245,14 +246,8 @@ private:
|
|||
void CollectDeviceParameters();
|
||||
void CollectToolingInfo();
|
||||
|
||||
/// Determines if a format is supported for images.
|
||||
[[nodiscard]] bool IsImageFormatSupported(vk::Format format) const;
|
||||
|
||||
/// Determines if a format is supported for vertex buffers.
|
||||
[[nodiscard]] bool IsVertexFormatSupported(vk::Format format) const;
|
||||
|
||||
/// Gets a commonly available alternative for an unsupported pixel format.
|
||||
vk::Format GetAlternativeFormat(const vk::Format format) const;
|
||||
/// Determines if a format is supported for a set of feature flags.
|
||||
[[nodiscard]] bool IsFormatSupported(vk::Format format, vk::FormatFeatureFlags2 flags) const;
|
||||
|
||||
private:
|
||||
vk::UniqueInstance instance;
|
||||
|
|
|
@ -86,6 +86,28 @@ static vk::ImageUsageFlags ImageUsageFlags(const ImageInfo& info) {
|
|||
return usage;
|
||||
}
|
||||
|
||||
static vk::FormatFeatureFlags2 FormatFeatureFlags(const vk::ImageUsageFlags usage_flags) {
|
||||
vk::FormatFeatureFlags2 feature_flags{};
|
||||
if (usage_flags & vk::ImageUsageFlagBits::eTransferSrc) {
|
||||
feature_flags |= vk::FormatFeatureFlagBits2::eTransferSrc;
|
||||
}
|
||||
if (usage_flags & vk::ImageUsageFlagBits::eTransferDst) {
|
||||
feature_flags |= vk::FormatFeatureFlagBits2::eTransferDst;
|
||||
}
|
||||
if (usage_flags & vk::ImageUsageFlagBits::eSampled) {
|
||||
feature_flags |= vk::FormatFeatureFlagBits2::eSampledImage;
|
||||
}
|
||||
if (usage_flags & vk::ImageUsageFlagBits::eColorAttachment) {
|
||||
feature_flags |= vk::FormatFeatureFlagBits2::eColorAttachment;
|
||||
}
|
||||
if (usage_flags & vk::ImageUsageFlagBits::eDepthStencilAttachment) {
|
||||
feature_flags |= vk::FormatFeatureFlagBits2::eDepthStencilAttachment;
|
||||
}
|
||||
// Note: StorageImage is intentionally ignored for now since it is always set, and can mess up
|
||||
// compatibility checks.
|
||||
return feature_flags;
|
||||
}
|
||||
|
||||
UniqueImage::UniqueImage(vk::Device device_, VmaAllocator allocator_)
|
||||
: device{device_}, allocator{allocator_} {}
|
||||
|
||||
|
@ -132,6 +154,7 @@ Image::Image(const Vulkan::Instance& instance_, Vulkan::Scheduler& scheduler_,
|
|||
}
|
||||
|
||||
usage = ImageUsageFlags(info);
|
||||
format_features = FormatFeatureFlags(usage);
|
||||
|
||||
switch (info.pixel_format) {
|
||||
case vk::Format::eD16Unorm:
|
||||
|
@ -149,7 +172,7 @@ Image::Image(const Vulkan::Instance& instance_, Vulkan::Scheduler& scheduler_,
|
|||
}
|
||||
|
||||
constexpr auto tiling = vk::ImageTiling::eOptimal;
|
||||
const auto supported_format = instance->GetSupportedFormat(info.pixel_format);
|
||||
const auto supported_format = instance->GetSupportedFormat(info.pixel_format, format_features);
|
||||
const auto properties = instance->GetPhysicalDevice().getImageFormatProperties(
|
||||
supported_format, info.type, tiling, usage, flags);
|
||||
const auto supported_samples = properties.result == vk::Result::eSuccess
|
||||
|
|
|
@ -114,6 +114,7 @@ struct Image {
|
|||
|
||||
// Resource state tracking
|
||||
vk::ImageUsageFlags usage;
|
||||
vk::FormatFeatureFlags2 format_features;
|
||||
struct State {
|
||||
vk::Flags<vk::PipelineStageFlagBits2> pl_stage = vk::PipelineStageFlagBits2::eAllCommands;
|
||||
vk::Flags<vk::AccessFlagBits2> access_mask = vk::AccessFlagBits2::eNone;
|
||||
|
|
|
@ -164,8 +164,9 @@ ImageView::ImageView(const Vulkan::Instance& instance, const ImageViewInfo& info
|
|||
.pNext = &usage_ci,
|
||||
.image = image.image,
|
||||
.viewType = info.type,
|
||||
.format = instance.GetSupportedFormat(format),
|
||||
.components = instance.GetSupportedComponentSwizzle(format, info.mapping),
|
||||
.format = instance.GetSupportedFormat(format, image.format_features),
|
||||
.components =
|
||||
instance.GetSupportedComponentSwizzle(format, info.mapping, image.format_features),
|
||||
.subresourceRange{
|
||||
.aspectMask = aspect,
|
||||
.baseMipLevel = info.range.base.level,
|
||||
|
|
Loading…
Reference in a new issue