diff options
| author | TellowKrinkle <tellowkrinkle@gmail.com> | 2022-06-11 21:03:09 -0500 |
|---|---|---|
| committer | TellowKrinkle <tellowkrinkle@gmail.com> | 2022-07-13 21:51:24 -0500 |
| commit | 6ab24e6c176bfd288296bf8284a30b0835fa45c3 (patch) | |
| tree | a35536d212d2cc22777672454e84cc883883c46e /Source/Core/VideoBackends | |
| parent | 99eef447651d40ed1954ccd5a83557478546face (diff) | |
VideoCommon: Better driver bug handling
Adds a pass to process driver deficiencies between UID caching and use, allowing a full view of the whole pipeline, since some bugs/workarounds involve interactions between blend modes and the pixel shader
Diffstat (limited to 'Source/Core/VideoBackends')
| -rw-r--r-- | Source/Core/VideoBackends/OGL/OGLRender.cpp | 84 | ||||
| -rw-r--r-- | Source/Core/VideoBackends/Software/Rasterizer.cpp | 2 | ||||
| -rw-r--r-- | Source/Core/VideoBackends/Software/Tev.cpp | 2 | ||||
| -rw-r--r-- | Source/Core/VideoBackends/Vulkan/VKPipeline.cpp | 88 | ||||
| -rw-r--r-- | Source/Core/VideoBackends/Vulkan/VulkanContext.cpp | 7 |
5 files changed, 76 insertions, 107 deletions
diff --git a/Source/Core/VideoBackends/OGL/OGLRender.cpp b/Source/Core/VideoBackends/OGL/OGLRender.cpp index 4c686941fe..93df1ccc29 100644 --- a/Source/Core/VideoBackends/OGL/OGLRender.cpp +++ b/Source/Core/VideoBackends/OGL/OGLRender.cpp @@ -1168,55 +1168,43 @@ void Renderer::ApplyBlendingState(const BlendingState state) if (m_current_blend_state == state) return; - bool useDualSource = - state.usedualsrc && g_ActiveConfig.backend_info.bSupportsDualSourceBlend && - (!DriverDetails::HasBug(DriverDetails::BUG_BROKEN_DUAL_SOURCE_BLENDING) || state.dstalpha); - // Only use shader blend if we need to and we don't support dual-source blending directly - bool useShaderBlend = !useDualSource && state.usedualsrc && state.dstalpha && - g_ActiveConfig.backend_info.bSupportsFramebufferFetch; - - if (useShaderBlend) - { - glDisable(GL_BLEND); - } + bool useDualSource = state.usedualsrc; + + const GLenum src_factors[8] = {GL_ZERO, + GL_ONE, + GL_DST_COLOR, + GL_ONE_MINUS_DST_COLOR, + useDualSource ? GL_SRC1_ALPHA : (GLenum)GL_SRC_ALPHA, + useDualSource ? GL_ONE_MINUS_SRC1_ALPHA : + (GLenum)GL_ONE_MINUS_SRC_ALPHA, + GL_DST_ALPHA, + GL_ONE_MINUS_DST_ALPHA}; + const GLenum dst_factors[8] = {GL_ZERO, + GL_ONE, + GL_SRC_COLOR, + GL_ONE_MINUS_SRC_COLOR, + useDualSource ? GL_SRC1_ALPHA : (GLenum)GL_SRC_ALPHA, + useDualSource ? GL_ONE_MINUS_SRC1_ALPHA : + (GLenum)GL_ONE_MINUS_SRC_ALPHA, + GL_DST_ALPHA, + GL_ONE_MINUS_DST_ALPHA}; + + if (state.blendenable) + glEnable(GL_BLEND); else - { - const GLenum src_factors[8] = {GL_ZERO, - GL_ONE, - GL_DST_COLOR, - GL_ONE_MINUS_DST_COLOR, - useDualSource ? GL_SRC1_ALPHA : (GLenum)GL_SRC_ALPHA, - useDualSource ? GL_ONE_MINUS_SRC1_ALPHA : - (GLenum)GL_ONE_MINUS_SRC_ALPHA, - GL_DST_ALPHA, - GL_ONE_MINUS_DST_ALPHA}; - const GLenum dst_factors[8] = {GL_ZERO, - GL_ONE, - GL_SRC_COLOR, - GL_ONE_MINUS_SRC_COLOR, - useDualSource ? GL_SRC1_ALPHA : (GLenum)GL_SRC_ALPHA, - useDualSource ? GL_ONE_MINUS_SRC1_ALPHA : - (GLenum)GL_ONE_MINUS_SRC_ALPHA, - GL_DST_ALPHA, - GL_ONE_MINUS_DST_ALPHA}; - - if (state.blendenable) - glEnable(GL_BLEND); - else - glDisable(GL_BLEND); - - // Always call glBlendEquationSeparate and glBlendFuncSeparate, even when - // GL_BLEND is disabled, as a workaround for some bugs (possibly graphics - // driver issues?). See https://bugs.dolphin-emu.org/issues/10120 : "Sonic - // Adventure 2 Battle: graphics crash when loading first Dark level" - GLenum equation = state.subtract ? GL_FUNC_REVERSE_SUBTRACT : GL_FUNC_ADD; - GLenum equationAlpha = state.subtractAlpha ? GL_FUNC_REVERSE_SUBTRACT : GL_FUNC_ADD; - glBlendEquationSeparate(equation, equationAlpha); - glBlendFuncSeparate(src_factors[u32(state.srcfactor.Value())], - dst_factors[u32(state.dstfactor.Value())], - src_factors[u32(state.srcfactoralpha.Value())], - dst_factors[u32(state.dstfactoralpha.Value())]); - } + glDisable(GL_BLEND); + + // Always call glBlendEquationSeparate and glBlendFuncSeparate, even when + // GL_BLEND is disabled, as a workaround for some bugs (possibly graphics + // driver issues?). See https://bugs.dolphin-emu.org/issues/10120 : "Sonic + // Adventure 2 Battle: graphics crash when loading first Dark level" + GLenum equation = state.subtract ? GL_FUNC_REVERSE_SUBTRACT : GL_FUNC_ADD; + GLenum equationAlpha = state.subtractAlpha ? GL_FUNC_REVERSE_SUBTRACT : GL_FUNC_ADD; + glBlendEquationSeparate(equation, equationAlpha); + glBlendFuncSeparate(src_factors[u32(state.srcfactor.Value())], + dst_factors[u32(state.dstfactor.Value())], + src_factors[u32(state.srcfactoralpha.Value())], + dst_factors[u32(state.dstfactoralpha.Value())]); const GLenum logic_op_codes[16] = { GL_CLEAR, GL_AND, GL_AND_REVERSE, GL_COPY, GL_AND_INVERTED, GL_NOOP, diff --git a/Source/Core/VideoBackends/Software/Rasterizer.cpp b/Source/Core/VideoBackends/Software/Rasterizer.cpp index 4b3f02758d..b7170527d5 100644 --- a/Source/Core/VideoBackends/Software/Rasterizer.cpp +++ b/Source/Core/VideoBackends/Software/Rasterizer.cpp @@ -153,7 +153,7 @@ static void Draw(s32 x, s32 y, s32 xi, s32 yi) s32 z = (s32)std::clamp<float>(ZSlope.GetValue(x, y), 0.0f, 16777215.0f); - if (bpmem.UseEarlyDepthTest()) + if (bpmem.GetEmulatedZ() == EmulatedZ::Early) { // TODO: Test if perf regs are incremented even if test is disabled EfbInterface::IncPerfCounterQuadCount(PQ_ZCOMP_INPUT_ZCOMPLOC); diff --git a/Source/Core/VideoBackends/Software/Tev.cpp b/Source/Core/VideoBackends/Software/Tev.cpp index 64e0f7774b..c2039df3ea 100644 --- a/Source/Core/VideoBackends/Software/Tev.cpp +++ b/Source/Core/VideoBackends/Software/Tev.cpp @@ -840,7 +840,7 @@ void Tev::Draw() output[BLU_C] = (output[BLU_C] * invFog + fogInt * bpmem.fog.color.b) >> 8; } - if (bpmem.UseLateDepthTest()) + if (bpmem.GetEmulatedZ() == EmulatedZ::Late) { // TODO: Check against hw if these values get incremented even if depth testing is disabled EfbInterface::IncPerfCounterQuadCount(PQ_ZCOMP_INPUT); diff --git a/Source/Core/VideoBackends/Vulkan/VKPipeline.cpp b/Source/Core/VideoBackends/Vulkan/VKPipeline.cpp index 61c51b5d34..f21fb9bf5e 100644 --- a/Source/Core/VideoBackends/Vulkan/VKPipeline.cpp +++ b/Source/Core/VideoBackends/Vulkan/VKPipeline.cpp @@ -137,60 +137,48 @@ GetVulkanAttachmentBlendState(const BlendingState& state, AbstractPipelineUsage { VkPipelineColorBlendAttachmentState vk_state = {}; - bool use_dual_source = - state.usedualsrc && g_ActiveConfig.backend_info.bSupportsDualSourceBlend && - (!DriverDetails::HasBug(DriverDetails::BUG_BROKEN_DUAL_SOURCE_BLENDING) || state.dstalpha); - bool use_shader_blend = !use_dual_source && state.usedualsrc && state.dstalpha && - g_ActiveConfig.backend_info.bSupportsFramebufferFetch; - - if (use_shader_blend || (usage == AbstractPipelineUsage::GX && - DriverDetails::HasBug(DriverDetails::BUG_BROKEN_DISCARD_WITH_EARLY_Z))) + bool use_dual_source = state.usedualsrc; + + vk_state.blendEnable = static_cast<VkBool32>(state.blendenable); + vk_state.colorBlendOp = state.subtract ? VK_BLEND_OP_REVERSE_SUBTRACT : VK_BLEND_OP_ADD; + vk_state.alphaBlendOp = state.subtractAlpha ? VK_BLEND_OP_REVERSE_SUBTRACT : VK_BLEND_OP_ADD; + + if (use_dual_source) { - vk_state.blendEnable = VK_FALSE; + static constexpr std::array<VkBlendFactor, 8> src_factors = { + {VK_BLEND_FACTOR_ZERO, VK_BLEND_FACTOR_ONE, VK_BLEND_FACTOR_DST_COLOR, + VK_BLEND_FACTOR_ONE_MINUS_DST_COLOR, VK_BLEND_FACTOR_SRC1_ALPHA, + VK_BLEND_FACTOR_ONE_MINUS_SRC1_ALPHA, VK_BLEND_FACTOR_DST_ALPHA, + VK_BLEND_FACTOR_ONE_MINUS_DST_ALPHA}}; + static constexpr std::array<VkBlendFactor, 8> dst_factors = { + {VK_BLEND_FACTOR_ZERO, VK_BLEND_FACTOR_ONE, VK_BLEND_FACTOR_SRC_COLOR, + VK_BLEND_FACTOR_ONE_MINUS_SRC_COLOR, VK_BLEND_FACTOR_SRC1_ALPHA, + VK_BLEND_FACTOR_ONE_MINUS_SRC1_ALPHA, VK_BLEND_FACTOR_DST_ALPHA, + VK_BLEND_FACTOR_ONE_MINUS_DST_ALPHA}}; + + vk_state.srcColorBlendFactor = src_factors[u32(state.srcfactor.Value())]; + vk_state.srcAlphaBlendFactor = src_factors[u32(state.srcfactoralpha.Value())]; + vk_state.dstColorBlendFactor = dst_factors[u32(state.dstfactor.Value())]; + vk_state.dstAlphaBlendFactor = dst_factors[u32(state.dstfactoralpha.Value())]; } else { - vk_state.blendEnable = static_cast<VkBool32>(state.blendenable); - vk_state.colorBlendOp = state.subtract ? VK_BLEND_OP_REVERSE_SUBTRACT : VK_BLEND_OP_ADD; - vk_state.alphaBlendOp = state.subtractAlpha ? VK_BLEND_OP_REVERSE_SUBTRACT : VK_BLEND_OP_ADD; - - if (use_dual_source) - { - static constexpr std::array<VkBlendFactor, 8> src_factors = { - {VK_BLEND_FACTOR_ZERO, VK_BLEND_FACTOR_ONE, VK_BLEND_FACTOR_DST_COLOR, - VK_BLEND_FACTOR_ONE_MINUS_DST_COLOR, VK_BLEND_FACTOR_SRC1_ALPHA, - VK_BLEND_FACTOR_ONE_MINUS_SRC1_ALPHA, VK_BLEND_FACTOR_DST_ALPHA, - VK_BLEND_FACTOR_ONE_MINUS_DST_ALPHA}}; - static constexpr std::array<VkBlendFactor, 8> dst_factors = { - {VK_BLEND_FACTOR_ZERO, VK_BLEND_FACTOR_ONE, VK_BLEND_FACTOR_SRC_COLOR, - VK_BLEND_FACTOR_ONE_MINUS_SRC_COLOR, VK_BLEND_FACTOR_SRC1_ALPHA, - VK_BLEND_FACTOR_ONE_MINUS_SRC1_ALPHA, VK_BLEND_FACTOR_DST_ALPHA, - VK_BLEND_FACTOR_ONE_MINUS_DST_ALPHA}}; - - vk_state.srcColorBlendFactor = src_factors[u32(state.srcfactor.Value())]; - vk_state.srcAlphaBlendFactor = src_factors[u32(state.srcfactoralpha.Value())]; - vk_state.dstColorBlendFactor = dst_factors[u32(state.dstfactor.Value())]; - vk_state.dstAlphaBlendFactor = dst_factors[u32(state.dstfactoralpha.Value())]; - } - else - { - static constexpr std::array<VkBlendFactor, 8> src_factors = { - {VK_BLEND_FACTOR_ZERO, VK_BLEND_FACTOR_ONE, VK_BLEND_FACTOR_DST_COLOR, - VK_BLEND_FACTOR_ONE_MINUS_DST_COLOR, VK_BLEND_FACTOR_SRC_ALPHA, - VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA, VK_BLEND_FACTOR_DST_ALPHA, - VK_BLEND_FACTOR_ONE_MINUS_DST_ALPHA}}; - - static constexpr std::array<VkBlendFactor, 8> dst_factors = { - {VK_BLEND_FACTOR_ZERO, VK_BLEND_FACTOR_ONE, VK_BLEND_FACTOR_SRC_COLOR, - VK_BLEND_FACTOR_ONE_MINUS_SRC_COLOR, VK_BLEND_FACTOR_SRC_ALPHA, - VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA, VK_BLEND_FACTOR_DST_ALPHA, - VK_BLEND_FACTOR_ONE_MINUS_DST_ALPHA}}; - - vk_state.srcColorBlendFactor = src_factors[u32(state.srcfactor.Value())]; - vk_state.srcAlphaBlendFactor = src_factors[u32(state.srcfactoralpha.Value())]; - vk_state.dstColorBlendFactor = dst_factors[u32(state.dstfactor.Value())]; - vk_state.dstAlphaBlendFactor = dst_factors[u32(state.dstfactoralpha.Value())]; - } + static constexpr std::array<VkBlendFactor, 8> src_factors = { + {VK_BLEND_FACTOR_ZERO, VK_BLEND_FACTOR_ONE, VK_BLEND_FACTOR_DST_COLOR, + VK_BLEND_FACTOR_ONE_MINUS_DST_COLOR, VK_BLEND_FACTOR_SRC_ALPHA, + VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA, VK_BLEND_FACTOR_DST_ALPHA, + VK_BLEND_FACTOR_ONE_MINUS_DST_ALPHA}}; + + static constexpr std::array<VkBlendFactor, 8> dst_factors = { + {VK_BLEND_FACTOR_ZERO, VK_BLEND_FACTOR_ONE, VK_BLEND_FACTOR_SRC_COLOR, + VK_BLEND_FACTOR_ONE_MINUS_SRC_COLOR, VK_BLEND_FACTOR_SRC_ALPHA, + VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA, VK_BLEND_FACTOR_DST_ALPHA, + VK_BLEND_FACTOR_ONE_MINUS_DST_ALPHA}}; + + vk_state.srcColorBlendFactor = src_factors[u32(state.srcfactor.Value())]; + vk_state.srcAlphaBlendFactor = src_factors[u32(state.srcfactoralpha.Value())]; + vk_state.dstColorBlendFactor = dst_factors[u32(state.dstfactor.Value())]; + vk_state.dstAlphaBlendFactor = dst_factors[u32(state.dstfactoralpha.Value())]; } if (state.colorupdate) diff --git a/Source/Core/VideoBackends/Vulkan/VulkanContext.cpp b/Source/Core/VideoBackends/Vulkan/VulkanContext.cpp index 1dc02e689a..a6cb201d72 100644 --- a/Source/Core/VideoBackends/Vulkan/VulkanContext.cpp +++ b/Source/Core/VideoBackends/Vulkan/VulkanContext.cpp @@ -371,13 +371,6 @@ void VulkanContext::PopulateBackendInfoFeatures(VideoConfig* config, VkPhysicalD if (DriverDetails::HasBug(DriverDetails::BUG_BROKEN_REVERSED_DEPTH_RANGE)) config->backend_info.bSupportsReversedDepthRange = false; - // Calling discard when early depth test is enabled can break on some Apple Silicon GPU drivers. - if (DriverDetails::HasBug(DriverDetails::BUG_BROKEN_DISCARD_WITH_EARLY_Z)) - { - // We will use shader blending, so disable hardware dual source blending. - config->backend_info.bSupportsDualSourceBlend = false; - } - // Dynamic sampler indexing locks up Intel GPUs on MoltenVK/Metal if (DriverDetails::HasBug(DriverDetails::BUG_BROKEN_DYNAMIC_SAMPLER_INDEXING)) config->backend_info.bSupportsDynamicSamplerIndexing = false; |
