Module: Mesa Branch: main Commit: 68b099b8eb034724c9305012c3935a602ed1d09a URL: http://cgit.freedesktop.org/mesa/mesa/commit/?id=68b099b8eb034724c9305012c3935a602ed1d09a
Author: Mike Blumenkrantz <[email protected]> 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 <[email protected]> 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; }
