summaryrefslogtreecommitdiff
path: root/Source/Core/VideoCommon/PixelShaderGen.cpp
diff options
context:
space:
mode:
authorJMC47 <JMC4789@gmail.com>2022-04-24 13:30:04 -0400
committerGitHub <noreply@github.com>2022-04-24 13:30:04 -0400
commitc42392c565be2915af17588e2215c4b2861aeb53 (patch)
treeac554936562a3c49e0be5a1d17e070243baf0fcf /Source/Core/VideoCommon/PixelShaderGen.cpp
parent61edcf7e4fd2cef2ad95022abb2e5fc46f7433ed (diff)
parent259a5fc7c02d48f21d2479d8e259519bc4ed443e (diff)
Merge pull request #10290 from OatmealDome/m1-earlyz-bug
DriverDetails: Add broken discard with early-Z bug on Apple Silicon GPUs
Diffstat (limited to 'Source/Core/VideoCommon/PixelShaderGen.cpp')
-rw-r--r--Source/Core/VideoCommon/PixelShaderGen.cpp51
1 files changed, 37 insertions, 14 deletions
diff --git a/Source/Core/VideoCommon/PixelShaderGen.cpp b/Source/Core/VideoCommon/PixelShaderGen.cpp
index 82de68a290..4a9e9105a8 100644
--- a/Source/Core/VideoCommon/PixelShaderGen.cpp
+++ b/Source/Core/VideoCommon/PixelShaderGen.cpp
@@ -321,7 +321,9 @@ PixelShaderUid GetPixelShaderUid()
BlendingState state = {};
state.Generate(bpmem);
- if (state.usedualsrc && state.dstalpha && g_ActiveConfig.backend_info.bSupportsFramebufferFetch &&
+ if (((state.usedualsrc && state.dstalpha) ||
+ DriverDetails::HasBug(DriverDetails::BUG_BROKEN_DISCARD_WITH_EARLY_Z)) &&
+ g_ActiveConfig.backend_info.bSupportsFramebufferFetch &&
!g_ActiveConfig.backend_info.bSupportsDualSourceBlend)
{
uid_data->blend_enable = state.blendenable;
@@ -944,10 +946,15 @@ ShaderCode GeneratePixelShaderCode(APIType api_type, const ShaderHostConfig& hos
(!DriverDetails::HasBug(DriverDetails::BUG_BROKEN_DUAL_SOURCE_BLENDING) ||
uid_data->useDstAlpha);
const bool use_shader_blend =
- !use_dual_source && uid_data->useDstAlpha && host_config.backend_shader_framebuffer_fetch;
+ !use_dual_source &&
+ (uid_data->useDstAlpha ||
+ DriverDetails::HasBug(DriverDetails::BUG_BROKEN_DISCARD_WITH_EARLY_Z)) &&
+ host_config.backend_shader_framebuffer_fetch;
const bool use_shader_logic_op = !host_config.backend_logic_op && uid_data->logic_op_enable &&
host_config.backend_shader_framebuffer_fetch;
- const bool use_framebuffer_fetch = use_shader_blend || use_shader_logic_op;
+ const bool use_framebuffer_fetch =
+ use_shader_blend || use_shader_logic_op ||
+ DriverDetails::HasBug(DriverDetails::BUG_BROKEN_DISCARD_WITH_EARLY_Z);
if (api_type == APIType::OpenGL || api_type == APIType::Vulkan)
{
@@ -1869,9 +1876,23 @@ static void WriteAlphaTest(ShaderCode& out, const pixel_shader_uid_data* uid_dat
// ZCOMPLOC HACK:
if (!uid_data->alpha_test_use_zcomploc_hack)
{
- out.Write("\t\tdiscard;\n");
- if (api_type == APIType::D3D)
+#ifdef __APPLE__
+ if (uid_data->forced_early_z &&
+ DriverDetails::HasBug(DriverDetails::BUG_BROKEN_DISCARD_WITH_EARLY_Z))
+ {
+ // Instead of using discard, fetch the framebuffer's color value and use it as the output
+ // for this fragment.
+ out.Write("\t\t{} = float4(initial_ocol0.xyz, 1.0);\n",
+ use_dual_source ? "real_ocol0" : "ocol0");
out.Write("\t\treturn;\n");
+ }
+ else
+#endif
+ {
+ out.Write("\t\tdiscard;\n");
+ if (api_type == APIType::D3D)
+ out.Write("\t\treturn;\n");
+ }
}
out.Write("\t}}\n");
@@ -2018,8 +2039,8 @@ static void WriteBlend(ShaderCode& out, const pixel_shader_uid_data* uid_data)
"float3(1,1,1);", // ONE
"initial_ocol0.rgb;", // DSTCLR
"float3(1,1,1) - initial_ocol0.rgb;", // INVDSTCLR
- "ocol1.aaa;", // SRCALPHA
- "float3(1,1,1) - ocol1.aaa;", // INVSRCALPHA
+ "src_color.aaa;", // SRCALPHA
+ "float3(1,1,1) - src_color.aaa;", // INVSRCALPHA
"initial_ocol0.aaa;", // DSTALPHA
"float3(1,1,1) - initial_ocol0.aaa;", // INVDSTALPHA
};
@@ -2028,8 +2049,8 @@ static void WriteBlend(ShaderCode& out, const pixel_shader_uid_data* uid_data)
"1.0;", // ONE
"initial_ocol0.a;", // DSTCLR
"1.0 - initial_ocol0.a;", // INVDSTCLR
- "ocol1.a;", // SRCALPHA
- "1.0 - ocol1.a;", // INVSRCALPHA
+ "src_color.a;", // SRCALPHA
+ "1.0 - src_color.a;", // INVSRCALPHA
"initial_ocol0.a;", // DSTALPHA
"1.0 - initial_ocol0.a;", // INVDSTALPHA
};
@@ -2038,8 +2059,8 @@ static void WriteBlend(ShaderCode& out, const pixel_shader_uid_data* uid_data)
"float3(1,1,1);", // ONE
"ocol0.rgb;", // SRCCLR
"float3(1,1,1) - ocol0.rgb;", // INVSRCCLR
- "ocol1.aaa;", // SRCALHA
- "float3(1,1,1) - ocol1.aaa;", // INVSRCALPHA
+ "src_color.aaa;", // SRCALHA
+ "float3(1,1,1) - src_color.aaa;", // INVSRCALPHA
"initial_ocol0.aaa;", // DSTALPHA
"float3(1,1,1) - initial_ocol0.aaa;", // INVDSTALPHA
};
@@ -2048,12 +2069,14 @@ static void WriteBlend(ShaderCode& out, const pixel_shader_uid_data* uid_data)
"1.0;", // ONE
"ocol0.a;", // SRCCLR
"1.0 - ocol0.a;", // INVSRCCLR
- "ocol1.a;", // SRCALPHA
- "1.0 - ocol1.a;", // INVSRCALPHA
+ "src_color.a;", // SRCALPHA
+ "1.0 - src_color.a;", // INVSRCALPHA
"initial_ocol0.a;", // DSTALPHA
"1.0 - initial_ocol0.a;", // INVDSTALPHA
};
- out.Write("\tfloat4 blend_src;\n");
+ out.Write("\tfloat4 src_color = {};\n"
+ "\tfloat4 blend_src;",
+ uid_data->useDstAlpha ? "ocol1" : "ocol0");
out.Write("\tblend_src.rgb = {}\n", blend_src_factor[uid_data->blend_src_factor]);
out.Write("\tblend_src.a = {}\n", blend_src_factor_alpha[uid_data->blend_src_factor_alpha]);
out.Write("\tfloat4 blend_dst;\n");