diff --git a/src/freedreno/ir3/ir3_nir.c b/src/freedreno/ir3/ir3_nir.c index 93b8012e1d5..b1f5fb9669c 100644 --- a/src/freedreno/ir3/ir3_nir.c +++ b/src/freedreno/ir3/ir3_nir.c @@ -344,7 +344,10 @@ ir3_nir_lower_variant(struct ir3_shader_variant *so, nir_shader *s) progress |= OPT(s, nir_lower_tex, &tex_options); } - progress |= OPT(s, ir3_nir_analyze_ubo_ranges, so); + if (!so->binning_pass) + OPT_V(s, ir3_nir_analyze_ubo_ranges, so); + + progress |= OPT(s, ir3_nir_lower_ubo_loads, so); /* UBO offset lowering has to come after we've decided what will * be left as load_ubo diff --git a/src/freedreno/ir3/ir3_nir.h b/src/freedreno/ir3/ir3_nir.h index 915f1638419..b84525bd69f 100644 --- a/src/freedreno/ir3/ir3_nir.h +++ b/src/freedreno/ir3/ir3_nir.h @@ -57,7 +57,8 @@ void ir3_nir_lower_variant(struct ir3_shader_variant *so, nir_shader *s); void ir3_setup_const_state(nir_shader *nir, struct ir3_shader_variant *v, struct ir3_const_state *const_state); -bool ir3_nir_analyze_ubo_ranges(nir_shader *nir, struct ir3_shader_variant *v); +void ir3_nir_analyze_ubo_ranges(nir_shader *nir, struct ir3_shader_variant *v); +bool ir3_nir_lower_ubo_loads(nir_shader *nir, struct ir3_shader_variant *v); nir_ssa_def * ir3_nir_try_propagate_bit_shift(nir_builder *b, nir_ssa_def *offset, int32_t shift); diff --git a/src/freedreno/ir3/ir3_nir_analyze_ubo_ranges.c b/src/freedreno/ir3/ir3_nir_analyze_ubo_ranges.c index 3feb60ed711..2cccee24dc8 100644 --- a/src/freedreno/ir3/ir3_nir_analyze_ubo_ranges.c +++ b/src/freedreno/ir3/ir3_nir_analyze_ubo_ranges.c @@ -229,9 +229,10 @@ track_ubo_use(nir_intrinsic_instr *instr, nir_builder *b, int *num_ubos) } } -static void +static bool lower_ubo_load_to_uniform(nir_intrinsic_instr *instr, nir_builder *b, - struct ir3_ubo_analysis_state *state, int *num_ubos, uint32_t alignment) + const struct ir3_ubo_analysis_state *state, + int *num_ubos, uint32_t alignment) { b->cursor = nir_before_instr(&instr->instr); @@ -242,14 +243,14 @@ lower_ubo_load_to_uniform(nir_intrinsic_instr *instr, nir_builder *b, const struct ir3_ubo_range *range = get_existing_range(instr, state); if (!range) { track_ubo_use(instr, b, num_ubos); - return; + return false; } /* We don't have a good way of determining the range of the dynamic * access in general, so for now just fall back to pulling. */ if (!nir_src_is_const(instr->src[1]) && !ubo_is_gl_uniforms(&range->ubo)) - return; + return false; /* After gathering the UBO access ranges, we limit the total * upload. Don't lower if this load is outside the range. @@ -258,7 +259,7 @@ lower_ubo_load_to_uniform(nir_intrinsic_instr *instr, nir_builder *b, instr, alignment); if (!(range->start <= r.start && r.end <= range->end)) { track_ubo_use(instr, b, num_ubos); - return; + return false; } nir_ssa_def *ubo_offset = nir_ssa_for_src(b, instr->src[1], 1); @@ -313,7 +314,7 @@ lower_ubo_load_to_uniform(nir_intrinsic_instr *instr, nir_builder *b, nir_instr_remove(&instr->instr); - state->lower_count++; + return true; } static bool @@ -330,7 +331,7 @@ instr_is_load_ubo(nir_instr *instr) return op == nir_intrinsic_load_ubo; } -bool +void ir3_nir_analyze_ubo_ranges(nir_shader *nir, struct ir3_shader_variant *v) { struct ir3_const_state *const_state = ir3_const_state(v); @@ -394,15 +395,30 @@ ir3_nir_analyze_ubo_ranges(nir_shader *nir, struct ir3_shader_variant *v) } state->size = offset; +} + +bool +ir3_nir_lower_ubo_loads(nir_shader *nir, struct ir3_shader_variant *v) +{ + struct ir3_compiler *compiler = v->shader->compiler; + /* For the binning pass variant, we re-use the corresponding draw-pass + * variants const_state and ubo state. To make these clear, in this + * pass it is const (read-only) + */ + const struct ir3_const_state *const_state = ir3_const_state(v); + const struct ir3_ubo_analysis_state *state = &const_state->ubo_state; int num_ubos = 0; + bool progress = false; nir_foreach_function (function, nir) { if (function->impl) { nir_builder builder; nir_builder_init(&builder, function->impl); nir_foreach_block (block, function->impl) { nir_foreach_instr_safe (instr, block) { - if (instr_is_load_ubo(instr)) + if (!instr_is_load_ubo(instr)) + continue; + progress |= lower_ubo_load_to_uniform(nir_instr_as_intrinsic(instr), &builder, state, &num_ubos, compiler->const_upload_unit); @@ -420,5 +436,5 @@ ir3_nir_analyze_ubo_ranges(nir_shader *nir, struct ir3_shader_variant *v) if (nir->info.first_ubo_is_default_ubo) nir->info.num_ubos = num_ubos; - return state->lower_count > 0; + return progress; } diff --git a/src/freedreno/ir3/ir3_shader.h b/src/freedreno/ir3/ir3_shader.h index e7e6f381293..5ccbd8cb658 100644 --- a/src/freedreno/ir3/ir3_shader.h +++ b/src/freedreno/ir3/ir3_shader.h @@ -97,7 +97,6 @@ struct ir3_ubo_analysis_state { struct ir3_ubo_range range[IR3_MAX_UBO_PUSH_RANGES]; uint32_t num_enabled; uint32_t size; - uint32_t lower_count; uint32_t cmdstream_size; /* for per-gen backend to stash required cmdstream size */ };