diff --git a/.pick_status.json b/.pick_status.json index 0b8552d8d09..3a34ea12ce8 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 81436d21395..a57bb7e13c2 100644 --- a/src/gallium/drivers/iris/iris_program.c +++ b/src/gallium/drivers/iris/iris_program.c @@ -567,6 +567,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 06672b8150c..35252a492ab 100644 --- a/src/gallium/drivers/iris/iris_state.c +++ b/src/gallium/drivers/iris/iris_state.c @@ -5186,7 +5186,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: @@ -6395,6 +6396,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, @@ -6404,9 +6441,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; }