From b86cf0a82031571604047ec97ea87893c1511713 Mon Sep 17 00:00:00 2001 From: nmzik Date: Thu, 1 Oct 2026 22:09:59 +0400 Subject: [PATCH] Reuse pipelines when inactive blend settings change --- .../renderer/pipeline/pipelineCache.cpp | 18 +++++++++++------- tests/ShaderRecompilerComputeTests.cpp | 19 +++++++++++++++---- 2 files changed, 26 insertions(+), 11 deletions(-) diff --git a/src/graphics/host_gpu/renderer/pipeline/pipelineCache.cpp b/src/graphics/host_gpu/renderer/pipeline/pipelineCache.cpp index 9760753a2..e9b310d77 100644 --- a/src/graphics/host_gpu/renderer/pipeline/pipelineCache.cpp +++ b/src/graphics/host_gpu/renderer/pipeline/pipelineCache.cpp @@ -714,13 +714,6 @@ PipelineCache::Pipeline& PipelineCache::GetGraphicsPipeline( } const auto& rt = ctx.GetRenderTarget(colors[i].target_slot); const auto& bc = ctx.GetBlendControl(colors[i].target_slot); - static_params.color_srcblend[slot] = bc.color_srcblend; - static_params.color_comb_fcn[slot] = bc.color_comb_fcn; - static_params.color_destblend[slot] = bc.color_destblend; - static_params.alpha_srcblend[slot] = bc.alpha_srcblend; - static_params.alpha_comb_fcn[slot] = bc.alpha_comb_fcn; - static_params.alpha_destblend[slot] = bc.alpha_destblend; - static_params.separate_alpha_blend[slot] = bc.separate_alpha_blend; const bool alpha_remap = slot == 0 && ps_input_info != nullptr && ps_input_info->alpha_blend_source_remap; static_params.blend_enable[slot] = bc.enable && !rt.info.blend_bypass; @@ -739,6 +732,17 @@ PipelineCache::Pipeline& PipelineCache::GetGraphicsPipeline( if (alpha_remap) { static_params.blend_alpha_source_remap = true; } + if (static_params.blend_enable[slot]) { + static_params.color_srcblend[slot] = bc.color_srcblend; + static_params.color_comb_fcn[slot] = bc.color_comb_fcn; + static_params.color_destblend[slot] = bc.color_destblend; + static_params.separate_alpha_blend[slot] = bc.separate_alpha_blend; + if (bc.separate_alpha_blend) { + static_params.alpha_srcblend[slot] = bc.alpha_srcblend; + static_params.alpha_comb_fcn[slot] = bc.alpha_comb_fcn; + static_params.alpha_destblend[slot] = bc.alpha_destblend; + } + } } const bool with_depth = depth.desc.view_info.format != vk::Format::eUndefined && static_cast(depth.image_id); diff --git a/tests/ShaderRecompilerComputeTests.cpp b/tests/ShaderRecompilerComputeTests.cpp index b1b0d9ada..61a63450c 100644 --- a/tests/ShaderRecompilerComputeTests.cpp +++ b/tests/ShaderRecompilerComputeTests.cpp @@ -14507,11 +14507,14 @@ public: "last-vertex flat shading changed coverage or did not use vertex two"); } - const auto blend_pipeline = [&](bool enabled, bool bypass) -> PipelineCache::Pipeline & { + const auto blend_pipeline = [&](bool enabled, bool bypass, + bool alternate = false) -> PipelineCache::Pipeline & { auto blend = registers.GetBlendControl(0); blend.enable = enabled; - blend.color_srcblend = static_cast(Prospero::BlendFactor::kZero); - blend.alpha_srcblend = static_cast(Prospero::BlendFactor::kZero); + blend.color_srcblend = static_cast(alternate ? Prospero::BlendFactor::kOne + : Prospero::BlendFactor::kZero); + blend.alpha_srcblend = blend.color_srcblend; + blend.separate_alpha_blend = alternate; registers.SetBlendControl(0, blend); auto target = registers.GetRenderTarget(0).info; target.blend_bypass = bypass; @@ -14521,13 +14524,21 @@ public: auto &disabled_blend = blend_pipeline(false, false); Require(name, "effective blend pipeline cache", blend_pipeline(false, true).pipeline == disabled_blend.pipeline && - blend_pipeline(true, true).pipeline == disabled_blend.pipeline, + blend_pipeline(true, true).pipeline == disabled_blend.pipeline && + blend_pipeline(false, false, true).pipeline == disabled_blend.pipeline && + blend_pipeline(true, true, true).pipeline == disabled_blend.pipeline, "disabled and bypassed blending did not share the same host pipeline"); auto &enabled_blend = blend_pipeline(true, false); Require(name, "enabled blend pipeline cache", enabled_blend.pipeline != disabled_blend.pipeline && blend_pipeline(true, false).pipeline == enabled_blend.pipeline, "active blending was lost from the pipeline key or missed its cached pipeline"); + auto dormant_alpha = registers.GetBlendControl(0); + dormant_alpha.alpha_srcblend = static_cast(Prospero::BlendFactor::kOne); + registers.SetBlendControl(0, dormant_alpha); + Require(name, "dormant alpha blend pipeline cache", + pipeline(true, 2, 2).pipeline == enabled_blend.pipeline, + "inactive separate-alpha state recompiled the pipeline"); draw(enabled_blend); const auto blended_pixels = read_color(); Require(name, "active blend output",