From 5e8cdfda92f267d1d778268e640c4847a1e6f62a Mon Sep 17 00:00:00 2001 From: Billy Laws Date: Mon, 20 Feb 2023 17:32:21 +0000 Subject: [PATCH] Don't populate colour targets with an empty write mask Avoids breaking VK spec in BOTW, as it has the same colour attachment bound twice, but the former is masked out entirely. --- .../gpu/interconnect/maxwell_3d/pipeline_state.cpp | 8 ++++++-- .../skyline/gpu/interconnect/maxwell_3d/pipeline_state.h | 2 ++ .../main/cpp/skyline/soc/gm20b/engines/maxwell/types.h | 4 ++++ 3 files changed, 12 insertions(+), 2 deletions(-) diff --git a/app/src/main/cpp/skyline/gpu/interconnect/maxwell_3d/pipeline_state.cpp b/app/src/main/cpp/skyline/gpu/interconnect/maxwell_3d/pipeline_state.cpp index c9abcfa0..771f2e93 100644 --- a/app/src/main/cpp/skyline/gpu/interconnect/maxwell_3d/pipeline_state.cpp +++ b/app/src/main/cpp/skyline/gpu/interconnect/maxwell_3d/pipeline_state.cpp @@ -300,6 +300,7 @@ namespace skyline::gpu::interconnect::maxwell3d { void ColorBlendState::Flush(PackedPipelineState &packedState) { packedState.logicOpEnable = engine->logicOp.enable; packedState.SetLogicOp(engine->logicOp.func); + writtenCtMask.reset(); for (u32 i{}; i < engine::ColorTargetCount; i++) { auto ctWrite{[&]() { @@ -315,6 +316,8 @@ namespace skyline::gpu::interconnect::maxwell3d { packedState.SetAttachmentBlendState(i, enable, ctWrite, engine->blendPerTargets[i]); else packedState.SetAttachmentBlendState(i, enable, ctWrite, engine->blend); + + writtenCtMask.set(i, ctWrite.Any()); } } @@ -392,10 +395,12 @@ namespace skyline::gpu::interconnect::maxwell3d { shaderBinaries[i] = stage.binary; } + colorBlend.Update(packedState); + colorAttachments.clear(); packedState.colorRenderTargetFormats = {}; for (size_t i{}; i < engine::ColorTargetCount; i++) { - if (i < ctSelect.count) { + if (i < ctSelect.count && colorBlend.Get().writtenCtMask.test(i)) { const auto &rt{colorRenderTargets[ctSelect[i]].UpdateGet(ctx, packedState)}; const auto view{rt.view.get()}; packedState.SetColorRenderTargetFormat(ctSelect[i], rt.format); @@ -417,7 +422,6 @@ namespace skyline::gpu::interconnect::maxwell3d { tessellation.Update(packedState); rasterization.Update(packedState); depthStencil.Update(packedState); - colorBlend.Update(packedState); transformFeedback.Update(packedState); globalShaderConfig.Update(packedState); diff --git a/app/src/main/cpp/skyline/gpu/interconnect/maxwell_3d/pipeline_state.h b/app/src/main/cpp/skyline/gpu/interconnect/maxwell_3d/pipeline_state.h index 31e89dd9..5f6a84e3 100644 --- a/app/src/main/cpp/skyline/gpu/interconnect/maxwell_3d/pipeline_state.h +++ b/app/src/main/cpp/skyline/gpu/interconnect/maxwell_3d/pipeline_state.h @@ -234,6 +234,8 @@ namespace skyline::gpu::interconnect::maxwell3d { dirty::BoundSubresource engine; public: + std::bitset writtenCtMask{}; + ColorBlendState(dirty::Handle dirtyHandle, DirtyManager &manager, const EngineRegisters &engine); void Flush(PackedPipelineState &packedState); diff --git a/app/src/main/cpp/skyline/soc/gm20b/engines/maxwell/types.h b/app/src/main/cpp/skyline/soc/gm20b/engines/maxwell/types.h index b239fd43..e75d4669 100644 --- a/app/src/main/cpp/skyline/soc/gm20b/engines/maxwell/types.h +++ b/app/src/main/cpp/skyline/soc/gm20b/engines/maxwell/types.h @@ -718,6 +718,10 @@ namespace skyline::soc::gm20b::engine::maxwell3d::type { static_assert(sizeof(ViewportClipControl) == sizeof(u32)); union CtWrite { + bool Any() const { + return rEnable || gEnable || bEnable || aEnable; + } + u32 raw; struct {