vc4: Avoid generating a custom shader per level in glGenerateMipmaps().
authorEric Anholt <eric@anholt.net>
Tue, 2 Aug 2016 23:01:34 +0000 (16:01 -0700)
committerEric Anholt <eric@anholt.net>
Wed, 3 Aug 2016 17:55:54 +0000 (10:55 -0700)
We were baking in the LOD of the source level to each shader.  Instead,
pass it in as a uniform -- this requires storing it to a temp register,
but that's better than compiling a ton of separate shaders:

total instructions in shared programs: 115032 -> 115036 (0.00%)
instructions in affected programs:     96 -> 100 (4.17%)
LOST:                                  572

src/gallium/drivers/vc4/vc4_program.c
src/gallium/drivers/vc4/vc4_qir.h
src/gallium/drivers/vc4/vc4_uniforms.c

index 0afd8c6e36eba2f0a1a3d31babecf1b3f5432c15..28b39810756e46e56c7b5599e65b35d5f5e7d863 100644 (file)
@@ -393,8 +393,8 @@ ntq_emit_tex(struct vc4_compile *c, nir_tex_instr *instr)
                 }
         }
 
-        if (c->key->tex[unit].forced_first_level) {
-                lod = qir_uniform_f(c, c->key->tex[unit].forced_first_level);
+        if (c->key->tex[unit].force_first_level) {
+                lod = qir_uniform(c, QUNIFORM_TEXTURE_FIRST_LEVEL, unit);
                 is_txl = true;
                 is_txb = false;
         }
@@ -2353,10 +2353,8 @@ vc4_setup_shared_key(struct vc4_context *vc4, struct vc4_key *key,
                         key->tex[i].compare_func = sampler_state->compare_func;
                         key->tex[i].wrap_s = sampler_state->wrap_s;
                         key->tex[i].wrap_t = sampler_state->wrap_t;
-                        if (vc4_sampler->force_first_level) {
-                                key->tex[i].forced_first_level =
-                                        sampler->u.tex.first_level;
-                        }
+                        key->tex[i].force_first_level =
+                                vc4_sampler->force_first_level;
                 }
         }
 
index 81b55651cecaf8e6d8381429fc28bbfcf3a21651..b8ded30711ca7d0a94f20ea24da99e920b0c99c2 100644 (file)
@@ -246,6 +246,8 @@ enum quniform_contents {
         /** A reference to a texture config parameter 2 cubemap stride uniform */
         QUNIFORM_TEXTURE_CONFIG_P2,
 
+        QUNIFORM_TEXTURE_FIRST_LEVEL,
+
         QUNIFORM_TEXTURE_MSAA_ADDR,
 
         QUNIFORM_UBO_ADDR,
@@ -314,7 +316,7 @@ struct vc4_key {
                                 unsigned compare_func:3;
                                 unsigned wrap_s:3;
                                 unsigned wrap_t:3;
-                                unsigned forced_first_level:8;
+                                bool force_first_level:1;
                         };
                         struct {
                                 uint16_t msaa_width, msaa_height;
index 528f10eb25af897bd94b361b7f2cb687e364446f..e8cd153ce2078f966412e70578b6025234bc8766 100644 (file)
@@ -71,6 +71,18 @@ write_texture_p2(struct vc4_context *vc4,
                VC4_SET_FIELD((data >> 16) & 1, VC4_TEX_P2_BSLOD));
 }
 
+static void
+write_texture_first_level(struct vc4_context *vc4,
+                          struct vc4_cl_out **uniforms,
+                          struct vc4_texture_stateobj *texstate,
+                          uint32_t data)
+{
+        uint32_t unit = data & 0xffff;
+        struct pipe_sampler_view *texture = texstate->textures[unit];
+
+        cl_aligned_f(uniforms, texture->u.tex.first_level);
+}
+
 static void
 write_texture_msaa_addr(struct vc4_context *vc4,
                  struct vc4_cl_out **uniforms,
@@ -253,6 +265,11 @@ vc4_write_uniforms(struct vc4_context *vc4, struct vc4_compiled_shader *shader,
                                          uinfo->data[i]);
                         break;
 
+                case QUNIFORM_TEXTURE_FIRST_LEVEL:
+                        write_texture_first_level(vc4, &uniforms, texstate,
+                                                  uinfo->data[i]);
+                        break;
+
                 case QUNIFORM_UBO_ADDR:
                         cl_aligned_reloc(vc4, &vc4->uniforms, &uniforms, ubo, 0);
                         break;
@@ -373,6 +390,7 @@ vc4_set_shader_uniform_dirty_flags(struct vc4_compiled_shader *shader)
                 case QUNIFORM_TEXTURE_CONFIG_P1:
                 case QUNIFORM_TEXTURE_CONFIG_P2:
                 case QUNIFORM_TEXTURE_BORDER_COLOR:
+                case QUNIFORM_TEXTURE_FIRST_LEVEL:
                 case QUNIFORM_TEXTURE_MSAA_ADDR:
                 case QUNIFORM_TEXRECT_SCALE_X:
                 case QUNIFORM_TEXRECT_SCALE_Y: