brw: add a NOP in between WHILE instructions on LNL

This is a workaround that is still in progress, see HSD 22020521218.
If we don't have these NOPs we may see rendering corruption or even
GPU hangs.

While we still don't fully understand the issue from the hardware
point of view, let's have this workaround so we can pass CTS and move
things forward. If we need to change this later, we can. Besides, the
impact is minimal. Shaderdb/fossilize report no changes for this
patch.

On our Blackops trace, the lack of this patch causes corruption in fog
rendering (rectangles where fog was supposed to be shown don't show
the fog).

On dEQP-VK.graphicsfuzz.cov-array-copies-loops-with-limiters, without
this patch we get a GPU hang.

Backport-to: 24.2
Testcase: dEQP-VK.graphicsfuzz.cov-array-copies-loops-with-limiters
Closes: https://gitlab.freedesktop.org/mesa/mesa/-/issues/11813
Reviewed-by: Ivan Briano <ivan.briano@intel.com>
Signed-off-by: Paulo Zanoni <paulo.r.zanoni@intel.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/31331>
This commit is contained in:
Paulo Zanoni 2024-09-23 11:58:16 -07:00 committed by Marge Bot
parent a39d6f5003
commit 5ca883505e

View file

@ -773,6 +773,7 @@ fs_generator::generate_code(const cfg_t *cfg, int dispatch_width,
struct disasm_info *disasm_info = disasm_initialize(p->isa, cfg);
enum opcode prev_opcode = BRW_OPCODE_ILLEGAL;
foreach_block_and_inst (block, fs_inst, inst, cfg) {
if (inst->opcode == SHADER_OPCODE_UNDEF)
continue;
@ -1084,9 +1085,16 @@ fs_generator::generate_code(const cfg_t *cfg, int dispatch_width,
break;
case BRW_OPCODE_WHILE:
brw_WHILE(p);
/* On LNL and newer, if we don't put a NOP in between two consecutive
* WHILE instructions we may end up with misrendering or GPU hangs.
* See HSD 22020521218.
*/
if (devinfo->ver >= 20 && unlikely(prev_opcode == BRW_OPCODE_WHILE))
brw_NOP(p);
brw_WHILE(p);
loop_count++;
break;
break;
case SHADER_OPCODE_RCP:
case SHADER_OPCODE_RSQ:
@ -1354,6 +1362,7 @@ fs_generator::generate_code(const cfg_t *cfg, int dispatch_width,
case SHADER_OPCODE_LOAD_PAYLOAD:
unreachable("Should be lowered by lower_load_payload()");
}
prev_opcode = inst->opcode;
if (multiple_instructions_emitted)
continue;