summaryrefslogtreecommitdiff
path: root/Source
diff options
context:
space:
mode:
authorTellowKrinkle <tellowkrinkle@gmail.com>2022-06-12 21:27:11 -0500
committerTellowKrinkle <tellowkrinkle@gmail.com>2022-07-15 15:31:47 -0500
commit991024173e3d048ea3a056c8debb6f92ae7b2da0 (patch)
tree93259d094433a7ca7a1e9341508be4f2209d63f6 /Source
parent6ab24e6c176bfd288296bf8284a30b0835fa45c3 (diff)
VideoCommon: Always use fbfetch in ubershaders if available
Reduce the number of different pipelines needed. Also works around drivers that break when you combine fbfetch with dual source blending
Diffstat (limited to 'Source')
-rw-r--r--Source/Core/VideoCommon/ShaderCache.cpp14
-rw-r--r--Source/Core/VideoCommon/UberShaderPixel.cpp45
2 files changed, 30 insertions, 29 deletions
diff --git a/Source/Core/VideoCommon/ShaderCache.cpp b/Source/Core/VideoCommon/ShaderCache.cpp
index e4d2115c3b..6049fd29a7 100644
--- a/Source/Core/VideoCommon/ShaderCache.cpp
+++ b/Source/Core/VideoCommon/ShaderCache.cpp
@@ -743,9 +743,17 @@ static GXUberPipelineUid ApplyDriverBugs(const GXUberPipelineUid& in)
{
GXUberPipelineUid out;
memcpy(&out, &in, sizeof(out)); // Copy padding
- if (!g_ActiveConfig.backend_info.bSupportsDualSourceBlend ||
- (DriverDetails::HasBug(DriverDetails::BUG_BROKEN_DUAL_SOURCE_BLENDING) &&
- !out.blending_state.RequiresDualSrc()))
+ if (g_ActiveConfig.backend_info.bSupportsFramebufferFetch)
+ {
+ // Always blend in shader
+ out.blending_state.hex = 0;
+ out.blending_state.colorupdate = in.blending_state.colorupdate.Value();
+ out.blending_state.alphaupdate = in.blending_state.alphaupdate.Value();
+ out.ps_uid.GetUidData()->no_dual_src = true;
+ }
+ else if (!g_ActiveConfig.backend_info.bSupportsDualSourceBlend ||
+ (DriverDetails::HasBug(DriverDetails::BUG_BROKEN_DUAL_SOURCE_BLENDING) &&
+ !out.blending_state.RequiresDualSrc()))
{
out.blending_state.usedualsrc = false;
out.ps_uid.GetUidData()->no_dual_src = true;
diff --git a/Source/Core/VideoCommon/UberShaderPixel.cpp b/Source/Core/VideoCommon/UberShaderPixel.cpp
index 8b89b045e8..7bfe36c517 100644
--- a/Source/Core/VideoCommon/UberShaderPixel.cpp
+++ b/Source/Core/VideoCommon/UberShaderPixel.cpp
@@ -3,6 +3,8 @@
#include "VideoCommon/UberShaderPixel.h"
+#include "Common/Assert.h"
+
#include "VideoCommon/BPMemory.h"
#include "VideoCommon/DriverDetails.h"
#include "VideoCommon/NativeVertexFormat.h"
@@ -39,8 +41,11 @@ void ClearUnusedPixelShaderUidBits(APIType api_type, const ShaderHostConfig& hos
{
pixel_ubershader_uid_data* const uid_data = uid->GetUidData();
+ // With fbfetch, ubershaders always blend using that and don't use dual src
+ if (host_config.backend_shader_framebuffer_fetch || !host_config.backend_dual_source_blend)
+ uid_data->no_dual_src = 1;
// Dual source is always enabled in the shader if this bug is not present
- if (!DriverDetails::HasBug(DriverDetails::BUG_BROKEN_DUAL_SOURCE_BLENDING))
+ else if (!DriverDetails::HasBug(DriverDetails::BUG_BROKEN_DUAL_SOURCE_BLENDING))
uid_data->no_dual_src = 0;
// OpenGL and Vulkan convert implicitly normalized color outputs to their uint representation.
@@ -57,20 +62,17 @@ ShaderCode GenPixelShader(APIType api_type, const ShaderHostConfig& host_config,
const bool msaa = host_config.msaa;
const bool ssaa = host_config.ssaa;
const bool stereo = host_config.stereo;
+ const bool use_framebuffer_fetch = host_config.backend_shader_framebuffer_fetch;
const bool use_dual_source = host_config.backend_dual_source_blend && !uid_data->no_dual_src;
- const bool use_shader_blend = !host_config.backend_dual_source_blend &&
- host_config.backend_shader_framebuffer_fetch;
- const bool use_shader_logic_op =
- !host_config.backend_logic_op && host_config.backend_shader_framebuffer_fetch;
- const bool use_framebuffer_fetch =
- use_shader_blend || use_shader_logic_op ||
- DriverDetails::HasBug(DriverDetails::BUG_BROKEN_DISCARD_WITH_EARLY_Z);
const bool early_depth = uid_data->early_depth != 0;
const bool per_pixel_depth = uid_data->per_pixel_depth != 0;
const bool bounding_box = host_config.bounding_box;
const u32 numTexgen = uid_data->num_texgens;
ShaderCode out;
+ ASSERT_MSG(VIDEO, !(use_dual_source && use_framebuffer_fetch),
+ "If you're using framebuffer fetch, you shouldn't need dual source blend!");
+
out.Write("// {}\n", *uid_data);
WriteBitfieldExtractHeader(out, api_type, host_config);
WritePixelShaderCommonHeader(out, api_type, host_config, bounding_box);
@@ -84,9 +86,8 @@ ShaderCode GenPixelShader(APIType api_type, const ShaderHostConfig& host_config,
{
if (use_dual_source)
{
- out.Write("FRAGMENT_OUTPUT_LOCATION_INDEXED(0, 0) out vec4 {};\n"
- "FRAGMENT_OUTPUT_LOCATION_INDEXED(0, 1) out vec4 ocol1;\n",
- use_framebuffer_fetch ? "real_ocol0" : "ocol0");
+ out.Write("FRAGMENT_OUTPUT_LOCATION_INDEXED(0, 0) out vec4 ocol0;\n"
+ "FRAGMENT_OUTPUT_LOCATION_INDEXED(0, 1) out vec4 ocol1;\n");
}
else
{
@@ -525,12 +526,8 @@ ShaderCode GenPixelShader(APIType api_type, const ShaderHostConfig& host_config,
// intermediate value with multiple reads & modifications, so we pull out the "real" output
// value above and use a temporary for calculations, then set the output value once at the
// end of the shader.
- out.Write(" float4 ocol0;\n");
- }
-
- if (use_shader_blend)
- {
- out.Write(" float4 ocol1;\n");
+ out.Write(" float4 ocol0;\n"
+ " float4 ocol1;\n");
}
if (host_config.backend_geometry_shaders && stereo)
@@ -948,8 +945,8 @@ ShaderCode GenPixelShader(APIType api_type, const ShaderHostConfig& host_config,
{
// Instead of using discard, fetch the framebuffer's color value and use it as the output
// for this fragment.
- out.Write(" #define discard_fragment {{ {} = float4(initial_ocol0.xyz, 1.0); return; }}\n",
- use_shader_blend ? "real_ocol0" : "ocol0");
+ out.Write(
+ " #define discard_fragment {{ real_ocol0 = float4(initial_ocol0.xyz, 1.0); return; }}\n");
}
else
{
@@ -1060,7 +1057,7 @@ ShaderCode GenPixelShader(APIType api_type, const ShaderHostConfig& host_config,
" }}\n"
"\n");
- if (use_shader_logic_op)
+ if (use_framebuffer_fetch)
{
static constexpr std::array<const char*, 16> logic_op_mode{
"int4(0, 0, 0, 0)", // CLEAR
@@ -1117,7 +1114,7 @@ ShaderCode GenPixelShader(APIType api_type, const ShaderHostConfig& host_config,
" ocol0.a = float(TevResult.a >> 2) / 63.0;\n"
" \n");
- if (use_dual_source || use_shader_blend)
+ if (use_dual_source || use_framebuffer_fetch)
{
out.Write(" // Dest alpha override (dual source blending)\n"
" // Colors will be blended against the alpha from ocol1 and\n"
@@ -1133,7 +1130,7 @@ ShaderCode GenPixelShader(APIType api_type, const ShaderHostConfig& host_config,
" }}\n");
}
- if (use_shader_blend)
+ if (use_framebuffer_fetch)
{
using Common::EnumMap;
@@ -1212,10 +1209,6 @@ ShaderCode GenPixelShader(APIType api_type, const ShaderHostConfig& host_config,
" real_ocol0 = ocol0;\n"
" }}\n");
}
- else if (use_framebuffer_fetch)
- {
- out.Write(" real_ocol0 = ocol0;\n");
- }
out.Write("}}\n"
"\n"