From 05be0659fe33727d2bd26b68994fdff4cad006dd Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Wed, 15 Apr 2020 14:21:07 -0700 Subject: [PATCH] freedreno: Fix assertion failures on GS/tess shaders with shader-db enabled. 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: --- src/freedreno/ir3/ir3_shader.h | 15 ++++++++++ src/gallium/drivers/freedreno/a6xx/fd6_draw.c | 14 +-------- .../drivers/freedreno/ir3/ir3_gallium.c | 30 ++++++++++++++++++- 3 files changed, 45 insertions(+), 14 deletions(-) diff --git a/src/freedreno/ir3/ir3_shader.h b/src/freedreno/ir3/ir3_shader.h index 2a9d7962248..0896bd1b185 100644 --- a/src/freedreno/ir3/ir3_shader.h +++ b/src/freedreno/ir3/ir3_shader.h @@ -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) { diff --git a/src/gallium/drivers/freedreno/a6xx/fd6_draw.c b/src/gallium/drivers/freedreno/a6xx/fd6_draw.c index 78bd62051f6..39588ecb504 100644 --- a/src/gallium/drivers/freedreno/a6xx/fd6_draw.c +++ b/src/gallium/drivers/freedreno/a6xx/fd6_draw.c @@ -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) diff --git a/src/gallium/drivers/freedreno/ir3/ir3_gallium.c b/src/gallium/drivers/freedreno/ir3/ir3_gallium.c index 8d392801363..f58e295b5a7 100644 --- a/src/gallium/drivers/freedreno/ir3/ir3_gallium.c +++ b/src/gallium/drivers/freedreno/ir3/ir3_gallium.c @@ -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) -- 2.30.2