mirror of https://github.com/PCSX2/pcsx2.git
GS/HW: Improvements to rt alpha accuracy
This commit is contained in:
parent
244a8775dd
commit
812a3c1123
|
@ -5055,6 +5055,8 @@ __ri void GSRendererHW::DrawPrims(GSTextureCache::Target* rt, GSTextureCache::Ta
|
|||
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;
|
||||
|
||||
if (is_24_bit)
|
||||
{
|
||||
// C24/Z24 - alpha is 1.
|
||||
|
@ -5062,10 +5064,11 @@ __ri void GSRendererHW::DrawPrims(GSTextureCache::Target* rt, GSTextureCache::Ta
|
|||
blend_alpha_max = 128;
|
||||
}
|
||||
|
||||
if (!m_channel_shuffle && !m_texture_shuffle)
|
||||
if (GSUtil::GetChannelMask(m_cached_ctx.FRAME.PSM) & 0x8 && !m_channel_shuffle && !m_texture_shuffle)
|
||||
{
|
||||
const int fba_value = m_prev_env.CTXT[m_prev_env.PRIM.CTXT].FBA.FBA * 128;
|
||||
if ((m_cached_ctx.FRAME.FBMSK & 0xff000000) == 0)
|
||||
|
||||
if ((m_cached_ctx.FRAME.FBMSK & alpha_mask) == 0)
|
||||
{
|
||||
if (rt->m_valid.rintersect(m_r).eq(rt->m_valid) && PrimitiveCoversWithoutGaps() && !(m_cached_ctx.TEST.DATE || m_cached_ctx.TEST.ATE || m_cached_ctx.TEST.ZTST != ZTST_ALWAYS))
|
||||
{
|
||||
|
@ -5078,22 +5081,13 @@ __ri void GSRendererHW::DrawPrims(GSTextureCache::Target* rt, GSTextureCache::Ta
|
|||
rt->m_alpha_min = std::min(GetAlphaMinMax().min | fba_value, rt->m_alpha_min);
|
||||
}
|
||||
}
|
||||
else if ((m_cached_ctx.FRAME.FBMSK & 0xff000000) != 0xff000000) // We can't be sure of the alpha if it's partially masked.
|
||||
else if ((m_cached_ctx.FRAME.FBMSK & alpha_mask) != alpha_mask) // We can't be sure of the alpha if it's partially masked.
|
||||
{
|
||||
rt->m_alpha_max |= std::max(GetAlphaMinMax().max | fba_value, rt->m_alpha_max);
|
||||
rt->m_alpha_min = std::min(GetAlphaMinMax().min | fba_value, rt->m_alpha_min);
|
||||
}
|
||||
else if (!is_24_bit)
|
||||
{
|
||||
// If both are zero then we probably don't know what the alpha is.
|
||||
if (rt->m_alpha_max == 0 && rt->m_alpha_min == 0)
|
||||
{
|
||||
rt->m_alpha_max = 255;
|
||||
rt->m_alpha_min = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if ((m_texture_shuffle && m_conf.ps.write_rg == false) || m_channel_shuffle)
|
||||
else if ((m_texture_shuffle && m_conf.colormask.wa) || (m_channel_shuffle && (m_cached_ctx.FRAME.FBMSK & alpha_mask) != alpha_mask))
|
||||
{
|
||||
rt->m_alpha_max = 255;
|
||||
rt->m_alpha_min = 0;
|
||||
|
@ -6143,8 +6137,12 @@ bool GSRendererHW::TryTargetClear(GSTextureCache::Target* rt, GSTextureCache::Ta
|
|||
const u32 c = GetConstantDirectWriteMemClearColor();
|
||||
GL_INS("TryTargetClear(): RT at %x <= %08X", rt->m_TEX0.TBP0, c);
|
||||
g_gs_device->ClearRenderTarget(rt->m_texture, c);
|
||||
rt->m_alpha_max = c >> 24;
|
||||
rt->m_alpha_min = c >> 24;
|
||||
|
||||
if (GSLocalMemory::m_psm[rt->m_TEX0.PSM].trbpp != 24)
|
||||
{
|
||||
rt->m_alpha_max = c >> 24;
|
||||
rt->m_alpha_min = c >> 24;
|
||||
}
|
||||
|
||||
if (!rt->m_32_bits_fmt)
|
||||
{
|
||||
|
|
|
@ -3807,6 +3807,14 @@ bool GSTextureCache::ShuffleMove(u32 BP, u32 BW, u32 PSM, int sx, int sy, int dx
|
|||
config.ps.write_rg = write_rg;
|
||||
config.ps.shuffle = true;
|
||||
GSRendererHW::GetInstance()->EndHLEHardwareDraw(false);
|
||||
|
||||
if (!write_rg)
|
||||
{
|
||||
// Because we don't know the new alpha value which came from green, just go full paranoid.
|
||||
tgt->m_alpha_min = 0;
|
||||
tgt->m_alpha_max = 255;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -5809,8 +5817,17 @@ GSTextureCache::Target::Target(GIFRegTEX0 TEX0, int type, const GSVector2i& unsc
|
|||
m_unscaled_size = unscaled_size;
|
||||
m_scale = scale;
|
||||
m_texture = texture;
|
||||
m_alpha_min = 0;
|
||||
m_alpha_max = 0;
|
||||
|
||||
if ((m_TEX0.PSM & 0xf) == PSMCT24)
|
||||
{
|
||||
m_alpha_min = 128;
|
||||
m_alpha_max = 128;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_alpha_min = 0;
|
||||
m_alpha_max = 0;
|
||||
}
|
||||
m_32_bits_fmt |= (GSLocalMemory::m_psm[TEX0.PSM].trbpp != 16);
|
||||
}
|
||||
|
||||
|
@ -5901,7 +5918,10 @@ void GSTextureCache::Target::Update()
|
|||
u32 ndrects = 0;
|
||||
|
||||
const GSOffset off(g_gs_renderer->m_mem.GetOffset(m_TEX0.TBP0, m_TEX0.TBW, m_TEX0.PSM));
|
||||
const u32 bpp = GSLocalMemory::m_psm[m_TEX0.PSM].bpp;
|
||||
|
||||
std::pair<u8, u8> alpha_minmax = {255, 0};
|
||||
bool transferring_alpha = false;
|
||||
|
||||
for (size_t i = 0; i < m_dirty.size(); i++)
|
||||
{
|
||||
|
@ -5914,11 +5934,13 @@ void GSTextureCache::Target::Update()
|
|||
if (update_r.rempty())
|
||||
continue;
|
||||
|
||||
transferring_alpha |= m_dirty[i].rgba.c.a;
|
||||
|
||||
const GSVector4i read_r = m_dirty.GetDirtyRect(i, m_TEX0, total_rect, true);
|
||||
const GSVector4i t_r(read_r - t_offset);
|
||||
if (mapped)
|
||||
{
|
||||
if (m_32_bits_fmt && (m_TEX0.PSM & 0xf) != PSMCT24)
|
||||
if ((m_TEX0.PSM & 0xf) != PSMCT24 && m_dirty[i].rgba.c.a && bpp >= 16)
|
||||
{
|
||||
// TODO: Only read once in 32bit and copy to the mapped texture. Bit out of scope of this PR and not a huge impact.
|
||||
const int pitch = VectorAlign(read_r.width() * sizeof(u32));
|
||||
|
@ -5937,7 +5959,7 @@ void GSTextureCache::Target::Update()
|
|||
const int pitch = VectorAlign(read_r.width() * sizeof(u32));
|
||||
g_gs_renderer->m_mem.ReadTexture(off, read_r, s_unswizzle_buffer, pitch, TEXA);
|
||||
|
||||
if (m_32_bits_fmt && (m_TEX0.PSM & 0xf) != PSMCT24)
|
||||
if ((m_TEX0.PSM & 0xf) != PSMCT24 && m_dirty[i].rgba.c.a && bpp >= 16)
|
||||
{
|
||||
std::pair<u8, u8> new_alpha_minmax = GSGetRGBA8AlphaMinMax(s_unswizzle_buffer, read_r.width(), read_r.height(), pitch);
|
||||
alpha_minmax.first = std::min(alpha_minmax.first, new_alpha_minmax.first);
|
||||
|
@ -5994,30 +6016,17 @@ void GSTextureCache::Target::Update()
|
|||
g_gs_device->DrawMultiStretchRects(drects, ndrects, m_texture, shader);
|
||||
}
|
||||
|
||||
if ((m_TEX0.PSM & 0xf) == PSMCT24)
|
||||
if (transferring_alpha && bpp >= 16)
|
||||
{
|
||||
m_alpha_min = 128;
|
||||
m_alpha_max = 128;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (m_32_bits_fmt)
|
||||
if (m_dirty.size() != 1 || !total_rect.eq(m_valid))
|
||||
{
|
||||
if (!total_rect.eq(m_valid))
|
||||
{
|
||||
m_alpha_min = std::min(static_cast<int>(alpha_minmax.first), m_alpha_min);
|
||||
m_alpha_max = std::max(static_cast<int>(alpha_minmax.second), m_alpha_max);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_alpha_min = alpha_minmax.first;
|
||||
m_alpha_max = alpha_minmax.second;
|
||||
}
|
||||
m_alpha_min = std::min(static_cast<int>(alpha_minmax.first), m_alpha_min);
|
||||
m_alpha_max = std::max(static_cast<int>(alpha_minmax.second), m_alpha_max);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_alpha_min = 0;
|
||||
m_alpha_max = 128;
|
||||
m_alpha_min = alpha_minmax.first;
|
||||
m_alpha_max = alpha_minmax.second;
|
||||
}
|
||||
}
|
||||
g_gs_device->Recycle(t);
|
||||
|
|
Loading…
Reference in New Issue