From 7e047cdb4a4e8f623a047ef0446ea554b2d19297 Mon Sep 17 00:00:00 2001 From: Francisco Jerez Date: Mon, 1 Jul 2024 17:23:03 -0700 Subject: [PATCH] iris/gfx12.5: Pass non-empty push constant data to PS stage for TBIMR workaround. Note that this bug leading to GPU hangs hasn't been reproduced on GL so far, workaround is mainly included for completeness. Fixes: 57decad9768a445 ("intel/xehp: Enable TBIMR by default.") Reviewed-by: Lionel Landwerlin Part-of: (cherry picked from commit 49144ebcf93d48e3a95bc291747e49990dac7fe3) --- .pick_status.json | 2 +- src/gallium/drivers/iris/iris_program.c | 2 + src/gallium/drivers/iris/iris_state.c | 53 +++++++++++++++++++++++-- 3 files changed, 52 insertions(+), 5 deletions(-) diff --git a/.pick_status.json b/.pick_status.json index d318f403510..2628743d80a 100644 --- a/.pick_status.json +++ b/.pick_status.json @@ -304,7 +304,7 @@ "description": "iris/gfx12.5: Pass non-empty push constant data to PS stage for TBIMR workaround.", "nominated": true, "nomination_type": 1, - "resolution": 0, + "resolution": 1, "main_sha": null, "because_sha": "57decad9768a445de23d093cc8e004269a352b50", "notes": null diff --git a/src/gallium/drivers/iris/iris_program.c b/src/gallium/drivers/iris/iris_program.c index d425d9dfce8..f006bcd6cd3 100644 --- a/src/gallium/drivers/iris/iris_program.c +++ b/src/gallium/drivers/iris/iris_program.c @@ -572,6 +572,8 @@ iris_to_brw_fs_key(const struct iris_screen *screen, .color_outputs_valid = key->color_outputs_valid, .input_slots_valid = key->input_slots_valid, .ignore_sample_mask_out = !key->multisample_fbo, + .null_push_constant_tbimr_workaround = + screen->devinfo->needs_null_push_constant_tbimr_workaround, }; } diff --git a/src/gallium/drivers/iris/iris_state.c b/src/gallium/drivers/iris/iris_state.c index 0fd4f954f83..d9c8d6d04c4 100644 --- a/src/gallium/drivers/iris/iris_state.c +++ b/src/gallium/drivers/iris/iris_state.c @@ -5210,7 +5210,8 @@ iris_store_fs_state(const struct intel_device_info *devinfo, devinfo->max_threads_per_psd - (GFX_VER == 8 ? 2 : 1); #if GFX_VER < 20 - ps.PushConstantEnable = shader->ubo_ranges[0].length > 0; + ps.PushConstantEnable = devinfo->needs_null_push_constant_tbimr_workaround || + shader->ubo_ranges[0].length > 0; #endif /* From the documentation for this packet: @@ -6430,6 +6431,42 @@ emit_push_constant_packets(struct iris_context *ice, } #if GFX_VER >= 12 +static void +emit_null_push_constant_tbimr_workaround(struct iris_batch *batch) +{ + struct isl_device *isl_dev = &batch->screen->isl_dev; + /* Pass a single-register push constant payload for the PS + * stage even if empty, since PS invocations with zero push + * constant cycles have been found to cause hangs with TBIMR + * enabled. See HSDES #22020184996. + * + * XXX - Use workaround infrastructure and final workaround + * when provided by hardware team. + */ + const struct iris_address null_addr = { + .bo = batch->screen->workaround_bo, + .offset = 1024, + }; + const uint32_t num_dwords = 2 + 2 * 1; + uint32_t const_all[num_dwords]; + uint32_t *dw = &const_all[0]; + + iris_pack_command(GENX(3DSTATE_CONSTANT_ALL), dw, all) { + all.DWordLength = num_dwords - 2; + all.MOCS = isl_mocs(isl_dev, 0, false); + all.ShaderUpdateEnable = (1 << MESA_SHADER_FRAGMENT); + all.PointerBufferMask = 1; + } + dw += 2; + + _iris_pack_state(batch, GENX(3DSTATE_CONSTANT_ALL_DATA), dw, data) { + data.PointerToConstantBuffer = null_addr; + data.ConstantBufferReadLength = 1; + } + + iris_batch_emit(batch, const_all, sizeof(uint32_t) * num_dwords); +} + static void emit_push_constant_packet_all(struct iris_context *ice, struct iris_batch *batch, @@ -6439,9 +6476,17 @@ emit_push_constant_packet_all(struct iris_context *ice, struct isl_device *isl_dev = &batch->screen->isl_dev; if (!push_bos) { - iris_emit_cmd(batch, GENX(3DSTATE_CONSTANT_ALL), pc) { - pc.ShaderUpdateEnable = shader_mask; - pc.MOCS = iris_mocs(NULL, isl_dev, 0); + if (batch->screen->devinfo->needs_null_push_constant_tbimr_workaround && + (shader_mask & (1 << MESA_SHADER_FRAGMENT))) { + emit_null_push_constant_tbimr_workaround(batch); + shader_mask &= ~(1 << MESA_SHADER_FRAGMENT); + } + + if (shader_mask) { + iris_emit_cmd(batch, GENX(3DSTATE_CONSTANT_ALL), pc) { + pc.ShaderUpdateEnable = shader_mask; + pc.MOCS = iris_mocs(NULL, isl_dev, 0); + } } return; }