unsigned stages_present = prog->stages_present;
if (prog->shaders[MESA_SHADER_TESS_CTRL] && prog->shaders[MESA_SHADER_TESS_CTRL]->is_generated)
stages_present &= ~BITFIELD_BIT(MESA_SHADER_TESS_CTRL);
- struct hash_table *ht = &ctx->program_cache[zink_program_cache_stages(stages_present)];
+ unsigned idx = zink_program_cache_stages(stages_present);
+ struct hash_table *ht = &ctx->program_cache[idx];
+ simple_mtx_lock(&ctx->program_lock[idx]);
struct hash_entry *he = _mesa_hash_table_search(ht, prog->shaders);
assert(he);
_mesa_hash_table_remove(ht, he);
prog->base.removed = true;
+ simple_mtx_unlock(&ctx->program_lock[idx]);
}
if (stage != MESA_SHADER_TESS_CTRL || !shader->is_generated) {
prog->shaders[stage] = NULL;
}
for (unsigned i = 0; i < ARRAY_SIZE(ctx->program_cache); i++) {
+ simple_mtx_lock((&ctx->program_lock[i]));
hash_table_foreach(&ctx->program_cache[i], entry) {
struct zink_program *pg = entry->data;
pg->removed = true;
}
+ simple_mtx_unlock((&ctx->program_lock[i]));
}
if (ctx->blitter)
slab_destroy_child(&ctx->transfer_pool);
for (unsigned i = 0; i < ARRAY_SIZE(ctx->program_cache); i++)
_mesa_hash_table_clear(&ctx->program_cache[i], NULL);
+ for (unsigned i = 0; i < ARRAY_SIZE(ctx->program_lock); i++)
+ simple_mtx_destroy(&ctx->program_lock[i]);
_mesa_hash_table_destroy(ctx->render_pass_cache, NULL);
slab_destroy_child(&ctx->transfer_pool_unsync);
_mesa_hash_table_init(&ctx->program_cache[5], ctx, hash_gfx_program<5>, equals_gfx_program<5>);
_mesa_hash_table_init(&ctx->program_cache[6], ctx, hash_gfx_program<6>, equals_gfx_program<6>);
_mesa_hash_table_init(&ctx->program_cache[7], ctx, hash_gfx_program<7>, equals_gfx_program<7>);
+ for (unsigned i = 0; i < ARRAY_SIZE(ctx->program_lock); i++)
+ simple_mtx_init(&ctx->program_lock[i], mtx_plain);
}
void
if (ctx->gfx_dirty) {
struct zink_gfx_program *prog = NULL;
+ simple_mtx_lock(&ctx->program_lock[zink_program_cache_stages(ctx->shader_stages)]);
struct hash_table *ht = &ctx->program_cache[zink_program_cache_stages(ctx->shader_stages)];
const uint32_t hash = ctx->gfx_hash;
struct hash_entry *entry = _mesa_hash_table_search_pre_hashed(ht, hash, ctx->gfx_stages);
_mesa_hash_table_insert_pre_hashed(ht, hash, prog->shaders, prog);
generate_gfx_program_modules(ctx, zink_screen(ctx->base.screen), prog, &ctx->gfx_pipeline_state);
}
+ simple_mtx_unlock(&ctx->program_lock[zink_program_cache_stages(ctx->shader_stages)]);
if (prog && prog != ctx->curr_program)
zink_batch_reference_program(&ctx->batch, &prog->base);
if (ctx->curr_program)
* thus only 3 stages need to be considered, giving 2^3 = 8 program caches.
*/
struct hash_table program_cache[8];
+ simple_mtx_t program_lock[8];
uint32_t gfx_hash;
struct zink_gfx_program *curr_program;
struct set gfx_inputs;