aco/gfx11: export mrtz in discard early exit for non-color shaders
authorRhys Perry <pendingchaos02@gmail.com>
Thu, 15 Dec 2022 20:31:52 +0000 (20:31 +0000)
committerMarge Bot <emma+marge@anholt.net>
Fri, 16 Dec 2022 15:35:28 +0000 (15:35 +0000)
If a shader doesn't export any color targets and instead only exports
mrtz, the discard early exit block should match.

Fixes artifacts on Lara in Rise of the Tomb Raider benchmark and hair in
The Witcher 3 (classic).

https://reviews.llvm.org/D128185

Signed-off-by: Rhys Perry <pendingchaos02@gmail.com>
Reviewed-by: Bas Nieuwenhuizen <bas@basnieuwenhuizen.nl>
Reviewed-by: Samuel Pitoiset <samuel.pitoiset@gmail.com>
Fixes: bc8da20dda6 ("aco: export MRT0 instead of NULL on GFX11")
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/20345>

src/amd/compiler/aco_instruction_selection.cpp
src/amd/compiler/aco_ir.h
src/amd/compiler/aco_lower_to_hw_instr.cpp

index b9df226..e8808e4 100644 (file)
@@ -11198,6 +11198,8 @@ export_mrt(isel_context* ctx, const struct aco_export_mrt* mrt)
 
    bld.exp(aco_opcode::exp, mrt->out[0], mrt->out[1], mrt->out[2], mrt->out[3],
            mrt->enabled_channels, mrt->target, mrt->compr);
+
+   ctx->program->has_color_exports = true;
 }
 
 static bool
@@ -11392,6 +11394,8 @@ create_fs_null_export(isel_context* ctx)
    unsigned dest = ctx->options->gfx_level >= GFX11 ? V_008DFC_SQ_EXP_MRT : V_008DFC_SQ_EXP_NULL;
    bld.exp(aco_opcode::exp, Operand(v1), Operand(v1), Operand(v1), Operand(v1),
            /* enabled_mask */ 0, dest, /* compr */ false, /* done */ true, /* vm */ true);
+
+   ctx->program->has_color_exports = true;
 }
 
 static void
@@ -11467,6 +11471,8 @@ create_fs_dual_src_export_gfx11(isel_context* ctx, const struct aco_export_mrt*
    exp->definitions[4] = bld.def(bld.lm, vcc);
    exp->definitions[5] = bld.def(s1, scc);
    ctx->block->instructions.emplace_back(std::move(exp));
+
+   ctx->program->has_color_exports = true;
 }
 
 static void
index 583857f..7d9a34b 100644 (file)
@@ -2156,6 +2156,7 @@ public:
    Stage stage;
    bool needs_exact = false; /* there exists an instruction with disable_wqm = true */
    bool needs_wqm = false;   /* there exists a p_wqm instruction */
+   bool has_color_exports = false;
 
    std::vector<uint8_t> constant_data;
    Temp private_segment_buffer;
index a0a746f..ccd53b2 100644 (file)
@@ -2198,9 +2198,12 @@ lower_to_hw_instr(Program* program)
                   block = &program->blocks[block_idx];
 
                   bld.reset(discard_block);
+                  unsigned target = V_008DFC_SQ_EXP_NULL;
+                  if (program->gfx_level >= GFX11)
+                     target =
+                        program->has_color_exports ? V_008DFC_SQ_EXP_MRT : V_008DFC_SQ_EXP_MRTZ;
                   bld.exp(aco_opcode::exp, Operand(v1), Operand(v1), Operand(v1), Operand(v1), 0,
-                          program->gfx_level >= GFX11 ? V_008DFC_SQ_EXP_MRT : V_008DFC_SQ_EXP_NULL,
-                          false, true, true);
+                          target, false, true, true);
                   if (should_dealloc_vgprs)
                      bld.sopp(aco_opcode::s_sendmsg, -1, sendmsg_dealloc_vgprs);
                   bld.sopp(aco_opcode::s_endpgm);