Mesa (main): zink: handle shader key variants that have nonseamless cubemaps
GitLab Mirror
gitlab-mirror at kemper.freedesktop.org
Thu Apr 7 14:47:38 UTC 2022
Module: Mesa
Branch: main
Commit: 5b2d0cca1739d40973a3a177438d1f915631a425
URL: http://cgit.freedesktop.org/mesa/mesa/commit/?id=5b2d0cca1739d40973a3a177438d1f915631a425
Author: Mike Blumenkrantz <michael.blumenkrantz at gmail.com>
Date: Mon Mar 21 14:48:19 2022 -0400
zink: handle shader key variants that have nonseamless cubemaps
this is just the program-based handling, which means finding the right
variant and/or creating new ones based on matching a 32bit mask indicating
which textures must be rewritten
Reviewed-by: Erik Faye-Lund <erik.faye-lund at collabora.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/15536>
---
src/gallium/drivers/zink/zink_program.c | 90 +++++++++++++++++------------
src/gallium/drivers/zink/zink_program.h | 5 +-
src/gallium/drivers/zink/zink_shader_keys.h | 1 +
3 files changed, 56 insertions(+), 40 deletions(-)
diff --git a/src/gallium/drivers/zink/zink_program.c b/src/gallium/drivers/zink/zink_program.c
index a72c881d97c..95b0f39cba4 100644
--- a/src/gallium/drivers/zink/zink_program.c
+++ b/src/gallium/drivers/zink/zink_program.c
@@ -69,16 +69,20 @@ debug_describe_zink_compute_program(char *buf, const struct zink_compute_program
static bool
shader_key_matches(const struct zink_shader_module *zm, const struct zink_shader_key *key, unsigned num_uniforms)
{
- if (zm->key_size != key->size || zm->num_uniforms != num_uniforms)
+ if (zm->key_size != key->size || zm->num_uniforms != num_uniforms || zm->has_nonseamless != !!key->base.nonseamless_cube_mask)
return false;
+ const uint32_t nonseamless_size = zm->has_nonseamless ? sizeof(uint32_t) : 0;
return !memcmp(zm->key, key, zm->key_size) &&
- (!num_uniforms || !memcmp(zm->key + zm->key_size, key->base.inlined_uniform_values, zm->num_uniforms * sizeof(uint32_t)));
+ (!nonseamless_size || !memcmp(zm->key + zm->key_size, &key->base.nonseamless_cube_mask, nonseamless_size)) &&
+ (!num_uniforms || !memcmp(zm->key + zm->key_size + nonseamless_size,
+ key->base.inlined_uniform_values, zm->num_uniforms * sizeof(uint32_t)));
}
static uint32_t
shader_module_hash(const struct zink_shader_module *zm)
{
- unsigned key_size = zm->key_size + zm->num_uniforms * sizeof(uint32_t);
+ const uint32_t nonseamless_size = zm->has_nonseamless ? sizeof(uint32_t) : 0;
+ unsigned key_size = zm->key_size + nonseamless_size + zm->num_uniforms * sizeof(uint32_t);
return _mesa_hash_data(zm->key, key_size);
}
@@ -91,7 +95,7 @@ get_shader_module_for_stage(struct zink_context *ctx, struct zink_screen *screen
enum pipe_shader_type pstage = pipe_shader_type_from_mesa(stage);
VkShaderModule mod;
struct zink_shader_module *zm = NULL;
- unsigned inline_size = 0;
+ unsigned inline_size = 0, nonseamless_size = 0;
struct zink_shader_key *key = &state->shader_keys.key[pstage];
if (ctx && zs->nir->info.num_inlinable_uniforms &&
@@ -101,9 +105,11 @@ get_shader_module_for_stage(struct zink_context *ctx, struct zink_screen *screen
else
key->inline_uniforms = false;
}
+ if (key->base.nonseamless_cube_mask)
+ nonseamless_size = sizeof(uint32_t);
struct zink_shader_module *iter, *next;
- LIST_FOR_EACH_ENTRY_SAFE(iter, next, &prog->shader_cache[pstage][!!inline_size], list) {
+ LIST_FOR_EACH_ENTRY_SAFE(iter, next, &prog->shader_cache[pstage][!!nonseamless_size][!!inline_size], list) {
if (!shader_key_matches(iter, key, inline_size))
continue;
list_delinit(&iter->list);
@@ -112,7 +118,7 @@ get_shader_module_for_stage(struct zink_context *ctx, struct zink_screen *screen
}
if (!zm) {
- zm = malloc(sizeof(struct zink_shader_module) + key->size + inline_size * sizeof(uint32_t));
+ zm = malloc(sizeof(struct zink_shader_module) + key->size + nonseamless_size + inline_size * sizeof(uint32_t));
if (!zm) {
return NULL;
}
@@ -137,17 +143,22 @@ get_shader_module_for_stage(struct zink_context *ctx, struct zink_screen *screen
zm->key_size = 0;
memset(zm->key, 0, key->size);
}
+ if (nonseamless_size) {
+ /* nonseamless mask gets added to base key if it exists */
+ memcpy(zm->key + key->size, &key->base.nonseamless_cube_mask, nonseamless_size);
+ }
+ zm->has_nonseamless = !!nonseamless_size;
if (inline_size)
- memcpy(zm->key + key->size, key->base.inlined_uniform_values, inline_size * sizeof(uint32_t));
+ memcpy(zm->key + key->size + nonseamless_size, key->base.inlined_uniform_values, inline_size * sizeof(uint32_t));
if (zs->is_generated)
zm->hash = zink_get_tcs_key(ctx)->patch_vertices;
else
zm->hash = shader_module_hash(zm);
- zm->default_variant = !inline_size && list_is_empty(&prog->shader_cache[pstage][0]);
+ zm->default_variant = !inline_size && list_is_empty(&prog->shader_cache[pstage][0][0]);
if (inline_size)
prog->inlined_variant_count[pstage]++;
}
- list_add(&zm->list, &prog->shader_cache[pstage][!!inline_size]);
+ list_add(&zm->list, &prog->shader_cache[pstage][!!nonseamless_size][!!inline_size]);
return zm;
}
@@ -258,19 +269,6 @@ zink_update_gfx_program(struct zink_context *ctx, struct zink_gfx_program *prog)
update_gfx_shader_modules(ctx, zink_screen(ctx->base.screen), prog, ctx->dirty_shader_stages & prog->stages_present, &ctx->gfx_pipeline_state);
}
-static bool
-uniforms_match(const struct zink_shader_module *zm, uint32_t *uniforms, unsigned num_uniforms)
-{
- assert(zm->num_uniforms == num_uniforms);
- return !memcmp(zm->key, uniforms, zm->num_uniforms * sizeof(uint32_t));
-}
-
-static uint32_t
-cs_module_hash(const struct zink_shader_module *zm)
-{
- return _mesa_hash_data(zm->key, zm->num_uniforms * sizeof(uint32_t));
-}
-
static void
update_cs_shader_module(struct zink_context *ctx, struct zink_compute_program *comp)
{
@@ -278,7 +276,7 @@ update_cs_shader_module(struct zink_context *ctx, struct zink_compute_program *c
struct zink_shader *zs = comp->shader;
VkShaderModule mod;
struct zink_shader_module *zm = NULL;
- unsigned inline_size = 0;
+ unsigned inline_size = 0, nonseamless_size = 0;
struct zink_shader_key *key = &ctx->compute_pipeline_state.key;
if (ctx && zs->nir->info.num_inlinable_uniforms &&
@@ -288,11 +286,13 @@ update_cs_shader_module(struct zink_context *ctx, struct zink_compute_program *c
else
key->inline_uniforms = false;
}
+ if (key->base.nonseamless_cube_mask)
+ nonseamless_size = sizeof(uint32_t);
- if (inline_size) {
+ if (inline_size || nonseamless_size) {
struct zink_shader_module *iter, *next;
- LIST_FOR_EACH_ENTRY_SAFE(iter, next, &comp->shader_cache, list) {
- if (!uniforms_match(iter, key->base.inlined_uniform_values, inline_size))
+ LIST_FOR_EACH_ENTRY_SAFE(iter, next, &comp->shader_cache[!!nonseamless_size], list) {
+ if (!shader_key_matches(iter, key, inline_size))
continue;
list_delinit(&iter->list);
zm = iter;
@@ -303,7 +303,7 @@ update_cs_shader_module(struct zink_context *ctx, struct zink_compute_program *c
}
if (!zm) {
- zm = malloc(sizeof(struct zink_shader_module) + inline_size * sizeof(uint32_t));
+ zm = malloc(sizeof(struct zink_shader_module) + nonseamless_size + inline_size * sizeof(uint32_t));
if (!zm) {
return;
}
@@ -316,14 +316,19 @@ update_cs_shader_module(struct zink_context *ctx, struct zink_compute_program *c
list_inithead(&zm->list);
zm->num_uniforms = inline_size;
zm->key_size = 0;
- assert(inline_size);
- memcpy(zm->key, key->base.inlined_uniform_values, inline_size * sizeof(uint32_t));
- zm->hash = cs_module_hash(zm);
+ zm->has_nonseamless = !!nonseamless_size;
+ assert(nonseamless_size || inline_size);
+ if (nonseamless_size)
+ memcpy(zm->key, &key->base.nonseamless_cube_mask, nonseamless_size);
+ if (inline_size)
+ memcpy(zm->key + nonseamless_size, key->base.inlined_uniform_values, inline_size * sizeof(uint32_t));
+ zm->hash = shader_module_hash(zm);
zm->default_variant = false;
- comp->inlined_variant_count++;
+ if (inline_size)
+ comp->inlined_variant_count++;
}
- if (zm->num_uniforms)
- list_add(&zm->list, &comp->shader_cache);
+ if (zm->num_uniforms || nonseamless_size)
+ list_add(&zm->list, &comp->shader_cache[!!nonseamless_size]);
if (comp->curr == zm)
return;
ctx->compute_pipeline_state.final_hash ^= ctx->compute_pipeline_state.module_hash;
@@ -417,8 +422,10 @@ zink_create_gfx_program(struct zink_context *ctx,
pipe_reference_init(&prog->base.reference, 1);
for (int i = 0; i < ZINK_SHADER_COUNT; ++i) {
- list_inithead(&prog->shader_cache[i][0]);
- list_inithead(&prog->shader_cache[i][1]);
+ list_inithead(&prog->shader_cache[i][0][0]);
+ list_inithead(&prog->shader_cache[i][0][1]);
+ list_inithead(&prog->shader_cache[i][1][0]);
+ list_inithead(&prog->shader_cache[i][1][1]);
if (stages[i]) {
prog->shaders[i] = stages[i];
prog->stages_present |= BITFIELD_BIT(i);
@@ -530,7 +537,8 @@ zink_create_compute_program(struct zink_context *ctx, struct zink_shader *shader
assert(comp->module);
comp->module->shader = zink_shader_compile(screen, shader, shader->nir, NULL);
assert(comp->module->shader);
- list_inithead(&comp->shader_cache);
+ list_inithead(&comp->shader_cache[0]);
+ list_inithead(&comp->shader_cache[1]);
comp->pipelines = _mesa_hash_table_create(NULL, NULL,
equals_compute_pipeline_state);
@@ -666,8 +674,10 @@ zink_destroy_gfx_program(struct zink_context *ctx,
_mesa_set_remove_key(prog->shaders[i]->programs, prog);
prog->shaders[i] = NULL;
}
- destroy_shader_cache(screen, &prog->shader_cache[i][0]);
- destroy_shader_cache(screen, &prog->shader_cache[i][1]);
+ destroy_shader_cache(screen, &prog->shader_cache[i][0][0]);
+ destroy_shader_cache(screen, &prog->shader_cache[i][0][1]);
+ destroy_shader_cache(screen, &prog->shader_cache[i][1][0]);
+ destroy_shader_cache(screen, &prog->shader_cache[i][1][1]);
ralloc_free(prog->nir[i]);
}
@@ -709,6 +719,8 @@ zink_destroy_compute_program(struct zink_context *ctx,
if (comp->shader)
_mesa_set_remove_key(comp->shader->programs, comp);
+ destroy_shader_cache(screen, &comp->shader_cache[0]);
+ destroy_shader_cache(screen, &comp->shader_cache[1]);
hash_table_foreach(comp->pipelines, entry) {
struct compute_pipeline_cache_entry *pc_entry = entry->data;
@@ -899,6 +911,8 @@ bind_stage(struct zink_context *ctx, enum pipe_shader_type stage,
ctx->compute_pipeline_state.module_hash = ctx->curr_compute->curr->hash;
ctx->compute_pipeline_state.module = ctx->curr_compute->curr->shader;
ctx->compute_pipeline_state.final_hash ^= ctx->compute_pipeline_state.module_hash;
+ if (ctx->compute_pipeline_state.key.base.nonseamless_cube_mask)
+ ctx->dirty_shader_stages |= BITFIELD_BIT(PIPE_SHADER_COMPUTE);
} else if (!shader)
ctx->curr_compute = NULL;
ctx->compute_stage = shader;
diff --git a/src/gallium/drivers/zink/zink_program.h b/src/gallium/drivers/zink/zink_program.h
index 20b99c0e691..775919af331 100644
--- a/src/gallium/drivers/zink/zink_program.h
+++ b/src/gallium/drivers/zink/zink_program.h
@@ -68,6 +68,7 @@ struct zink_shader_module {
VkShaderModule shader;
uint32_t hash;
bool default_variant;
+ bool has_nonseamless;
uint8_t num_uniforms;
uint8_t key_size;
uint8_t key[0]; /* | key | uniforms | */
@@ -104,7 +105,7 @@ struct zink_gfx_program {
struct zink_shader *last_vertex_stage;
- struct list_head shader_cache[ZINK_SHADER_COUNT][2]; //normal, inline uniforms
+ struct list_head shader_cache[ZINK_SHADER_COUNT][2][2]; //normal, nonseamless cubes, inline uniforms
unsigned inlined_variant_count[ZINK_SHADER_COUNT];
struct zink_shader *shaders[ZINK_SHADER_COUNT];
@@ -119,7 +120,7 @@ struct zink_compute_program {
struct zink_shader_module *curr;
struct zink_shader_module *module; //base
- struct list_head shader_cache; //inline uniforms
+ struct list_head shader_cache[2]; //nonseamless cubes, inline uniforms
unsigned inlined_variant_count;
struct zink_shader *shader;
diff --git a/src/gallium/drivers/zink/zink_shader_keys.h b/src/gallium/drivers/zink/zink_shader_keys.h
index 0857d63b734..531a729416a 100644
--- a/src/gallium/drivers/zink/zink_shader_keys.h
+++ b/src/gallium/drivers/zink/zink_shader_keys.h
@@ -68,6 +68,7 @@ struct zink_tcs_key {
};
struct zink_shader_key_base {
+ uint32_t nonseamless_cube_mask;
uint32_t inlined_uniform_values[MAX_INLINABLE_UNIFORMS];
};
More information about the mesa-commit
mailing list