From 904c9d64643fedcfd7a8f080de59b04dbde2755b Mon Sep 17 00:00:00 2001 From: Paulo Zanoni Date: Mon, 23 Sep 2024 11:58:16 -0700 Subject: [PATCH] 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 Signed-off-by: Paulo Zanoni Part-of: (cherry picked from commit 5ca883505e29870c7ae8929049397b9ef85666e9) --- .pick_status.json | 2 +- src/intel/compiler/brw_fs_generator.cpp | 13 +++++++++++-- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/.pick_status.json b/.pick_status.json index 5b427976263..3c800c44ace 100644 --- a/.pick_status.json +++ b/.pick_status.json @@ -224,7 +224,7 @@ "description": "brw: add a NOP in between WHILE instructions on LNL", "nominated": true, "nomination_type": 4, - "resolution": 0, + "resolution": 1, "main_sha": null, "because_sha": null, "notes": null diff --git a/src/intel/compiler/brw_fs_generator.cpp b/src/intel/compiler/brw_fs_generator.cpp index 3e56c935b52..e7cf4890fb1 100644 --- a/src/intel/compiler/brw_fs_generator.cpp +++ b/src/intel/compiler/brw_fs_generator.cpp @@ -771,6 +771,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; @@ -1082,9 +1083,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: @@ -1352,6 +1360,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;