mirror of https://github.com/PCSX2/pcsx2.git
GS/HW: Allow transition to RTA on full cover draw
This commit is contained in:
parent
aa48256010
commit
e734eb415c
|
@ -216,7 +216,6 @@ public:
|
|||
bool m_texflush_flag = false;
|
||||
bool m_isPackedUV_HackFlag = false;
|
||||
bool m_channel_shuffle = false;
|
||||
bool m_can_correct_alpha = false;
|
||||
u8 m_scanmask_used = 0;
|
||||
u32 m_dirty_gs_regs = 0;
|
||||
int m_backed_up_ctx = 0;
|
||||
|
|
|
@ -3869,7 +3869,8 @@ __ri bool GSRendererHW::EmulateChannelShuffle(GSTextureCache::Target* src, bool
|
|||
return true;
|
||||
}
|
||||
|
||||
void GSRendererHW::EmulateBlending(int rt_alpha_min, int rt_alpha_max, bool& DATE_PRIMID, bool& DATE_BARRIER, GSTextureCache::Target* rt)
|
||||
void GSRendererHW::EmulateBlending(int rt_alpha_min, int rt_alpha_max, bool& DATE_PRIMID, bool& DATE_BARRIER,
|
||||
GSTextureCache::Target* rt, bool can_scale_rt_alpha, bool& new_rt_alpha_scale)
|
||||
{
|
||||
{
|
||||
// AA1: Blending needs to be enabled on draw.
|
||||
|
@ -3941,7 +3942,7 @@ void GSRendererHW::EmulateBlending(int rt_alpha_min, int rt_alpha_max, bool& DAT
|
|||
const bool alpha_c0_less_max_one = (m_conf.ps.blend_c == 0 && GetAlphaMinMax().max <= 128);
|
||||
const bool alpha_c1_high_min_one = (m_conf.ps.blend_c == 1 && rt_alpha_min > 128);
|
||||
const bool alpha_c1_high_max_one = (m_conf.ps.blend_c == 1 && rt_alpha_max > 128);
|
||||
const bool alpha_c1_high_no_rta_correct = m_conf.ps.blend_c == 1 && !(rt->m_rt_alpha_scale || m_can_correct_alpha);
|
||||
const bool alpha_c1_high_no_rta_correct = m_conf.ps.blend_c == 1 && !(new_rt_alpha_scale || can_scale_rt_alpha);
|
||||
const bool alpha_c2_zero = (m_conf.ps.blend_c == 2 && AFIX == 0u);
|
||||
const bool alpha_c2_one = (m_conf.ps.blend_c == 2 && AFIX == 128u);
|
||||
const bool alpha_c2_less_one = (m_conf.ps.blend_c == 2 && AFIX <= 128u);
|
||||
|
@ -4397,7 +4398,7 @@ void GSRendererHW::EmulateBlending(int rt_alpha_min, int rt_alpha_max, bool& DAT
|
|||
m_conf.ps.blend_b = 0;
|
||||
m_conf.ps.blend_d = 0;
|
||||
|
||||
const bool rta_correction = m_can_correct_alpha && !blend_ad_alpha_masked && m_conf.ps.blend_c == 1 && !(blend_flag & BLEND_A_MAX);
|
||||
const bool rta_correction = can_scale_rt_alpha && !blend_ad_alpha_masked && m_conf.ps.blend_c == 1 && !(blend_flag & BLEND_A_MAX);
|
||||
if (rta_correction)
|
||||
{
|
||||
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);
|
||||
|
@ -4409,8 +4410,8 @@ void GSRendererHW::EmulateBlending(int rt_alpha_min, int rt_alpha_max, bool& DAT
|
|||
rt->RTACorrect();
|
||||
m_conf.rt = rt->m_texture;
|
||||
}
|
||||
else
|
||||
rt->m_rt_alpha_scale = true;
|
||||
|
||||
new_rt_alpha_scale = true;
|
||||
|
||||
m_conf.ps.rta_correction = rt->m_rt_alpha_scale;
|
||||
}
|
||||
|
@ -5317,6 +5318,8 @@ __ri void GSRendererHW::DrawPrims(GSTextureCache::Target* rt, GSTextureCache::Ta
|
|||
int rt_new_alpha_min = 0, rt_new_alpha_max = 255;
|
||||
if (rt)
|
||||
{
|
||||
GL_INS("RT alpha was %s before draw", rt->m_rt_alpha_scale ? "scaled" : "NOT scaled");
|
||||
|
||||
blend_alpha_min = rt_new_alpha_min = rt->m_alpha_min;
|
||||
blend_alpha_max = rt_new_alpha_max = rt->m_alpha_max;
|
||||
|
||||
|
@ -5536,10 +5539,14 @@ __ri void GSRendererHW::DrawPrims(GSTextureCache::Target* rt, GSTextureCache::Ta
|
|||
// If we Correct/Decorrect and tex is rt, we will need to update the texture reference
|
||||
const bool req_src_update = tex && rt && tex->m_target && tex->m_target_direct && tex->m_texture == rt->m_texture;
|
||||
|
||||
m_can_correct_alpha = !needs_ad && (GSUtil::GetChannelMask(m_cached_ctx.FRAME.PSM) & 0x8) && rt_new_alpha_max <= 128;
|
||||
|
||||
// We defer updating the alpha scaled flag until after the texture setup if we're scaling as part of the draw,
|
||||
// because otherwise we'll treat tex-is-fb as a scaled source, when it's not yet.
|
||||
bool can_scale_rt_alpha = false;
|
||||
bool new_scale_rt_alpha = false;
|
||||
if (rt)
|
||||
{
|
||||
can_scale_rt_alpha = !needs_ad && (GSUtil::GetChannelMask(m_cached_ctx.FRAME.PSM) & 0x8) && rt_new_alpha_max <= 128;
|
||||
|
||||
const bool partial_fbmask = (m_conf.ps.fbmask && m_conf.cb_ps.FbMask.a != 0xFF && m_conf.cb_ps.FbMask.a != 0);
|
||||
const bool rta_decorrection = m_channel_shuffle || m_texture_shuffle || (m_conf.colormask.wa && (rt_new_alpha_max > 128 || partial_fbmask));
|
||||
|
||||
|
@ -5549,7 +5556,7 @@ __ri void GSRendererHW::DrawPrims(GSTextureCache::Target* rt, GSTextureCache::Ta
|
|||
{
|
||||
if (m_conf.ps.process_ba & SHUFFLE_READ)
|
||||
{
|
||||
m_can_correct_alpha = false;
|
||||
can_scale_rt_alpha = false;
|
||||
|
||||
rt->RTADecorrect();
|
||||
m_conf.rt = rt->m_texture;
|
||||
|
@ -5561,12 +5568,12 @@ __ri void GSRendererHW::DrawPrims(GSTextureCache::Target* rt, GSTextureCache::Ta
|
|||
{
|
||||
if (!(m_cached_ctx.FRAME.FBMSK & 0xFFFC0000))
|
||||
{
|
||||
m_can_correct_alpha = false;
|
||||
can_scale_rt_alpha = false;
|
||||
rt->m_rt_alpha_scale = false;
|
||||
}
|
||||
else if (m_cached_ctx.FRAME.FBMSK & 0xFFFC0000)
|
||||
{
|
||||
m_can_correct_alpha = false;
|
||||
can_scale_rt_alpha = false;
|
||||
rt->RTADecorrect();
|
||||
m_conf.rt = rt->m_texture;
|
||||
|
||||
|
@ -5579,7 +5586,7 @@ __ri void GSRendererHW::DrawPrims(GSTextureCache::Target* rt, GSTextureCache::Ta
|
|||
{
|
||||
if (m_conf.ps.tales_of_abyss_hle || (tex && tex->m_from_target && tex->m_from_target == rt && m_conf.ps.channel == ChannelFetch_ALPHA) || partial_fbmask || rt_new_alpha_max > 128)
|
||||
{
|
||||
m_can_correct_alpha = false;
|
||||
can_scale_rt_alpha = false;
|
||||
rt->RTADecorrect();
|
||||
m_conf.rt = rt->m_texture;
|
||||
|
||||
|
@ -5589,12 +5596,12 @@ __ri void GSRendererHW::DrawPrims(GSTextureCache::Target* rt, GSTextureCache::Ta
|
|||
}
|
||||
else if (rt->m_last_draw == s_n)
|
||||
{
|
||||
m_can_correct_alpha = false;
|
||||
can_scale_rt_alpha = false;
|
||||
rt->m_rt_alpha_scale = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_can_correct_alpha = false;
|
||||
can_scale_rt_alpha = false;
|
||||
rt->RTADecorrect();
|
||||
m_conf.rt = rt->m_texture;
|
||||
|
||||
|
@ -5602,37 +5609,27 @@ __ri void GSRendererHW::DrawPrims(GSTextureCache::Target* rt, GSTextureCache::Ta
|
|||
tex->m_texture = rt->m_texture;
|
||||
}
|
||||
}
|
||||
else if (!rt->m_rt_alpha_scale)
|
||||
m_can_correct_alpha = m_can_correct_alpha;
|
||||
|
||||
m_conf.ps.rta_correction = rt->m_rt_alpha_scale;
|
||||
new_scale_rt_alpha = rt->m_rt_alpha_scale;
|
||||
}
|
||||
|
||||
if ((!IsOpaque() || m_context->ALPHA.IsBlack()) && rt && ((m_conf.colormask.wrgba & 0x7) || (m_texture_shuffle && !m_copy_16bit_to_target_shuffle && !m_same_group_texture_shuffle)))
|
||||
{
|
||||
EmulateBlending(blend_alpha_min, blend_alpha_max, DATE_PRIMID, DATE_BARRIER, rt);
|
||||
EmulateBlending(blend_alpha_min, blend_alpha_max, DATE_PRIMID, DATE_BARRIER, rt, can_scale_rt_alpha, new_scale_rt_alpha);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_conf.blend = {}; // No blending please
|
||||
m_conf.ps.no_color1 = true;
|
||||
|
||||
// Try to avoid palette draws
|
||||
if (rt && m_can_correct_alpha && !rt->m_rt_alpha_scale && rt->m_alpha_max == rt->m_alpha_min )
|
||||
if (can_scale_rt_alpha && !new_scale_rt_alpha && m_conf.colormask.wa)
|
||||
{
|
||||
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);
|
||||
const bool full_cover = rt->m_valid.rintersect(m_r).eq(rt->m_valid) && PrimitiveCoversWithoutGaps() && !(DATE || !always_passing_alpha || !IsDepthAlwaysPassing());
|
||||
|
||||
if (!full_cover)
|
||||
{
|
||||
rt->RTACorrect();
|
||||
m_conf.rt = rt->m_texture;
|
||||
}
|
||||
else
|
||||
rt->m_rt_alpha_scale = true;
|
||||
|
||||
m_conf.ps.rta_correction = rt->m_rt_alpha_scale;
|
||||
// Restrict this to only when we're overwriting the whole target.
|
||||
new_scale_rt_alpha = full_cover;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -5750,7 +5747,7 @@ __ri void GSRendererHW::DrawPrims(GSTextureCache::Target* rt, GSTextureCache::Ta
|
|||
else if (features.stencil_buffer)
|
||||
m_conf.destination_alpha = GSHWDrawConfig::DestinationAlphaMode::Stencil;
|
||||
|
||||
if (m_conf.ps.rta_correction)
|
||||
if (new_scale_rt_alpha)
|
||||
m_conf.datm = static_cast<SetDATM>(m_cached_ctx.TEST.DATM + 2);
|
||||
else
|
||||
m_conf.datm = static_cast<SetDATM>(m_cached_ctx.TEST.DATM);
|
||||
|
@ -5873,6 +5870,14 @@ __ri void GSRendererHW::DrawPrims(GSTextureCache::Target* rt, GSTextureCache::Ta
|
|||
m_conf.ps.tfx = 4;
|
||||
}
|
||||
|
||||
// Update RT scaled alpha flag, nothing's going to read it anymore.
|
||||
if (rt)
|
||||
{
|
||||
GL_INS("RT alpha is now %s", rt->m_rt_alpha_scale ? "scaled" : "NOT scaled");
|
||||
rt->m_rt_alpha_scale = new_scale_rt_alpha;
|
||||
m_conf.ps.rta_correction = rt->m_rt_alpha_scale;
|
||||
}
|
||||
|
||||
if (features.framebuffer_fetch)
|
||||
{
|
||||
// Intel GPUs on Metal lock up if you try to use DSB and framebuffer fetch at once
|
||||
|
|
|
@ -87,7 +87,8 @@ private:
|
|||
void SetupIA(float target_scale, float sx, float sy);
|
||||
void EmulateTextureShuffleAndFbmask(GSTextureCache::Target* rt, GSTextureCache::Source* tex);
|
||||
bool EmulateChannelShuffle(GSTextureCache::Target* src, bool test_only);
|
||||
void EmulateBlending(int rt_alpha_min, int rt_alpha_max, bool& DATE_PRIMID, bool& DATE_BARRIER, GSTextureCache::Target* rt);
|
||||
void EmulateBlending(int rt_alpha_min, int rt_alpha_max, bool& DATE_PRIMID, bool& DATE_BARRIER, GSTextureCache::Target* rt,
|
||||
bool can_scale_rt_alpha, bool& new_rt_alpha_scale);
|
||||
void CleanupDraw(bool invalidate_temp_src);
|
||||
|
||||
void EmulateTextureSampler(const GSTextureCache::Target* rt, const GSTextureCache::Target* ds,
|
||||
|
|
Loading…
Reference in New Issue