mirror of https://github.com/PCSX2/pcsx2.git
GS: Remove separate alpha pass fallback
This is just wrong when overlap and depth writes are involved.
This commit is contained in:
parent
0d61f154d7
commit
0917d49a01
|
@ -76,8 +76,6 @@
|
|||
#define PS_TEX_IS_FB 0
|
||||
#define PS_NO_COLOR 0
|
||||
#define PS_NO_COLOR1 0
|
||||
#define PS_NO_ABLEND 0
|
||||
#define PS_ONLY_ALPHA 0
|
||||
#define PS_DATE 0
|
||||
#endif
|
||||
|
||||
|
@ -1127,18 +1125,9 @@ PS_OUTPUT ps_main(PS_INPUT input)
|
|||
#if !PS_NO_COLOR1
|
||||
output.c1 = alpha_blend;
|
||||
#endif
|
||||
#endif // !PS_NO_COLOR
|
||||
|
||||
#if PS_NO_ABLEND
|
||||
// write alpha blend factor into col0
|
||||
output.c0.a = alpha_blend.a;
|
||||
#endif
|
||||
#if PS_ONLY_ALPHA
|
||||
// rgb isn't used
|
||||
output.c0.rgb = float3(0.0f, 0.0f, 0.0f);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#endif
|
||||
#endif // PS_DATE != 1/2
|
||||
|
||||
#if PS_ZCLAMP
|
||||
output.depth = min(input.p.z, MaxDepthPS);
|
||||
|
|
|
@ -86,15 +86,13 @@ in SHADER
|
|||
#endif
|
||||
#endif
|
||||
|
||||
#if !PS_NO_COLOR
|
||||
#if !defined(DISABLE_DUAL_SOURCE) && !PS_NO_COLOR1
|
||||
#if !PS_NO_COLOR && !PS_NO_COLOR1
|
||||
// Same buffer but 2 colors for dual source blending
|
||||
layout(location = 0, index = 0) TARGET_0_QUALIFIER vec4 SV_Target0;
|
||||
layout(location = 0, index = 1) out vec4 SV_Target1;
|
||||
#else
|
||||
#elif !PS_NO_COLOR
|
||||
layout(location = 0) TARGET_0_QUALIFIER vec4 SV_Target0;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if NEEDS_TEX
|
||||
layout(binding = 0) uniform sampler2D TextureSampler;
|
||||
|
@ -1118,15 +1116,6 @@ void ps_main()
|
|||
#if !defined(DISABLE_DUAL_SOURCE) && !PS_NO_COLOR1
|
||||
SV_Target1 = alpha_blend;
|
||||
#endif
|
||||
|
||||
#if PS_NO_ABLEND
|
||||
// write alpha blend factor into col0
|
||||
SV_Target0.a = alpha_blend.a;
|
||||
#endif
|
||||
#if PS_ONLY_ALPHA
|
||||
// rgb isn't used
|
||||
SV_Target0.rgb = vec3(0.0f);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if PS_ZCLAMP
|
||||
|
|
|
@ -335,7 +335,7 @@ layout(location = 0) in VSOutput
|
|||
#endif
|
||||
} vsIn;
|
||||
|
||||
#if !defined(DISABLE_DUAL_SOURCE) && !PS_NO_COLOR1
|
||||
#if !PS_NO_COLOR && !PS_NO_COLOR1
|
||||
layout(location = 0, index = 0) out vec4 o_col0;
|
||||
layout(location = 0, index = 1) out vec4 o_col1;
|
||||
#elif !PS_NO_COLOR
|
||||
|
@ -1368,18 +1368,9 @@ void main()
|
|||
#else
|
||||
o_col0.rgb = C.rgb / 255.0f;
|
||||
#endif
|
||||
#if !defined(DISABLE_DUAL_SOURCE) && !PS_NO_COLOR1
|
||||
#if !PS_NO_COLOR1
|
||||
o_col1 = alpha_blend;
|
||||
#endif
|
||||
|
||||
#if PS_NO_ABLEND
|
||||
// write alpha blend factor into col0
|
||||
o_col0.a = alpha_blend.a;
|
||||
#endif
|
||||
#if PS_ONLY_ALPHA
|
||||
// rgb isn't used
|
||||
o_col0.rgb = vec3(0.0f);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if PS_ZCLAMP
|
||||
|
|
|
@ -230,7 +230,6 @@ GraphicsSettingsWidget::GraphicsSettingsWidget(SettingsWindow* dialog, QWidget*
|
|||
SettingWidgetBinder::BindWidgetToIntSetting(
|
||||
sif, m_ui.gsDumpCompression, "EmuCore/GS", "GSDumpCompression", static_cast<int>(GSDumpCompressionMethod::Zstandard));
|
||||
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.disableFramebufferFetch, "EmuCore/GS", "DisableFramebufferFetch", false);
|
||||
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.disableDualSource, "EmuCore/GS", "DisableDualSourceBlend", false);
|
||||
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.disableShaderCache, "EmuCore/GS", "DisableShaderCache", false);
|
||||
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.disableVertexShaderExpand, "EmuCore/GS", "DisableVertexShaderExpand", false);
|
||||
SettingWidgetBinder::BindWidgetToIntSetting(
|
||||
|
@ -334,7 +333,6 @@ GraphicsSettingsWidget::GraphicsSettingsWidget(SettingsWindow* dialog, QWidget*
|
|||
m_ui.skipPresentingDuplicateFrames = nullptr;
|
||||
m_ui.threadedPresentation = nullptr;
|
||||
m_ui.overrideTextureBarriers = nullptr;
|
||||
m_ui.disableDualSource = nullptr;
|
||||
m_ui.disableFramebufferFetch = nullptr;
|
||||
m_ui.disableShaderCache = nullptr;
|
||||
m_ui.disableVertexShaderExpand = nullptr;
|
||||
|
|
|
@ -2151,13 +2151,6 @@
|
|||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
<widget class="QCheckBox" name="disableDualSource">
|
||||
<property name="text">
|
||||
<string>Disable Dual-Source Blending</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QCheckBox" name="disableShaderCache">
|
||||
<property name="text">
|
||||
|
@ -2165,13 +2158,6 @@
|
|||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QCheckBox" name="useDebugDevice">
|
||||
<property name="text">
|
||||
<string>Use Debug Device</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QCheckBox" name="disableVertexShaderExpand">
|
||||
<property name="text">
|
||||
|
@ -2179,6 +2165,13 @@
|
|||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
<widget class="QCheckBox" name="useDebugDevice">
|
||||
<property name="text">
|
||||
<string>Use Debug Device</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
|
|
|
@ -594,7 +594,6 @@ struct Pcsx2Config
|
|||
UseDebugDevice : 1,
|
||||
UseBlitSwapChain : 1,
|
||||
DisableShaderCache : 1,
|
||||
DisableDualSourceBlend : 1,
|
||||
DisableFramebufferFetch : 1,
|
||||
DisableVertexShaderExpand : 1,
|
||||
DisableThreadedPresentation : 1,
|
||||
|
|
|
@ -787,33 +787,6 @@ bool GSDevice::ResizeRenderTarget(GSTexture** t, int w, int h, bool preserve_con
|
|||
return true;
|
||||
}
|
||||
|
||||
void GSDevice::SetHWDrawConfigForAlphaPass(GSHWDrawConfig::PSSelector* ps,
|
||||
GSHWDrawConfig::ColorMaskSelector* cms,
|
||||
GSHWDrawConfig::BlendState* bs,
|
||||
GSHWDrawConfig::DepthStencilSelector* dss)
|
||||
{
|
||||
// only need to compute the alpha component (allow the shader to optimize better)
|
||||
ps->no_ablend = false;
|
||||
ps->only_alpha = true;
|
||||
|
||||
// definitely don't need to compute software blend (this may get rid of some barriers)
|
||||
ps->blend_a = ps->blend_b = ps->blend_c = ps->blend_d = 0;
|
||||
|
||||
// only write alpha (RGB=0,A=1)
|
||||
cms->wrgba = (1 << 3);
|
||||
|
||||
// no need for hardware blending, since we're not writing RGB
|
||||
bs->enable = false;
|
||||
|
||||
// if depth writes are on, we can optimize to an EQUAL test, otherwise we leave the tests alone
|
||||
// since the alpha channel isn't blended, the last fragment wins and this'll be okay
|
||||
if (dss->zwe)
|
||||
{
|
||||
dss->zwe = false;
|
||||
dss->ztst = ZTST_GEQUAL;
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(__clang__)
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wunused-function"
|
||||
|
@ -887,26 +860,6 @@ void GSDevice::CAS(GSTexture*& tex, GSVector4i& src_rect, GSVector4& src_uv, con
|
|||
|
||||
// clang-format off
|
||||
|
||||
const std::array<u8, 16> GSDevice::m_replaceDualSrcBlendMap =
|
||||
{{
|
||||
SRC_COLOR, // SRC_COLOR
|
||||
INV_SRC_COLOR, // INV_SRC_COLOR
|
||||
DST_COLOR, // DST_COLOR
|
||||
INV_DST_COLOR, // INV_DST_COLOR
|
||||
SRC_COLOR, // SRC1_COLOR
|
||||
INV_SRC_COLOR, // INV_SRC1_COLOR
|
||||
SRC_ALPHA, // SRC_ALPHA
|
||||
INV_SRC_ALPHA, // INV_SRC_ALPHA
|
||||
DST_ALPHA, // DST_ALPHA
|
||||
INV_DST_ALPHA, // INV_DST_ALPHA
|
||||
SRC_ALPHA, // SRC1_ALPHA
|
||||
INV_SRC_ALPHA, // INV_SRC1_ALPHA
|
||||
CONST_COLOR, // CONST_COLOR
|
||||
INV_CONST_COLOR, // INV_CONST_COLOR
|
||||
CONST_ONE, // CONST_ONE
|
||||
CONST_ZERO // CONST_ZERO
|
||||
}};
|
||||
|
||||
const std::array<HWBlend, 3*3*3*3> GSDevice::m_blendMap =
|
||||
{{
|
||||
{ BLEND_NO_REC , OP_ADD , CONST_ONE , CONST_ZERO} , // 0000: (Cs - Cs)*As + Cs ==> Cs
|
||||
|
|
|
@ -340,8 +340,6 @@ struct alignas(16) GSHWDrawConfig
|
|||
u32 pabe : 1;
|
||||
u32 no_color : 1; // disables color output entirely (depth only)
|
||||
u32 no_color1 : 1; // disables second color output (when unnecessary)
|
||||
u32 no_ablend : 1; // output alpha blend in col0 (for no-DSB)
|
||||
u32 only_alpha : 1; // don't bother computing RGB
|
||||
|
||||
// Others ways to fetch the texture
|
||||
u32 channel : 3;
|
||||
|
@ -671,8 +669,6 @@ struct alignas(16) GSHWDrawConfig
|
|||
DestinationAlphaMode destination_alpha;
|
||||
SetDATM datm : 2;
|
||||
bool line_expand : 1;
|
||||
bool separate_alpha_pass : 1;
|
||||
bool second_separate_alpha_pass : 1;
|
||||
|
||||
struct AlphaPass
|
||||
{
|
||||
|
@ -763,7 +759,6 @@ private:
|
|||
u64 m_pool_memory_usage = 0;
|
||||
|
||||
static const std::array<HWBlend, 3*3*3*3> m_blendMap;
|
||||
static const std::array<u8, 16> m_replaceDualSrcBlendMap;
|
||||
|
||||
protected:
|
||||
static constexpr int NUM_INTERLACE_SHADERS = 5;
|
||||
|
@ -970,28 +965,8 @@ public:
|
|||
|
||||
// Convert the GS blend equations to HW blend factors/ops
|
||||
// Index is computed as ((((A * 3 + B) * 3) + C) * 3) + D. A, B, C, D taken from ALPHA register.
|
||||
__ri static HWBlend GetBlend(u32 index, bool replace_dual_src)
|
||||
{
|
||||
HWBlend ret = m_blendMap[index];
|
||||
if (replace_dual_src)
|
||||
{
|
||||
ret.src = m_replaceDualSrcBlendMap[ret.src];
|
||||
ret.dst = m_replaceDualSrcBlendMap[ret.dst];
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
__ri static HWBlend GetBlend(u32 index) { return m_blendMap[index]; }
|
||||
__ri static u16 GetBlendFlags(u32 index) { return m_blendMap[index].flags; }
|
||||
__fi static bool IsDualSourceBlend(u32 index)
|
||||
{
|
||||
return (IsDualSourceBlendFactor(m_blendMap[index].src) ||
|
||||
IsDualSourceBlendFactor(m_blendMap[index].dst));
|
||||
}
|
||||
|
||||
/// Alters the pipeline configuration for drawing the separate alpha pass.
|
||||
static void SetHWDrawConfigForAlphaPass(GSHWDrawConfig::PSSelector* ps,
|
||||
GSHWDrawConfig::ColorMaskSelector* cms,
|
||||
GSHWDrawConfig::BlendState* bs,
|
||||
GSHWDrawConfig::DepthStencilSelector* dss);
|
||||
};
|
||||
|
||||
template <>
|
||||
|
|
|
@ -1710,8 +1710,6 @@ void GSDevice11::SetupPS(const PSSelector& sel, const GSHWDrawConfig::PSConstant
|
|||
sm.AddMacro("PS_TEX_IS_FB", sel.tex_is_fb);
|
||||
sm.AddMacro("PS_NO_COLOR", sel.no_color);
|
||||
sm.AddMacro("PS_NO_COLOR1", sel.no_color1);
|
||||
sm.AddMacro("PS_NO_ABLEND", sel.no_ablend);
|
||||
sm.AddMacro("PS_ONLY_ALPHA", sel.only_alpha);
|
||||
|
||||
wil::com_ptr_nothrow<ID3D11PixelShader> ps = m_shader_cache.GetPixelShader(m_dev.get(), m_tfx_source, sm.GetPtr(), "ps_main");
|
||||
i = m_ps.try_emplace(sel, std::move(ps)).first;
|
||||
|
@ -2619,15 +2617,6 @@ void GSDevice11::RenderHW(GSHWDrawConfig& config)
|
|||
OMSetRenderTargets(hdr_rt ? hdr_rt : config.rt, config.ds, &config.scissor);
|
||||
DrawIndexedPrimitive();
|
||||
|
||||
if (config.separate_alpha_pass)
|
||||
{
|
||||
GSHWDrawConfig::BlendState sap_blend = {};
|
||||
SetHWDrawConfigForAlphaPass(&config.ps, &config.colormask, &sap_blend, &config.depth);
|
||||
SetupOM(config.depth, convertSel(config.colormask, sap_blend), config.blend.constant);
|
||||
SetupPS(config.ps, &config.cb_ps, config.sampler);
|
||||
DrawIndexedPrimitive();
|
||||
}
|
||||
|
||||
if (config.alpha_second_pass.enable)
|
||||
{
|
||||
preprocessSel(config.alpha_second_pass.ps);
|
||||
|
@ -2644,15 +2633,6 @@ void GSDevice11::RenderHW(GSHWDrawConfig& config)
|
|||
|
||||
SetupOM(config.alpha_second_pass.depth, convertSel(config.alpha_second_pass.colormask, config.blend), config.blend.constant);
|
||||
DrawIndexedPrimitive();
|
||||
|
||||
if (config.second_separate_alpha_pass)
|
||||
{
|
||||
GSHWDrawConfig::BlendState sap_blend = {};
|
||||
SetHWDrawConfigForAlphaPass(&config.alpha_second_pass.ps, &config.alpha_second_pass.colormask, &sap_blend, &config.alpha_second_pass.depth);
|
||||
SetupOM(config.alpha_second_pass.depth, convertSel(config.alpha_second_pass.colormask, sap_blend), config.blend.constant);
|
||||
SetupPS(config.alpha_second_pass.ps, &config.cb_ps, config.sampler);
|
||||
DrawIndexedPrimitive();
|
||||
}
|
||||
}
|
||||
|
||||
if (rt_copy)
|
||||
|
|
|
@ -2864,8 +2864,6 @@ const ID3DBlob* GSDevice12::GetTFXPixelShader(const GSHWDrawConfig::PSSelector&
|
|||
sm.AddMacro("PS_TEX_IS_FB", sel.tex_is_fb);
|
||||
sm.AddMacro("PS_NO_COLOR", sel.no_color);
|
||||
sm.AddMacro("PS_NO_COLOR1", sel.no_color1);
|
||||
sm.AddMacro("PS_NO_ABLEND", sel.no_ablend);
|
||||
sm.AddMacro("PS_ONLY_ALPHA", sel.only_alpha);
|
||||
|
||||
ComPtr<ID3DBlob> ps(m_shader_cache.GetPixelShader(m_tfx_source, sm.GetPtr(), "ps_main"));
|
||||
it = m_tfx_pixel_shaders.emplace(sel, std::move(ps)).first;
|
||||
|
@ -3924,17 +3922,8 @@ void GSDevice12::RenderHW(GSHWDrawConfig& config)
|
|||
|
||||
// now we can do the actual draw
|
||||
if (BindDrawPipeline(pipe))
|
||||
{
|
||||
DrawIndexedPrimitive();
|
||||
|
||||
if (config.second_separate_alpha_pass)
|
||||
{
|
||||
SetHWDrawConfigForAlphaPass(&pipe.ps, &pipe.cms, &pipe.bs, &pipe.dss);
|
||||
if (BindDrawPipeline(pipe))
|
||||
DrawIndexedPrimitive();
|
||||
}
|
||||
}
|
||||
|
||||
// and the alpha pass
|
||||
if (config.alpha_second_pass.enable)
|
||||
{
|
||||
|
@ -3950,16 +3939,7 @@ void GSDevice12::RenderHW(GSHWDrawConfig& config)
|
|||
pipe.dss = config.alpha_second_pass.depth;
|
||||
pipe.bs = config.blend;
|
||||
if (BindDrawPipeline(pipe))
|
||||
{
|
||||
DrawIndexedPrimitive();
|
||||
|
||||
if (config.second_separate_alpha_pass)
|
||||
{
|
||||
SetHWDrawConfigForAlphaPass(&pipe.ps, &pipe.cms, &pipe.bs, &pipe.dss);
|
||||
if (BindDrawPipeline(pipe))
|
||||
DrawIndexedPrimitive();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (draw_rt_clone)
|
||||
|
|
|
@ -3784,7 +3784,7 @@ __ri bool GSRendererHW::EmulateChannelShuffle(GSTextureCache::Target* src, bool
|
|||
return true;
|
||||
}
|
||||
|
||||
void GSRendererHW::EmulateBlending(int rt_alpha_min, int rt_alpha_max, bool& DATE_PRIMID, bool& DATE_BARRIER, bool& blending_alpha_pass, GSTextureCache::Target* rt)
|
||||
void GSRendererHW::EmulateBlending(int rt_alpha_min, int rt_alpha_max, bool& DATE_PRIMID, bool& DATE_BARRIER, GSTextureCache::Target* rt)
|
||||
{
|
||||
{
|
||||
// AA1: Blending needs to be enabled on draw.
|
||||
|
@ -3928,7 +3928,7 @@ void GSRendererHW::EmulateBlending(int rt_alpha_min, int rt_alpha_max, bool& DAT
|
|||
blend_ad_alpha_masked = false;
|
||||
|
||||
u8 blend_index = static_cast<u8>(((m_conf.ps.blend_a * 3 + m_conf.ps.blend_b) * 3 + m_conf.ps.blend_c) * 3 + m_conf.ps.blend_d);
|
||||
const HWBlend blend_preliminary = GSDevice::GetBlend(blend_index, false);
|
||||
const HWBlend blend_preliminary = GSDevice::GetBlend(blend_index);
|
||||
const int blend_flag = blend_preliminary.flags;
|
||||
|
||||
// Re set alpha, it was modified, must be done after index calculation
|
||||
|
@ -4068,33 +4068,7 @@ void GSRendererHW::EmulateBlending(int rt_alpha_min, int rt_alpha_max, bool& DAT
|
|||
}
|
||||
}
|
||||
|
||||
bool replace_dual_src = false;
|
||||
if (!features.dual_source_blend && GSDevice::IsDualSourceBlend(blend_index))
|
||||
{
|
||||
// if we don't have an alpha channel, we don't need a second pass, just output the alpha blend
|
||||
// in the single colour's alpha chnanel, and blend with it
|
||||
if (!m_conf.colormask.wa)
|
||||
{
|
||||
GL_INS("Outputting alpha blend in col0 because of no alpha write");
|
||||
m_conf.ps.no_ablend = true;
|
||||
replace_dual_src = true;
|
||||
}
|
||||
else if (features.framebuffer_fetch || m_conf.require_one_barrier || m_conf.require_full_barrier)
|
||||
{
|
||||
// prefer single pass sw blend (if barrier) or framebuffer fetch over dual pass alpha when supported
|
||||
sw_blending = true;
|
||||
color_dest_blend = false;
|
||||
accumulation_blend &= !features.framebuffer_fetch;
|
||||
blend_mix = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
// split the draw into two
|
||||
blending_alpha_pass = true;
|
||||
replace_dual_src = true;
|
||||
}
|
||||
}
|
||||
else if (features.framebuffer_fetch)
|
||||
if (features.framebuffer_fetch)
|
||||
{
|
||||
// If we have fbfetch, use software blending when we need the fb value for anything else.
|
||||
// This saves outputting the second color when it's not needed.
|
||||
|
@ -4209,12 +4183,11 @@ void GSRendererHW::EmulateBlending(int rt_alpha_min, int rt_alpha_max, bool& DAT
|
|||
if (m_conf.ps.blend_c == 2)
|
||||
m_conf.cb_ps.TA_MaxDepth_Af.a = static_cast<float>(AFIX) / 128.0f;
|
||||
|
||||
const HWBlend blend = GSDevice::GetBlend(blend_index, replace_dual_src);
|
||||
const HWBlend blend = GSDevice::GetBlend(blend_index);
|
||||
if (accumulation_blend)
|
||||
{
|
||||
// Keep HW blending to do the addition/subtraction
|
||||
m_conf.blend = {true, GSDevice::CONST_ONE, GSDevice::CONST_ONE, blend.op, false, 0};
|
||||
blending_alpha_pass = false;
|
||||
|
||||
// Remove Cd from sw blend, it's handled in hw
|
||||
if (m_conf.ps.blend_a == 1)
|
||||
|
@ -4319,8 +4292,6 @@ void GSRendererHW::EmulateBlending(int rt_alpha_min, int rt_alpha_max, bool& DAT
|
|||
// Disable HW blending
|
||||
m_conf.blend = {};
|
||||
m_conf.ps.no_color1 = true;
|
||||
replace_dual_src = false;
|
||||
blending_alpha_pass = false;
|
||||
|
||||
// No need to set a_masked bit for blend_ad_alpha_masked case
|
||||
const bool blend_non_recursive_one_barrier = blend_non_recursive && blend_ad_alpha_masked;
|
||||
|
@ -4364,7 +4335,7 @@ void GSRendererHW::EmulateBlending(int rt_alpha_min, int rt_alpha_max, bool& DAT
|
|||
m_conf.ps.blend_hw = 3;
|
||||
}
|
||||
|
||||
const HWBlend blend(GSDevice::GetBlend(blend_index, replace_dual_src));
|
||||
const HWBlend blend = GSDevice::GetBlend(blend_index);
|
||||
m_conf.blend = {true, blend.src, blend.dst, blend.op, m_conf.ps.blend_c == 2, AFIX};
|
||||
|
||||
// Remove second color output when unused. Works around bugs in some drivers (e.g. Intel).
|
||||
|
@ -5441,10 +5412,9 @@ __ri void GSRendererHW::DrawPrims(GSTextureCache::Target* rt, GSTextureCache::Ta
|
|||
m_conf.ps.rta_correction = rt->m_rt_alpha_scale;
|
||||
}
|
||||
|
||||
bool blending_alpha_pass = false;
|
||||
if ((!IsOpaque() || m_context->ALPHA.IsBlack()) && rt && ((m_conf.colormask.wrgba & 0x7) || (m_texture_shuffle && !m_copy_16bit_to_target_shuffle && !m_same_group_texture_shuffle)))
|
||||
{
|
||||
EmulateBlending(blend_alpha_min, blend_alpha_max, DATE_PRIMID, DATE_BARRIER, blending_alpha_pass, rt);
|
||||
EmulateBlending(blend_alpha_min, blend_alpha_max, DATE_PRIMID, DATE_BARRIER, rt);
|
||||
|
||||
if (req_src_update && tex->m_texture != rt->m_texture)
|
||||
tex->m_texture = rt->m_texture;
|
||||
|
@ -5775,35 +5745,6 @@ __ri void GSRendererHW::DrawPrims(GSTextureCache::Target* rt, GSTextureCache::Ta
|
|||
m_conf.alpha_second_pass.enable = false;
|
||||
}
|
||||
|
||||
if (blending_alpha_pass)
|
||||
{
|
||||
// write alpha blend as the single alpha output
|
||||
m_conf.ps.no_ablend = true;
|
||||
|
||||
// there's a case we can skip this: RGB_then_ZA alternate handling.
|
||||
// but otherwise, we need to write alpha separately.
|
||||
if (m_conf.colormask.wa)
|
||||
{
|
||||
m_conf.colormask.wa = false;
|
||||
m_conf.separate_alpha_pass = true;
|
||||
}
|
||||
|
||||
// do we need to do this for the failed alpha fragments?
|
||||
if (m_conf.alpha_second_pass.enable)
|
||||
{
|
||||
// there's also a case we can skip here: when we're not writing RGB, there's
|
||||
// no blending, so we can just write the normal alpha!
|
||||
const u8 second_pass_wrgba = m_conf.alpha_second_pass.colormask.wrgba;
|
||||
if ((second_pass_wrgba & (1 << 3)) != 0 && second_pass_wrgba != (1 << 3))
|
||||
{
|
||||
// this sucks. potentially up to 4 passes. but no way around it when we don't have dual-source blend.
|
||||
m_conf.alpha_second_pass.ps.no_ablend = true;
|
||||
m_conf.alpha_second_pass.colormask.wa = false;
|
||||
m_conf.second_separate_alpha_pass = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
m_conf.drawlist = (m_conf.require_full_barrier && m_vt.m_primclass == GS_SPRITE_CLASS) ? &m_drawlist : nullptr;
|
||||
|
||||
g_gs_device->RenderHW(m_conf);
|
||||
|
@ -7069,8 +7010,6 @@ GSHWDrawConfig& GSRendererHW::BeginHLEHardwareDraw(
|
|||
config.destination_alpha = GSHWDrawConfig::DestinationAlphaMode::Off;
|
||||
config.datm = SetDATM::DATM0;
|
||||
config.line_expand = false;
|
||||
config.separate_alpha_pass = false;
|
||||
config.second_separate_alpha_pass = false;
|
||||
config.alpha_second_pass.enable = false;
|
||||
config.vs.key = 0;
|
||||
config.vs.tme = tex != nullptr;
|
||||
|
|
|
@ -88,7 +88,7 @@ private:
|
|||
void SetupIA(float target_scale, float sx, float sy);
|
||||
void EmulateTextureShuffleAndFbmask(GSTextureCache::Target* rt, GSTextureCache::Source* tex);
|
||||
bool EmulateChannelShuffle(GSTextureCache::Target* src, bool test_only);
|
||||
void EmulateBlending(int rt_alpha_min, int rt_alpha_max, bool& DATE_PRIMID, bool& DATE_BARRIER, bool& blending_alpha_pass, GSTextureCache::Target* rt);
|
||||
void EmulateBlending(int rt_alpha_min, int rt_alpha_max, bool& DATE_PRIMID, bool& DATE_BARRIER, GSTextureCache::Target* rt);
|
||||
void CleanupDraw(bool invalidate_temp_src);
|
||||
|
||||
void EmulateTextureSampler(const GSTextureCache::Target* rt, const GSTextureCache::Target* ds,
|
||||
|
|
|
@ -1836,8 +1836,6 @@ void GSDeviceMTL::MRESetHWPipelineState(GSHWDrawConfig::VSSelector vssel, GSHWDr
|
|||
setFnConstantB(m_fn_constants, pssel.pabe, GSMTLConstantIndex_PS_PABE);
|
||||
setFnConstantB(m_fn_constants, pssel.no_color, GSMTLConstantIndex_PS_NO_COLOR);
|
||||
setFnConstantB(m_fn_constants, pssel.no_color1, GSMTLConstantIndex_PS_NO_COLOR1);
|
||||
// no_ablend ignored for now (No Metal driver has had DSB so broken that it's needed to be disabled, though Intel's was pretty close)
|
||||
setFnConstantB(m_fn_constants, pssel.only_alpha, GSMTLConstantIndex_PS_ONLY_ALPHA);
|
||||
setFnConstantI(m_fn_constants, pssel.channel, GSMTLConstantIndex_PS_CHANNEL);
|
||||
setFnConstantI(m_fn_constants, pssel.dither, GSMTLConstantIndex_PS_DITHER);
|
||||
setFnConstantI(m_fn_constants, pssel.dither_adjust, GSMTLConstantIndex_PS_DITHER_ADJUST);
|
||||
|
|
|
@ -193,7 +193,6 @@ enum GSMTLFnConstants
|
|||
GSMTLConstantIndex_PS_PABE,
|
||||
GSMTLConstantIndex_PS_NO_COLOR,
|
||||
GSMTLConstantIndex_PS_NO_COLOR1,
|
||||
GSMTLConstantIndex_PS_ONLY_ALPHA,
|
||||
GSMTLConstantIndex_PS_CHANNEL,
|
||||
GSMTLConstantIndex_PS_DITHER,
|
||||
GSMTLConstantIndex_PS_DITHER_ADJUST,
|
||||
|
|
|
@ -56,7 +56,6 @@ constant bool PS_FIXED_ONE_A [[function_constant(GSMTLConstantIndex_PS_FI
|
|||
constant bool PS_PABE [[function_constant(GSMTLConstantIndex_PS_PABE)]];
|
||||
constant bool PS_NO_COLOR [[function_constant(GSMTLConstantIndex_PS_NO_COLOR)]];
|
||||
constant bool PS_NO_COLOR1 [[function_constant(GSMTLConstantIndex_PS_NO_COLOR1)]];
|
||||
constant bool PS_ONLY_ALPHA [[function_constant(GSMTLConstantIndex_PS_ONLY_ALPHA)]];
|
||||
constant uint PS_CHANNEL [[function_constant(GSMTLConstantIndex_PS_CHANNEL)]];
|
||||
constant uint PS_DITHER [[function_constant(GSMTLConstantIndex_PS_DITHER)]];
|
||||
constant uint PS_DITHER_ADJUST [[function_constant(GSMTLConstantIndex_PS_DITHER_ADJUST)]];
|
||||
|
@ -1193,8 +1192,6 @@ struct PSMain
|
|||
if (PS_COLOR0)
|
||||
out.c0.a = PS_RTA_CORRECTION ? C.a / 128.f : C.a / 255.f;
|
||||
out.c0.rgb = PS_HDR ? float3(C.rgb / 65535.f) : C.rgb / 255.f;
|
||||
if (PS_COLOR0 && PS_ONLY_ALPHA)
|
||||
out.c0.rgb = 0;
|
||||
if (PS_COLOR1)
|
||||
out.c1 = alpha_blend;
|
||||
if (PS_ZCLAMP)
|
||||
|
|
|
@ -733,7 +733,7 @@ bool GSDeviceOGL::CheckFeatures(bool& buggy_pbo)
|
|||
m_features.bptc_textures =
|
||||
GLAD_GL_VERSION_4_2 || GLAD_GL_ARB_texture_compression_bptc || GLAD_GL_EXT_texture_compression_bptc;
|
||||
m_features.prefer_new_textures = false;
|
||||
m_features.dual_source_blend = !GSConfig.DisableDualSourceBlend;
|
||||
m_features.dual_source_blend = true;
|
||||
m_features.clip_control = GLAD_GL_ARB_clip_control;
|
||||
if (!m_features.clip_control)
|
||||
Host::AddOSDMessage(
|
||||
|
@ -1386,8 +1386,6 @@ std::string GSDeviceOGL::GetPSSource(const PSSelector& sel)
|
|||
+ fmt::format("#define PS_SCANMSK {}\n", sel.scanmsk)
|
||||
+ fmt::format("#define PS_NO_COLOR {}\n", sel.no_color)
|
||||
+ fmt::format("#define PS_NO_COLOR1 {}\n", sel.no_color1)
|
||||
+ fmt::format("#define PS_NO_ABLEND {}\n", sel.no_ablend)
|
||||
+ fmt::format("#define PS_ONLY_ALPHA {}\n", sel.only_alpha)
|
||||
;
|
||||
|
||||
std::string src = GenGlslHeader("ps_main", GL_FRAGMENT_SHADER, macro);
|
||||
|
@ -2244,15 +2242,6 @@ void GSDeviceOGL::OMSetBlendState(bool enable, GLenum src_factor, GLenum dst_fac
|
|||
{
|
||||
if (GLState::blend)
|
||||
{
|
||||
// make sure we're not using dual source
|
||||
if (GLState::f_sRGB == GL_SRC1_ALPHA || GLState::f_sRGB == GL_ONE_MINUS_SRC1_ALPHA ||
|
||||
GLState::f_dRGB == GL_SRC1_ALPHA || GLState::f_dRGB == GL_ONE_MINUS_SRC1_ALPHA)
|
||||
{
|
||||
glBlendFuncSeparate(GL_ONE, GL_ZERO, GL_ONE, GL_ZERO);
|
||||
GLState::f_sRGB = GL_ONE;
|
||||
GLState::f_dRGB = GL_ZERO;
|
||||
}
|
||||
|
||||
GLState::blend = false;
|
||||
glDisable(GL_BLEND);
|
||||
}
|
||||
|
@ -2570,25 +2559,6 @@ void GSDeviceOGL::RenderHW(GSHWDrawConfig& config)
|
|||
|
||||
SendHWDraw(config, psel.ps.IsFeedbackLoop());
|
||||
|
||||
if (config.separate_alpha_pass)
|
||||
{
|
||||
GSHWDrawConfig::BlendState dummy_bs;
|
||||
SetHWDrawConfigForAlphaPass(&psel.ps, &config.colormask, &dummy_bs, &config.depth);
|
||||
SetupPipeline(psel);
|
||||
OMSetColorMaskState(config.alpha_second_pass.colormask);
|
||||
SetupOM(config.alpha_second_pass.depth);
|
||||
OMSetBlendState();
|
||||
SendHWDraw(config, psel.ps.IsFeedbackLoop());
|
||||
|
||||
// restore blend state if we're doing a second pass
|
||||
if (config.alpha_second_pass.enable)
|
||||
{
|
||||
OMSetBlendState(config.blend.enable, s_gl_blend_factors[config.blend.src_factor],
|
||||
s_gl_blend_factors[config.blend.dst_factor], s_gl_blend_ops[config.blend.op],
|
||||
config.blend.constant_enable, config.blend.constant);
|
||||
}
|
||||
}
|
||||
|
||||
if (config.alpha_second_pass.enable)
|
||||
{
|
||||
// cbuffer will definitely be dirty if aref changes, no need to check it
|
||||
|
@ -2604,17 +2574,6 @@ void GSDeviceOGL::RenderHW(GSHWDrawConfig& config)
|
|||
OMSetColorMaskState(config.alpha_second_pass.colormask);
|
||||
SetupOM(config.alpha_second_pass.depth);
|
||||
SendHWDraw(config, psel.ps.IsFeedbackLoop());
|
||||
|
||||
if (config.second_separate_alpha_pass)
|
||||
{
|
||||
GSHWDrawConfig::BlendState dummy_bs;
|
||||
SetHWDrawConfigForAlphaPass(&psel.ps, &config.colormask, &dummy_bs, &config.depth);
|
||||
SetupPipeline(psel);
|
||||
OMSetColorMaskState(config.alpha_second_pass.colormask);
|
||||
SetupOM(config.alpha_second_pass.depth);
|
||||
OMSetBlendState();
|
||||
SendHWDraw(config, psel.ps.IsFeedbackLoop());
|
||||
}
|
||||
}
|
||||
|
||||
if (primid_texture)
|
||||
|
|
|
@ -2669,7 +2669,7 @@ bool GSDeviceVK::CheckFeatures()
|
|||
|
||||
m_features.prefer_new_textures = true;
|
||||
m_features.provoking_vertex_last = m_optional_extensions.vk_ext_provoking_vertex;
|
||||
m_features.dual_source_blend = m_device_features.dualSrcBlend && !GSConfig.DisableDualSourceBlend;
|
||||
m_features.dual_source_blend = m_device_features.dualSrcBlend;
|
||||
m_features.clip_control = true;
|
||||
m_features.vs_expand = !GSConfig.DisableVertexShaderExpand;
|
||||
|
||||
|
@ -4830,8 +4830,6 @@ VkShaderModule GSDeviceVK::GetTFXFragmentShader(const GSHWDrawConfig::PSSelector
|
|||
AddMacro(ss, "PS_TEX_IS_FB", sel.tex_is_fb);
|
||||
AddMacro(ss, "PS_NO_COLOR", sel.no_color);
|
||||
AddMacro(ss, "PS_NO_COLOR1", sel.no_color1);
|
||||
AddMacro(ss, "PS_NO_ABLEND", sel.no_ablend);
|
||||
AddMacro(ss, "PS_ONLY_ALPHA", sel.only_alpha);
|
||||
ss << m_tfx_source;
|
||||
|
||||
VkShaderModule mod = g_vulkan_shader_cache->GetFragmentShader(ss.str());
|
||||
|
@ -5850,15 +5848,7 @@ void GSDeviceVK::RenderHW(GSHWDrawConfig& config)
|
|||
|
||||
// now we can do the actual draw
|
||||
if (BindDrawPipeline(pipe))
|
||||
{
|
||||
SendHWDraw(config, draw_rt, skip_first_barrier);
|
||||
if (config.separate_alpha_pass)
|
||||
{
|
||||
SetHWDrawConfigForAlphaPass(&pipe.ps, &pipe.cms, &pipe.bs, &pipe.dss);
|
||||
if (BindDrawPipeline(pipe))
|
||||
SendHWDraw(config, draw_rt, false);
|
||||
}
|
||||
}
|
||||
|
||||
// and the alpha pass
|
||||
if (config.alpha_second_pass.enable)
|
||||
|
@ -5875,15 +5865,7 @@ void GSDeviceVK::RenderHW(GSHWDrawConfig& config)
|
|||
pipe.dss = config.alpha_second_pass.depth;
|
||||
pipe.bs = config.blend;
|
||||
if (BindDrawPipeline(pipe))
|
||||
{
|
||||
SendHWDraw(config, draw_rt, false);
|
||||
if (config.second_separate_alpha_pass)
|
||||
{
|
||||
SetHWDrawConfigForAlphaPass(&pipe.ps, &pipe.cms, &pipe.bs, &pipe.dss);
|
||||
if (BindDrawPipeline(pipe))
|
||||
SendHWDraw(config, draw_rt, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (draw_rt_clone)
|
||||
|
|
|
@ -3556,8 +3556,6 @@ void FullscreenUI::DrawGraphicsSettingsPage()
|
|||
"GSDumpCompression", static_cast<int>(GSDumpCompressionMethod::LZMA), s_gsdump_compression, std::size(s_gsdump_compression), true);
|
||||
DrawToggleSetting(bsi, FSUI_CSTR("Disable Framebuffer Fetch"),
|
||||
FSUI_CSTR("Prevents the usage of framebuffer fetch when supported by host GPU."), "EmuCore/GS", "DisableFramebufferFetch", false);
|
||||
DrawToggleSetting(bsi, FSUI_CSTR("Disable Dual-Source Blending"),
|
||||
FSUI_CSTR("Prevents the usage of dual-source blending when supported by host GPU."), "EmuCore/GS", "DisableDualSourceBlend", false);
|
||||
DrawToggleSetting(bsi, FSUI_CSTR("Disable Shader Cache"), FSUI_CSTR("Prevents the loading and saving of shaders/pipelines to disk."),
|
||||
"EmuCore/GS", "DisableShaderCache", false);
|
||||
DrawToggleSetting(bsi, FSUI_CSTR("Disable Vertex Shader Expand"), FSUI_CSTR("Falls back to the CPU for expanding sprites/lines."),
|
||||
|
@ -6664,8 +6662,6 @@ TRANSLATE_NOOP("FullscreenUI", "GS Dump Compression");
|
|||
TRANSLATE_NOOP("FullscreenUI", "Sets the compression algorithm for GS dumps.");
|
||||
TRANSLATE_NOOP("FullscreenUI", "Disable Framebuffer Fetch");
|
||||
TRANSLATE_NOOP("FullscreenUI", "Prevents the usage of framebuffer fetch when supported by host GPU.");
|
||||
TRANSLATE_NOOP("FullscreenUI", "Disable Dual-Source Blending");
|
||||
TRANSLATE_NOOP("FullscreenUI", "Prevents the usage of dual-source blending when supported by host GPU.");
|
||||
TRANSLATE_NOOP("FullscreenUI", "Disable Shader Cache");
|
||||
TRANSLATE_NOOP("FullscreenUI", "Prevents the loading and saving of shaders/pipelines to disk.");
|
||||
TRANSLATE_NOOP("FullscreenUI", "Disable Vertex Shader Expand");
|
||||
|
|
|
@ -781,7 +781,6 @@ bool Pcsx2Config::GSOptions::RestartOptionsAreEqual(const GSOptions& right) cons
|
|||
OpEqu(UseDebugDevice) &&
|
||||
OpEqu(UseBlitSwapChain) &&
|
||||
OpEqu(DisableShaderCache) &&
|
||||
OpEqu(DisableDualSourceBlend) &&
|
||||
OpEqu(DisableFramebufferFetch) &&
|
||||
OpEqu(DisableVertexShaderExpand) &&
|
||||
OpEqu(DisableThreadedPresentation) &&
|
||||
|
@ -834,7 +833,6 @@ void Pcsx2Config::GSOptions::LoadSave(SettingsWrapper& wrap)
|
|||
GSSettingBool(UseDebugDevice);
|
||||
GSSettingBool(UseBlitSwapChain);
|
||||
GSSettingBool(DisableShaderCache);
|
||||
GSSettingBool(DisableDualSourceBlend);
|
||||
GSSettingBool(DisableFramebufferFetch);
|
||||
GSSettingBool(DisableVertexShaderExpand);
|
||||
GSSettingBool(DisableThreadedPresentation);
|
||||
|
|
Loading…
Reference in New Issue