From 770debce96ed91a0a25e180c7b75e9ec4b551af3 Mon Sep 17 00:00:00 2001 From: Mike Blumenkrantz Date: Thu, 4 Sep 2025 16:42:36 -0400 Subject: [PATCH] zink: add another flag to determine whether linked program compile is done it's otherwise possible for this to race and hit the draw before precompile finishes without ever waiting on the fence I guess this just worked coincidentally before? cc: mesa-stable Part-of: (cherry picked from commit 6596bf69c636ccf6c3abee1ef8f2e266c8007718) --- .pick_status.json | 2 +- src/gallium/drivers/zink/zink_program.c | 17 +++++++++++++---- src/gallium/drivers/zink/zink_types.h | 1 + 3 files changed, 15 insertions(+), 5 deletions(-) diff --git a/.pick_status.json b/.pick_status.json index d1eb12bc009..bda64282ee1 100644 --- a/.pick_status.json +++ b/.pick_status.json @@ -8534,7 +8534,7 @@ "description": "zink: add another flag to determine whether linked program compile is done", "nominated": true, "nomination_type": 1, - "resolution": 0, + "resolution": 1, "main_sha": null, "because_sha": null, "notes": null diff --git a/src/gallium/drivers/zink/zink_program.c b/src/gallium/drivers/zink/zink_program.c index 357dbfd9967..f78e0bd9b2c 100644 --- a/src/gallium/drivers/zink/zink_program.c +++ b/src/gallium/drivers/zink/zink_program.c @@ -751,6 +751,8 @@ zink_gfx_program_update_optimal(struct zink_context *ctx) real->base.removed = false; prog->base.removed = true; prog = real; + } else if (!prog->base.precompile_done) { + util_queue_fence_wait(&prog->base.cache_fence); } update_gfx_program_optimal(ctx, prog); } else { @@ -1000,6 +1002,7 @@ create_program(struct zink_context *ctx, bool is_compute) u_rwlock_init(&pg->pipeline_cache_lock); util_queue_fence_init(&pg->cache_fence); pg->is_compute = is_compute; + pg->precompile_done = true; pg->ctx = ctx; return (void*)pg; } @@ -1513,6 +1516,7 @@ precompile_compute_job(void *data, void *gdata, int thread_index) zink_screen_get_pipeline_cache(screen, &comp->base, true); if (comp->base.can_precompile) comp->base_pipeline = zink_create_compute_pipeline(screen, comp, NULL); + comp->base.precompile_done = true; if (comp->base_pipeline) zink_screen_update_pipeline_cache(screen, &comp->base, true); } @@ -1540,11 +1544,13 @@ create_compute_program(struct zink_context *ctx, nir_shader *nir) equals_compute_pipeline_state_local_size : equals_compute_pipeline_state); - if (zink_debug & (ZINK_DEBUG_NOBGC|ZINK_DEBUG_SHADERDB)) + if (zink_debug & (ZINK_DEBUG_NOBGC|ZINK_DEBUG_SHADERDB)) { precompile_compute_job(comp, screen, 0); - else + } else { + comp->base.precompile_done = false; util_queue_add_job(&screen->cache_get_thread, comp, &comp->base.cache_fence, precompile_compute_job, NULL, 0); + } if (zink_debug & ZINK_DEBUG_SHADERDB) { print_pipeline_stats(screen, comp->base_pipeline, &ctx->dbg); @@ -2194,6 +2200,7 @@ gfx_program_precompile_job(void *data, void *gdata, int thread_index) zink_create_pipeline_lib(screen, prog, &state); simple_mtx_unlock(&prog->libs->lock); } + prog->base.precompile_done = true; zink_screen_update_pipeline_cache(screen, &prog->base, true); } @@ -2253,10 +2260,12 @@ zink_link_gfx_shader(struct pipe_context *pctx, void **shaders) } else { if (zink_screen(pctx->screen)->info.have_EXT_shader_object) prog->base.uses_shobj = !zshaders[MESA_SHADER_VERTEX]->info.view_mask && !BITSET_TEST(zshaders[MESA_SHADER_FRAGMENT]->info.system_values_read, SYSTEM_VALUE_SAMPLE_MASK_IN); - if (zink_debug & ZINK_DEBUG_NOBGC) + if (zink_debug & ZINK_DEBUG_NOBGC) { gfx_program_precompile_job(prog, pctx->screen, 0); - else + } else { + prog->base.precompile_done = false; util_queue_add_job(&zink_screen(pctx->screen)->cache_get_thread, prog, &prog->base.cache_fence, gfx_program_precompile_job, NULL, 0); + } } } diff --git a/src/gallium/drivers/zink/zink_types.h b/src/gallium/drivers/zink/zink_types.h index cfa4556ec61..b1aaf158f91 100644 --- a/src/gallium/drivers/zink/zink_types.h +++ b/src/gallium/drivers/zink/zink_types.h @@ -1011,6 +1011,7 @@ struct zink_program { bool is_compute; bool can_precompile; bool uses_shobj; //whether shader objects are used; programs CANNOT mix shader objects and shader modules + bool precompile_done; struct zink_program_descriptor_data dd;