diff --git a/pcsx2/GS/GSRegs.h b/pcsx2/GS/GSRegs.h index d3797a6c64712..9d26fb09e21fb 100644 --- a/pcsx2/GS/GSRegs.h +++ b/pcsx2/GS/GSRegs.h @@ -531,6 +531,7 @@ REG_END2 // output will be Cd, Cs is discarded __forceinline bool IsCdOutput() const { return (C == 2 && D != 1 && FIX == 0x00); } + __forceinline bool IsCdInBlend() const { return (A == 1 || B == 1 || D == 1); } __forceinline bool IsUsingCs() const { return (A == 0 || B == 0 || D == 0); } __forceinline bool IsUsingAs() const { return (A != B && C == 0); } diff --git a/pcsx2/GS/Renderers/HW/GSHwHack.cpp b/pcsx2/GS/Renderers/HW/GSHwHack.cpp index ee8417915a9fc..78a5867b9dc91 100644 --- a/pcsx2/GS/Renderers/HW/GSHwHack.cpp +++ b/pcsx2/GS/Renderers/HW/GSHwHack.cpp @@ -282,8 +282,8 @@ bool GSHwHack::GSC_BurnoutGames(GSRendererHW& r, int& skip) case 2: // downsample { - const GSVector4i downsample_rect = GSVector4i(0, 0, ((main_fb_size.x / 2) - 1), ((main_fb_size.y / 2) - 1)); - const GSVector4i uv_rect = GSVector4i(0, 0, (downsample_rect.z * 2) - std::min(r.GetUpscaleMultiplier()-1.0f, 4.0f) * 3 , (downsample_rect.w * 2) - std::min(r.GetUpscaleMultiplier()-1.0f, 4.0f) * 3); + const GSVector4i downsample_rect = GSVector4i(0, 0, ((main_fb_size.x / 2)), ((main_fb_size.y / 2))); + const GSVector4i uv_rect = GSVector4i(0, 0, main_fb_size.x, main_fb_size.y); r.ReplaceVerticesWithSprite(downsample_rect, uv_rect, main_fb_size, downsample_rect); downsample_fb = GIFRegTEX0::Create(RFBP, RFBW, RFPSM); state = 3; diff --git a/pcsx2/GS/Renderers/HW/GSRendererHW.cpp b/pcsx2/GS/Renderers/HW/GSRendererHW.cpp index 60f659b73a5c2..0d8cb10fcf1bb 100644 --- a/pcsx2/GS/Renderers/HW/GSRendererHW.cpp +++ b/pcsx2/GS/Renderers/HW/GSRendererHW.cpp @@ -7124,7 +7124,7 @@ bool GSRendererHW::IsDiscardingDstColor() bool GSRendererHW::IsDiscardingDstRGB() { - return ((!PRIM->ABE || IsOpaque() || m_context->ALPHA.IsBlack()) && // no blending or writing black + return ((!PRIM->ABE || IsOpaque() || m_context->ALPHA.IsBlack() || !m_context->ALPHA.IsCdInBlend()) && // no blending or writing black ((m_cached_ctx.FRAME.FBMSK & GSLocalMemory::m_psm[m_cached_ctx.FRAME.PSM].fmsk) & 0xFFFFFFu) == 0); // RGB isn't masked } @@ -7237,8 +7237,8 @@ int GSRendererHW::IsScalingDraw(GSTextureCache::Source* src, bool no_gaps) // but good enough for what we want. const bool no_gaps_or_single_sprite = (is_downscale || is_upscale) && (no_gaps || (m_vt.m_primclass == GS_SPRITE_CLASS && SpriteDrawWithoutGaps())); - const bool dst_discarded = IsDiscardingDstColor(); - if (no_gaps_or_single_sprite && ((is_upscale && !dst_discarded) || + const bool dst_discarded = IsDiscardingDstRGB() || IsDiscardingDstAlpha(); + if (no_gaps_or_single_sprite && ((is_upscale && !m_context->ALPHA.IsOpaque()) || (is_downscale && (dst_discarded || (PRIM->ABE && m_context->ALPHA.C == 2 && m_context->ALPHA.FIX == 255))))) { GL_INS("%s draw detected - from %dx%d to %dx%d draw %d", is_downscale ? "Downscale" : "Upscale", tex_size.x, tex_size.y, draw_size.x, draw_size.y, s_n);