video_core: Check DB_SHADER_CONTROL register before performing depth exports (#3588)

The DB_SHADER_CONTROL register has several enable flags which must be set before certain depth exports are enabled.
This commit adds logic to respect the values in this register when performing depth exports, which fixes the regression in earlier versions of KNACK.
I've also renamed DepthBufferControl to DepthShaderControl, since that's closer to the official name for the register.
This commit is contained in:
Stephen Miller
2025-09-13 06:32:24 -05:00
committed by GitHub
parent c885b522db
commit 0bfde1fcde
4 changed files with 12 additions and 4 deletions

View File

@@ -145,7 +145,8 @@ void Translator::ExportDepth(const GcnInst& inst) {
}
} else {
// Components are float32 into separate VGPRS
u32 mask = MaskFromExportFormat(exp.en, runtime_info.fs_info.z_export_format);
u32 mask = MaskFromExportFormat(exp.en & runtime_info.fs_info.mrtz_mask,
runtime_info.fs_info.z_export_format);
for (u32 i = 0; i < 4; i++, mask >>= 1) {
if ((mask & 1) == 0) {
continue;

View File

@@ -206,13 +206,14 @@ struct FragmentRuntimeInfo {
std::array<PsInput, 32> inputs;
std::array<PsColorBuffer, MaxColorBuffers> color_buffers;
AmdGpu::Liverpool::ShaderExportFormat z_export_format;
u8 mrtz_mask;
bool dual_source_blending;
bool operator==(const FragmentRuntimeInfo& other) const noexcept {
return std::ranges::equal(color_buffers, other.color_buffers) &&
en_flags.raw == other.en_flags.raw && addr_flags.raw == other.addr_flags.raw &&
num_inputs == other.num_inputs && z_export_format == other.z_export_format &&
dual_source_blending == other.dual_source_blending &&
mrtz_mask == other.mrtz_mask && dual_source_blending == other.dual_source_blending &&
std::ranges::equal(inputs.begin(), inputs.begin() + num_inputs, other.inputs.begin(),
other.inputs.begin() + num_inputs);
}

View File

@@ -338,7 +338,7 @@ struct Liverpool {
GreaterThanZ = 2,
};
union DepthBufferControl {
union DepthShaderControl {
u32 raw;
BitField<0, 1, u32> z_export_enable;
BitField<1, 1, u32> stencil_test_val_export_enable;
@@ -1410,7 +1410,7 @@ struct Liverpool {
DepthControl depth_control;
INSERT_PADDING_WORDS(1);
ColorControl color_control;
DepthBufferControl depth_buffer_control;
DepthShaderControl depth_shader_control;
ClipperControl clipper_control;
PolygonControl polygon_control;
ViewportControl viewport_control;

View File

@@ -169,6 +169,12 @@ const Shader::RuntimeInfo& PipelineCache::BuildRuntimeInfo(Stage stage, LogicalS
info.fs_info.addr_flags = regs.ps_input_addr;
info.fs_info.num_inputs = regs.num_interp;
info.fs_info.z_export_format = regs.z_export_format;
u8 stencil_ref_export_enable = regs.depth_shader_control.stencil_op_val_export_enable |
regs.depth_shader_control.stencil_test_val_export_enable;
info.fs_info.mrtz_mask = regs.depth_shader_control.z_export_enable |
(stencil_ref_export_enable << 1) |
(regs.depth_shader_control.mask_export_enable << 2) |
(regs.depth_shader_control.coverage_to_mask_enable << 3);
const auto& cb0_blend = regs.blend_control[0];
if (cb0_blend.enable) {
info.fs_info.dual_source_blending =