freedreno: Only upload the used part of UBO0 to the constant buffer.
authorEric Anholt <eric@anholt.net>
Wed, 5 Jun 2019 22:15:07 +0000 (15:15 -0700)
committerEric Anholt <eric@anholt.net>
Mon, 24 Jun 2019 21:23:07 +0000 (14:23 -0700)
We were pessimistically uploading all of it in case of indirection,
but we can just bump that when we encounter indirection.

total constlen in shared programs: 2529623 -> 2485933 (-1.73%)

Reviewed-by: Kristian H. Kristensen <hoegsberg@google.com>
Reviewed-by: Rob Clark <robdclark@gmail.com>
src/freedreno/ir3/ir3_compiler_nir.c
src/freedreno/ir3/ir3_nir_analyze_ubo_ranges.c

index e453f33fb91ffe968cc96345b13fc9d9b65904a0..d84c56b01957fd1f7f31bd587cebabda31a31a0e 100644 (file)
@@ -1262,7 +1262,8 @@ emit_intrinsic(struct ir3_context *ctx, nir_intrinsic_instr *intr)
                         * since we don't know in the assembler what the max
                         * addr reg value can be:
                         */
-                       ctx->so->constlen = MAX2(ctx->so->constlen, ctx->s->num_uniforms);
+                       ctx->so->constlen = MAX2(ctx->so->constlen,
+                                       ctx->so->shader->ubo_state.size / 16);
                }
                break;
        case nir_intrinsic_load_ubo:
index 46216a6f8621e52490479c8cb691fcaa779bd922..b3191a36c14b8f9a341f1e426f6139368ba5b10d 100644 (file)
@@ -42,14 +42,22 @@ get_ubo_load_range(nir_intrinsic_instr *instr)
 }
 
 static void
-gather_ubo_ranges(nir_intrinsic_instr *instr,
+gather_ubo_ranges(nir_shader *nir, nir_intrinsic_instr *instr,
                                  struct ir3_ubo_analysis_state *state)
 {
        if (!nir_src_is_const(instr->src[0]))
                return;
 
-       if (!nir_src_is_const(instr->src[1]))
+       if (!nir_src_is_const(instr->src[1])) {
+               if (nir_src_as_uint(instr->src[0]) == 0) {
+                       /* If this is an indirect on UBO 0, we'll still lower it back to
+                        * load_uniform.  Set the range to cover all of UBO 0.
+                        */
+                       state->range[0].end = align(nir->num_uniforms * 16, 16 * 4);
+               }
+
                return;
+       }
 
        const struct ir3_ubo_range r = get_ubo_load_range(instr);
        const uint32_t block = nir_src_as_uint(instr->src[0]);
@@ -132,7 +140,6 @@ ir3_nir_analyze_ubo_ranges(nir_shader *nir, struct ir3_shader *shader)
        struct ir3_ubo_analysis_state *state = &shader->ubo_state;
 
        memset(state, 0, sizeof(*state));
-       state->range[0].end = align(nir->num_uniforms * 16, 16 * 4); /* align to 4*vec4 */
 
        nir_foreach_function(function, nir) {
                if (function->impl) {
@@ -140,7 +147,7 @@ ir3_nir_analyze_ubo_ranges(nir_shader *nir, struct ir3_shader *shader)
                                nir_foreach_instr(instr, block) {
                                        if (instr->type == nir_instr_type_intrinsic &&
                                                nir_instr_as_intrinsic(instr)->intrinsic == nir_intrinsic_load_ubo)
-                                               gather_ubo_ranges(nir_instr_as_intrinsic(instr), state);
+                                               gather_ubo_ranges(nir, nir_instr_as_intrinsic(instr), state);
                                }
                        }
                }