brw: compute consistent clip/cull distance masks with VUE

We can optimize the VUE layout in cases where all shaders are compiled
together and some outputs are unused. So we need to have consistent
clip/cull_distance_mask with the VUE.

Previously we could have a VUE without ClipDistance present in the
header and yet have a non zero clip_distance_mask. This would trip the
HW into taking into account a VUE field that doesn't exist.

Here we set the clip/cull_distance_mask to 0 if the associated output
is not written by the shader. The written outputs are always
consistent with what's in the VUE.

Signed-off-by: Lionel Landwerlin <lionel.g.landwerlin@intel.com>
Fixes: 2d396f6085 ("intel: prepare VUE layout for more than 2 layouts")
Closes: https://gitlab.freedesktop.org/mesa/mesa/-/issues/13685
Reviewed-by: Ivan Briano <ivan.briano@intel.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/36734>
(cherry picked from commit 46c16f854e)
This commit is contained in:
Lionel Landwerlin 2025-08-12 08:45:16 +03:00 committed by Eric Engestrom
parent 8d535efa7c
commit 8236b0fe2b
5 changed files with 38 additions and 13 deletions

View file

@ -3424,7 +3424,7 @@
"description": "brw: compute consistent clip/cull distance masks with VUE",
"nominated": true,
"nomination_type": 2,
"resolution": 0,
"resolution": 1,
"main_sha": null,
"because_sha": "2d396f608500d88fa00eeb99d14ed5727f1cece9",
"notes": null

View file

@ -169,10 +169,16 @@ brw_compile_gs(const struct brw_compiler *compiler,
brw_postprocess_nir(nir, compiler, debug_enabled,
key->base.robust_flags);
prog_data->base.clip_distance_mask =
((1 << nir->info.clip_distance_array_size) - 1);
const bool has_clip_cull_dist =
nir->info.outputs_written & (VARYING_BIT_CLIP_DIST0 |
VARYING_BIT_CLIP_DIST1 |
VARYING_BIT_CULL_DIST0 |
VARYING_BIT_CULL_DIST1);
prog_data->base.clip_distance_mask = has_clip_cull_dist ?
((1 << nir->info.clip_distance_array_size) - 1) : 0;
prog_data->base.cull_distance_mask =
((1 << nir->info.cull_distance_array_size) - 1) <<
(has_clip_cull_dist ?
((1 << nir->info.cull_distance_array_size) - 1) : 0) <<
nir->info.clip_distance_array_size;
prog_data->include_primitive_id =

View file

@ -1171,10 +1171,17 @@ brw_compile_mesh(const struct brw_compiler *compiler,
prog_data->base.local_size[1] = nir->info.workgroup_size[1];
prog_data->base.local_size[2] = nir->info.workgroup_size[2];
prog_data->clip_distance_mask = (1 << nir->info.clip_distance_array_size) - 1;
const bool has_clip_cull_dist =
nir->info.outputs_written & (VARYING_BIT_CLIP_DIST0 |
VARYING_BIT_CLIP_DIST1 |
VARYING_BIT_CULL_DIST0 |
VARYING_BIT_CULL_DIST1);
prog_data->clip_distance_mask = has_clip_cull_dist ?
(1 << nir->info.clip_distance_array_size) - 1 : 0;
prog_data->cull_distance_mask =
((1 << nir->info.cull_distance_array_size) - 1) <<
nir->info.clip_distance_array_size;
(has_clip_cull_dist ?
((1 << nir->info.cull_distance_array_size) - 1) : 0) <<
nir->info.clip_distance_array_size;
prog_data->primitive_type = nir->info.mesh.primitive_type;
/* Apply this workaround before trying to pack indices because this can

View file

@ -95,10 +95,16 @@ brw_compile_tes(const struct brw_compiler *compiler,
return NULL;
}
prog_data->base.clip_distance_mask =
((1 << nir->info.clip_distance_array_size) - 1);
const bool has_clip_cull_dist =
nir->info.outputs_written & (VARYING_BIT_CLIP_DIST0 |
VARYING_BIT_CLIP_DIST1 |
VARYING_BIT_CULL_DIST0 |
VARYING_BIT_CULL_DIST1);
prog_data->base.clip_distance_mask = has_clip_cull_dist ?
((1 << nir->info.clip_distance_array_size) - 1) : 0;
prog_data->base.cull_distance_mask =
((1 << nir->info.cull_distance_array_size) - 1) <<
(has_clip_cull_dist ?
((1 << nir->info.cull_distance_array_size) - 1) : 0) <<
nir->info.clip_distance_array_size;
prog_data->include_primitive_id =

View file

@ -266,10 +266,16 @@ brw_compile_vs(const struct brw_compiler *compiler,
brw_postprocess_nir(nir, compiler, debug_enabled,
key->base.robust_flags);
prog_data->base.clip_distance_mask =
((1 << nir->info.clip_distance_array_size) - 1);
const bool has_clip_cull_dist =
nir->info.outputs_written & (VARYING_BIT_CLIP_DIST0 |
VARYING_BIT_CLIP_DIST1 |
VARYING_BIT_CULL_DIST0 |
VARYING_BIT_CULL_DIST1);
prog_data->base.clip_distance_mask = has_clip_cull_dist ?
((1 << nir->info.clip_distance_array_size) - 1) : 0;
prog_data->base.cull_distance_mask =
((1 << nir->info.cull_distance_array_size) - 1) <<
(has_clip_cull_dist ?
((1 << nir->info.cull_distance_array_size) - 1) : 0) <<
nir->info.clip_distance_array_size;
unsigned nr_attribute_slots = util_bitcount64(prog_data->inputs_read);