@@ -7346,22 +7346,43 @@ void GSRendererHW::EmulateAlphaTest(const bool& DATE, bool& DATE_BARRIER, bool&
73467346 // Determine whether the feedback methods require a single pass.
73477347 const bool feedback_one_pass = simple_fb_only || simple_rgb_only || simple_zb_only;
73487348
7349+ // Determine if the method for doing depth feedback uses multiple render targets.
7350+ // This should not be used in conjunction with dual source blend.
7351+ // This also requires 2 full screen copies of depth <-> color so avoid if possible.
7352+ const bool depth_as_rt_feedback = afail_needs_depth && features.depth_as_rt_feedback ;
7353+
73497354 // If we are already have the required barriers for the accurate feedback path.
7350- const bool already_have_barriers =
7355+ const bool free_to_use_barriers =
73517356 ((m_conf.require_one_barrier && feedback_one_pass) || m_conf.require_full_barrier ) &&
7352- (features.texture_barrier || features.multidraw_fb_copy );
7357+ (features.texture_barrier || features.multidraw_fb_copy ) &&
7358+ !depth_as_rt_feedback;
73537359
73547360 // Dual source blend comes with some restrictions, so detect and avoid them here.
73557361 const bool using_dual_source_blend = !m_conf.ps .no_color1 ;
73567362
7357- // Determines if the method for doing depth feedback uses multiple render targets.
7358- // This should not be used in conjunction with dual source blend.
7359- const bool depth_as_rt_feedback = afail_needs_depth && features.depth_as_rt_feedback ;
7363+ // Determine if we have the correct features for depth feedback.
7364+ const bool depth_feedback_supported = features.depth_feedback || features.depth_as_rt_feedback ;
7365+
7366+ const bool avoid_feedback =
7367+ // Do not use dual source blend with FB-fetch, which breaks Intel GPUs on Metal.
7368+ // Also do not use dual source blend with multiple render targets, which is against spec.
7369+ ((features.framebuffer_fetch || depth_as_rt_feedback) && using_dual_source_blend) ||
7370+ // We need depth feedback but do not have the correct features.
7371+ (afail_needs_depth && !depth_feedback_supported);
7372+
7373+ // Determine if we can use FB-fetch for color only feedback.
7374+ const bool free_fbfetch_feedback = features.framebuffer_fetch && !depth_as_rt_feedback;
73607375
7361- // Also do not use dual source blend with FB-fetch, which breaks Intel GPUs on Metal.
7362- const bool avoid_feedback = (features.framebuffer_fetch || depth_as_rt_feedback) && using_dual_source_blend;
7376+ // Prefer feedback method only if blend level requests it or it's free.
7377+ const bool prefer_feedback = (GSConfig.AccurateBlendingUnit >= AccBlendLevel::Maximum) ||
7378+ free_to_use_barriers || free_fbfetch_feedback;
73637379
7364- if ((GSConfig.HWAFAILFeedback || already_have_barriers || features.framebuffer_fetch ) && !avoid_feedback)
7380+ // The two simple cases can be handle accurately in two passes so no point
7381+ // in requiring barriers if they are not already being used.
7382+ const bool prefer_two_pass = !(m_conf.require_full_barrier || m_conf.require_full_barrier ) &&
7383+ (simple_fb_only || simple_rgb_only);
7384+
7385+ if (prefer_feedback && !prefer_two_pass && !avoid_feedback)
73657386 {
73667387 // Use RT and/or depth sampling for accurate AFAIL in the shader.
73677388 GL_INS (" Alpha test with RT/depth feedback (accurate)" );
@@ -7377,7 +7398,7 @@ void GSRendererHW::EmulateAlphaTest(const bool& DATE, bool& DATE_BARRIER, bool&
73777398 // In that case, we don't need barriers.
73787399 const bool use_full_fbfetch = features.framebuffer_fetch &&
73797400 (!afail_needs_depth || features.depth_as_rt_feedback );
7380- if (!use_full_fbfetch)
7401+ if (!use_full_fbfetch && (features. texture_barrier || features. multidraw_fb_copy ) )
73817402 {
73827403 m_conf.require_one_barrier |= feedback_one_pass;
73837404 m_conf.require_full_barrier |= !feedback_one_pass;
@@ -8320,14 +8341,15 @@ __ri void GSRendererHW::DrawPrims(GSTextureCache::Target* rt, GSTextureCache::Ta
83208341 if (m_conf.alpha_second_pass .enable )
83218342 {
83228343 m_conf.alpha_second_pass .depth .zwe = 0 ;
8323- m_conf.alpha_second_pass .depth .ztst = 0 ;
8344+ m_conf.alpha_second_pass .depth .ztst = ZTST_ALWAYS ;
83248345 }
83258346
83268347 // Create the temporary depth copy
83278348 m_conf.ds_as_rt = g_gs_device->CreateRenderTarget (m_conf.ds ->GetWidth (), m_conf.ds ->GetHeight (),
83288349 GSTexture::Format::Float32, false , true );
83298350 const GSVector4 dRect (0 .0f , 0 .0f , static_cast <float >(m_conf.ds ->GetWidth ()), static_cast <float >(m_conf.ds ->GetHeight ()));
83308351 g_gs_device->StretchRect (m_conf.ds , m_conf.ds_as_rt , dRect, ShaderConvert::FLOAT32_DEPTH_TO_COLOR, false );
8352+ g_perfmon.Put (GSPerfMon::TextureCopies, 1.0 );
83318353 }
83328354
83338355 // rs
@@ -8362,6 +8384,7 @@ __ri void GSRendererHW::DrawPrims(GSTextureCache::Target* rt, GSTextureCache::Ta
83628384 g_gs_device->StretchRect (m_conf.ds_as_rt , m_conf.ds , dRect, ShaderConvert::FLOAT32_COLOR_TO_DEPTH, false );
83638385 g_gs_device->Recycle (m_conf.ds_as_rt );
83648386 m_conf.ds_as_rt = nullptr ;
8387+ g_perfmon.Put (GSPerfMon::TextureCopies, 1.0 );
83658388 }
83668389}
83678390
0 commit comments