diff --git a/src/gallium/drivers/zink/zink_program.c b/src/gallium/drivers/zink/zink_program.c index 44abd6cbae0..a6c2549c5a7 100644 --- a/src/gallium/drivers/zink/zink_program.c +++ b/src/gallium/drivers/zink/zink_program.c @@ -714,7 +714,7 @@ zink_gfx_program_update_optimal(struct zink_context *ctx) struct zink_screen *screen = zink_screen(ctx->base.screen); if (ctx->gfx_dirty) { struct zink_gfx_program *prog = NULL; - ctx->gfx_pipeline_state.optimal_key = ctx->gfx_pipeline_state.shader_keys_optimal.key.val; + ctx->gfx_pipeline_state.optimal_key = zink_sanitize_optimal_key(ctx->gfx_stages, ctx->gfx_pipeline_state.shader_keys_optimal.key.val); struct hash_table *ht = &ctx->program_cache[zink_program_cache_stages(ctx->shader_stages)]; const uint32_t hash = ctx->gfx_hash; simple_mtx_lock(&ctx->program_lock[zink_program_cache_stages(ctx->shader_stages)]); @@ -752,7 +752,7 @@ zink_gfx_program_update_optimal(struct zink_context *ctx) ctx->gfx_pipeline_state.final_hash ^= ctx->curr_program->last_variant_hash; } else if (ctx->dirty_gfx_stages) { /* remove old hash */ - ctx->gfx_pipeline_state.optimal_key = ctx->gfx_pipeline_state.shader_keys_optimal.key.val; + ctx->gfx_pipeline_state.optimal_key = zink_sanitize_optimal_key(ctx->gfx_stages, ctx->gfx_pipeline_state.shader_keys_optimal.key.val); ctx->gfx_pipeline_state.final_hash ^= ctx->curr_program->last_variant_hash; if (ctx->curr_program->is_separable && !(zink_debug & ZINK_DEBUG_NOOPT)) { struct zink_gfx_program *prog = ctx->curr_program; diff --git a/src/gallium/drivers/zink/zink_program.h b/src/gallium/drivers/zink/zink_program.h index b8142cce066..8df5e3388ab 100644 --- a/src/gallium/drivers/zink/zink_program.h +++ b/src/gallium/drivers/zink/zink_program.h @@ -428,6 +428,21 @@ zink_driver_thread_add_job(struct pipe_screen *pscreen, void *data, const size_t job_size); equals_gfx_pipeline_state_func zink_get_gfx_pipeline_eq_func(struct zink_screen *screen, struct zink_gfx_program *prog); + +static inline uint32_t +zink_sanitize_optimal_key(struct zink_shader **shaders, uint32_t val) +{ + union zink_shader_key_optimal k; + if (shaders[MESA_SHADER_TESS_EVAL] && !shaders[MESA_SHADER_TESS_CTRL]) + k.val = val; + else + k.val = zink_shader_key_optimal_no_tcs(val); + if (!(shaders[MESA_SHADER_FRAGMENT]->info.outputs_written & BITFIELD64_BIT(FRAG_RESULT_SAMPLE_MASK))) + k.fs.samples = false; + if (!(shaders[MESA_SHADER_FRAGMENT]->info.outputs_written & BITFIELD64_BIT(FRAG_RESULT_DATA1))) + k.fs.force_dual_color_blend = false; + return k.val; +} #ifdef __cplusplus } #endif diff --git a/src/gallium/drivers/zink/zink_program_state.hpp b/src/gallium/drivers/zink/zink_program_state.hpp index 0c6c85a95a4..bdf3a872a89 100644 --- a/src/gallium/drivers/zink/zink_program_state.hpp +++ b/src/gallium/drivers/zink/zink_program_state.hpp @@ -128,8 +128,9 @@ zink_get_gfx_pipeline(struct zink_context *ctx, /* extra safety asserts for optimal path to catch refactoring bugs */ if (prog->optimal_keys) { ASSERTED const union zink_shader_key_optimal *opt = (union zink_shader_key_optimal*)&prog->last_variant_hash; - assert(opt->val == state->shader_keys_optimal.key.val); - assert(state->optimal_key == state->shader_keys_optimal.key.val); + ASSERTED uint32_t sanitized = zink_sanitize_optimal_key(ctx->gfx_stages, ctx->gfx_pipeline_state.shader_keys_optimal.key.val); + assert(opt->val == sanitized); + assert(state->optimal_key == sanitized); } /* recalc vertex state if missing optimal extensions */ if (DYNAMIC_STATE != ZINK_DYNAMIC_VERTEX_INPUT2 && DYNAMIC_STATE != ZINK_DYNAMIC_VERTEX_INPUT && ctx->vertex_state_changed) {