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
This commit is contained in:
parent
6ab24e6c17
commit
991024173e
|
@ -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;
|
||||
|
|
|
@ -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"
|
||||
|
|
Loading…
Reference in New Issue