diff --git a/src/video_core/renderer_vulkan/liverpool_to_vk.cpp b/src/video_core/renderer_vulkan/liverpool_to_vk.cpp index 16aa4d695..f4f5a0d91 100644 --- a/src/video_core/renderer_vulkan/liverpool_to_vk.cpp +++ b/src/video_core/renderer_vulkan/liverpool_to_vk.cpp @@ -665,454 +665,33 @@ std::span SurfaceFormats() { return formats; } -vk::Format SurfaceFormat(AmdGpu::DataFormat data_format, AmdGpu::NumberFormat num_format) { - bool found = false; - vk::Format result = vk::Format::eUndefined; +// Table 8.13 Data and Image Formats [Sea Islands Series Instruction Set Architecture] +static const size_t amd_gpu_data_format_bit_size = 6; // All values are under 64 +static const size_t amd_gpu_number_format_bit_size = 4; // All values are under 16 - switch (data_format) { - case AmdGpu::DataFormat::FormatInvalid: - result = vk::Format::eUndefined; - found = true; - break; - case AmdGpu::DataFormat::Format8: - found = true; - switch (num_format) { - case AmdGpu::NumberFormat::Unorm: - result = vk::Format::eR8Unorm; - break; - case AmdGpu::NumberFormat::Snorm: - result = vk::Format::eR8Snorm; - break; - case AmdGpu::NumberFormat::Uscaled: - result = vk::Format::eR8Uscaled; - break; - case AmdGpu::NumberFormat::Sscaled: - result = vk::Format::eR8Sscaled; - break; - case AmdGpu::NumberFormat::Uint: - result = vk::Format::eR8Uint; - break; - case AmdGpu::NumberFormat::Sint: - result = vk::Format::eR8Sint; - break; - case AmdGpu::NumberFormat::Srgb: - result = vk::Format::eR8Srgb; - break; - default: - found = false; - break; - } - break; - case AmdGpu::DataFormat::Format16: - found = true; - switch (num_format) { - case AmdGpu::NumberFormat::Unorm: - result = vk::Format::eR16Unorm; - break; - case AmdGpu::NumberFormat::Snorm: - result = vk::Format::eR16Snorm; - break; - case AmdGpu::NumberFormat::Uscaled: - result = vk::Format::eR16Uscaled; - break; - case AmdGpu::NumberFormat::Sscaled: - result = vk::Format::eR16Sscaled; - break; - case AmdGpu::NumberFormat::Uint: - result = vk::Format::eR16Uint; - break; - case AmdGpu::NumberFormat::Sint: - result = vk::Format::eR16Sint; - break; - case AmdGpu::NumberFormat::Float: - result = vk::Format::eR16Sfloat; - break; - default: - found = false; - break; - } - break; - case AmdGpu::DataFormat::Format8_8: - found = true; - switch (num_format) { - case AmdGpu::NumberFormat::Unorm: - result = vk::Format::eR8G8Unorm; - break; - case AmdGpu::NumberFormat::Snorm: - result = vk::Format::eR8G8Snorm; - break; - case AmdGpu::NumberFormat::Uscaled: - result = vk::Format::eR8G8Uscaled; - break; - case AmdGpu::NumberFormat::Sscaled: - result = vk::Format::eR8G8Sscaled; - break; - case AmdGpu::NumberFormat::Uint: - result = vk::Format::eR8G8Uint; - break; - case AmdGpu::NumberFormat::Sint: - result = vk::Format::eR8G8Sint; - break; - case AmdGpu::NumberFormat::Srgb: - result = vk::Format::eR8G8Srgb; - break; - default: - found = false; - break; - } - break; - case AmdGpu::DataFormat::Format32: - found = true; - switch (num_format) { - case AmdGpu::NumberFormat::Uint: - result = vk::Format::eR32Uint; - break; - case AmdGpu::NumberFormat::Sint: - result = vk::Format::eR32Sint; - break; - case AmdGpu::NumberFormat::Float: - result = vk::Format::eR32Sfloat; - break; - default: - found = false; - break; - } - break; - case AmdGpu::DataFormat::Format16_16: - found = true; - switch (num_format) { - case AmdGpu::NumberFormat::Unorm: - result = vk::Format::eR16G16Unorm; - break; - case AmdGpu::NumberFormat::Snorm: - result = vk::Format::eR16G16Snorm; - break; - case AmdGpu::NumberFormat::Uscaled: - result = vk::Format::eR16G16Uscaled; - break; - case AmdGpu::NumberFormat::Sscaled: - result = vk::Format::eR16G16Sscaled; - break; - case AmdGpu::NumberFormat::Uint: - result = vk::Format::eR16G16Uint; - break; - case AmdGpu::NumberFormat::Sint: - result = vk::Format::eR16G16Sint; - break; - case AmdGpu::NumberFormat::Float: - result = vk::Format::eR16G16Sfloat; - break; - default: - found = false; - break; - } - break; - case AmdGpu::DataFormat::Format10_11_11: - found = true; - switch (num_format) { - case AmdGpu::NumberFormat::Float: - result = vk::Format::eB10G11R11UfloatPack32; - break; - default: - found = false; - break; - } - break; - case AmdGpu::DataFormat::Format11_11_10: - found = true; - switch (num_format) { - case AmdGpu::NumberFormat::Float: - result = vk::Format::eB10G11R11UfloatPack32; - break; - default: - found = false; - break; - } - break; - case AmdGpu::DataFormat::Format2_10_10_10: - found = true; - switch (num_format) { - case AmdGpu::NumberFormat::Unorm: - result = vk::Format::eA2B10G10R10UnormPack32; - break; - case AmdGpu::NumberFormat::Snorm: - result = vk::Format::eA2B10G10R10SnormPack32; - break; - case AmdGpu::NumberFormat::Uscaled: - result = vk::Format::eA2B10G10R10UscaledPack32; - break; - case AmdGpu::NumberFormat::Sscaled: - result = vk::Format::eA2B10G10R10SscaledPack32; - break; - case AmdGpu::NumberFormat::Uint: - result = vk::Format::eA2B10G10R10UintPack32; - break; - case AmdGpu::NumberFormat::Sint: - result = vk::Format::eA2B10G10R10SintPack32; - break; - default: - found = false; - break; - } - break; - case AmdGpu::DataFormat::Format8_8_8_8: - found = true; - switch (num_format) { - case AmdGpu::NumberFormat::Unorm: - result = vk::Format::eR8G8B8A8Unorm; - break; - case AmdGpu::NumberFormat::Snorm: - result = vk::Format::eR8G8B8A8Snorm; - break; - case AmdGpu::NumberFormat::Uscaled: - result = vk::Format::eR8G8B8A8Uscaled; - break; - case AmdGpu::NumberFormat::Sscaled: - result = vk::Format::eR8G8B8A8Sscaled; - break; - case AmdGpu::NumberFormat::Uint: - result = vk::Format::eR8G8B8A8Uint; - break; - case AmdGpu::NumberFormat::Sint: - result = vk::Format::eR8G8B8A8Sint; - break; - case AmdGpu::NumberFormat::Srgb: - result = vk::Format::eR8G8B8A8Srgb; - break; - default: - found = false; - break; - } - break; - case AmdGpu::DataFormat::Format32_32: - found = true; - switch (num_format) { - case AmdGpu::NumberFormat::Uint: - result = vk::Format::eR32G32Uint; - break; - case AmdGpu::NumberFormat::Sint: - result = vk::Format::eR32G32Sint; - break; - case AmdGpu::NumberFormat::Float: - result = vk::Format::eR32G32Sfloat; - break; - default: - found = false; - break; - } - break; - case AmdGpu::DataFormat::Format16_16_16_16: - found = true; - switch (num_format) { - case AmdGpu::NumberFormat::Unorm: - result = vk::Format::eR16G16B16A16Unorm; - break; - case AmdGpu::NumberFormat::Snorm: - result = vk::Format::eR16G16B16A16Snorm; - break; - case AmdGpu::NumberFormat::Uscaled: - result = vk::Format::eR16G16B16A16Uscaled; - break; - case AmdGpu::NumberFormat::Sscaled: - result = vk::Format::eR16G16B16A16Sscaled; - break; - case AmdGpu::NumberFormat::Uint: - result = vk::Format::eR16G16B16A16Uint; - break; - case AmdGpu::NumberFormat::Sint: - result = vk::Format::eR16G16B16A16Sint; - break; - case AmdGpu::NumberFormat::SnormNz: - result = vk::Format::eR16G16B16A16Snorm; - break; - case AmdGpu::NumberFormat::Float: - result = vk::Format::eR16G16B16A16Sfloat; - break; - default: - found = false; - break; - } - break; - case AmdGpu::DataFormat::Format32_32_32: - found = true; - switch (num_format) { - case AmdGpu::NumberFormat::Uint: - result = vk::Format::eR32G32B32Uint; - break; - case AmdGpu::NumberFormat::Sint: - result = vk::Format::eR32G32B32Sint; - break; - case AmdGpu::NumberFormat::Float: - result = vk::Format::eR32G32B32Sfloat; - break; - default: - found = false; - break; - } - break; - case AmdGpu::DataFormat::Format32_32_32_32: - found = true; - switch (num_format) { - case AmdGpu::NumberFormat::Uint: - result = vk::Format::eR32G32B32A32Uint; - break; - case AmdGpu::NumberFormat::Sint: - result = vk::Format::eR32G32B32A32Sint; - break; - case AmdGpu::NumberFormat::Float: - result = vk::Format::eR32G32B32A32Sfloat; - break; - default: - found = false; - break; - } - break; - case AmdGpu::DataFormat::Format5_6_5: - found = true; - switch (num_format) { - case AmdGpu::NumberFormat::Unorm: - result = vk::Format::eB5G6R5UnormPack16; - break; - default: - found = false; - break; - } - break; - case AmdGpu::DataFormat::Format1_5_5_5: - found = true; - switch (num_format) { - case AmdGpu::NumberFormat::Unorm: - result = vk::Format::eR5G5B5A1UnormPack16; - break; - default: - found = false; - break; - } - break; - case AmdGpu::DataFormat::Format4_4_4_4: - found = true; - switch (num_format) { - case AmdGpu::NumberFormat::Unorm: - result = vk::Format::eR4G4B4A4UnormPack16; - break; - default: - found = false; - break; - } - break; - case AmdGpu::DataFormat::Format5_9_9_9: - found = true; - switch (num_format) { - case AmdGpu::NumberFormat::Float: - result = vk::Format::eE5B9G9R9UfloatPack32; - break; - default: - found = false; - break; - } - break; - case AmdGpu::DataFormat::FormatBc1: - found = true; - switch (num_format) { - case AmdGpu::NumberFormat::Unorm: - result = vk::Format::eBc1RgbaUnormBlock; - break; - case AmdGpu::NumberFormat::Srgb: - result = vk::Format::eBc1RgbaSrgbBlock; - break; - default: - found = false; - break; - } - break; - case AmdGpu::DataFormat::FormatBc2: - found = true; - switch (num_format) { - case AmdGpu::NumberFormat::Unorm: - result = vk::Format::eBc2UnormBlock; - break; - case AmdGpu::NumberFormat::Srgb: - result = vk::Format::eBc2SrgbBlock; - break; - default: - found = false; - break; - } - break; - case AmdGpu::DataFormat::FormatBc3: - found = true; - switch (num_format) { - case AmdGpu::NumberFormat::Unorm: - result = vk::Format::eBc3UnormBlock; - break; - case AmdGpu::NumberFormat::Srgb: - result = vk::Format::eBc3SrgbBlock; - break; - default: - found = false; - break; - } - break; - case AmdGpu::DataFormat::FormatBc4: - found = true; - switch (num_format) { - case AmdGpu::NumberFormat::Unorm: - result = vk::Format::eBc4UnormBlock; - break; - case AmdGpu::NumberFormat::Snorm: - result = vk::Format::eBc4SnormBlock; - break; - default: - found = false; - break; - } - break; - case AmdGpu::DataFormat::FormatBc5: - found = true; - switch (num_format) { - case AmdGpu::NumberFormat::Unorm: - result = vk::Format::eBc5UnormBlock; - break; - case AmdGpu::NumberFormat::Snorm: - result = vk::Format::eBc5SnormBlock; - break; - default: - found = false; - break; - } - break; - case AmdGpu::DataFormat::FormatBc6: - found = true; - switch (num_format) { - case AmdGpu::NumberFormat::Unorm: - result = vk::Format::eBc6HUfloatBlock; - break; - case AmdGpu::NumberFormat::Snorm: - result = vk::Format::eBc6HSfloatBlock; - break; - default: - found = false; - break; - } - break; - case AmdGpu::DataFormat::FormatBc7: - found = true; - switch (num_format) { - case AmdGpu::NumberFormat::Unorm: - result = vk::Format::eBc7UnormBlock; - break; - case AmdGpu::NumberFormat::Srgb: - result = vk::Format::eBc7SrgbBlock; - break; - default: - found = false; - break; - } - break; - default: - found = false; +static size_t GetSurfaceFormatTableIndex(AmdGpu::DataFormat data_format, AmdGpu::NumberFormat num_format) { + DEBUG_ASSERT(data_format < 1 << amd_gpu_data_format_bit_size); + DEBUG_ASSERT(num_format < 1 << amd_gpu_number_format_bit_size); + size_t result = static_cast(num_format) | (static_cast(data_format) << amd_gpu_number_format_bit_size); + return result; +} + +static auto surface_format_table = []() constexpr { + std::array result; + for (auto& entry : result) { + entry = vk::Format::eUndefined; } + for (const auto& supported_format : SurfaceFormats()) { + result[GetSurfaceFormatTableIndex(supported_format.data_format, + supported_format.number_format)] = + supported_format.vk_format; + } + return result; +}(); +vk::Format SurfaceFormat(AmdGpu::DataFormat data_format, AmdGpu::NumberFormat num_format) { + vk::Format result = surface_format_table[GetSurfaceFormatTableIndex(data_format, num_format)]; + bool found = result != vk::Format::eUndefined || data_format == AmdGpu::DataFormat::FormatInvalid; ASSERT_MSG(found, "Unknown data_format={} and num_format={}", static_cast(data_format), static_cast(num_format)); return result;