Mesa (main): zink: implement generated tcs variants using spirv shortcut

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Fri Feb 11 01:41:37 UTC 2022


Module: Mesa
Branch: main
Commit: 68b099b8eb034724c9305012c3935a602ed1d09a
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=68b099b8eb034724c9305012c3935a602ed1d09a

Author: Mike Blumenkrantz <michael.blumenkrantz at gmail.com>
Date:   Wed Feb  9 10:37:17 2022 -0500

zink: implement generated tcs variants using spirv shortcut

this codepath needs to update literally one spirv word to get the right shader
(why can't this be a spec constant?)
so just update that word instead of running all the nir passes and doing a
full recompile

fixes:
KHR-GL46.tessellation_shader.tessellation_control_to_tessellation_evaluation.gl_MaxPatchVertices_Position_PointSize
KHR-GL46.tessellation_shader.tessellation_control_to_tessellation_evaluation.gl_PatchVerticesIn

Reviewed-by: Dave Airlie <airlied at redhat.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/14976>

---

 src/gallium/drivers/zink/zink_compiler.c | 12 ++++++++++++
 src/gallium/drivers/zink/zink_compiler.h |  2 ++
 src/gallium/drivers/zink/zink_draw.cpp   |  3 ++-
 src/gallium/drivers/zink/zink_program.c  | 21 +++++++++++++++++----
 src/gallium/drivers/zink/zink_program.h  |  1 +
 5 files changed, 34 insertions(+), 5 deletions(-)

diff --git a/src/gallium/drivers/zink/zink_compiler.c b/src/gallium/drivers/zink/zink_compiler.c
index 1a35bab24a1..18266e1a81c 100644
--- a/src/gallium/drivers/zink/zink_compiler.c
+++ b/src/gallium/drivers/zink/zink_compiler.c
@@ -1026,6 +1026,9 @@ zink_shader_spirv_compile(struct zink_screen *screen, struct zink_shader *zs, st
    VkShaderModule mod;
    VkShaderModuleCreateInfo smci = {0};
 
+   if (!spirv)
+      spirv = zs->spirv;
+
    if (zink_debug & ZINK_DEBUG_SPIRV) {
       char buf[256];
       static int i;
@@ -1969,6 +1972,15 @@ zink_shader_free(struct zink_context *ctx, struct zink_shader *shader)
 }
 
 
+VkShaderModule
+zink_shader_tcs_compile(struct zink_screen *screen, struct zink_shader *zs, unsigned patch_vertices)
+{
+   assert(zs->nir->info.stage == MESA_SHADER_TESS_CTRL);
+   /* shortcut all the nir passes since we just have to change this one word */
+   zs->spirv->words[zs->spirv->tcs_vertices_out_word] = patch_vertices;
+   return zink_shader_spirv_compile(screen, zs, NULL);
+}
+
 /* creating a passthrough tcs shader that's roughly:
 
 #version 150
diff --git a/src/gallium/drivers/zink/zink_compiler.h b/src/gallium/drivers/zink/zink_compiler.h
index 71dd2cb7926..935997df90e 100644
--- a/src/gallium/drivers/zink/zink_compiler.h
+++ b/src/gallium/drivers/zink/zink_compiler.h
@@ -118,6 +118,8 @@ zink_shader_finalize(struct pipe_screen *pscreen, void *nirptr);
 void
 zink_shader_free(struct zink_context *ctx, struct zink_shader *shader);
 
+VkShaderModule
+zink_shader_tcs_compile(struct zink_screen *screen, struct zink_shader *zs, unsigned patch_vertices);
 struct zink_shader *
 zink_shader_tcs_create(struct zink_screen *screen, struct zink_shader *vs, unsigned vertices_per_patch);
 
diff --git a/src/gallium/drivers/zink/zink_draw.cpp b/src/gallium/drivers/zink/zink_draw.cpp
index 98e0b700fbc..5d606154a03 100644
--- a/src/gallium/drivers/zink/zink_draw.cpp
+++ b/src/gallium/drivers/zink/zink_draw.cpp
@@ -794,10 +794,11 @@ zink_draw(struct pipe_context *pctx,
                          offsetof(struct zink_gfx_push_constant, draw_mode_is_indexed), sizeof(unsigned),
                          &draw_mode_is_indexed);
    }
-   if (ctx->curr_program->shaders[PIPE_SHADER_TESS_CTRL] && ctx->curr_program->shaders[PIPE_SHADER_TESS_CTRL]->is_generated)
+   if (ctx->curr_program->shaders[PIPE_SHADER_TESS_CTRL] && ctx->curr_program->shaders[PIPE_SHADER_TESS_CTRL]->is_generated) {
       VKCTX(CmdPushConstants)(batch->state->cmdbuf, ctx->curr_program->base.layout, VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT,
                          offsetof(struct zink_gfx_push_constant, default_inner_level), sizeof(float) * 6,
                          &ctx->tess_levels[0]);
+   }
 
    if (have_streamout) {
       for (unsigned i = 0; i < ctx->num_so_targets; i++) {
diff --git a/src/gallium/drivers/zink/zink_program.c b/src/gallium/drivers/zink/zink_program.c
index c06a1e3bea8..79d6be19e4a 100644
--- a/src/gallium/drivers/zink/zink_program.c
+++ b/src/gallium/drivers/zink/zink_program.c
@@ -116,7 +116,12 @@ get_shader_module_for_stage(struct zink_context *ctx, struct zink_screen *screen
       if (!zm) {
          return NULL;
       }
-      mod = zink_shader_compile(screen, zs, prog->nir[stage], key);
+      if (zs->is_generated && zs->spirv) {
+         assert(ctx); //TODO async
+         mod = zink_shader_tcs_compile(screen, zs, zink_get_tcs_key(ctx)->patch_vertices);
+      } else {
+         mod = zink_shader_compile(screen, zs, prog->nir[stage], key);
+      }
       if (!mod) {
          FREE(zm);
          return NULL;
@@ -124,11 +129,19 @@ get_shader_module_for_stage(struct zink_context *ctx, struct zink_screen *screen
       zm->shader = mod;
       list_inithead(&zm->list);
       zm->num_uniforms = base_size;
-      zm->key_size = key->size;
-      memcpy(zm->key, key, key->size);
+      if (pstage != PIPE_SHADER_TESS_CTRL || zs->is_generated) {
+         /* non-generated tcs won't use the shader key */
+         zm->key_size = key->size;
+         memcpy(zm->key, key, key->size);
+      } else {
+         memset(zm->key, 0, key->size);
+      }
       if (base_size)
          memcpy(zm->key + key->size, &key->base, base_size * sizeof(uint32_t));
-      zm->hash = shader_module_hash(zm);
+      if (zs->is_generated)
+         zm->hash = zink_get_tcs_key(ctx)->patch_vertices;
+      else
+         zm->hash = shader_module_hash(zm);
       zm->default_variant = !base_size && list_is_empty(&prog->shader_cache[pstage][0]);
       if (base_size)
          prog->inlined_variant_count[pstage]++;
diff --git a/src/gallium/drivers/zink/zink_program.h b/src/gallium/drivers/zink/zink_program.h
index 2d186f84ccb..17a12ff89f5 100644
--- a/src/gallium/drivers/zink/zink_program.h
+++ b/src/gallium/drivers/zink/zink_program.h
@@ -309,6 +309,7 @@ zink_set_tcs_key_patches(struct zink_context *ctx, uint8_t patch_vertices)
    struct zink_tcs_key *tcs = (struct zink_tcs_key*)&ctx->gfx_pipeline_state.shader_keys.key[PIPE_SHADER_TESS_CTRL];
    if (tcs->patch_vertices == patch_vertices)
       return false;
+   ctx->dirty_shader_stages |= BITFIELD_BIT(PIPE_SHADER_TESS_CTRL);
    tcs->patch_vertices = patch_vertices;
    return true;
 }



More information about the mesa-commit mailing list