});
if (radv_use_llvm_for_stage(device, stage->stage))
- NIR_PASS_V(stage->nir, nir_lower_io_to_scalar, nir_var_mem_global);
+ NIR_PASS_V(stage->nir, nir_lower_io_to_scalar, nir_var_mem_global, NULL, NULL);
NIR_PASS(_, stage->nir, ac_nir_lower_global_access);
NIR_PASS_V(stage->nir, ac_nir_lower_intrinsics_to_args, gfx_level, radv_select_hw_stage(&stage->info, gfx_level),
* transform feedback programs will use vector output.
*/
if (nir->info.stage == MESA_SHADER_VERTEX)
- NIR_PASS_V(nir, nir_lower_io_to_scalar, nir_var_shader_out);
+ NIR_PASS_V(nir, nir_lower_io_to_scalar, nir_var_shader_out, NULL, NULL);
out->push_count = key->reserved_preamble;
agx_optimize_nir(nir, &out->push_count);
}
/* Note: GS output scalarizing must happen after nir_lower_clip_gs. */
- NIR_PASS_V(c->s, nir_lower_io_to_scalar, nir_var_shader_out);
+ NIR_PASS_V(c->s, nir_lower_io_to_scalar, nir_var_shader_out, NULL, NULL);
}
static void
NIR_PASS(_, c->s, nir_lower_clip_vs, c->key->ucp_enables,
false, false, NULL);
NIR_PASS_V(c->s, nir_lower_io_to_scalar,
- nir_var_shader_out);
+ nir_var_shader_out, NULL, NULL);
}
/* Note: VS output scalarizing must happen after nir_lower_clip_vs. */
- NIR_PASS_V(c->s, nir_lower_io_to_scalar, nir_var_shader_out);
+ NIR_PASS_V(c->s, nir_lower_io_to_scalar, nir_var_shader_out, NULL, NULL);
}
static void
if (c->key->ucp_enables)
NIR_PASS(_, c->s, nir_lower_clip_fs, c->key->ucp_enables, true);
- NIR_PASS_V(c->s, nir_lower_io_to_scalar, nir_var_shader_in);
+ NIR_PASS_V(c->s, nir_lower_io_to_scalar, nir_var_shader_in, NULL, NULL);
}
static uint32_t
void nir_lower_io_arrays_to_elements(nir_shader *producer, nir_shader *consumer);
void nir_lower_io_arrays_to_elements_no_indirects(nir_shader *shader,
bool outputs_only);
-bool nir_lower_io_to_scalar(nir_shader *shader, nir_variable_mode mask);
+bool nir_lower_io_to_scalar(nir_shader *shader, nir_variable_mode mask, nir_instr_filter_cb filter, void *filter_data);
bool nir_lower_io_to_scalar_early(nir_shader *shader, nir_variable_mode mask);
bool nir_lower_io_to_vector(nir_shader *shader, nir_variable_mode mask);
bool nir_vectorize_tess_levels(nir_shader *shader);
nir_instr_remove(&intr->instr);
}
+struct scalarize_state {
+ nir_variable_mode mask;
+ nir_instr_filter_cb filter;
+ void *filter_data;
+};
+
static bool
nir_lower_io_to_scalar_instr(nir_builder *b, nir_instr *instr, void *data)
{
- nir_variable_mode mask = *(nir_variable_mode *)data;
+ struct scalarize_state *state = data;
if (instr->type != nir_instr_type_intrinsic)
return false;
if ((intr->intrinsic == nir_intrinsic_load_input ||
intr->intrinsic == nir_intrinsic_load_per_vertex_input ||
intr->intrinsic == nir_intrinsic_load_interpolated_input) &&
- (mask & nir_var_shader_in)) {
+ (state->mask & nir_var_shader_in) &&
+ (!state->filter || state->filter(instr, state->filter_data))) {
lower_load_input_to_scalar(b, intr);
return true;
}
if ((intr->intrinsic == nir_intrinsic_load_output ||
intr->intrinsic == nir_intrinsic_load_per_vertex_output) &&
- (mask & nir_var_shader_out)) {
+ (state->mask & nir_var_shader_out) &&
+ (!state->filter || state->filter(instr, state->filter_data))) {
lower_load_input_to_scalar(b, intr);
return true;
}
- if ((intr->intrinsic == nir_intrinsic_load_ubo && (mask & nir_var_mem_ubo)) ||
- (intr->intrinsic == nir_intrinsic_load_ssbo && (mask & nir_var_mem_ssbo)) ||
- (intr->intrinsic == nir_intrinsic_load_global && (mask & nir_var_mem_global)) ||
- (intr->intrinsic == nir_intrinsic_load_shared && (mask & nir_var_mem_shared))) {
+ if (((intr->intrinsic == nir_intrinsic_load_ubo && (state->mask & nir_var_mem_ubo)) ||
+ (intr->intrinsic == nir_intrinsic_load_ssbo && (state->mask & nir_var_mem_ssbo)) ||
+ (intr->intrinsic == nir_intrinsic_load_global && (state->mask & nir_var_mem_global)) ||
+ (intr->intrinsic == nir_intrinsic_load_shared && (state->mask & nir_var_mem_shared))) &&
+ (!state->filter || state->filter(instr, state->filter_data))) {
lower_load_to_scalar(b, intr);
return true;
}
if ((intr->intrinsic == nir_intrinsic_store_output ||
intr->intrinsic == nir_intrinsic_store_per_vertex_output) &&
- mask & nir_var_shader_out) {
+ state->mask & nir_var_shader_out &&
+ (!state->filter || state->filter(instr, state->filter_data))) {
lower_store_output_to_scalar(b, intr);
return true;
}
- if ((intr->intrinsic == nir_intrinsic_store_ssbo && (mask & nir_var_mem_ssbo)) ||
- (intr->intrinsic == nir_intrinsic_store_global && (mask & nir_var_mem_global)) ||
- (intr->intrinsic == nir_intrinsic_store_shared && (mask & nir_var_mem_shared))) {
+ if (((intr->intrinsic == nir_intrinsic_store_ssbo && (state->mask & nir_var_mem_ssbo)) ||
+ (intr->intrinsic == nir_intrinsic_store_global && (state->mask & nir_var_mem_global)) ||
+ (intr->intrinsic == nir_intrinsic_store_shared && (state->mask & nir_var_mem_shared))) &&
+ (!state->filter || state->filter(instr, state->filter_data))) {
lower_store_to_scalar(b, intr);
return true;
}
}
bool
-nir_lower_io_to_scalar(nir_shader *shader, nir_variable_mode mask)
+nir_lower_io_to_scalar(nir_shader *shader, nir_variable_mode mask, nir_instr_filter_cb filter, void *filter_data)
{
+ struct scalarize_state state = {
+ mask,
+ filter,
+ filter_data
+ };
return nir_shader_instructions_pass(shader,
nir_lower_io_to_scalar_instr,
nir_metadata_block_index |
nir_metadata_dominance,
- &mask);
+ &state);
}
static nir_variable **
bool progress = false;
- NIR_PASS_V(s, nir_lower_io_to_scalar, nir_var_mem_ssbo);
+ NIR_PASS_V(s, nir_lower_io_to_scalar, nir_var_mem_ssbo, NULL, NULL);
if (so->key.has_gs || so->key.tessellation) {
switch (so->type) {
break;
case MESA_SHADER_TESS_CTRL:
NIR_PASS_V(s, nir_lower_io_to_scalar,
- nir_var_shader_in | nir_var_shader_out);
+ nir_var_shader_in | nir_var_shader_out, NULL, NULL);
NIR_PASS_V(s, ir3_nir_lower_tess_ctrl, so, so->key.tessellation);
NIR_PASS_V(s, ir3_nir_lower_to_explicit_input, so);
progress = true;
NIR_PASS_V(s, nir_lower_load_const_to_scalar);
NIR_PASS_V(s, lima_nir_lower_uniform_to_scalar);
NIR_PASS_V(s, nir_lower_io_to_scalar,
- nir_var_shader_in|nir_var_shader_out);
+ nir_var_shader_in|nir_var_shader_out, NULL, NULL);
do {
progress = false;
NIR_PASS_V(nir, nir_lower_subgroups, &si_nir_subgroups_options);
/* may generate some vector output store */
- NIR_PASS_V(nir, nir_lower_io_to_scalar, nir_var_shader_out);
+ NIR_PASS_V(nir, nir_lower_io_to_scalar, nir_var_shader_out, NULL, NULL);
}
struct nir_shader *si_deserialize_shader(struct si_shader_selector *sel)
if (nir->info.stage == MESA_SHADER_VERTEX ||
nir->info.stage == MESA_SHADER_TESS_EVAL ||
nir->info.stage == MESA_SHADER_GEOMETRY)
- NIR_PASS_V(nir, nir_lower_io_to_scalar, nir_var_shader_out);
+ NIR_PASS_V(nir, nir_lower_io_to_scalar, nir_var_shader_out, NULL, NULL);
if (nir->info.stage == MESA_SHADER_GEOMETRY) {
unsigned flags = nir_lower_gs_intrinsics_per_stream;
NIR_PASS_V(c->s, nir_lower_clip_vs,
c->key->ucp_enables, false, false, NULL);
NIR_PASS_V(c->s, nir_lower_io_to_scalar,
- nir_var_shader_out);
+ nir_var_shader_out, NULL, NULL);
}
}
* scalarizing must happen after nir_lower_clip_vs.
*/
if (c->stage == QSTAGE_FRAG)
- NIR_PASS_V(c->s, nir_lower_io_to_scalar, nir_var_shader_in);
+ NIR_PASS_V(c->s, nir_lower_io_to_scalar, nir_var_shader_in, NULL, NULL);
else
- NIR_PASS_V(c->s, nir_lower_io_to_scalar, nir_var_shader_out);
+ NIR_PASS_V(c->s, nir_lower_io_to_scalar, nir_var_shader_out, NULL, NULL);
NIR_PASS_V(c->s, vc4_nir_lower_io, c);
NIR_PASS_V(c->s, vc4_nir_lower_txf_ms, c);
}
}
if (screen->driconf.inline_uniforms) {
- NIR_PASS_V(nir, nir_lower_io_to_scalar, nir_var_mem_global | nir_var_mem_ubo | nir_var_mem_ssbo | nir_var_mem_shared);
+ NIR_PASS_V(nir, nir_lower_io_to_scalar, nir_var_mem_global | nir_var_mem_ubo | nir_var_mem_ssbo | nir_var_mem_shared, NULL, NULL);
NIR_PASS_V(nir, rewrite_bo_access, screen);
NIR_PASS_V(nir, remove_bo_access, zs);
need_optimize = true;
}
}
if (screen->driconf.inline_uniforms) {
- NIR_PASS_V(nir, nir_lower_io_to_scalar, nir_var_mem_global | nir_var_mem_ubo | nir_var_mem_ssbo | nir_var_mem_shared);
+ NIR_PASS_V(nir, nir_lower_io_to_scalar, nir_var_mem_global | nir_var_mem_ubo | nir_var_mem_ssbo | nir_var_mem_shared, NULL, NULL);
NIR_PASS_V(nir, rewrite_bo_access, screen);
NIR_PASS_V(nir, remove_bo_access, zs);
}
NIR_PASS_V(nir, unbreak_bos, ret, needs_size);
/* run in compile if there could be inlined uniforms */
if (!screen->driconf.inline_uniforms && !nir->info.num_inlinable_uniforms) {
- NIR_PASS_V(nir, nir_lower_io_to_scalar, nir_var_mem_global | nir_var_mem_ubo | nir_var_mem_ssbo | nir_var_mem_shared);
+ NIR_PASS_V(nir, nir_lower_io_to_scalar, nir_var_mem_global | nir_var_mem_ubo | nir_var_mem_ssbo | nir_var_mem_shared, NULL, NULL);
NIR_PASS_V(nir, rewrite_bo_access, screen);
NIR_PASS_V(nir, remove_bo_access, ret);
}
/* Load inputs to scalars (single registers later). */
/* TODO: Fitrp can process multiple frag inputs at once, scalarise I/O. */
- NIR_PASS_V(nir, nir_lower_io_to_scalar, nir_var_shader_in);
+ NIR_PASS_V(nir, nir_lower_io_to_scalar, nir_var_shader_in, NULL, NULL);
/* Optimize GL access qualifiers. */
const nir_opt_access_options opt_access_options = {
NIR_PASS_V(nir, rogue_nir_pfo);
/* Load outputs to scalars (single registers later). */
- NIR_PASS_V(nir, nir_lower_io_to_scalar, nir_var_shader_out);
+ NIR_PASS_V(nir, nir_lower_io_to_scalar, nir_var_shader_out, NULL, NULL);
/* Lower ALU operations to scalars. */
NIR_PASS_V(nir, nir_lower_alu_to_scalar, NULL, NULL);
nir_lower_explicit_io,
nir_var_mem_ubo,
spirv_options.ubo_addr_format);
- NIR_PASS_V(nir, nir_lower_io_to_scalar, nir_var_mem_ubo);
+ NIR_PASS_V(nir, nir_lower_io_to_scalar, nir_var_mem_ubo, NULL, NULL);
NIR_PASS_V(nir, rogue_nir_lower_io);
/* Algebraic opts. */
NIR_PASS_V(s, nir_lower_io, nir_var_shader_in | nir_var_shader_out, type_size_vec4, nir_lower_io_lower_64bit_to_32);
NIR_PASS_V(s, dxil_nir_ensure_position_writes);
NIR_PASS_V(s, dxil_nir_lower_system_values);
- NIR_PASS_V(s, nir_lower_io_to_scalar, nir_var_shader_in | nir_var_system_value | nir_var_shader_out);
+ NIR_PASS_V(s, nir_lower_io_to_scalar, nir_var_shader_in | nir_var_system_value | nir_var_shader_out, NULL, NULL);
/* Do a round of optimization to try to vectorize loads/stores. Otherwise the addresses used for loads
* might be too opaque for the pass to see that they're next to each other. */