Compare commits

...
3 changed files with 33 additions and 7 deletions
+6 -2
View File
@@ -9827,8 +9827,12 @@ bool GSRendererHW::CanUseSwPrimRender(bool no_rt, bool no_ds, bool draw_sprite_t
return false;
}
}
if (PRIM->ABE && m_vt.m_eq.rgba == 0xffff && !m_context->ALPHA.IsOpaque(GetAlphaMinMax().min, GetAlphaMinMax().max))
const u32 frame_mask = GSLocalMemory::m_psm[m_cached_ctx.FRAME.PSM].fmsk;
const u32 alpha_mask = ((m_cached_ctx.FRAME.FBMSK & frame_mask) & 0xFF000000);
const u32 rgb_mask = ((m_cached_ctx.FRAME.FBMSK & frame_mask) & 0x00FFFFFF);
const bool difficult_fbmsk = m_cached_ctx.FRAME.FBMSK != 0 && (GSLocalMemory::m_psm[m_cached_ctx.FRAME.PSM].bpp == 16 || (alpha_mask != 0 && alpha_mask != (GSLocalMemory::m_psm[m_cached_ctx.FRAME.PSM].fmsk & 0xFF000000)) ||
(rgb_mask != 0 && rgb_mask != (GSLocalMemory::m_psm[m_cached_ctx.FRAME.PSM].fmsk & 0x00FFFFFF)));
if (difficult_fbmsk || (PRIM->ABE && m_vt.m_eq.rgba == 0xffff && !m_context->ALPHA.IsOpaque(GetAlphaMinMax().min, GetAlphaMinMax().max)))
{
GSTextureCache::Target* rt = g_texture_cache->GetTargetWithSharedBits(m_cached_ctx.FRAME.Block(), m_cached_ctx.FRAME.PSM);
+13 -1
View File
@@ -545,7 +545,19 @@ bool GSRendererHWFunctions::SwPrimRender(GSRendererHW& hw, bool invalidate_tc, b
static_cast<GSSingleRasterizer*>(hw.m_sw_rasterizer.get())->Draw(data);
if (invalidate_tc)
g_texture_cache->InvalidateVideoMem(context->offset.fb, bbox);
{
GSOffset frame_offs = context->offset.fb;
if (GSLocalMemory::m_psm[context->FRAME.PSM].trbpp == 32 && context->FRAME.FBMSK)
{
if (context->FRAME.FBMSK == 0xFF000000)
frame_offs = GSRendererHW::GetInstance()->m_mem.GetOffset(context->FRAME.Block(), context->FRAME.FBW, PSMCT24);
else if (context->FRAME.FBMSK == 0x00FFFFFF)
frame_offs = GSRendererHW::GetInstance()->m_mem.GetOffset(context->FRAME.Block(), context->FRAME.FBW, PSMT8H);
}
g_texture_cache->InvalidateVideoMem(frame_offs, bbox);
}
// Jak does sw prim render, then draws to the same target, and it needs to be uploaded.
if (add_ee_transfer)
+14 -4
View File
@@ -1734,6 +1734,11 @@ GSTextureCache::Source* GSTextureCache::LookupSource(const bool is_color, const
if (found_t && (bw != t->m_TEX0.TBW || t->m_TEX0.PSM != psm))
match = false;
// Situations where font has been uploaded to the alpha channel and they use a different buffer width, this can't currently be translated correctly.
GSLocalMemory::psm_t req_psm = GSLocalMemory::m_psm[psm];
if (!possible_shuffle && req_psm.trbpp <= 8 && req_psm.bpp == 32 && t->m_TEX0.TBW != bw && (bw * 64) != t->m_valid.z && r.w > req_psm.pgs.y)
match = false;
// Different swizzle, different width, and dirty, so probably not what we want.
// DevCon.Warning("Expected %x Got %x shuffle %d draw %d", psm, t_psm, possible_shuffle, GSState::s_n);
if (match)
@@ -7273,6 +7278,9 @@ GSTexture* GSTextureCache::LookupPaletteSource(u32 CBP, u32 CPSM, u32 CBW, GSVec
else if (GSConfig.UserHacks_GPUTargetCLUTMode == GSGPUTargetCLUTMode::InsideTarget &&
t->m_TEX0.TBP0 < CBP && t->m_end_block >= CBP)
{
// If it's more than one group of 4 blocks, it's probably going to fail, horribly.
if ((size.x > GSLocalMemory::m_psm[CPSM].bs.x || size.y > GSLocalMemory::m_psm[CPSM].bs.y) && (CBP & 0x3) != (t->m_TEX0.TBP0 & 0x3))
continue;
// Somewhere within this target, can we find it?
const GSVector4i rc(0, 0, size.x, size.y);
SurfaceOffset so = ComputeSurfaceOffset(CBP, std::max<u32>(CBW, 0), CPSM, rc, t);
@@ -7285,7 +7293,7 @@ GSTexture* GSTextureCache::LookupPaletteSource(u32 CBP, u32 CPSM, u32 CBW, GSVec
}
else
{
// Not inside this target, skip.
// Not inside this target or not aligned, skip.
continue;
}
@@ -7953,7 +7961,9 @@ void GSTextureCache::Target::Update(bool cannot_scale)
alloca(sizeof(GSDevice::MultiStretchRect) * static_cast<u32>(m_dirty.size())));
u32 ndrects = 0;
const GSOffset off(g_gs_renderer->m_mem.GetOffset(m_TEX0.TBP0, m_TEX0.TBW, m_TEX0.PSM));
// There are cases where the alpha gets populated with font data, and the target has previously been PSMCT32 (or will be) so we need to make sure it gets filled in.
const u32 psm = (m_TEX0.PSM == PSMCT24) ? PSMCT32 : m_TEX0.PSM;
const GSOffset off(g_gs_renderer->m_mem.GetOffset(m_TEX0.TBP0, m_TEX0.TBW, psm));
const u32 bpp = GSLocalMemory::m_psm[m_TEX0.PSM].bpp;
std::pair<u8, u8> alpha_minmax = {255, 0};
@@ -7976,7 +7986,7 @@ void GSTextureCache::Target::Update(bool cannot_scale)
const GSVector4i t_r(read_r - t_offset);
if (mapped)
{
if ((m_TEX0.PSM & 0xf) != PSMCT24 && m_dirty[i].rgba.c.a && bpp >= 16)
if (((m_TEX0.PSM & 0xf) != PSMCT24 || m_valid_alpha_high || m_valid_alpha_low) && 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));
@@ -7995,7 +8005,7 @@ void GSTextureCache::Target::Update(bool cannot_scale)
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_TEX0.PSM & 0xf) != PSMCT24 && m_dirty[i].rgba.c.a && bpp >= 16)
if (((m_TEX0.PSM & 0xf) != PSMCT24 || m_valid_alpha_high || m_valid_alpha_low) &&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);