freedreno/turnip: Use the NIR info to decide if we need helper invocations.
authorEric Anholt <eric@anholt.net>
Tue, 24 Mar 2020 16:59:16 +0000 (09:59 -0700)
committerMarge Bot <eric+marge@anholt.net>
Tue, 31 Mar 2020 22:29:22 +0000 (22:29 +0000)
We had an approximation that was assuming any ddx or tex instruction
needed helper invocations, but that's not true for texelFetch() or
textureSize().  It also meant that we were setting PIXLOD on vertex and
compute shaders doing texturing, which doesn't really make sense.

shader-db (with a hack to log pixlod):
total pixlod in shared programs: 582 -> 573 (-1.55%)

Closes: https://gitlab.freedesktop.org/mesa/mesa/issues/2681
Tested-by: Marge Bot <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/4308>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/4308>

src/freedreno/ir3/ir3_compiler_nir.c
src/freedreno/ir3/ir3_legalize.c
src/freedreno/ir3/ir3_nir_lower_load_barycentric_at_offset.c

index cf70ae5..a24605b 100644 (file)
@@ -3543,6 +3543,10 @@ ir3_compile_shader_nir(struct ir3_compiler *compiler,
        /* Collect sampling instructions eligible for pre-dispatch. */
        collect_tex_prefetches(ctx, ir);
 
+       if (so->type == MESA_SHADER_FRAGMENT &&
+                       ctx->s->info.fs.needs_helper_invocations)
+               so->need_pixlod = true;
+
 out:
        if (ret) {
                if (so->ir)
index d88ef00..bed8cd1 100644 (file)
@@ -239,7 +239,6 @@ legalize_block(struct ir3_legalize_ctx *ctx, struct ir3_block *block)
 
                if (is_tex_or_prefetch(n)) {
                        regmask_set(&state->needs_sy, n->regs[0]);
-                       ctx->so->need_pixlod = true;
                        if (n->opc == OPC_META_TEX_PREFETCH)
                                has_tex_prefetch = true;
                } else if (n->opc == OPC_RESINFO) {
index 903bb8e..fe5f42d 100644 (file)
@@ -63,6 +63,9 @@ ir3_nir_lower_load_barycentric_at_offset_instr(nir_builder *b,
        nir_ssa_def *foo = nir_fddx(b, sij);
        nir_ssa_def *bar = nir_fddy(b, sij);
 
+       if (b->shader->info.stage == MESA_SHADER_FRAGMENT)
+               b->shader->info.fs.needs_helper_invocations = true;
+
        nir_ssa_def *x, *y, *z, *i, *j;
 
        x = nir_ffma(b, chan(off, 0), chan(foo, 0), chan(sij, 0));