intel/brw: Implement null push constant workaround.

This implements an undocumented workaround for a hardware bug that
affects draw calls with a pixel shader that has 0 push constant cycles
when TBIMR is enabled, which has been seen to lead to a hang with
Fallout 3 and Metal Gear Rising Revengeance.  This hardware bug has
been reported as HSDES#22020184996 which is still pending a resolution
by the hardware team.  However since this workaround found empirically
has been confirmed to fix the issue reliably and it's relatively
harmless it seems worth checking in already even though no final W/A
number is available nor has the W/A json file been updated.

To avoid the issue we simply pad the push constant payload to be at
least 1 register.  This is enabled via a brw_wm_prog_key since the
driver needs to be in agreement with the compiler on whether the dummy
push constant cycle is present, and it can be avoided in cases where
the driver knows that TBIMR will be disabled (e.g. for BLORP).

Related: https://gitlab.freedesktop.org/mesa/mesa/-/issues/10728
Related: https://gitlab.freedesktop.org/mesa/mesa/-/issues/11399
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>
(cherry picked from commit b98eebbcb2)
This commit is contained in:
Francisco Jerez 2024-07-01 14:45:38 -07:00 committed by Eric Engestrom
parent 816c835c84
commit 7802cd2b99
3 changed files with 6 additions and 2 deletions

View file

@ -324,7 +324,7 @@
"description": "intel/brw: Implement null push constant workaround.",
"nominated": true,
"nomination_type": 1,
"resolution": 0,
"resolution": 1,
"main_sha": null,
"because_sha": "57decad9768a445de23d093cc8e004269a352b50",
"notes": null

View file

@ -330,8 +330,9 @@ struct brw_wm_prog_key {
bool coherent_fb_fetch:1;
bool ignore_sample_mask_out:1;
bool coarse_pixel:1;
bool null_push_constant_tbimr_workaround:1;
uint64_t padding:36;
uint64_t padding:35;
};
struct brw_cs_prog_key {

View file

@ -1230,6 +1230,9 @@ fs_visitor::assign_curb_setup()
}
prog_data->curb_read_length = uniform_push_length + ubo_push_length;
if (stage == MESA_SHADER_FRAGMENT &&
((struct brw_wm_prog_key *)key)->null_push_constant_tbimr_workaround)
prog_data->curb_read_length = MAX2(1, prog_data->curb_read_length);
uint64_t used = 0;
bool is_compute = gl_shader_stage_is_compute(stage);