vc4: fail VS compilation on divergent loops

VC4 hardware doesn't have a dispatch mask for the VS, so divergent
loops can have undefined/garbage contents in some execution channels,
potentially causing infinite loops and GPU hangs.

Fail shader linking instead of hanging the GPU when a divergent loop is
detected in a vertex shader.

Reviewed-by: Iago Toral Quiroga <itoral@igalia.com>
Signed-off-by: Maíra Canal <mcanal@igalia.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/39768>
This commit is contained in:
Maíra Canal 2026-02-02 11:39:26 -03:00 committed by Marge Bot
parent 5a1e0112a9
commit e1aac4f7e0

View file

@ -2465,6 +2465,17 @@ vc4_shader_precompile(struct vc4_context *vc4,
}
}
static bool
vc4_check_divergent_loops(nir_shader *s)
{
nir_foreach_block(block, nir_shader_get_entrypoint(s)) {
nir_loop *loop = nir_block_get_following_loop(block);
if (loop && nir_loop_is_divergent(loop))
return true;
}
return false;
}
static void *
vc4_shader_state_create(struct pipe_context *pctx,
const struct pipe_shader_state *cso)
@ -2514,6 +2525,26 @@ vc4_shader_state_create(struct pipe_context *pctx,
/* Garbage collect dead instructions */
nir_sweep(s);
/* VC4 hardware doesn't have a dispatch mask for the VS. This means
* that, if we submit a divergent loop to the hardware, some execution
* channels can have undefined/garbage contents and cause infinite
* loops and GPU hangs.
*
* Instead of potentially hanging the GPU, refuse shader linking.
*/
if (s->info.stage == MESA_SHADER_VERTEX) {
nir_divergence_analysis(s);
if (vc4_check_divergent_loops(s) && cso->report_compile_error) {
((struct pipe_shader_state *)cso)->error_message =
strdup("Non-uniform loops are unsupported "
"in the vertex shader.");
ralloc_free(s);
free(so);
return NULL;
}
}
so->base.type = PIPE_SHADER_IR_NIR;
so->base.ir.nir = s;