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;