zink: break out zink_gfx_program::libs into refcounted object

no functional changes yet, and these are still 1:1 with their programs

Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/21223>
This commit is contained in:
Mike Blumenkrantz 2023-02-09 12:16:12 -05:00 committed by Marge Bot
parent 6482cf12ca
commit b282761839
4 changed files with 51 additions and 16 deletions

View file

@ -930,6 +930,33 @@ assign_io(struct zink_screen *screen,
}
}
void
zink_gfx_lib_cache_unref(struct zink_screen *screen, struct zink_gfx_lib_cache *libs)
{
if (!p_atomic_dec_zero(&libs->refcount))
return;
simple_mtx_destroy(&libs->lock);
set_foreach_remove(&libs->libs, he) {
struct zink_gfx_library_key *gkey = (void*)he->key;
VKSCR(DestroyPipeline)(screen->dev, gkey->pipeline, NULL);
FREE(gkey);
}
ralloc_free(libs);
}
static struct zink_gfx_lib_cache *
create_lib_cache(struct zink_gfx_program *prog, bool generated_tcs)
{
struct zink_gfx_lib_cache *libs = rzalloc(NULL, struct zink_gfx_lib_cache);
simple_mtx_init(&libs->lock, mtx_plain);
if (generated_tcs)
_mesa_set_init(&libs->libs, libs, hash_pipeline_lib_generated_tcs, equals_pipeline_lib_generated_tcs);
else
_mesa_set_init(&libs->libs, libs, hash_pipeline_lib, equals_pipeline_lib);
return libs;
}
struct zink_gfx_program *
zink_create_gfx_program(struct zink_context *ctx,
struct zink_shader **stages,
@ -983,10 +1010,8 @@ zink_create_gfx_program(struct zink_context *ctx,
}
}
if (generated_tcs)
_mesa_set_init(&prog->libs, prog, hash_pipeline_lib_generated_tcs, equals_pipeline_lib_generated_tcs);
else
_mesa_set_init(&prog->libs, prog, hash_pipeline_lib, equals_pipeline_lib);
prog->libs = create_lib_cache(prog, generated_tcs);
p_atomic_set(&prog->libs, 1);
struct mesa_sha1 sctx;
_mesa_sha1_init(&sctx);
@ -1051,7 +1076,8 @@ create_gfx_program_separable(struct zink_context *ctx, struct zink_shader **stag
prog->stages_remaining = prog->stages_present = shader_stages;
prog->shaders[MESA_SHADER_FRAGMENT] = stages[MESA_SHADER_FRAGMENT];
prog->last_vertex_stage = stages[MESA_SHADER_VERTEX];
_mesa_set_init(&prog->libs, prog, hash_pipeline_lib, equals_pipeline_lib);
prog->libs = create_lib_cache(prog, false);
p_atomic_set(&prog->libs->refcount, 1);
unsigned refs = 0;
for (int i = 0; i < ZINK_GFX_SHADER_COUNT; ++i) {
@ -1108,7 +1134,7 @@ create_gfx_program_separable(struct zink_context *ctx, struct zink_shader **stag
gkey->optimal_key = prog->last_variant_hash;
assert(gkey->optimal_key);
gkey->pipeline = zink_create_gfx_pipeline_combined(screen, prog, VK_NULL_HANDLE, libs, 2, VK_NULL_HANDLE, false);
_mesa_set_add(&prog->libs, gkey);
_mesa_set_add(&prog->libs->libs, gkey);
util_queue_add_job(&screen->cache_get_thread, prog, &prog->base.cache_fence, create_linked_separable_job, NULL, 0);
@ -1383,11 +1409,7 @@ zink_destroy_gfx_program(struct zink_screen *screen,
ralloc_free(prog->nir[i]);
}
}
set_foreach_remove(&prog->libs, he) {
struct zink_gfx_library_key *gkey = (void*)he->key;
VKSCR(DestroyPipeline)(screen->dev, gkey->pipeline, NULL);
}
zink_gfx_lib_cache_unref(screen, prog->libs);
ralloc_free(prog);
}
@ -1806,15 +1828,16 @@ zink_create_cached_shader_state(struct pipe_context *pctx, const struct pipe_sha
return util_live_shader_cache_get(pctx, &screen->shaders, shader, &cache_hit);
}
/* caller must lock prog->libs->lock */
struct zink_gfx_library_key *
zink_create_pipeline_lib(struct zink_screen *screen, struct zink_gfx_program *prog, struct zink_gfx_pipeline_state *state)
{
struct zink_gfx_library_key *gkey = rzalloc(prog, struct zink_gfx_library_key);
struct zink_gfx_library_key *gkey = CALLOC_STRUCT(zink_gfx_library_key);
gkey->optimal_key = state->optimal_key;
assert(gkey->optimal_key);
memcpy(gkey->modules, prog->modules, sizeof(gkey->modules));
gkey->pipeline = zink_create_gfx_pipeline_library(screen, prog);
_mesa_set_add(&prog->libs, gkey);
_mesa_set_add(&prog->libs->libs, gkey);
return gkey;
}
@ -1911,7 +1934,9 @@ precompile_job(void *data, void *gdata, int thread_index)
state.optimal_key = state.shader_keys_optimal.key.val;
generate_gfx_program_modules_optimal(NULL, screen, prog, &state);
zink_screen_get_pipeline_cache(screen, &prog->base, true);
simple_mtx_lock(&prog->libs->lock);
zink_create_pipeline_lib(screen, prog, &state);
simple_mtx_unlock(&prog->libs->lock);
zink_screen_update_pipeline_cache(screen, &prog->base, true);
}

View file

@ -155,7 +155,8 @@ zink_create_gfx_program(struct zink_context *ctx,
void
zink_destroy_gfx_program(struct zink_screen *screen,
struct zink_gfx_program *prog);
void
zink_gfx_lib_cache_unref(struct zink_screen *screen, struct zink_gfx_lib_cache *libs);
void
zink_program_init(struct zink_context *ctx);

View file

@ -188,7 +188,8 @@ zink_get_gfx_pipeline(struct zink_context *ctx,
entry = _mesa_hash_table_insert_pre_hashed(&prog->pipelines[rp_idx][idx], state->final_hash, pc_entry, pc_entry);
if (HAVE_LIB && zink_can_use_pipeline_libs(ctx)) {
/* this is the graphics pipeline library path: find/construct all partial pipelines */
struct set_entry *he = _mesa_set_search(&prog->libs, &ctx->gfx_pipeline_state.optimal_key);
simple_mtx_lock(&prog->libs->lock);
struct set_entry *he = _mesa_set_search(&prog->libs->libs, &ctx->gfx_pipeline_state.optimal_key);
struct zink_gfx_library_key *gkey;
if (he) {
gkey = (struct zink_gfx_library_key *)he->key;
@ -196,6 +197,7 @@ zink_get_gfx_pipeline(struct zink_context *ctx,
assert(!prog->is_separable);
gkey = zink_create_pipeline_lib(screen, prog, &ctx->gfx_pipeline_state);
}
simple_mtx_unlock(&prog->libs->lock);
struct zink_gfx_input_key *ikey = DYNAMIC_STATE == ZINK_DYNAMIC_VERTEX_INPUT ?
zink_find_or_create_input_dynamic(ctx, vkmode) :
zink_find_or_create_input(ctx, vkmode);

View file

@ -983,6 +983,13 @@ struct zink_gfx_pipeline_cache_entry {
VkPipeline unoptimized_pipeline;
};
struct zink_gfx_lib_cache {
unsigned refcount;
simple_mtx_t lock;
struct set libs; //zink_gfx_library_key -> VkPipeline
};
struct zink_gfx_program {
struct zink_program base;
@ -1014,7 +1021,7 @@ struct zink_gfx_program {
uint32_t last_finalized_hash[2][4]; //[dynamic, renderpass][primtype idx]
VkPipeline last_pipeline[2][4]; //[dynamic, renderpass][primtype idx]
struct set libs; //zink_gfx_library_key -> VkPipeline
struct zink_gfx_lib_cache *libs;
};
struct zink_compute_program {