Skip to content

Commit ddf6fe3

Browse files
TellowKrinklelightningterror
authored andcommitted
GS: Add helper to check if devices support feedback loops
1 parent e5f0c99 commit ddf6fe3

6 files changed

Lines changed: 28 additions & 28 deletions

File tree

pcsx2/GS/Renderers/Common/GSDevice.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -948,12 +948,14 @@ class GSDevice : public GSAlignedClass<32>
948948
bool stencil_buffer : 1; ///< Supports stencil buffer, and can use for DATE.
949949
bool cas_sharpening : 1; ///< Supports sufficient functionality for contrast adaptive sharpening.
950950
bool test_and_sample_depth: 1; ///< Supports concurrently binding the depth-stencil buffer for sampling and depth testing.
951-
bool depth_feedback : 1; ///< Depth feedback loops can be done with DS directly (otherwise need to copy to separate RT).
951+
bool depth_feedback : 1; ///< Depth feedback loops can be done with DS directly (otherwise need to copy to separate RT). Implies `feedback_loops`.
952952
bool aa1 : 1; ///< Supports the GS AA1 feature.
953953
FeatureSupport()
954954
{
955955
memset(this, 0, sizeof(*this));
956956
}
957+
/// Supports feedback loops through either texture barriers or rt copies.
958+
bool feedback_loops() const { return texture_barrier || multidraw_fb_copy; }
957959
};
958960

959961
struct MultiStretchRect

pcsx2/GS/Renderers/DX11/GSDevice11.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -646,7 +646,7 @@ void GSDevice11::SetFeatures(IDXGIAdapter1* adapter)
646646
m_features.vs_expand = (!GSConfig.DisableVertexShaderExpand && m_feature_level >= D3D_FEATURE_LEVEL_11_0);
647647
m_features.cas_sharpening = (m_feature_level >= D3D_FEATURE_LEVEL_11_0);
648648
m_features.test_and_sample_depth = (m_feature_level >= D3D_FEATURE_LEVEL_11_0);
649-
m_features.aa1 = GSConfig.HWAA1 && m_features.vs_expand && m_features.multidraw_fb_copy;
649+
m_features.aa1 = GSConfig.HWAA1 && m_features.vs_expand && m_features.feedback_loops();
650650

651651
m_max_texture_size = (m_feature_level >= D3D_FEATURE_LEVEL_11_0) ?
652652
D3D11_REQ_TEXTURE2D_U_OR_V_DIMENSION :

pcsx2/GS/Renderers/DX12/GSDevice12.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1406,7 +1406,7 @@ bool GSDevice12::CheckFeatures(const u32& vendor_id)
14061406
m_features.test_and_sample_depth = true;
14071407
m_features.vs_expand = !GSConfig.DisableVertexShaderExpand;
14081408
m_features.depth_feedback = false;
1409-
m_features.aa1 = GSConfig.HWAA1 && m_features.vs_expand && m_features.texture_barrier;
1409+
m_features.aa1 = GSConfig.HWAA1 && m_features.vs_expand && m_features.feedback_loops();
14101410

14111411
m_features.dxt_textures = SupportsTextureFormat(DXGI_FORMAT_BC1_UNORM) &&
14121412
SupportsTextureFormat(DXGI_FORMAT_BC2_UNORM) &&

pcsx2/GS/Renderers/HW/GSRendererHW.cpp

Lines changed: 20 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -5796,7 +5796,7 @@ void GSRendererHW::EmulateZbufferAA1()
57965796
{
57975797
const GSDevice::FeatureSupport& features = g_gs_device->Features();
57985798

5799-
pxAssert(!features.aa1 || features.texture_barrier || features.multidraw_fb_copy);
5799+
pxAssert(!features.aa1 || features.feedback_loops());
58005800

58015801
if (IsCoverageAlphaSupported())
58025802
{
@@ -5817,7 +5817,7 @@ void GSRendererHW::EmulateZbufferAA1()
58175817
m_conf.depth.ztst = ZTST_ALWAYS; // Disable HW Z test.
58185818

58195819
// We need barriers for the feedback
5820-
if (features.texture_barrier || features.multidraw_fb_copy)
5820+
if (features.feedback_loops())
58215821
{
58225822
m_conf.require_one_barrier |= (m_prim_overlap == PRIM_OVERLAP_NO);
58235823
m_conf.require_full_barrier |= (m_prim_overlap != PRIM_OVERLAP_NO);
@@ -5938,7 +5938,7 @@ void GSRendererHW::EmulateDATESelectMethod(DATEOptions& date_options, GSTextureC
59385938
m_conf.require_full_barrier = true;
59395939
date_options.barrier = true;
59405940
}
5941-
else if ((features.texture_barrier || features.multidraw_fb_copy) && m_conf.require_full_barrier)
5941+
else if (features.feedback_loops() && m_conf.require_full_barrier)
59425942
{
59435943
// Full barrier is enabled (likely sw fbmask), we need to use date barrier.
59445944
GL_PERF("DATE: Accurate with alpha %d-%d", GetAlphaMinMax().min, GetAlphaMinMax().max);
@@ -5950,7 +5950,7 @@ void GSRendererHW::EmulateDATESelectMethod(DATEOptions& date_options, GSTextureC
59505950
GL_PERF("DATE: Accurate with alpha %d-%d", GetAlphaMinMax().min, GetAlphaMinMax().max);
59515951
date_options.primid = true;
59525952
}
5953-
else if (features.texture_barrier || features.multidraw_fb_copy)
5953+
else if (features.feedback_loops())
59545954
{
59555955
GL_PERF("DATE: Accurate with alpha %d-%d", GetAlphaMinMax().min, GetAlphaMinMax().max);
59565956
m_conf.require_full_barrier = true;
@@ -6162,19 +6162,19 @@ void GSRendererHW::DetermineBarriers(GSTextureCache::Target* rt)
61626162
pxAssert(!m_conf.require_full_barrier || !m_conf.ps.colclip_hw);
61636163

61646164
// Swap full barrier for one barrier when there's no overlap, or a shuffle.
6165-
if ((features.texture_barrier || features.multidraw_fb_copy) && m_conf.require_full_barrier && (m_prim_overlap == PRIM_OVERLAP_NO || m_conf.ps.shuffle || m_channel_shuffle))
6165+
if (features.feedback_loops() && m_conf.require_full_barrier && (m_prim_overlap == PRIM_OVERLAP_NO || m_conf.ps.shuffle || m_channel_shuffle))
61666166
{
61676167
m_conf.require_full_barrier = false;
61686168
m_conf.require_one_barrier = true;
61696169
}
6170-
else if (!(features.texture_barrier || features.multidraw_fb_copy))
6170+
else if (!features.feedback_loops())
61716171
{
61726172
// These shouldn't be enabled if texture barriers aren't supported, make sure they are off.
61736173
m_conf.ps.write_rg = 0;
61746174
m_conf.require_full_barrier = false;
61756175
}
61766176

6177-
if (m_conf.require_full_barrier && (g_gs_device->Features().texture_barrier || g_gs_device->Features().multidraw_fb_copy))
6177+
if (m_conf.require_full_barrier && features.feedback_loops())
61786178
{
61796179
ComputeDrawlistGetSize(rt->m_scale);
61806180
m_conf.drawlist = &m_drawlist;
@@ -6246,9 +6246,8 @@ void GSRendererHW::EmulateTextureShuffleAndFbmask(GSTextureCache::Target* rt, GS
62466246

62476247
// If date is enabled you need to test the green channel instead of the alpha channel.
62486248
// Only enable this code in DATE mode to reduce the number of shaders.
6249-
m_conf.ps.write_rg = (process_rg & SHUFFLE_WRITE) && (features.texture_barrier || features.multidraw_fb_copy) &&
6250-
m_cached_ctx.TEST.DATE;
6251-
6249+
m_conf.ps.write_rg = (process_rg & SHUFFLE_WRITE) && features.feedback_loops() && m_cached_ctx.TEST.DATE;
6250+
62526251
m_conf.ps.real16src = m_texture_shuffle.real_16_bit_source;
62536252

62546253
// Shuffle that copies B to A, which are in the same column.
@@ -6362,7 +6361,7 @@ void GSRendererHW::EmulateTextureShuffleAndFbmask(GSTextureCache::Target* rt, GS
63626361
have been invalidated before subsequent Draws are executed.
63636362
*/
63646363
// No blending so hit unsafe path.
6365-
if (!PRIM->ABE || !(~ff_fbmask & ~zero_fbmask & 0x7) || !(features.texture_barrier || features.multidraw_fb_copy))
6364+
if (!PRIM->ABE || !(~ff_fbmask & ~zero_fbmask & 0x7) || !features.feedback_loops())
63666365
{
63676366
GL_INS("HW: FBMASK Unsafe SW emulated fb_mask:%x on %d bits format", m_cached_ctx.FRAME.FBMSK,
63686367
(m_conf.ps.dst_fmt == GSLocalMemory::PSM_FMT_16) ? 16 : 32);
@@ -6872,7 +6871,7 @@ void GSRendererHW::EmulateBlending(int rt_alpha_min, int rt_alpha_max, DATEOptio
68726871
// Condition 2: One barrier is already enabled, prims don't overlap or is a channel shuffle so let's use sw blend instead.
68736872
// Condition 3: A texture shuffle is unlikely to overlap, so we can prefer full sw blend.
68746873
// Condition 4: If it's tex in fb draw and there's no overlap prefer sw blend, fb is already being read.
6875-
const bool prefer_sw_blend = ((features.texture_barrier || features.multidraw_fb_copy) && m_conf.require_full_barrier) || (m_conf.require_one_barrier && (no_prim_overlap || m_channel_shuffle)) || m_conf.ps.shuffle || (no_prim_overlap && (m_conf.tex == m_conf.rt));
6874+
const bool prefer_sw_blend = (features.feedback_loops() && m_conf.require_full_barrier) || (m_conf.require_one_barrier && (no_prim_overlap || m_channel_shuffle)) || m_conf.ps.shuffle || (no_prim_overlap && (m_conf.tex == m_conf.rt));
68766875
const bool free_blend = blend_non_recursive // Free sw blending, doesn't require barriers or reading fb
68776876
|| accumulation_blend; // Mix of hw/sw blending
68786877

@@ -6883,7 +6882,7 @@ void GSRendererHW::EmulateBlending(int rt_alpha_min, int rt_alpha_max, DATEOptio
68836882
const bool blend_multipass_group = blend_multi_pass_support && !features.texture_barrier &&
68846883
(bmix1_multi_pass1 || bmix1_multi_pass2 || bmix3_multi_pass || (blend_flag & (BLEND_HW3 | BLEND_HW4 | BLEND_HW5 | BLEND_HW6 | BLEND_HW7 | BLEND_HW8 | BLEND_HW9)));
68856884

6886-
const bool barriers_supported = features.texture_barrier || features.multidraw_fb_copy;
6885+
const bool barriers_supported = features.feedback_loops();
68876886
const bool blend_requires_barrier =
68886887
// We don't want the cases to be enabled if barriers aren't supported so limit it to no overlap.
68896888
(no_prim_overlap || barriers_supported)
@@ -7049,7 +7048,7 @@ void GSRendererHW::EmulateBlending(int rt_alpha_min, int rt_alpha_max, DATEOptio
70497048

70507049
m_conf.ps.pabe = 1;
70517050
}
7052-
else if (features.texture_barrier || features.multidraw_fb_copy)
7051+
else if (features.feedback_loops())
70537052
{
70547053
// PABE sw blend:
70557054
// Disable hw/sw mix and do pure sw blend with reading the framebuffer.
@@ -7222,7 +7221,7 @@ void GSRendererHW::EmulateBlending(int rt_alpha_min, int rt_alpha_max, DATEOptio
72227221
const bool blend_non_recursive_one_barrier = blend_non_recursive && blend_ad_alpha_masked;
72237222
if (blend_non_recursive_one_barrier)
72247223
m_conf.require_one_barrier |= true;
7225-
else if (features.texture_barrier || features.multidraw_fb_copy)
7224+
else if (features.feedback_loops())
72267225
m_conf.require_full_barrier |= !blend_non_recursive;
72277226
else
72287227
m_conf.require_one_barrier |= !blend_non_recursive;
@@ -7875,7 +7874,7 @@ __ri void GSRendererHW::HandleTextureHazards(const GSTextureCache::Target* rt, c
78757874
{
78767875
m_conf.tex = nullptr;
78777876
m_conf.ps.tex_is_fb = true;
7878-
if (m_prim_overlap == PRIM_OVERLAP_NO || !(g_gs_device->Features().texture_barrier || g_gs_device->Features().multidraw_fb_copy))
7877+
if (m_prim_overlap == PRIM_OVERLAP_NO || !g_gs_device->Features().feedback_loops())
78797878
m_conf.require_one_barrier = true;
78807879
else
78817880
m_conf.require_full_barrier = true;
@@ -7955,7 +7954,7 @@ __ri void GSRendererHW::HandleTextureHazards(const GSTextureCache::Target* rt, c
79557954
const int horizontal_offset = ((page_offset % src_target->m_TEX0.TBW) * GSLocalMemory::m_psm[src_target->m_TEX0.PSM].pgs.x);
79567955
const int vertical_offset = ((page_offset / src_target->m_TEX0.TBW) * GSLocalMemory::m_psm[src_target->m_TEX0.PSM].pgs.y);
79577956

7958-
if (g_gs_device->Features().texture_barrier || g_gs_device->Features().multidraw_fb_copy)
7957+
if (g_gs_device->Features().feedback_loops())
79597958
{
79607959
const u32 max_skip = ((m_channel_shuffle_finish || !m_channel_shuffle_width) ? 1 : m_channel_shuffle_width) << 5;
79617960
const bool new_shuffle = !(m_last_channel_shuffle_fbmsk == m_context->FRAME.FBMSK &&
@@ -8179,7 +8178,7 @@ bool GSRendererHW::CanUseTexIsFB(const GSTextureCache::Target* rt, const GSTextu
81798178
}
81808179

81818180
// No barriers -> we can't use tex-is-fb when there's overlap.
8182-
if (!(g_gs_device->Features().texture_barrier || g_gs_device->Features().multidraw_fb_copy) && m_prim_overlap != PRIM_OVERLAP_NO)
8181+
if (!g_gs_device->Features().feedback_loops() && m_prim_overlap != PRIM_OVERLAP_NO)
81838182
{
81848183
GL_CACHE("HW: Disabling tex-is-fb due to no barriers.");
81858184
return false;
@@ -8426,14 +8425,13 @@ void GSRendererHW::EmulateAlphaTest(DATEOptions& date_options)
84268425
// do not require depth feedback.
84278426
const bool free_barrier_feedback =
84288427
((m_conf.require_one_barrier && feedback_one_pass) || m_conf.require_full_barrier) &&
8429-
(features.texture_barrier || features.multidraw_fb_copy) &&
8430-
!afail_needs_depth;
8428+
features.feedback_loops() && !afail_needs_depth;
84318429

84328430
// Determine if we can use FB-fetch for color only feedback.
84338431
const bool free_fbfetch_feedback = features.framebuffer_fetch && !afail_needs_depth;
84348432

84358433
// Determine if we have the correct features for depth feedback.
8436-
const bool depth_feedback_supported = features.texture_barrier || features.multidraw_fb_copy;
8434+
const bool depth_feedback_supported = features.feedback_loops();
84378435

84388436
// We need depth feedback but do not have the correct features.
84398437
const bool avoid_feedback = afail_needs_depth && !depth_feedback_supported;
@@ -8456,7 +8454,7 @@ void GSRendererHW::EmulateAlphaTest(DATEOptions& date_options)
84568454
m_conf.cb_ps.FogColor_AREF.a = ps_aref;
84578455
m_conf.ps.afail = static_cast<PS_AFAIL>(afail);
84588456

8459-
if ((afail_needs_rt || afail_needs_depth) && (features.texture_barrier || features.multidraw_fb_copy))
8457+
if ((afail_needs_rt || afail_needs_depth) && features.feedback_loops())
84608458
{
84618459
m_conf.require_one_barrier |= feedback_one_pass;
84628460
m_conf.require_full_barrier |= !feedback_one_pass;

pcsx2/GS/Renderers/OpenGL/GSDeviceOGL.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -883,7 +883,7 @@ bool GSDeviceOGL::CheckFeatures()
883883
Console.Warning("GLAD_GL_ARB_conservative_depth is not supported. This will reduce performance.");
884884
}
885885

886-
m_features.aa1 = GSConfig.HWAA1 && m_features.vs_expand && (m_features.texture_barrier || m_features.multidraw_fb_copy);
886+
m_features.aa1 = GSConfig.HWAA1 && m_features.vs_expand && m_features.feedback_loops();
887887

888888
return true;
889889
}

pcsx2/GS/Renderers/Vulkan/GSDeviceVK.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2701,8 +2701,8 @@ bool GSDeviceVK::CheckFeatures()
27012701
m_features.line_expand =
27022702
(m_device_features.wideLines && limits.lineWidthRange[0] <= f_upscale && limits.lineWidthRange[1] >= f_upscale);
27032703

2704-
m_features.depth_feedback = m_features.texture_barrier;
2705-
m_features.aa1 = GSConfig.HWAA1 && m_features.vs_expand && m_features.texture_barrier;
2704+
m_features.depth_feedback = m_features.feedback_loops();
2705+
m_features.aa1 = GSConfig.HWAA1 && m_features.vs_expand && m_features.feedback_loops();
27062706

27072707
DevCon.WriteLn("Optional features:%s%s%s%s%s", m_features.primitive_id ? " primitive_id" : "",
27082708
m_features.texture_barrier ? " texture_barrier" : "", m_features.framebuffer_fetch ? " framebuffer_fetch" : "",

0 commit comments

Comments
 (0)