aboutsummaryrefslogtreecommitdiff
path: root/src/shader_recompiler/backend/spirv/spirv_emit_context.cpp
diff options
context:
space:
mode:
authortarako <r76036296@gmail.com>2026-03-03 01:54:57 +0100
committercrueter <crueter@eden-emu.dev>2026-03-03 01:54:57 +0100
commitd720a7b4b4e3c2bc4f7e2c1b16e282ec91766aa8 (patch)
tree4c1eebb39329f97e2bf75d73768734ac20ee988c /src/shader_recompiler/backend/spirv/spirv_emit_context.cpp
parent464212393e296c59488171692df1d096ecfa5607 (diff)
[vulkan] Fixed dual-source blending to correctly map shader outputs. (#3637)
Fixes Skyward Sword HD eye gitch and a related MoltenVK crash due to the incorrect output mapping. Verified working on mac and android. The test in vk_pipeline_cache.cpp is a bit ugly, but it didn't seem worth it to go lambda/macro just to make it look cleaner. Could change if necessary. Co-authored-by: tarako <none@none.com> Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/3637 Reviewed-by: CamilleLaVey <camillelavey99@gmail.com> Co-authored-by: tarako <r76036296@gmail.com> Co-committed-by: tarako <r76036296@gmail.com>
Diffstat (limited to 'src/shader_recompiler/backend/spirv/spirv_emit_context.cpp')
-rw-r--r--src/shader_recompiler/backend/spirv/spirv_emit_context.cpp15
1 files changed, 12 insertions, 3 deletions
diff --git a/src/shader_recompiler/backend/spirv/spirv_emit_context.cpp b/src/shader_recompiler/backend/spirv/spirv_emit_context.cpp
index cd3394bdf0..b9a24496c9 100644
--- a/src/shader_recompiler/backend/spirv/spirv_emit_context.cpp
+++ b/src/shader_recompiler/backend/spirv/spirv_emit_context.cpp
@@ -1670,13 +1670,22 @@ void EmitContext::DefineOutputs(const IR::Program& program) {
break;
case Stage::Fragment:
for (u32 index = 0; index < 8; ++index) {
- if (!info.stores_frag_color[index] && !profile.need_declared_frag_colors) {
+ const bool need_dual_source = runtime_info.dual_source_blend && index <= 1;
+ if (!need_dual_source && !info.stores_frag_color[index] &&
+ !profile.need_declared_frag_colors) {
continue;
}
const Id type{GetAttributeType(*this, runtime_info.color_output_types[index])};
frag_color[index] = DefineOutput(*this, type, std::nullopt);
- Decorate(frag_color[index], spv::Decoration::Location, index);
- Name(frag_color[index], fmt::format("frag_color{}", index));
+ // Correct mapping for dual-source blending
+ if (runtime_info.dual_source_blend && index <= 1) {
+ Decorate(frag_color[index], spv::Decoration::Location, 0u);
+ Decorate(frag_color[index], spv::Decoration::Index, index);
+ Name(frag_color[index], index == 0 ? "frag_color0" : "frag_color0_secondary");
+ } else {
+ Decorate(frag_color[index], spv::Decoration::Location, index);
+ Name(frag_color[index], fmt::format("frag_color{}", index));
+ }
}
if (info.stores_frag_depth) {
frag_depth = DefineOutput(*this, F32[1], std::nullopt);