nir: allow using sysvals in nir_lower_clip

By passing a `NULL` pointer for the `ucp_enable` argument the
value will be loaded from a sysval
This commit is contained in:
antonino 2023-08-02 17:44:39 +02:00 committed by Anna Maniscalco
parent 0068da6f45
commit cd269ebfa2
9 changed files with 88 additions and 60 deletions

View file

@ -1255,8 +1255,9 @@ v3d_nir_lower_fs_late(struct v3d_compile *c)
* array variable, so we have GL's clip lowering follow suit * array variable, so we have GL's clip lowering follow suit
* (compact_arrays option at nir_shader_compiler_options) * (compact_arrays option at nir_shader_compiler_options)
*/ */
if (c->fs_key->ucp_enables) unsigned ucp_enables = c->fs_key->ucp_enables;
NIR_PASS(_, c->s, nir_lower_clip_fs, c->fs_key->ucp_enables, true, false); if (ucp_enables)
NIR_PASS(_, c->s, nir_lower_clip_fs, &ucp_enables, true, false);
NIR_PASS(_, c->s, nir_lower_io_to_scalar, nir_var_shader_in, NULL, NULL); NIR_PASS(_, c->s, nir_lower_io_to_scalar, nir_var_shader_in, NULL, NULL);
} }

View file

@ -6051,14 +6051,14 @@ typedef struct nir_input_attachment_options {
bool nir_lower_input_attachments(nir_shader *shader, bool nir_lower_input_attachments(nir_shader *shader,
const nir_input_attachment_options *options); const nir_input_attachment_options *options);
bool nir_lower_clip_vs(nir_shader *shader, unsigned ucp_enables, bool nir_lower_clip_vs(nir_shader *shader, unsigned *ucp_enables,
bool use_vars, bool use_vars,
bool use_clipdist_array, bool use_clipdist_array,
const gl_state_index16 clipplane_state_tokens[][STATE_LENGTH]); const gl_state_index16 clipplane_state_tokens[][STATE_LENGTH]);
bool nir_lower_clip_gs(nir_shader *shader, unsigned ucp_enables, bool nir_lower_clip_gs(nir_shader *shader, unsigned *ucp_enables,
bool use_clipdist_array, bool use_clipdist_array,
const gl_state_index16 clipplane_state_tokens[][STATE_LENGTH]); const gl_state_index16 clipplane_state_tokens[][STATE_LENGTH]);
bool nir_lower_clip_fs(nir_shader *shader, unsigned ucp_enables, bool nir_lower_clip_fs(nir_shader *shader, unsigned *ucp_enables,
bool use_clipdist_array, bool use_load_interp); bool use_clipdist_array, bool use_load_interp);
bool nir_lower_clip_cull_distance_to_vec4s(nir_shader *shader); bool nir_lower_clip_cull_distance_to_vec4s(nir_shader *shader);

View file

@ -275,6 +275,7 @@ struct lower_clip_state {
nir_variable *out[2]; nir_variable *out[2];
unsigned ucp_enables; unsigned ucp_enables;
bool use_clipdist_array; bool use_clipdist_array;
bool use_enables_sysval;
const gl_state_index16 (*clipplane_state_tokens)[STATE_LENGTH]; const gl_state_index16 (*clipplane_state_tokens)[STATE_LENGTH];
/* This holds the current CLIP_VERTEX value for GS. */ /* This holds the current CLIP_VERTEX value for GS. */
@ -294,17 +295,16 @@ lower_clip_vertex_var(nir_builder *b, const struct lower_clip_state *state)
} }
for (int plane = 0; plane < MAX_CLIP_PLANES; plane++) { for (int plane = 0; plane < MAX_CLIP_PLANES; plane++) {
if (state->ucp_enables & (1 << plane)) { nir_def *ucp = get_ucp(b, plane, state->clipplane_state_tokens);
nir_def *ucp = get_ucp(b, plane, state->clipplane_state_tokens); nir_def *ucp_enable_def;
if (state->use_enables_sysval)
/* calculate clipdist[plane] - dot(ucp, cv): */ ucp_enable_def = nir_load_clip_plane_enable(b);
clipdist[plane] = nir_fdot(b, ucp, cv); else
} else { ucp_enable_def = nir_imm_int(b, state->ucp_enables);
/* 0.0 == don't-clip == disabled: */ clipdist[plane] = nir_bcsel(b, nir_b2b1(b, nir_iand_imm(b, ucp_enable_def, 1 << plane)),
clipdist[plane] = nir_imm_float(b, 0.0); nir_fdot(b, ucp, cv), nir_imm_float(b, 0.0));
}
if (state->use_clipdist_array && if (state->use_clipdist_array &&
plane < util_last_bit(state->ucp_enables)) { (state->use_enables_sysval || plane < util_last_bit(state->ucp_enables))) {
nir_deref_instr *deref; nir_deref_instr *deref;
deref = nir_build_deref_array_imm(b, deref = nir_build_deref_array_imm(b,
nir_build_deref_var(b, state->out[0]), nir_build_deref_var(b, state->out[0]),
@ -338,15 +338,14 @@ lower_clip_vertex_intrin(nir_builder *b, const struct lower_clip_state *state)
} }
for (int plane = 0; plane < MAX_CLIP_PLANES; plane++) { for (int plane = 0; plane < MAX_CLIP_PLANES; plane++) {
if (state->ucp_enables & (1 << plane)) { nir_def *ucp = get_ucp(b, plane, state->clipplane_state_tokens);
nir_def *ucp = get_ucp(b, plane, state->clipplane_state_tokens); nir_def *ucp_enable_def;
if (state->use_enables_sysval)
/* calculate clipdist[plane] - dot(ucp, cv): */ ucp_enable_def = nir_load_clip_plane_enable(b);
clipdist[plane] = nir_fdot(b, ucp, cv); else
} else { ucp_enable_def = nir_imm_int(b, state->ucp_enables);
/* 0.0 == don't-clip == disabled: */ clipdist[plane] = nir_bcsel(b, nir_b2b1(b, nir_iand_imm(b, ucp_enable_def, 1 << plane)),
clipdist[plane] = nir_imm_float(b, 0.0); nir_fdot(b, ucp, cv), nir_imm_float(b, 0.0));
}
} }
if (state->use_clipdist_array) { if (state->use_clipdist_array) {
@ -383,11 +382,13 @@ lower_clip_vertex_intrin(nir_builder *b, const struct lower_clip_state *state)
* clipdist output instead of two vec4s. * clipdist output instead of two vec4s.
*/ */
bool bool
nir_lower_clip_vs(nir_shader *shader, unsigned ucp_enables, bool use_vars, nir_lower_clip_vs(nir_shader *shader, unsigned *ucp_enables, bool use_vars,
bool use_clipdist_array, bool use_clipdist_array,
const gl_state_index16 clipplane_state_tokens[][STATE_LENGTH]) const gl_state_index16 clipplane_state_tokens[][STATE_LENGTH])
{ {
if (!ucp_enables) unsigned ucp_enables_val = ucp_enables ? *ucp_enables : 0xff;
if (!ucp_enables_val)
return false; return false;
nir_function_impl *impl = nir_shader_get_entrypoint(shader); nir_function_impl *impl = nir_shader_get_entrypoint(shader);
@ -406,8 +407,9 @@ nir_lower_clip_vs(nir_shader *shader, unsigned ucp_enables, bool use_vars,
b.cursor = nir_after_impl(impl); b.cursor = nir_after_impl(impl);
struct lower_clip_state state = { NULL }; struct lower_clip_state state = { NULL };
state.ucp_enables = ucp_enables; state.ucp_enables = ucp_enables_val;
state.use_clipdist_array = use_clipdist_array; state.use_clipdist_array = use_clipdist_array;
state.use_enables_sysval = !ucp_enables;
state.clipplane_state_tokens = clipplane_state_tokens; state.clipplane_state_tokens = clipplane_state_tokens;
/* find clipvertex/position outputs */ /* find clipvertex/position outputs */
@ -415,20 +417,20 @@ nir_lower_clip_vs(nir_shader *shader, unsigned ucp_enables, bool use_vars,
&state.position)) &state.position))
return false; return false;
shader->info.clip_distance_array_size = util_last_bit(ucp_enables); shader->info.clip_distance_array_size = util_last_bit(ucp_enables_val);
if (!use_vars || shader->info.io_lowered) { if (!use_vars || shader->info.io_lowered) {
/* If the driver has lowered IO instead of st/mesa, the driver expects /* If the driver has lowered IO instead of st/mesa, the driver expects
* that variables are present even with lowered IO, so create them. * that variables are present even with lowered IO, so create them.
*/ */
if (!shader->info.io_lowered) { if (!shader->info.io_lowered) {
create_clipdist_vars(shader, state.out, ucp_enables, true, create_clipdist_vars(shader, state.out, ucp_enables_val, true,
use_clipdist_array); use_clipdist_array);
} }
lower_clip_vertex_intrin(&b, &state); lower_clip_vertex_intrin(&b, &state);
} else { } else {
create_clipdist_vars(shader, state.out, ucp_enables, true, create_clipdist_vars(shader, state.out, ucp_enables_val, true,
use_clipdist_array); use_clipdist_array);
lower_clip_vertex_var(&b, &state); lower_clip_vertex_var(&b, &state);
} }
@ -504,16 +506,19 @@ save_clipvertex_to_temp_gs(nir_builder *b, nir_intrinsic_instr *intr,
} }
bool bool
nir_lower_clip_gs(nir_shader *shader, unsigned ucp_enables, nir_lower_clip_gs(nir_shader *shader, unsigned *ucp_enables,
bool use_clipdist_array, bool use_clipdist_array,
const gl_state_index16 clipplane_state_tokens[][STATE_LENGTH]) const gl_state_index16 clipplane_state_tokens[][STATE_LENGTH])
{ {
if (!ucp_enables) unsigned ucp_enables_val = ucp_enables ? *ucp_enables : 0xff;
if (!ucp_enables_val)
return false; return false;
struct lower_clip_state state = { NULL }; struct lower_clip_state state = { NULL };
state.ucp_enables = ucp_enables; state.ucp_enables = ucp_enables ? *ucp_enables : 0xff;
state.use_clipdist_array = use_clipdist_array; state.use_clipdist_array = use_clipdist_array;
state.use_enables_sysval = !ucp_enables;
state.clipplane_state_tokens = clipplane_state_tokens; state.clipplane_state_tokens = clipplane_state_tokens;
/* find clipvertex/position outputs */ /* find clipvertex/position outputs */
@ -521,7 +526,7 @@ nir_lower_clip_gs(nir_shader *shader, unsigned ucp_enables,
&state.position)) &state.position))
return false; return false;
shader->info.clip_distance_array_size = util_last_bit(ucp_enables); shader->info.clip_distance_array_size = util_last_bit(ucp_enables_val);
if (shader->info.io_lowered) { if (shader->info.io_lowered) {
/* Track the current value of CLIP_VERTEX or POS in a local variable. */ /* Track the current value of CLIP_VERTEX or POS in a local variable. */
@ -533,7 +538,7 @@ nir_lower_clip_gs(nir_shader *shader, unsigned ucp_enables,
return false; return false;
} else { } else {
/* insert CLIPDIST outputs */ /* insert CLIPDIST outputs */
create_clipdist_vars(shader, state.out, ucp_enables, true, create_clipdist_vars(shader, state.out, ucp_enables_val, true,
use_clipdist_array); use_clipdist_array);
} }
@ -548,7 +553,8 @@ nir_lower_clip_gs(nir_shader *shader, unsigned ucp_enables,
static void static void
lower_clip_fs(nir_function_impl *impl, unsigned ucp_enables, lower_clip_fs(nir_function_impl *impl, unsigned ucp_enables,
nir_variable **in, bool use_clipdist_array, bool use_load_interp) nir_variable **in, bool use_clipdist_array, bool use_load_interp,
bool use_enables_sysval)
{ {
nir_def *clipdist[MAX_CLIP_PLANES]; nir_def *clipdist[MAX_CLIP_PLANES];
nir_builder b = nir_builder_at(nir_before_impl(impl)); nir_builder b = nir_builder_at(nir_before_impl(impl));
@ -568,12 +574,23 @@ lower_clip_fs(nir_function_impl *impl, unsigned ucp_enables,
nir_def *cond = NULL; nir_def *cond = NULL;
for (int plane = 0; plane < MAX_CLIP_PLANES; plane++) { if (use_enables_sysval)
if (ucp_enables & (1 << plane)) { cond = nir_imm_int(&b, 0);
nir_def *this_cond =
nir_flt_imm(&b, clipdist[plane], 0.0);
cond = cond ? nir_ior(&b, cond, this_cond) : this_cond; for (int plane = 0; plane < MAX_CLIP_PLANES; plane++) {
if (use_enables_sysval) {
nir_def *this_cond =
nir_iand(&b, nir_flt(&b, clipdist[plane], nir_imm_float(&b, 0.0)),
nir_iand_imm(&b, nir_load_user_clip_plane(&b), (1 << plane)));
cond = nir_ior(&b, cond, this_cond);
} else {
if (ucp_enables & (1 << plane)) {
nir_def *this_cond =
nir_flt_imm(&b, clipdist[plane], 0.0);
cond = cond ? nir_ior(&b, cond, this_cond) : this_cond;
}
} }
} }
@ -607,31 +624,32 @@ fs_has_clip_dist_input_var(nir_shader *shader, nir_variable **io_vars,
/* insert conditional kill based on interpolated CLIPDIST /* insert conditional kill based on interpolated CLIPDIST
*/ */
bool bool
nir_lower_clip_fs(nir_shader *shader, unsigned ucp_enables, nir_lower_clip_fs(nir_shader *shader, unsigned *ucp_enables,
bool use_clipdist_array, bool use_load_interp) bool use_clipdist_array, bool use_load_interp)
{ {
nir_variable *in[2] = { 0 }; nir_variable *in[2] = { 0 };
unsigned ucp_enables_val = ucp_enables ? *ucp_enables : 0xff;
if (!ucp_enables) if (!ucp_enables_val)
return false; return false;
/* this is probably broken until https://gitlab.freedesktop.org/mesa/mesa/-/issues/10826 is fixed */ /* this is probably broken until https://gitlab.freedesktop.org/mesa/mesa/-/issues/10826 is fixed */
assert(!shader->info.io_lowered); assert(!shader->info.io_lowered);
shader->info.clip_distance_array_size = util_last_bit(ucp_enables); shader->info.clip_distance_array_size = util_last_bit(ucp_enables_val);
/* No hard reason to require use_clipdist_arr to work with /* No hard reason to require use_clipdist_arr to work with
* frag-shader-based gl_ClipDistance, except that the only user that does * frag-shader-based gl_ClipDistance, except that the only user that does
* not enable this does not support GL 3.0 (or EXT_clip_cull_distance). * not enable this does not support GL 3.0 (or EXT_clip_cull_distance).
*/ */
if (!fs_has_clip_dist_input_var(shader, in, &ucp_enables)) if (!fs_has_clip_dist_input_var(shader, in, &ucp_enables_val))
create_clipdist_vars(shader, in, ucp_enables, false, use_clipdist_array); create_clipdist_vars(shader, in, ucp_enables_val, false, use_clipdist_array);
else else
assert(use_clipdist_array); assert(use_clipdist_array);
nir_foreach_function_with_impl(function, impl, shader) { nir_foreach_function_with_impl(function, impl, shader) {
if (!strcmp(function->name, "main")) { if (!strcmp(function->name, "main")) {
lower_clip_fs(impl, ucp_enables, in, use_clipdist_array, lower_clip_fs(impl, ucp_enables_val, in, use_clipdist_array,
use_load_interp); use_load_interp, !ucp_enables);
} }
} }

View file

@ -1164,11 +1164,12 @@ ir3_nir_lower_variant(struct ir3_shader_variant *so,
/* Note that it is intentional to use the VS lowering pass for GS, since we /* Note that it is intentional to use the VS lowering pass for GS, since we
* lower GS into something that looks more like a VS in ir3_nir_lower_gs(): * lower GS into something that looks more like a VS in ir3_nir_lower_gs():
*/ */
unsigned ucp_enables = so->key.ucp_enables;
if (lower_ucp_vs(so)) { if (lower_ucp_vs(so)) {
progress |= OPT(s, nir_lower_clip_vs, so->key.ucp_enables, false, true, NULL); progress |= OPT(s, nir_lower_clip_vs, &ucp_enables, false, true, NULL);
} else if (s->info.stage == MESA_SHADER_FRAGMENT) { } else if (s->info.stage == MESA_SHADER_FRAGMENT) {
if (so->key.ucp_enables && !so->compiler->has_clip_cull) if (so->key.ucp_enables && !so->compiler->has_clip_cull)
progress |= OPT(s, nir_lower_clip_fs, so->key.ucp_enables, true, true); progress |= OPT(s, nir_lower_clip_fs, &ucp_enables, true, true);
} }
if (so->binning_pass) { if (so->binning_pass) {

View file

@ -1179,7 +1179,8 @@ crocus_compile_vs(struct crocus_context *ice,
if (key->nr_userclip_plane_consts) { if (key->nr_userclip_plane_consts) {
nir_function_impl *impl = nir_shader_get_entrypoint(nir); nir_function_impl *impl = nir_shader_get_entrypoint(nir);
/* Check if variables were found. */ /* Check if variables were found. */
if (nir_lower_clip_vs(nir, (1 << key->nr_userclip_plane_consts) - 1, unsigned ucp_enables = (1 << key->nr_userclip_plane_consts) - 1;
if (nir_lower_clip_vs(nir, &ucp_enables,
true, false, NULL)) { true, false, NULL)) {
nir_lower_io_vars_to_temporaries(nir, impl, nir_var_shader_out); nir_lower_io_vars_to_temporaries(nir, impl, nir_var_shader_out);
nir_lower_global_vars_to_local(nir); nir_lower_global_vars_to_local(nir);
@ -1539,7 +1540,8 @@ crocus_compile_tes(struct crocus_context *ice,
if (key->nr_userclip_plane_consts) { if (key->nr_userclip_plane_consts) {
nir_function_impl *impl = nir_shader_get_entrypoint(nir); nir_function_impl *impl = nir_shader_get_entrypoint(nir);
nir_lower_clip_vs(nir, (1 << key->nr_userclip_plane_consts) - 1, true, unsigned ucp_enables = (1 << key->nr_userclip_plane_consts) - 1;
nir_lower_clip_vs(nir, &ucp_enables, true,
false, NULL); false, NULL);
nir_lower_io_vars_to_temporaries(nir, impl, nir_var_shader_out); nir_lower_io_vars_to_temporaries(nir, impl, nir_var_shader_out);
nir_lower_global_vars_to_local(nir); nir_lower_global_vars_to_local(nir);
@ -1682,7 +1684,8 @@ crocus_compile_gs(struct crocus_context *ice,
if (key->nr_userclip_plane_consts) { if (key->nr_userclip_plane_consts) {
nir_function_impl *impl = nir_shader_get_entrypoint(nir); nir_function_impl *impl = nir_shader_get_entrypoint(nir);
nir_lower_clip_gs(nir, (1 << key->nr_userclip_plane_consts) - 1, false, unsigned ucp_enables = (1 << key->nr_userclip_plane_consts) - 1;
nir_lower_clip_gs(nir, &ucp_enables, false,
NULL); NULL);
nir_lower_io_vars_to_temporaries(nir, impl, nir_var_shader_out); nir_lower_io_vars_to_temporaries(nir, impl, nir_var_shader_out);
nir_lower_global_vars_to_local(nir); nir_lower_global_vars_to_local(nir);

View file

@ -1908,7 +1908,8 @@ iris_compile_vs(struct iris_screen *screen,
if (key->vue.nr_userclip_plane_consts) { if (key->vue.nr_userclip_plane_consts) {
nir_function_impl *impl = nir_shader_get_entrypoint(nir); nir_function_impl *impl = nir_shader_get_entrypoint(nir);
/* Check if variables were found. */ /* Check if variables were found. */
if (nir_lower_clip_vs(nir, (1 << key->vue.nr_userclip_plane_consts) - 1, unsigned ucp_enables = (1 << key->vue.nr_userclip_plane_consts) - 1;
if (nir_lower_clip_vs(nir, &ucp_enables,
true, false, NULL)) { true, false, NULL)) {
nir_lower_io_vars_to_temporaries(nir, impl, nir_var_shader_out); nir_lower_io_vars_to_temporaries(nir, impl, nir_var_shader_out);
nir_lower_global_vars_to_local(nir); nir_lower_global_vars_to_local(nir);
@ -2355,7 +2356,8 @@ iris_compile_tes(struct iris_screen *screen,
if (key->vue.nr_userclip_plane_consts) { if (key->vue.nr_userclip_plane_consts) {
nir_function_impl *impl = nir_shader_get_entrypoint(nir); nir_function_impl *impl = nir_shader_get_entrypoint(nir);
nir_lower_clip_vs(nir, (1 << key->vue.nr_userclip_plane_consts) - 1, unsigned ucp_enables = (1 << key->vue.nr_userclip_plane_consts) - 1;
nir_lower_clip_vs(nir, &ucp_enables,
true, false, NULL); true, false, NULL);
nir_lower_io_vars_to_temporaries(nir, impl, nir_var_shader_out); nir_lower_io_vars_to_temporaries(nir, impl, nir_var_shader_out);
nir_lower_global_vars_to_local(nir); nir_lower_global_vars_to_local(nir);
@ -2550,7 +2552,8 @@ iris_compile_gs(struct iris_screen *screen,
if (key->vue.nr_userclip_plane_consts) { if (key->vue.nr_userclip_plane_consts) {
nir_function_impl *impl = nir_shader_get_entrypoint(nir); nir_function_impl *impl = nir_shader_get_entrypoint(nir);
nir_lower_clip_gs(nir, (1 << key->vue.nr_userclip_plane_consts) - 1, unsigned ucp_enables = (1 << key->vue.nr_userclip_plane_consts) - 1;
nir_lower_clip_gs(nir, &ucp_enables,
false, NULL); false, NULL);
nir_lower_io_vars_to_temporaries(nir, impl, nir_var_shader_out); nir_lower_io_vars_to_temporaries(nir, impl, nir_var_shader_out);
nir_lower_global_vars_to_local(nir); nir_lower_global_vars_to_local(nir);

View file

@ -182,7 +182,8 @@ panfrost_shader_compile(struct panfrost_screen *screen, const nir_shader *ir,
} }
if (key->fs.clip_plane_enable) { if (key->fs.clip_plane_enable) {
NIR_PASS(_, s, nir_lower_clip_fs, key->fs.clip_plane_enable, unsigned ucp_enables = key->fs.clip_plane_enable;
NIR_PASS(_, s, nir_lower_clip_fs, &ucp_enables,
false, true); false, true);
inputs.fixed_varying_mask = inputs.fixed_varying_mask =
pan_get_fixed_varying_mask(s->info.inputs_read); pan_get_fixed_varying_mask(s->info.inputs_read);

View file

@ -2263,7 +2263,8 @@ vc4_shader_ntq(struct vc4_context *vc4, enum qstage stage,
NIR_PASS(_, c->s, nir_lower_tex, &tex_options); NIR_PASS(_, c->s, nir_lower_tex, &tex_options);
if (c->fs_key && c->fs_key->ucp_enables) { if (c->fs_key && c->fs_key->ucp_enables) {
NIR_PASS(_, c->s, nir_lower_clip_fs, c->fs_key->ucp_enables, false, false); unsigned ucp_enables = c->fs_key->ucp_enables;
NIR_PASS(_, c->s, nir_lower_clip_fs, &ucp_enables, false, false);
} }
if (c->stage == QSTAGE_FRAG) if (c->stage == QSTAGE_FRAG)

View file

@ -719,10 +719,10 @@ lower_ucp(struct st_context *st,
if (nir->info.stage == MESA_SHADER_VERTEX || if (nir->info.stage == MESA_SHADER_VERTEX ||
nir->info.stage == MESA_SHADER_TESS_EVAL) { nir->info.stage == MESA_SHADER_TESS_EVAL) {
NIR_PASS(_, nir, nir_lower_clip_vs, ucp_enables, NIR_PASS(_, nir, nir_lower_clip_vs, &ucp_enables,
true, can_compact, clipplane_state); true, can_compact, clipplane_state);
} else if (nir->info.stage == MESA_SHADER_GEOMETRY) { } else if (nir->info.stage == MESA_SHADER_GEOMETRY) {
NIR_PASS(_, nir, nir_lower_clip_gs, ucp_enables, NIR_PASS(_, nir, nir_lower_clip_gs, &ucp_enables,
can_compact, clipplane_state); can_compact, clipplane_state);
} }