summaryrefslogtreecommitdiff
path: root/Source/Core/VideoBackends
diff options
context:
space:
mode:
authorTellowKrinkle <tellowkrinkle@gmail.com>2022-06-11 21:03:09 -0500
committerTellowKrinkle <tellowkrinkle@gmail.com>2022-07-13 21:51:24 -0500
commit6ab24e6c176bfd288296bf8284a30b0835fa45c3 (patch)
treea35536d212d2cc22777672454e84cc883883c46e /Source/Core/VideoBackends
parent99eef447651d40ed1954ccd5a83557478546face (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.cpp84
-rw-r--r--Source/Core/VideoBackends/Software/Rasterizer.cpp2
-rw-r--r--Source/Core/VideoBackends/Software/Tev.cpp2
-rw-r--r--Source/Core/VideoBackends/Vulkan/VKPipeline.cpp88
-rw-r--r--Source/Core/VideoBackends/Vulkan/VulkanContext.cpp7
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;