vk_pipeline_cache: Cleanup graphics key refresh (#3449)

* vk_pipeline_cache: Cleanup graphics key refresh

* position: Don't assert on None mapping

Also check outputs in runtime info so shader is recompiled if they change
This commit is contained in:
TheTurtle
2025-08-24 03:16:58 +03:00
committed by GitHub
parent 6590f07772
commit 6d98a5ab60
16 changed files with 120 additions and 170 deletions

View File

@@ -93,17 +93,24 @@ void Translator::ExportRenderTarget(const GcnInst& inst) {
}
}
// Metal seems to have an issue where 8-bit unorm/snorm/sRGB outputs to render target
// need a bias applied to round correctly; detect and set the flag for that here.
const auto needs_unorm_fixup = profile.needs_unorm_fixup &&
(color_buffer.num_format == AmdGpu::NumberFormat::Unorm ||
color_buffer.num_format == AmdGpu::NumberFormat::Snorm ||
color_buffer.num_format == AmdGpu::NumberFormat::Srgb) &&
(color_buffer.data_format == AmdGpu::DataFormat::Format8 ||
color_buffer.data_format == AmdGpu::DataFormat::Format8_8 ||
color_buffer.data_format == AmdGpu::DataFormat::Format8_8_8_8);
// Swizzle components and export
for (u32 i = 0; i < 4; ++i) {
const u32 comp_swizzle = static_cast<u32>(color_buffer.swizzle.array[i]);
constexpr u32 min_swizzle = static_cast<u32>(AmdGpu::CompSwizzle::Red);
const auto swizzled_comp =
components[comp_swizzle >= min_swizzle ? comp_swizzle - min_swizzle : i];
const auto swizzled_comp = components[color_buffer.swizzle.Map(i)];
if (swizzled_comp.IsEmpty()) {
continue;
}
auto converted = ApplyWriteNumberConversion(ir, swizzled_comp, color_buffer.num_conversion);
if (color_buffer.needs_unorm_fixup) {
if (needs_unorm_fixup) {
// FIXME: Fix-up for GPUs where float-to-unorm rounding is off from expected.
converted = ir.FPSub(converted, ir.Imm32(1.f / 127500.f));
}

View File

@@ -3,6 +3,7 @@
#pragma once
#include "common/logging/log.h"
#include "shader_recompiler/ir/ir_emitter.h"
#include "shader_recompiler/runtime_info.h"
@@ -45,8 +46,12 @@ inline void ExportPosition(IREmitter& ir, const auto& stage, Attribute attribute
case Output::GsMrtIndex:
ir.SetAttribute(IR::Attribute::RenderTargetId, value);
break;
case Output::None:
LOG_WARNING(Render_Recompiler, "The {} component of {} isn't mapped, skipping",
"xyzw"[comp], NameOf(attribute));
break;
default:
UNREACHABLE_MSG("Unhandled output {} on attribute {}", u32(output), u32(attribute));
UNREACHABLE_MSG("Unhandled output {} on attribute {}", u32(output), NameOf(attribute));
}
}

View File

@@ -35,6 +35,7 @@ struct Profile {
bool needs_manual_interpolation{};
bool needs_lds_barriers{};
bool needs_buffer_offsets{};
bool needs_unorm_fixup{};
u64 max_ubo_size{};
u32 max_viewport_width{};
u32 max_viewport_height{};

View File

@@ -93,7 +93,8 @@ struct VertexRuntimeInfo {
u32 hs_output_cp_stride{};
bool operator==(const VertexRuntimeInfo& other) const noexcept {
return emulate_depth_negative_one_to_one == other.emulate_depth_negative_one_to_one &&
return num_outputs == other.num_outputs && outputs == other.outputs &&
emulate_depth_negative_one_to_one == other.emulate_depth_negative_one_to_one &&
clip_disable == other.clip_disable && tess_type == other.tess_type &&
tess_topology == other.tess_topology &&
tess_partitioning == other.tess_partitioning &&
@@ -158,8 +159,9 @@ struct GeometryRuntimeInfo {
u64 vs_copy_hash;
bool operator==(const GeometryRuntimeInfo& other) const noexcept {
return num_invocations && other.num_invocations &&
output_vertices == other.output_vertices && in_primitive == other.in_primitive &&
return num_outputs == other.num_outputs && outputs == other.outputs && num_invocations &&
other.num_invocations && output_vertices == other.output_vertices &&
in_primitive == other.in_primitive &&
std::ranges::equal(out_primitive, other.out_primitive);
}
};
@@ -177,8 +179,6 @@ struct PsColorBuffer {
AmdGpu::NumberFormat num_format : 4;
AmdGpu::NumberConversion num_conversion : 3;
AmdGpu::Liverpool::ShaderExportFormat export_format : 4;
u32 needs_unorm_fixup : 1;
u32 pad : 20;
AmdGpu::CompMapping swizzle;
bool operator==(const PsColorBuffer& other) const noexcept = default;