r300: remove gl_ClipVertex early

There is no HW support, but in some cases the shaders mostly work even
if we ignore it, and so far we have just done so. However since the
driver didn't know to what output position in the PVS we should
redirect it, it ended in the first slot. Importantly, if the
CLIP_VERTEX output would be written after position (which actually
belongs in the first slot) it would overwrite it and things blow up.

So just remove it early, and also improve the warning a bit, including
the part that we could use draw module to actually emulate the feature.

Signed-off-by: Pavel Ondračka <pavel.ondracka@gmail.com>
Closes: https://gitlab.freedesktop.org/mesa/mesa/-/issues/11856
Fixes: 5dcef1e7b8
Reviewed-by: Filip Gawin <filip@gawin.net>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/31547>
This commit is contained in:
Pavel Ondračka 2024-10-04 14:07:09 +02:00 committed by Marge Bot
parent a2b97b7b56
commit cc14d40239
3 changed files with 40 additions and 1 deletions

View file

@ -741,7 +741,9 @@ spec@glsl-1.10@execution@loops@glsl-vs-loop-300,Fail
spec@glsl-1.10@execution@variable-indexing@vs-output-array-vec2-index-wr-no-unroll,Fail
# HW limitation (no support for gl_ClipVertex)
spec@glsl-1.20@execution@clipping@vs-clip-vertex-const-accept,Fail
spec@glsl-1.20@execution@clipping@vs-clip-vertex-const-reject,Fail
spec@glsl-1.20@execution@clipping@vs-clip-vertex-different-from-position,Fail
spec@glsl-1.20@execution@clipping@vs-clip-vertex-homogeneity,Fail
spec@glsl-1.20@execution@clipping@vs-clip-vertex-primitives,Fail

View file

@ -118,6 +118,24 @@ set_speculate(nir_builder *b, nir_intrinsic_instr *intr, UNUSED void *_)
return false;
}
static bool
remove_clip_vertex(nir_builder *b, nir_instr *instr, UNUSED void *_)
{
if (instr->type != nir_instr_type_deref)
return false;
nir_deref_instr *deref = nir_instr_as_deref(instr);
if (deref->deref_type == nir_deref_type_var &&
deref->var->data.mode == nir_var_shader_out &&
deref->var->data.location == VARYING_SLOT_CLIP_VERTEX) {
nir_foreach_use_safe(src, &deref->def) {
nir_instr_remove(nir_src_parent_instr(src));
}
nir_instr_remove(instr);
return true;
}
return false;
}
static void
r300_optimize_nir(struct nir_shader *s, struct pipe_screen *screen)
{
@ -143,6 +161,25 @@ r300_optimize_nir(struct nir_shader *s, struct pipe_screen *screen)
NIR_PASS_V(s, r300_transform_vs_trig_input);
}
}
/* There is no HW support for gl_ClipVertex, so we just remove it early. */
if (nir_shader_instructions_pass(s, remove_clip_vertex,
nir_metadata_control_flow, NULL)) {
unsigned clip_vertex_location = 0;
nir_foreach_variable_with_modes(var, s, nir_var_shader_out) {
if (var->data.location == VARYING_SLOT_CLIP_VERTEX) {
clip_vertex_location = var->data.driver_location;
}
}
nir_foreach_variable_with_modes(var, s, nir_var_shader_out) {
if (var->data.driver_location > clip_vertex_location) {
var->data.driver_location--;
}
}
NIR_PASS_V(s, nir_remove_dead_variables, nir_var_shader_out, NULL);
fprintf(stderr, "r300: no HW support for clip vertex, expect misrendering.\n");
fprintf(stderr, "r300: software emulation can be enabled with RADEON_DEBUG=notcl.\n");
}
}
}

View file

@ -76,7 +76,7 @@ static void r300_shader_read_vs_outputs(
assert(index == 0);
/* Draw does clip vertex for us. */
if (r300->screen->caps.has_tcl) {
fprintf(stderr, "r300 VP: cannot handle clip vertex output.\n");
unreachable();
}
break;