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@collabora.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/15536>
This commit is contained in:
parent
a06b0e0d21
commit
5b2d0cca17
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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];
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in New Issue