From ec173559f833ae36230ead3d914817c86e46e4e0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Sun, 4 Sep 2022 00:00:33 +0200 Subject: [PATCH] Additional cleanup --- GPU/Common/GPUStateUtils.cpp | 14 ++++++++++++++ GPU/Common/GPUStateUtils.h | 25 +++++++++++++++++++++++++ GPU/D3D11/StateMappingD3D11.cpp | 1 + GPU/Directx9/StateMappingDX9.cpp | 1 + GPU/GLES/StateMappingGLES.cpp | 6 ++++-- GPU/Vulkan/StateMappingVulkan.cpp | 17 +++++++++-------- 6 files changed, 54 insertions(+), 10 deletions(-) diff --git a/GPU/Common/GPUStateUtils.cpp b/GPU/Common/GPUStateUtils.cpp index af88e77532..97f69be509 100644 --- a/GPU/Common/GPUStateUtils.cpp +++ b/GPU/Common/GPUStateUtils.cpp @@ -1466,6 +1466,19 @@ static void ConvertStencilFunc5551(GenericStencilFuncState &state) { } } +void ConvertLogicOpState(GenericLogicState &logicOpState, bool logicSupported, bool shaderBitOpsSupported) { + // Just do the non-shader case for now. + if (gstate_c.Supports(GPU_SUPPORTS_LOGIC_OP)) { + logicOpState.logicOpEnabled = gstate.isLogicOpEnabled() && logicSupported; + logicOpState.logicOp = gstate.isLogicOpEnabled() ? gstate.getLogicOp() : GE_LOGIC_COPY; + logicOpState.applyFramebufferRead = false; + } else { + logicOpState.logicOpEnabled = false; + logicOpState.logicOp = GE_LOGIC_COPY; + logicOpState.applyFramebufferRead = false; // true later? + } +} + static void ConvertStencilMask5551(GenericStencilFuncState &state) { state.writeMask = state.writeMask >= 0x80 ? 0xff : 0x00; } @@ -1524,5 +1537,6 @@ void GenericBlendState::Log() { void ComputedPipelineState::Convert(bool shaderBitOpsSuppported) { ConvertMaskState(maskState, shaderBitOpsSuppported); + ConvertLogicOpState(logicState, gstate_c.Supports(GPU_SUPPORTS_LOGIC_OP), shaderBitOpsSuppported); ConvertBlendState(blendState, maskState.applyFramebufferRead); } diff --git a/GPU/Common/GPUStateUtils.h b/GPU/Common/GPUStateUtils.h index 529e81cf87..23e41eb10f 100644 --- a/GPU/Common/GPUStateUtils.h +++ b/GPU/Common/GPUStateUtils.h @@ -218,9 +218,34 @@ struct GenericStencilFuncState { }; void ConvertStencilFuncState(GenericStencilFuncState &stencilFuncState); +struct GenericLogicState { + // If set, logic op is applied in the shader INSTEAD of in hardware. + // In this case, simulateLogicOpType and all that should be off. + bool applyFramebufferRead; + + // Hardware + bool logicOpEnabled; + + // Hardware and shader generation + GELogicOp logicOp; + + void ConvertToShaderBlend() { + if (logicOp != GE_LOGIC_COPY) { + logicOpEnabled = false; + applyFramebufferRead = true; + // Same logicOp is kept. + } + } + + void Log(); +}; + +void ConvertLogicOpState(GenericLogicState &logicOpState, bool logicSupported, bool shaderBitOpsSupported); + struct ComputedPipelineState { GenericBlendState blendState; GenericMaskState maskState; + GenericLogicState logicState; // TODO: Add logic and possibly stencil here. void Convert(bool shaderBitOpsSupported); diff --git a/GPU/D3D11/StateMappingD3D11.cpp b/GPU/D3D11/StateMappingD3D11.cpp index 0f2c55f19f..e525b3f765 100644 --- a/GPU/D3D11/StateMappingD3D11.cpp +++ b/GPU/D3D11/StateMappingD3D11.cpp @@ -150,6 +150,7 @@ void DrawEngineD3D11::ApplyDrawState(int prim) { pipelineState_.Convert(draw_->GetDeviceCaps().fragmentShaderInt32Supported); GenericMaskState &maskState = pipelineState_.maskState; GenericBlendState &blendState = pipelineState_.blendState; + // We ignore the logicState on D3D since there's no support, the emulation of it is blend-and-shader only. if (blendState.applyFramebufferRead || maskState.applyFramebufferRead) { bool fboTexNeedsBind = false; diff --git a/GPU/Directx9/StateMappingDX9.cpp b/GPU/Directx9/StateMappingDX9.cpp index 70c2f7518d..7a324219a5 100644 --- a/GPU/Directx9/StateMappingDX9.cpp +++ b/GPU/Directx9/StateMappingDX9.cpp @@ -130,6 +130,7 @@ void DrawEngineDX9::ApplyDrawState(int prim) { pipelineState_.Convert(draw_->GetDeviceCaps().fragmentShaderInt32Supported); GenericMaskState &maskState = pipelineState_.maskState; GenericBlendState &blendState = pipelineState_.blendState; + // We ignore the logicState on D3D since there's no support, the emulation of it is blend-and-shader only. if (blendState.applyFramebufferRead || maskState.applyFramebufferRead) { bool fboTexNeedsBind = false; diff --git a/GPU/GLES/StateMappingGLES.cpp b/GPU/GLES/StateMappingGLES.cpp index f86f35f830..007c280832 100644 --- a/GPU/GLES/StateMappingGLES.cpp +++ b/GPU/GLES/StateMappingGLES.cpp @@ -146,6 +146,7 @@ void DrawEngineGLES::ApplyDrawState(int prim) { pipelineState_.Convert(draw_->GetDeviceCaps().fragmentShaderInt32Supported); GenericMaskState &maskState = pipelineState_.maskState; GenericBlendState &blendState = pipelineState_.blendState; + GenericLogicState &logicState = pipelineState_.logicState; if (blendState.applyFramebufferRead || maskState.applyFramebufferRead) { bool fboTexNeedsBind = false; @@ -201,10 +202,11 @@ void DrawEngineGLES::ApplyDrawState(int prim) { } else { renderManager->SetNoBlendAndMask(mask); } + + // TODO: Get rid of the ifdef #ifndef USING_GLES2 if (gstate_c.Supports(GPU_SUPPORTS_LOGIC_OP)) { - renderManager->SetLogicOp(gstate.isLogicOpEnabled() && gstate.getLogicOp() != GE_LOGIC_COPY, - logicOps[gstate.getLogicOp()]); + renderManager->SetLogicOp(logicState.logicOpEnabled, logicOps[(int)logicState.logicOp]); } #endif } diff --git a/GPU/Vulkan/StateMappingVulkan.cpp b/GPU/Vulkan/StateMappingVulkan.cpp index 8532e8339c..5c7f7b77af 100644 --- a/GPU/Vulkan/StateMappingVulkan.cpp +++ b/GPU/Vulkan/StateMappingVulkan.cpp @@ -150,6 +150,7 @@ void DrawEngineVulkan::ConvertStateToVulkanKey(FramebufferManagerVulkan &fbManag pipelineState_.Convert(draw_->GetDeviceCaps().fragmentShaderInt32Supported); GenericMaskState &maskState = pipelineState_.maskState; GenericBlendState &blendState = pipelineState_.blendState; + GenericLogicState &logicState = pipelineState_.logicState; if (blendState.applyFramebufferRead || maskState.applyFramebufferRead) { ApplyFramebufferRead(&fboTexNeedsBind_); @@ -196,6 +197,14 @@ void DrawEngineVulkan::ConvertStateToVulkanKey(FramebufferManagerVulkan &fbManag key.colorWriteMask = maskState.channelMask; // flags match + if (logicState.logicOpEnabled) { + key.logicOpEnable = true; + key.logicOp = logicOps[(int)logicState.logicOp]; + } else { + key.logicOpEnable = false; + key.logicOp = VK_LOGIC_OP_COPY; + } + // Workaround proposed in #10421, for bug where the color write mask is not applied correctly on Adreno. if ((gstate.pmskc & 0x00FFFFFF) == 0x00FFFFFF && g_Config.bVendorBugChecksEnabled && draw_->GetBugs().Has(Draw::Bugs::COLORWRITEMASK_BROKEN_WITH_DEPTHTEST)) { key.colorWriteMask = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT; @@ -209,14 +218,6 @@ void DrawEngineVulkan::ConvertStateToVulkanKey(FramebufferManagerVulkan &fbManag key.srcColor = VK_BLEND_FACTOR_ZERO; key.destColor = VK_BLEND_FACTOR_ONE; } - - if (gstate_c.Supports(GPU_SUPPORTS_LOGIC_OP) && gstate.isLogicOpEnabled() && gstate.getLogicOp() != GE_LOGIC_COPY) { - key.logicOpEnable = true; - key.logicOp = logicOps[gstate.getLogicOp()]; - } else { - key.logicOpEnable = false; - key.logicOp = VK_LOGIC_OP_CLEAR; - } } }