freedreno: Fix assertion failures on GS/tess shaders with shader-db enabled.
authorEric Anholt <eric@anholt.net>
Wed, 15 Apr 2020 21:21:07 +0000 (14:21 -0700)
committerMarge Bot <eric+marge@anholt.net>
Fri, 1 May 2020 16:26:32 +0000 (16:26 +0000)
We weren't filling in the tess mode of the key, or setting has_gs on GS
shaders, resulting in assertion failures when NIR intrinsics didn't get
lowered.

We have to make a guess at prim mode for TCS, but it should be better to
have some shader-db coverage than none, and it will avoid these failures
happening when we start precompiling shaders.

Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/4562>

src/freedreno/ir3/ir3_shader.h
src/gallium/drivers/freedreno/a6xx/fd6_draw.c
src/gallium/drivers/freedreno/ir3/ir3_gallium.c

index 2a9d796224893542daa1cafd3b0bf985decc5270..0896bd1b185fb2aa9c658e40f3cb82a5a89c2c95 100644 (file)
@@ -288,6 +288,21 @@ struct ir3_shader_key {
        uint16_t vastc_srgb, fastc_srgb;
 };
 
+static inline unsigned
+ir3_tess_mode(unsigned gl_tess_mode)
+{
+       switch (gl_tess_mode) {
+       case GL_ISOLINES:
+               return  IR3_TESS_ISOLINES;
+       case GL_TRIANGLES:
+               return IR3_TESS_TRIANGLES;
+       case GL_QUADS:
+               return IR3_TESS_QUADS;
+       default:
+               unreachable("bad tessmode");
+       }
+}
+
 static inline bool
 ir3_shader_key_equal(struct ir3_shader_key *a, struct ir3_shader_key *b)
 {
index 78bd62051f69ae33118bf440017fda4355b03961..39588ecb5046a1fd30d5d3ac1ba66422fbc913e4 100644 (file)
@@ -182,19 +182,7 @@ fd6_draw_vbo(struct fd_context *ctx, const struct pipe_draw_info *info,
                emit.key.ds = ctx->prog.ds;
 
                shader_info *ds_info = &emit.key.ds->nir->info;
-               switch (ds_info->tess.primitive_mode) {
-               case GL_ISOLINES:
-                       emit.key.key.tessellation = IR3_TESS_ISOLINES;
-                       break;
-               case GL_TRIANGLES:
-                       emit.key.key.tessellation = IR3_TESS_TRIANGLES;
-                       break;
-               case GL_QUADS:
-                       emit.key.key.tessellation = IR3_TESS_QUADS;
-                       break;
-               default:
-                       unreachable("bad tessmode");
-               }
+               emit.key.key.tessellation = ir3_tess_mode(ds_info->tess.primitive_mode);
        }
 
        if (emit.key.gs)
index 8d3928013633918a81d94a15c8b35bc9f0b955a3..f58e295b5a779933a97cbb36b613e6f5790f5f40 100644 (file)
@@ -141,7 +141,35 @@ ir3_shader_create(struct ir3_compiler *compiler,
                 * (as otherwise nothing will trigger the shader to be
                 * actually compiled)
                 */
-               static struct ir3_shader_key key; /* static is implicitly zeroed */
+               struct ir3_shader_key key = {
+                       .tessellation = IR3_TESS_NONE,
+               };
+
+               switch (nir->info.stage) {
+               case MESA_SHADER_TESS_EVAL:
+                       key.tessellation = ir3_tess_mode(nir->info.tess.primitive_mode);
+                       break;
+
+               case MESA_SHADER_TESS_CTRL:
+                       /* The primitive_mode field, while it exists for TCS, is not
+                        * populated (since separable shaders between TCS/TES are legal,
+                        * so TCS wouldn't have access to TES's declaration).  Make a
+                        * guess so that we shader-db something plausible for TCS.
+                        */
+                       if (nir->info.outputs_written & VARYING_BIT_TESS_LEVEL_INNER)
+                               key.tessellation = IR3_TESS_TRIANGLES;
+                       else
+                               key.tessellation = IR3_TESS_ISOLINES;
+                       break;
+
+               case MESA_SHADER_GEOMETRY:
+                       key.has_gs = true;
+                       break;
+
+               default:
+                       break;
+               }
+
                ir3_shader_variant(shader, key, false, debug);
 
                if (nir->info.stage == MESA_SHADER_VERTEX)