mirror of https://github.com/PCSX2/pcsx2.git
GS/HW: Instead of adjusting blend min/max, adjust GetAlphaMinMax.
Might help in blending cases.
This commit is contained in:
parent
74df63ff94
commit
b4992856f7
|
@ -3962,6 +3962,41 @@ void GSState::CalcAlphaMinMax(const int tex_alpha_min, const int tex_alpha_max)
|
|||
m_vt.m_alpha.valid = true;
|
||||
}
|
||||
|
||||
void GSState::CorrectATEAlphaMinMax(const u32 atst, const int aref)
|
||||
{
|
||||
const GSVertexTrace::VertexAlpha& aminmax = GetAlphaMinMax();
|
||||
int amin = aminmax.min;
|
||||
int amax = aminmax.max;
|
||||
switch (atst)
|
||||
{
|
||||
case ATST_LESS:
|
||||
amin = std::min(amin, std::max(aref - 1, amin));
|
||||
amax = std::min(amax, std::max(aref - 1, amin));
|
||||
break;
|
||||
case ATST_LEQUAL:
|
||||
amin = std::min(amin, std::max(aref, amin));
|
||||
amax = std::min(amax, std::max(aref, amin));
|
||||
break;
|
||||
case ATST_EQUAL:
|
||||
amax = aref;
|
||||
amin = aref;
|
||||
break;
|
||||
case ATST_GEQUAL:
|
||||
amax = std::max(amax, std::min(aref, amax));
|
||||
amin = std::max(amin, std::min(aref, amax));
|
||||
break;
|
||||
case ATST_GREATER:
|
||||
amax = std::max(amax, std::min(aref + 1, amax));
|
||||
amin = std::max(amin, std::min(aref + 1, amax));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
m_vt.m_alpha.min = amin;
|
||||
m_vt.m_alpha.max = amax;
|
||||
}
|
||||
|
||||
bool GSState::TryAlphaTest(u32& fm, u32& zm)
|
||||
{
|
||||
// Shortcut for the easy case
|
||||
|
|
|
@ -187,6 +187,7 @@ protected:
|
|||
bool IsMipMapActive();
|
||||
bool IsCoverageAlpha();
|
||||
void CalcAlphaMinMax(const int tex_min, const int tex_max);
|
||||
void CorrectATEAlphaMinMax(const u32 atst, const int aref);
|
||||
|
||||
public:
|
||||
struct GSUploadQueue
|
||||
|
|
|
@ -682,6 +682,8 @@ bool GSHwHack::GSC_PolyphonyDigitalGames(GSRendererHW& r, int& skip)
|
|||
{
|
||||
GL_PUSH("GSC_PolyphonyDigitalGames(): HLE Gran Turismo RGB channel shuffle");
|
||||
|
||||
src->m_alpha_max = 255;
|
||||
src->m_alpha_min = 0;
|
||||
GSHWDrawConfig& config = r.BeginHLEHardwareDraw(
|
||||
src->GetTexture(), nullptr, src->GetScale(), src->GetTexture(), src->GetScale(), src->GetUnscaledRect());
|
||||
config.pal = palette->GetPaletteGSTexture();
|
||||
|
|
|
@ -5060,53 +5060,22 @@ __ri void GSRendererHW::DrawPrims(GSTextureCache::Target* rt, GSTextureCache::Ta
|
|||
}
|
||||
}
|
||||
|
||||
const int fail_type = m_cached_ctx.TEST.GetAFAIL(m_cached_ctx.FRAME.PSM);
|
||||
const int aref = static_cast<int>(m_cached_ctx.TEST.AREF);
|
||||
if (m_cached_ctx.TEST.ATE && ((fail_type != AFAIL_FB_ONLY && fail_type != AFAIL_RGB_ONLY) || !PRIM->ABE || !IsUsingAsInBlend()))
|
||||
CorrectATEAlphaMinMax(m_cached_ctx.TEST.ATST, aref);
|
||||
|
||||
// Blend
|
||||
int blend_alpha_min = 0, blend_alpha_max = 255;
|
||||
if (rt)
|
||||
{
|
||||
|
||||
blend_alpha_min = rt->m_alpha_min;
|
||||
blend_alpha_max = rt->m_alpha_max;
|
||||
|
||||
const bool is_24_bit = (GSLocalMemory::m_psm[rt->m_TEX0.PSM].trbpp == 24);
|
||||
const u32 alpha_mask = GSLocalMemory::m_psm[rt->m_TEX0.PSM].fmsk & 0xFF000000;
|
||||
const int fba_value = m_draw_env->CTXT[m_draw_env->PRIM.CTXT].FBA.FBA * 128;
|
||||
int s_alpha_max = GetAlphaMinMax().max;
|
||||
int s_alpha_min = GetAlphaMinMax().min;
|
||||
{
|
||||
const int fail_type = m_cached_ctx.TEST.GetAFAIL(m_cached_ctx.FRAME.PSM);
|
||||
if (m_cached_ctx.TEST.ATE && ((fail_type != AFAIL_FB_ONLY) || ((fail_type == AFAIL_RGB_ONLY) && (m_conf.ps.dst_fmt != GSLocalMemory::PSM_FMT_32))))
|
||||
{
|
||||
const int aref = static_cast<int>(m_cached_ctx.TEST.AREF);
|
||||
switch (m_cached_ctx.TEST.ATST)
|
||||
{
|
||||
case ATST_LESS:
|
||||
s_alpha_max = std::min(s_alpha_max, aref - 1);
|
||||
s_alpha_min = std::min(s_alpha_min, s_alpha_max);
|
||||
break;
|
||||
case ATST_LEQUAL:
|
||||
s_alpha_max = std::min(s_alpha_max, aref);
|
||||
s_alpha_min = std::min(s_alpha_min, s_alpha_max);
|
||||
break;
|
||||
case ATST_EQUAL:
|
||||
s_alpha_max = aref;
|
||||
s_alpha_min = aref;
|
||||
break;
|
||||
case ATST_GEQUAL:
|
||||
s_alpha_max = std::max(s_alpha_max, aref);
|
||||
s_alpha_min = std::max(s_alpha_min, aref);
|
||||
break;
|
||||
case ATST_GREATER:
|
||||
s_alpha_max = std::max(s_alpha_max, aref + 1);
|
||||
s_alpha_min = std::max(s_alpha_min, aref + 1);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
s_alpha_max |= fba_value;
|
||||
s_alpha_min |= fba_value;
|
||||
|
||||
if (is_24_bit)
|
||||
{
|
||||
|
@ -5117,9 +5086,13 @@ __ri void GSRendererHW::DrawPrims(GSTextureCache::Target* rt, GSTextureCache::Ta
|
|||
|
||||
if (GSUtil::GetChannelMask(m_cached_ctx.FRAME.PSM) & 0x8 && !m_channel_shuffle && !m_texture_shuffle)
|
||||
{
|
||||
const int s_alpha_max = GetAlphaMinMax().max | fba_value;
|
||||
const int s_alpha_min = GetAlphaMinMax().min | fba_value;
|
||||
if ((m_cached_ctx.FRAME.FBMSK & alpha_mask) == 0)
|
||||
{
|
||||
if (rt->m_valid.rintersect(m_r).eq(rt->m_valid) && PrimitiveCoversWithoutGaps() && !(DATE || m_cached_ctx.TEST.ATE || (m_cached_ctx.TEST.ZTE && m_cached_ctx.TEST.ZTST != ZTST_ALWAYS)))
|
||||
const bool afail_always_fb_alpha = m_cached_ctx.TEST.AFAIL == AFAIL_FB_ONLY || (m_cached_ctx.TEST.AFAIL == AFAIL_RGB_ONLY && GSLocalMemory::m_psm[m_cached_ctx.FRAME.PSM].trbpp != 32);
|
||||
const bool always_passing_alpha = !m_cached_ctx.TEST.ATE || afail_always_fb_alpha || (m_cached_ctx.TEST.ATE && m_cached_ctx.TEST.ATST == ATST_ALWAYS);
|
||||
if (rt->m_valid.rintersect(m_r).eq(rt->m_valid) && PrimitiveCoversWithoutGaps() && !(DATE || !always_passing_alpha || (m_cached_ctx.TEST.ZTE && m_cached_ctx.TEST.ZTST != ZTST_ALWAYS)))
|
||||
{
|
||||
rt->m_alpha_max = s_alpha_max;
|
||||
rt->m_alpha_min = s_alpha_min;
|
||||
|
|
Loading…
Reference in New Issue