@@ -7346,22 +7346,44 @@ 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 ||
7365+ features.depth_as_rt_feedback || features.multidraw_fb_copy ;
7366+
7367+ const bool avoid_feedback =
7368+ // Do not use dual source blend with FB-fetch, which breaks Intel GPUs on Metal.
7369+ // Also do not use dual source blend with multiple render targets, which is against spec.
7370+ ((features.framebuffer_fetch || depth_as_rt_feedback) && using_dual_source_blend) ||
7371+ // We need depth feedback but do not have the correct features.
7372+ (afail_needs_depth && !depth_feedback_supported);
7373+
7374+ // Determine if we can use FB-fetch for color only feedback.
7375+ const bool free_fbfetch_feedback = features.framebuffer_fetch && !depth_as_rt_feedback;
73607376
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;
7377+ // Prefer feedback method only if blend level requests it or it's free.
7378+ const bool prefer_feedback = (GSConfig.AccurateBlendingUnit >= AccBlendLevel::Maximum) ||
7379+ free_to_use_barriers || free_fbfetch_feedback;
73637380
7364- if ((GSConfig.HWAFAILFeedback || already_have_barriers || features.framebuffer_fetch ) && !avoid_feedback)
7381+ // The two simple cases can be handle accurately in two passes so no point
7382+ // in requiring barriers if they are not already being used.
7383+ const bool prefer_two_pass = !(m_conf.require_full_barrier || m_conf.require_full_barrier ) &&
7384+ (simple_fb_only || simple_rgb_only);
7385+
7386+ if (prefer_feedback && !prefer_two_pass && !avoid_feedback)
73657387 {
73667388 // Use RT and/or depth sampling for accurate AFAIL in the shader.
73677389 GL_INS (" Alpha test with RT/depth feedback (accurate)" );
@@ -8321,14 +8343,15 @@ __ri void GSRendererHW::DrawPrims(GSTextureCache::Target* rt, GSTextureCache::Ta
83218343 if (m_conf.alpha_second_pass .enable )
83228344 {
83238345 m_conf.alpha_second_pass .depth .zwe = 0 ;
8324- m_conf.alpha_second_pass .depth .ztst = 0 ;
8346+ m_conf.alpha_second_pass .depth .ztst = ZTST_ALWAYS ;
83258347 }
83268348
83278349 // Create the temporary depth copy
83288350 m_conf.ds_as_rt = g_gs_device->CreateRenderTarget (m_conf.ds ->GetWidth (), m_conf.ds ->GetHeight (),
83298351 GSTexture::Format::Float32, false , true );
83308352 const GSVector4 dRect (0 .0f , 0 .0f , static_cast <float >(m_conf.ds ->GetWidth ()), static_cast <float >(m_conf.ds ->GetHeight ()));
83318353 g_gs_device->StretchRect (m_conf.ds , m_conf.ds_as_rt , dRect, ShaderConvert::FLOAT32_DEPTH_TO_COLOR, false );
8354+ g_perfmon.Put (GSPerfMon::TextureCopies, 1.0 );
83328355 }
83338356
83348357 // rs
@@ -8363,6 +8386,7 @@ __ri void GSRendererHW::DrawPrims(GSTextureCache::Target* rt, GSTextureCache::Ta
83638386 g_gs_device->StretchRect (m_conf.ds_as_rt , m_conf.ds , dRect, ShaderConvert::FLOAT32_COLOR_TO_DEPTH, false );
83648387 g_gs_device->Recycle (m_conf.ds_as_rt );
83658388 m_conf.ds_as_rt = nullptr ;
8389+ g_perfmon.Put (GSPerfMon::TextureCopies, 1.0 );
83668390 }
83678391}
83688392
0 commit comments