nir: Add parameter divergence info

Indirect calls may have non-divergent parameters that need to be
explicitly marked as such.

Reviewed-by: Alyssa Rosenzweig <alyssa@rosenzweig.io>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/29577>
This commit is contained in:
Friedrich Vock 2024-10-19 12:31:21 +02:00 committed by Marge Bot
parent 7df869b7c9
commit 26cbb6b933
3 changed files with 17 additions and 1 deletions

View file

@ -3585,6 +3585,12 @@ typedef struct {
bool implicit_conversion_prohibited; bool implicit_conversion_prohibited;
/* True if this parameter is not divergent. This is inverted to make
* parameters divergent by default unless explicitly specified
* otherwise.
*/
bool is_uniform;
nir_variable_mode mode; nir_variable_mode mode;
/* The type of the function param */ /* The type of the function param */

View file

@ -39,6 +39,7 @@
struct divergence_state { struct divergence_state {
const gl_shader_stage stage; const gl_shader_stage stage;
nir_shader *shader; nir_shader *shader;
nir_function_impl *impl;
nir_divergence_options options; nir_divergence_options options;
nir_loop *loop; nir_loop *loop;
bool loop_all_invariant; bool loop_all_invariant;
@ -736,11 +737,15 @@ visit_intrinsic(nir_intrinsic_instr *instr, struct divergence_state *state)
src_divergent(instr->src[1], state); src_divergent(instr->src[1], state);
break; break;
case nir_intrinsic_load_param:
is_divergent =
!state->impl->function->params[nir_intrinsic_param_idx(instr)].is_uniform;
break;
/* Intrinsics which are always divergent */ /* Intrinsics which are always divergent */
case nir_intrinsic_inverse_ballot: case nir_intrinsic_inverse_ballot:
case nir_intrinsic_load_color0: case nir_intrinsic_load_color0:
case nir_intrinsic_load_color1: case nir_intrinsic_load_color1:
case nir_intrinsic_load_param:
case nir_intrinsic_load_sample_id: case nir_intrinsic_load_sample_id:
case nir_intrinsic_load_sample_id_no_per_sample: case nir_intrinsic_load_sample_id_no_per_sample:
case nir_intrinsic_load_sample_mask_in: case nir_intrinsic_load_sample_mask_in:
@ -1432,6 +1437,7 @@ nir_divergence_analysis_impl(nir_function_impl *impl, nir_divergence_options opt
struct divergence_state state = { struct divergence_state state = {
.stage = impl->function->shader->info.stage, .stage = impl->function->shader->info.stage,
.shader = impl->function->shader, .shader = impl->function->shader,
.impl = impl,
.options = options, .options = options,
.loop = NULL, .loop = NULL,
.loop_all_invariant = false, .loop_all_invariant = false,
@ -1466,6 +1472,7 @@ nir_vertex_divergence_analysis(nir_shader *shader)
struct divergence_state state = { struct divergence_state state = {
.stage = shader->info.stage, .stage = shader->info.stage,
.shader = shader, .shader = shader,
.impl = nir_shader_get_entrypoint(shader),
.options = shader->options->divergence_analysis_options, .options = shader->options->divergence_analysis_options,
.loop = NULL, .loop = NULL,
.loop_all_invariant = false, .loop_all_invariant = false,

View file

@ -2003,6 +2003,8 @@ write_function(write_ctx *ctx, const nir_function *fxn)
if (fxn->params[i].is_return) if (fxn->params[i].is_return)
val |= (1u << 17); val |= (1u << 17);
if (fxn->params[i].is_uniform)
val |= (1u << 18);
blob_write_uint32(ctx->blob, val); blob_write_uint32(ctx->blob, val);
if (has_name) if (has_name)
blob_write_string(ctx->blob, fxn->params[i].name); blob_write_string(ctx->blob, fxn->params[i].name);
@ -2053,6 +2055,7 @@ read_function(read_ctx *ctx)
fxn->params[i].num_components = val & 0xff; fxn->params[i].num_components = val & 0xff;
fxn->params[i].bit_size = (val >> 8) & 0xff; fxn->params[i].bit_size = (val >> 8) & 0xff;
fxn->params[i].is_return = val & (1u << 16); fxn->params[i].is_return = val & (1u << 16);
fxn->params[i].is_uniform = val & (1u << 17);
fxn->params[i].type = decode_type_from_blob(ctx->blob); fxn->params[i].type = decode_type_from_blob(ctx->blob);
fxn->params[i].mode = decode_deref_modes(blob_read_uint32(ctx->blob)); fxn->params[i].mode = decode_deref_modes(blob_read_uint32(ctx->blob));
} }