shader_recompiler: Add swizzle support for unsupported formats. (#1869)

* shader_recompiler: Add swizzle support for unsupported formats.

* renderer_vulkan: Rework MRT swizzles and add unsupported format swizzle support.

* shader_recompiler: Clean up swizzle handling and handle ImageRead storage swizzle.

* shader_recompiler: Fix type errors

* liverpool_to_vk: Remove redundant clear color swizzles.

* shader_recompiler: Reduce CompositeConstruct to constants where possible.

* shader_recompiler: Fix ImageRead/Write and StoreBufferFormatF32 types.

* amdgpu: Add a few more unsupported format remaps.
This commit is contained in:
squidbus 2024-12-30 20:14:47 -08:00 committed by GitHub
parent 284f473a52
commit 41d64a200d
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
22 changed files with 522 additions and 282 deletions

View file

@ -324,6 +324,34 @@ vk::BorderColor BorderColor(AmdGpu::BorderColor color) {
}
}
vk::ComponentSwizzle ComponentSwizzle(AmdGpu::CompSwizzle comp_swizzle) {
switch (comp_swizzle) {
case AmdGpu::CompSwizzle::Zero:
return vk::ComponentSwizzle::eZero;
case AmdGpu::CompSwizzle::One:
return vk::ComponentSwizzle::eOne;
case AmdGpu::CompSwizzle::Red:
return vk::ComponentSwizzle::eR;
case AmdGpu::CompSwizzle::Green:
return vk::ComponentSwizzle::eG;
case AmdGpu::CompSwizzle::Blue:
return vk::ComponentSwizzle::eB;
case AmdGpu::CompSwizzle::Alpha:
return vk::ComponentSwizzle::eA;
default:
UNREACHABLE();
}
}
vk::ComponentMapping ComponentMapping(AmdGpu::CompMapping comp_mapping) {
return vk::ComponentMapping{
.r = ComponentSwizzle(comp_mapping.r),
.g = ComponentSwizzle(comp_mapping.g),
.b = ComponentSwizzle(comp_mapping.b),
.a = ComponentSwizzle(comp_mapping.a),
};
}
static constexpr vk::FormatFeatureFlags2 BufferRead =
vk::FormatFeatureFlagBits2::eUniformTexelBuffer | vk::FormatFeatureFlagBits2::eVertexBuffer;
static constexpr vk::FormatFeatureFlags2 BufferWrite =
@ -538,10 +566,8 @@ std::span<const SurfaceFormatInfo> SurfaceFormats() {
// 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
// 11_11_10 - Remapped to 10_11_11.
// 10_10_10_2 - Remapped to 2_10_10_10.
// 2_10_10_10
CreateSurfaceFormatInfo(AmdGpu::DataFormat::Format2_10_10_10, AmdGpu::NumberFormat::Unorm,
vk::Format::eA2B10G10R10UnormPack32),
@ -614,7 +640,7 @@ std::span<const SurfaceFormatInfo> SurfaceFormats() {
// 1_5_5_5
CreateSurfaceFormatInfo(AmdGpu::DataFormat::Format1_5_5_5, AmdGpu::NumberFormat::Unorm,
vk::Format::eR5G5B5A1UnormPack16),
// 5_5_5_1
// 5_5_5_1 - Remapped to 1_5_5_5.
// 4_4_4_4
CreateSurfaceFormatInfo(AmdGpu::DataFormat::Format4_4_4_4, AmdGpu::NumberFormat::Unorm,
vk::Format::eR4G4B4A4UnormPack16),
@ -677,31 +703,6 @@ vk::Format SurfaceFormat(AmdGpu::DataFormat data_format, AmdGpu::NumberFormat nu
return format->vk_format;
}
vk::Format AdjustColorBufferFormat(vk::Format base_format,
Liverpool::ColorBuffer::SwapMode comp_swap) {
const bool comp_swap_alt = comp_swap == Liverpool::ColorBuffer::SwapMode::Alternate;
const bool comp_swap_reverse = comp_swap == Liverpool::ColorBuffer::SwapMode::StandardReverse;
const bool comp_swap_alt_reverse =
comp_swap == Liverpool::ColorBuffer::SwapMode::AlternateReverse;
if (comp_swap_alt) {
switch (base_format) {
case vk::Format::eR8G8B8A8Unorm:
return vk::Format::eB8G8R8A8Unorm;
case vk::Format::eB8G8R8A8Unorm:
return vk::Format::eR8G8B8A8Unorm;
case vk::Format::eR8G8B8A8Srgb:
return vk::Format::eB8G8R8A8Srgb;
case vk::Format::eB8G8R8A8Srgb:
return vk::Format::eR8G8B8A8Srgb;
case vk::Format::eA2B10G10R10UnormPack32:
return vk::Format::eA2R10G10B10UnormPack32;
default:
break;
}
}
return base_format;
}
static constexpr DepthFormatInfo CreateDepthFormatInfo(
const DepthBuffer::ZFormat z_format, const DepthBuffer::StencilFormat stencil_format,
const vk::Format vk_format) {
@ -744,21 +745,12 @@ vk::Format DepthFormat(DepthBuffer::ZFormat z_format, DepthBuffer::StencilFormat
}
vk::ClearValue ColorBufferClearValue(const AmdGpu::Liverpool::ColorBuffer& color_buffer) {
const auto comp_swap = color_buffer.info.comp_swap.Value();
const auto format = color_buffer.info.format.Value();
const auto number_type = color_buffer.info.number_type.Value();
const auto comp_swizzle = color_buffer.Swizzle();
const auto format = color_buffer.DataFormat();
const auto number_type = color_buffer.NumFormat();
const auto& c0 = color_buffer.clear_word0;
const auto& c1 = color_buffer.clear_word1;
const auto num_bits = AmdGpu::NumBits(color_buffer.info.format);
const auto num_components = AmdGpu::NumComponents(format);
const bool comp_swap_alt =
comp_swap == AmdGpu::Liverpool::ColorBuffer::SwapMode::Alternate ||
comp_swap == AmdGpu::Liverpool::ColorBuffer::SwapMode::AlternateReverse;
const bool comp_swap_reverse =
comp_swap == AmdGpu::Liverpool::ColorBuffer::SwapMode::StandardReverse ||
comp_swap == AmdGpu::Liverpool::ColorBuffer::SwapMode::AlternateReverse;
vk::ClearColorValue color{};
@ -1079,26 +1071,7 @@ vk::ClearValue ColorBufferClearValue(const AmdGpu::Liverpool::ColorBuffer& color
break;
}
if (num_components == 1) {
if (comp_swap != Liverpool::ColorBuffer::SwapMode::Standard) {
color.float32[static_cast<int>(comp_swap)] = color.float32[0];
color.float32[0] = 0.0f;
}
} else {
if (comp_swap_alt && num_components == 4) {
std::swap(color.float32[0], color.float32[2]);
}
if (comp_swap_reverse) {
std::reverse(std::begin(color.float32), std::begin(color.float32) + num_components);
}
if (comp_swap_alt && num_components != 4) {
color.float32[3] = color.float32[num_components - 1];
color.float32[num_components - 1] = 0.0f;
}
}
color.float32 = comp_swizzle.Apply(color.float32);
return {.color = color};
}

View file

@ -42,6 +42,10 @@ vk::SamplerMipmapMode MipFilter(AmdGpu::MipFilter filter);
vk::BorderColor BorderColor(AmdGpu::BorderColor color);
vk::ComponentSwizzle ComponentSwizzle(AmdGpu::CompSwizzle comp_swizzle);
vk::ComponentMapping ComponentMapping(AmdGpu::CompMapping comp_mapping);
struct SurfaceFormatInfo {
AmdGpu::DataFormat data_format;
AmdGpu::NumberFormat number_format;
@ -52,9 +56,6 @@ 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);
struct DepthFormatInfo {
Liverpool::DepthBuffer::ZFormat z_format;
Liverpool::DepthBuffer::StencilFormat stencil_format;

View file

@ -32,7 +32,7 @@ struct GraphicsPipelineKey {
u32 num_color_attachments;
std::array<vk::Format, Liverpool::NumColorBuffers> color_formats;
std::array<AmdGpu::NumberFormat, Liverpool::NumColorBuffers> color_num_formats;
std::array<Liverpool::ColorBuffer::SwapMode, Liverpool::NumColorBuffers> mrt_swizzles;
std::array<AmdGpu::CompMapping, Liverpool::NumColorBuffers> color_swizzles;
vk::Format depth_format;
vk::Format stencil_format;

View file

@ -168,7 +168,7 @@ const Shader::RuntimeInfo& PipelineCache::BuildRuntimeInfo(Stage stage, LogicalS
for (u32 i = 0; i < Shader::MaxColorBuffers; i++) {
info.fs_info.color_buffers[i] = {
.num_format = graphics_key.color_num_formats[i],
.mrt_swizzle = static_cast<Shader::MrtSwizzle>(graphics_key.mrt_swizzles[i]),
.swizzle = graphics_key.color_swizzles[i],
};
}
break;
@ -304,7 +304,7 @@ bool PipelineCache::RefreshGraphicsKey() {
key.color_num_formats.fill(AmdGpu::NumberFormat::Unorm);
key.blend_controls.fill({});
key.write_masks.fill({});
key.mrt_swizzles.fill(Liverpool::ColorBuffer::SwapMode::Standard);
key.color_swizzles.fill({});
key.vertex_buffer_formats.fill(vk::Format::eUndefined);
key.patch_control_points = 0;
@ -327,14 +327,10 @@ bool PipelineCache::RefreshGraphicsKey() {
continue;
}
const auto base_format =
LiverpoolToVK::SurfaceFormat(col_buf.info.format, col_buf.NumFormat());
key.color_formats[remapped_cb] =
LiverpoolToVK::AdjustColorBufferFormat(base_format, col_buf.info.comp_swap.Value());
LiverpoolToVK::SurfaceFormat(col_buf.DataFormat(), col_buf.NumFormat());
key.color_num_formats[remapped_cb] = col_buf.NumFormat();
if (base_format == key.color_formats[remapped_cb]) {
key.mrt_swizzles[remapped_cb] = col_buf.info.comp_swap.Value();
}
key.color_swizzles[remapped_cb] = col_buf.Swizzle();
}
fetch_shader = std::nullopt;
@ -450,7 +446,7 @@ bool PipelineCache::RefreshGraphicsKey() {
// of the latter we need to change format to undefined, and either way we need to
// increment the index for the null attachment binding.
key.color_formats[remapped_cb] = vk::Format::eUndefined;
key.mrt_swizzles[remapped_cb] = Liverpool::ColorBuffer::SwapMode::Standard;
key.color_swizzles[remapped_cb] = {};
++remapped_cb;
continue;
}