From af322c3a2f5680d77e4ef2283ef0112e7786bd58 Mon Sep 17 00:00:00 2001 From: squidbus <175574877+squidbus@users.noreply.github.com> Date: Fri, 29 Aug 2025 20:25:57 -0700 Subject: [PATCH] renderer_vulkan: Ignore blend parameters when disabled. (#3485) --- .../renderer_vulkan/liverpool_to_vk.cpp | 4 +-- .../renderer_vulkan/vk_graphics_pipeline.cpp | 35 ++++++++++++++----- .../renderer_vulkan/vk_pipeline_cache.cpp | 24 +++++++------ 3 files changed, 42 insertions(+), 21 deletions(-) diff --git a/src/video_core/renderer_vulkan/liverpool_to_vk.cpp b/src/video_core/renderer_vulkan/liverpool_to_vk.cpp index 51411be7f..1c51f9e80 100644 --- a/src/video_core/renderer_vulkan/liverpool_to_vk.cpp +++ b/src/video_core/renderer_vulkan/liverpool_to_vk.cpp @@ -210,7 +210,7 @@ vk::BlendFactor BlendFactor(Liverpool::BlendControl::BlendFactor factor) { case BlendFactor::OneMinusConstantAlpha: return vk::BlendFactor::eOneMinusConstantAlpha; default: - UNREACHABLE(); + UNREACHABLE_MSG("Unknown blend factor: {}", static_cast(factor)); } } @@ -241,7 +241,7 @@ vk::BlendOp BlendOp(Liverpool::BlendControl::BlendFunc func) { case BlendFunc::ReverseSubtract: return vk::BlendOp::eReverseSubtract; default: - UNREACHABLE(); + UNREACHABLE_MSG("Unknown blend op: {}", static_cast(func)); } } diff --git a/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp b/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp index 44bd8a316..d3821b761 100644 --- a/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp +++ b/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp @@ -274,23 +274,40 @@ GraphicsPipeline::GraphicsPipeline( std::array attachments; for (u32 i = 0; i < key.num_color_attachments; i++) { const auto& control = key.blend_controls[i]; + const auto src_color = LiverpoolToVK::BlendFactor(control.color_src_factor); const auto dst_color = LiverpoolToVK::BlendFactor(control.color_dst_factor); const auto color_blend = LiverpoolToVK::BlendOp(control.color_func); + + const auto src_alpha = control.separate_alpha_blend + ? LiverpoolToVK::BlendFactor(control.alpha_src_factor) + : src_color; + const auto dst_alpha = control.separate_alpha_blend + ? LiverpoolToVK::BlendFactor(control.alpha_dst_factor) + : dst_color; + const auto alpha_blend = + control.separate_alpha_blend ? LiverpoolToVK::BlendOp(control.alpha_func) : color_blend; + + const auto color_scaled_min_max = + (color_blend == vk::BlendOp::eMin || color_blend == vk::BlendOp::eMax) && + (src_color != vk::BlendFactor::eOne || dst_color != vk::BlendFactor::eOne); + const auto alpha_scaled_min_max = + (alpha_blend == vk::BlendOp::eMin || alpha_blend == vk::BlendOp::eMax) && + (src_alpha != vk::BlendFactor::eOne || dst_alpha != vk::BlendFactor::eOne); + if (color_scaled_min_max || alpha_scaled_min_max) { + LOG_WARNING( + Render_Vulkan, + "Unimplemented use of min/max blend op with blend factor not equal to one."); + } + attachments[i] = vk::PipelineColorBlendAttachmentState{ .blendEnable = control.enable, .srcColorBlendFactor = src_color, .dstColorBlendFactor = dst_color, .colorBlendOp = color_blend, - .srcAlphaBlendFactor = control.separate_alpha_blend - ? LiverpoolToVK::BlendFactor(control.alpha_src_factor) - : src_color, - .dstAlphaBlendFactor = control.separate_alpha_blend - ? LiverpoolToVK::BlendFactor(control.alpha_dst_factor) - : dst_color, - .alphaBlendOp = control.separate_alpha_blend - ? LiverpoolToVK::BlendOp(control.alpha_func) - : color_blend, + .srcAlphaBlendFactor = src_alpha, + .dstAlphaBlendFactor = dst_alpha, + .alphaBlendOp = alpha_blend, .colorWriteMask = instance.IsDynamicColorWriteMaskSupported() ? vk::ColorComponentFlagBits::eR | vk::ColorComponentFlagBits::eG | diff --git a/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp b/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp index 6a2c1f380..1345efae7 100644 --- a/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp +++ b/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp @@ -168,13 +168,17 @@ const Shader::RuntimeInfo& PipelineCache::BuildRuntimeInfo(Stage stage, LogicalS const auto& ps_inputs = regs.ps_inputs; info.fs_info.num_inputs = regs.num_interp; const auto& cb0_blend = regs.blend_control[0]; - info.fs_info.dual_source_blending = - LiverpoolToVK::IsDualSourceBlendFactor(cb0_blend.color_dst_factor) || - LiverpoolToVK::IsDualSourceBlendFactor(cb0_blend.color_src_factor); - if (cb0_blend.separate_alpha_blend) { - info.fs_info.dual_source_blending |= - LiverpoolToVK::IsDualSourceBlendFactor(cb0_blend.alpha_dst_factor) || - LiverpoolToVK::IsDualSourceBlendFactor(cb0_blend.alpha_src_factor); + if (cb0_blend.enable) { + info.fs_info.dual_source_blending = + LiverpoolToVK::IsDualSourceBlendFactor(cb0_blend.color_dst_factor) || + LiverpoolToVK::IsDualSourceBlendFactor(cb0_blend.color_src_factor); + if (cb0_blend.separate_alpha_blend) { + info.fs_info.dual_source_blending |= + LiverpoolToVK::IsDualSourceBlendFactor(cb0_blend.alpha_dst_factor) || + LiverpoolToVK::IsDualSourceBlendFactor(cb0_blend.alpha_src_factor); + } + } else { + info.fs_info.dual_source_blending = false; } for (u32 i = 0; i < regs.num_interp; i++) { info.fs_info.inputs[i] = { @@ -344,9 +348,9 @@ bool PipelineCache::RefreshGraphicsKey() { }; // Fill color blending information - key.blend_controls[cb] = regs.blend_control[cb]; - key.blend_controls[cb].enable.Assign(regs.blend_control[cb].enable && - !col_buf.info.blend_bypass); + if (regs.blend_control[cb].enable && !col_buf.info.blend_bypass) { + key.blend_controls[cb] = regs.blend_control[cb]; + } // Apply swizzle to target mask key.write_masks[cb] =