mirror of https://github.com/PCSX2/pcsx2.git
GS: Correct alpha test for RGB Only and non-32bit colours
This commit is contained in:
parent
ebd60d93f3
commit
60a2b246e2
|
@ -792,6 +792,7 @@ REG_END2
|
|||
__forceinline bool DoFirstPass() const { return !ATE || ATST != ATST_NEVER; } // not all pixels fail automatically
|
||||
__forceinline bool DoSecondPass() const { return ATE && ATST != ATST_ALWAYS && AFAIL != AFAIL_KEEP; } // pixels may fail, write fb/z
|
||||
__forceinline bool NoSecondPass() const { return ATE && ATST != ATST_ALWAYS && AFAIL == AFAIL_KEEP; } // pixels may fail, no output
|
||||
__forceinline u32 GetAFAIL(u32 fpsm) const { return (AFAIL == AFAIL_RGB_ONLY && (fpsm & 0xF) != 0) ? AFAIL_FB_ONLY : AFAIL; } // FB Only when not 32bit Framebuffer
|
||||
REG_END2
|
||||
|
||||
REG64_(GIFReg, TEX0)
|
||||
|
|
|
@ -3788,9 +3788,10 @@ bool GSState::TryAlphaTest(u32& fm, const u32 fm_mask, u32& zm)
|
|||
|
||||
const u32 framemask = GSLocalMemory::m_psm[m_context->FRAME.PSM].fmsk;
|
||||
const u32 framemaskalpha = GSLocalMemory::m_psm[m_context->FRAME.PSM].fmsk & 0xFF000000;
|
||||
const u32 fail_type = m_context->TEST.GetAFAIL(m_context->FRAME.PSM);
|
||||
// Alpha test can only control the write of some channels. If channels are already masked
|
||||
// the alpha test is therefore a nop.
|
||||
switch (m_context->TEST.AFAIL)
|
||||
switch (fail_type)
|
||||
{
|
||||
case AFAIL_KEEP:
|
||||
break;
|
||||
|
@ -3803,7 +3804,7 @@ bool GSState::TryAlphaTest(u32& fm, const u32 fm_mask, u32& zm)
|
|||
return true;
|
||||
break;
|
||||
case AFAIL_RGB_ONLY:
|
||||
if (zm == 0xFFFFFFFF && ((fm & framemaskalpha) == framemaskalpha || GSLocalMemory::m_psm[m_context->FRAME.PSM].fmt == 1))
|
||||
if (zm == 0xFFFFFFFF && (fm & framemaskalpha) == framemaskalpha)
|
||||
return true;
|
||||
break;
|
||||
default:
|
||||
|
@ -3887,7 +3888,7 @@ bool GSState::TryAlphaTest(u32& fm, const u32 fm_mask, u32& zm)
|
|||
|
||||
if (!pass)
|
||||
{
|
||||
switch (m_context->TEST.AFAIL)
|
||||
switch (fail_type)
|
||||
{
|
||||
case AFAIL_KEEP:
|
||||
fm = zm = 0xffffffff;
|
||||
|
|
|
@ -4933,8 +4933,8 @@ __ri void GSRendererHW::DrawPrims(GSTextureCache::Target* rt, GSTextureCache::Ta
|
|||
const bool commutative_depth = (m_conf.depth.ztst == ZTST_GEQUAL && m_vt.m_eq.z) || (m_conf.depth.ztst == ZTST_ALWAYS);
|
||||
const bool commutative_alpha = (m_context->ALPHA.C != 1); // when either Alpha Src or a constant
|
||||
|
||||
ate_RGBA_then_Z = (m_cached_ctx.TEST.AFAIL == AFAIL_FB_ONLY) && commutative_depth;
|
||||
ate_RGB_then_ZA = (m_cached_ctx.TEST.AFAIL == AFAIL_RGB_ONLY) && commutative_depth && commutative_alpha;
|
||||
ate_RGBA_then_Z = m_cached_ctx.TEST.GetAFAIL(m_cached_ctx.FRAME.PSM) == AFAIL_FB_ONLY && commutative_depth;
|
||||
ate_RGB_then_ZA = m_cached_ctx.TEST.GetAFAIL(m_cached_ctx.FRAME.PSM) == AFAIL_RGB_ONLY && commutative_depth && commutative_alpha;
|
||||
}
|
||||
|
||||
if (ate_RGBA_then_Z)
|
||||
|
@ -5030,8 +5030,8 @@ __ri void GSRendererHW::DrawPrims(GSTextureCache::Target* rt, GSTextureCache::Ta
|
|||
bool g = m_conf.colormask.wg;
|
||||
bool b = m_conf.colormask.wb;
|
||||
bool a = m_conf.colormask.wa;
|
||||
|
||||
switch (m_cached_ctx.TEST.AFAIL)
|
||||
const int fail_type = m_cached_ctx.TEST.GetAFAIL(m_cached_ctx.FRAME.PSM);
|
||||
switch (fail_type)
|
||||
{
|
||||
case AFAIL_KEEP: z = r = g = b = a = false; break; // none
|
||||
case AFAIL_FB_ONLY: z = false; break; // rgba
|
||||
|
@ -5159,7 +5159,7 @@ GSRendererHW::CLUTDrawTestResult GSRendererHW::PossibleCLUTDraw()
|
|||
return CLUTDrawTestResult::NotCLUTDraw;
|
||||
|
||||
// Keep the draws simple, no alpha testing, blending, mipmapping, Z writes, and make sure it's flat.
|
||||
const bool fb_only = m_cached_ctx.TEST.ATE && m_cached_ctx.TEST.AFAIL == 1 && m_cached_ctx.TEST.ATST == ATST_NEVER;
|
||||
const bool fb_only = m_cached_ctx.TEST.ATE && m_cached_ctx.TEST.GetAFAIL(m_cached_ctx.FRAME.PSM) == AFAIL_FB_ONLY && m_cached_ctx.TEST.ATST == ATST_NEVER;
|
||||
|
||||
// No Z writes, unless it's points, then it's quite likely to be a palette and they left it on.
|
||||
if (!m_cached_ctx.ZBUF.ZMSK && !fb_only && !(m_vt.m_primclass == GS_POINT_CLASS))
|
||||
|
|
|
@ -132,7 +132,7 @@ bool GSRendererHWFunctions::SwPrimRender(GSRendererHW& hw, bool invalidate_tc, b
|
|||
if (!hw.TryAlphaTest(fm, fm_mask, zm))
|
||||
{
|
||||
gd.sel.atst = context->TEST.ATST;
|
||||
gd.sel.afail = context->TEST.AFAIL;
|
||||
gd.sel.afail = context->TEST.GetAFAIL(context->FRAME.PSM);
|
||||
|
||||
gd.aref = GSVector4i((int)context->TEST.AREF);
|
||||
|
||||
|
|
|
@ -990,7 +990,7 @@ bool GSRendererSW::GetScanlineGlobalData(SharedData* data)
|
|||
if (!TryAlphaTest(fm, fm_mask, zm))
|
||||
{
|
||||
gd.sel.atst = context->TEST.ATST;
|
||||
gd.sel.afail = context->TEST.AFAIL;
|
||||
gd.sel.afail = context->TEST.GetAFAIL(context->FRAME.PSM);
|
||||
|
||||
gd.aref = GSVector4i((int)context->TEST.AREF);
|
||||
|
||||
|
|
Loading…
Reference in New Issue