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