diff --git a/src/gallium/drivers/zink/zink_draw.c b/src/gallium/drivers/zink/zink_draw.c index 3daafcf9833..d4153a44b1c 100644 --- a/src/gallium/drivers/zink/zink_draw.c +++ b/src/gallium/drivers/zink/zink_draw.c @@ -164,7 +164,9 @@ get_gfx_program(struct zink_context *ctx) if (ctx->dirty_shader_stages) { struct hash_entry *entry = _mesa_hash_table_search(ctx->program_cache, ctx->gfx_stages); - if (!entry) { + if (entry) + zink_update_gfx_program(ctx, entry->data); + else { struct zink_gfx_program *prog; prog = zink_create_gfx_program(ctx, ctx->gfx_stages); entry = _mesa_hash_table_insert(ctx->program_cache, prog->shaders, prog); diff --git a/src/gallium/drivers/zink/zink_program.c b/src/gallium/drivers/zink/zink_program.c index ebe0c1ab7ad..a4f1c3ac4d9 100644 --- a/src/gallium/drivers/zink/zink_program.c +++ b/src/gallium/drivers/zink/zink_program.c @@ -287,7 +287,7 @@ zink_shader_cache_reference(struct zink_screen *screen, } static void -update_shader_modules(struct zink_context *ctx, struct zink_shader *stages[ZINK_SHADER_COUNT], struct zink_gfx_program *prog) +update_shader_modules(struct zink_context *ctx, struct zink_shader *stages[ZINK_SHADER_COUNT], struct zink_gfx_program *prog, bool update) { struct zink_shader *dirty[ZINK_SHADER_COUNT] = {NULL}; @@ -307,7 +307,7 @@ update_shader_modules(struct zink_context *ctx, struct zink_shader *stages[ZINK_ dirty[i]->has_geometry_shader = dirty[MESA_SHADER_GEOMETRY] || stages[PIPE_SHADER_GEOMETRY]; zm = get_shader_module_for_stage(ctx, dirty[i], prog); zink_shader_module_reference(zink_screen(ctx->base.screen), &prog->modules[type], zm); - } else if (stages[type]) /* reuse existing shader module */ + } else if (stages[type] && !update) /* reuse existing shader module */ zink_shader_module_reference(zink_screen(ctx->base.screen), &prog->modules[type], ctx->curr_program->modules[type]); prog->shaders[type] = stages[type]; } @@ -330,7 +330,6 @@ static void init_slot_map(struct zink_context *ctx, struct zink_gfx_program *prog) { unsigned existing_shaders = 0; - /* if there's a case where we'll be reusing any shaders, we need to reuse the slot map too */ if (ctx->curr_program) { for (int i = 0; i < ZINK_SHADER_COUNT; ++i) { @@ -357,6 +356,12 @@ init_slot_map(struct zink_context *ctx, struct zink_gfx_program *prog) } } +void +zink_update_gfx_program(struct zink_context *ctx, struct zink_gfx_program *prog) +{ + update_shader_modules(ctx, ctx->gfx_stages, prog, true); +} + struct zink_gfx_program * zink_create_gfx_program(struct zink_context *ctx, struct zink_shader *stages[ZINK_SHADER_COUNT]) @@ -370,7 +375,7 @@ zink_create_gfx_program(struct zink_context *ctx, init_slot_map(ctx, prog); - update_shader_modules(ctx, stages, prog); + update_shader_modules(ctx, stages, prog, false); for (int i = 0; i < ARRAY_SIZE(prog->pipelines); ++i) { prog->pipelines[i] = _mesa_hash_table_create(NULL, diff --git a/src/gallium/drivers/zink/zink_program.h b/src/gallium/drivers/zink/zink_program.h index 760144787ef..bab2a2419c2 100644 --- a/src/gallium/drivers/zink/zink_program.h +++ b/src/gallium/drivers/zink/zink_program.h @@ -70,6 +70,10 @@ struct zink_gfx_program { struct set *render_passes; }; + +void +zink_update_gfx_program(struct zink_context *ctx, struct zink_gfx_program *prog); + struct zink_gfx_program * zink_create_gfx_program(struct zink_context *ctx, struct zink_shader *stages[ZINK_SHADER_COUNT]);