Skip to content

Commit b879dd5

Browse files
authored
shader_recompiler: Add workaround for drivers with unexpected unorm rounding behavior. (#2310)
1 parent b6ad512 commit b879dd5

File tree

3 files changed

+17
-1
lines changed

3 files changed

+17
-1
lines changed

src/shader_recompiler/frontend/translate/export.cpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,11 @@ u32 SwizzleMrtComponent(const FragmentRuntimeInfo::PsColorBuffer& color_buffer,
1717

1818
void Translator::ExportMrtValue(IR::Attribute attribute, u32 comp, const IR::F32& value,
1919
const FragmentRuntimeInfo::PsColorBuffer& color_buffer) {
20-
const auto converted = ApplyWriteNumberConversion(ir, value, color_buffer.num_conversion);
20+
auto converted = ApplyWriteNumberConversion(ir, value, color_buffer.num_conversion);
21+
if (color_buffer.needs_unorm_fixup) {
22+
// FIXME: Fix-up for GPUs where float-to-unorm rounding is off from expected.
23+
converted = ir.FPSub(converted, ir.Imm32(1.f / 127500.f));
24+
}
2125
ir.SetAttribute(attribute, converted, comp);
2226
}
2327

src/shader_recompiler/runtime_info.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -185,6 +185,7 @@ struct FragmentRuntimeInfo {
185185
AmdGpu::NumberConversion num_conversion;
186186
AmdGpu::CompMapping swizzle;
187187
AmdGpu::Liverpool::ShaderExportFormat export_format;
188+
bool needs_unorm_fixup;
188189

189190
auto operator<=>(const PsColorBuffer&) const noexcept = default;
190191
};

src/video_core/renderer_vulkan/vk_pipeline_cache.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -330,13 +330,24 @@ bool PipelineCache::RefreshGraphicsKey() {
330330
continue;
331331
}
332332

333+
// Metal seems to have an issue where 8-bit unorm/snorm/sRGB outputs to render target
334+
// need a bias applied to round correctly; detect and set the flag for that here.
335+
const auto needs_unorm_fixup = instance.GetDriverID() == vk::DriverId::eMoltenvk &&
336+
(col_buf.GetNumberFmt() == AmdGpu::NumberFormat::Unorm ||
337+
col_buf.GetNumberFmt() == AmdGpu::NumberFormat::Snorm ||
338+
col_buf.GetNumberFmt() == AmdGpu::NumberFormat::Srgb) &&
339+
(col_buf.GetDataFmt() == AmdGpu::DataFormat::Format8 ||
340+
col_buf.GetDataFmt() == AmdGpu::DataFormat::Format8_8 ||
341+
col_buf.GetDataFmt() == AmdGpu::DataFormat::Format8_8_8_8);
342+
333343
key.color_formats[remapped_cb] =
334344
LiverpoolToVK::SurfaceFormat(col_buf.GetDataFmt(), col_buf.GetNumberFmt());
335345
key.color_buffers[remapped_cb] = {
336346
.num_format = col_buf.GetNumberFmt(),
337347
.num_conversion = col_buf.GetNumberConversion(),
338348
.swizzle = col_buf.Swizzle(),
339349
.export_format = regs.color_export_format.GetFormat(cb),
350+
.needs_unorm_fixup = needs_unorm_fixup,
340351
};
341352
}
342353

0 commit comments

Comments
 (0)