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: 57decad976 ("intel/xehp: Enable TBIMR by default.")
Reviewed-by: Lionel Landwerlin <lionel.g.landwerlin@intel.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/30031>
This commit is contained in:
Francisco Jerez 2024-07-01 17:23:03 -07:00 committed by Marge Bot
parent ff3c3792b4
commit 49144ebcf9
2 changed files with 51 additions and 4 deletions

View file

@ -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,
};
}

View file

@ -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;
}