mirror of https://github.com/PCSX2/pcsx2.git
GS/HW: Rewrite invalidation and fix up surrounding behaviour.
This commit is contained in:
parent
dfba3c51fb
commit
9292bbcd1b
|
@ -62,16 +62,16 @@ GSVector4i GSDirtyRectList::GetTotalRect(GIFRegTEX0 TEX0, const GSVector2i& size
|
||||||
{
|
{
|
||||||
if (!empty())
|
if (!empty())
|
||||||
{
|
{
|
||||||
GSVector4i r(INT_MAX, INT_MAX, 0, 0);
|
GSVector4i r = GSVector4i::cxpr(INT_MAX, INT_MAX, 0, 0);
|
||||||
|
|
||||||
for (auto& dirty_rect : *this)
|
for (auto& dirty_rect : *this)
|
||||||
{
|
{
|
||||||
r = r.runion(dirty_rect.GetDirtyRect(TEX0));
|
r = r.runion(dirty_rect.GetDirtyRect(TEX0));
|
||||||
}
|
}
|
||||||
|
|
||||||
const GSVector2i bs = GSLocalMemory::m_psm[TEX0.PSM].bs;
|
const GSVector2i& bs = GSLocalMemory::m_psm[TEX0.PSM].bs;
|
||||||
|
|
||||||
return r.ralign<Align_Outside>(bs).rintersect(GSVector4i(0, 0, size.x, size.y));
|
return r.ralign<Align_Outside>(bs).rintersect(GSVector4i::loadh(size));
|
||||||
}
|
}
|
||||||
|
|
||||||
return GSVector4i::zero();
|
return GSVector4i::zero();
|
||||||
|
|
|
@ -996,6 +996,7 @@ bool GSHwHack::OI_RozenMaidenGebetGarden(GSRendererHW& r, GSTexture* rt, GSTextu
|
||||||
{
|
{
|
||||||
GL_INS("OI_RozenMaidenGebetGarden FB clear");
|
GL_INS("OI_RozenMaidenGebetGarden FB clear");
|
||||||
g_gs_device->ClearRenderTarget(tmp_rt->m_texture, 0);
|
g_gs_device->ClearRenderTarget(tmp_rt->m_texture, 0);
|
||||||
|
tmp_rt->UpdateDrawn(tmp_rt->m_valid);
|
||||||
tmp_rt->m_alpha_max = 0;
|
tmp_rt->m_alpha_max = 0;
|
||||||
tmp_rt->m_alpha_min = 0;
|
tmp_rt->m_alpha_min = 0;
|
||||||
}
|
}
|
||||||
|
@ -1061,9 +1062,10 @@ bool GSHwHack::OI_SonicUnleashed(GSRendererHW& r, GSTexture* rt, GSTexture* ds,
|
||||||
{
|
{
|
||||||
GSVector2i new_size = GSVector2i(std::max(rt_again->m_unscaled_size.x, src->m_unscaled_size.x),
|
GSVector2i new_size = GSVector2i(std::max(rt_again->m_unscaled_size.x, src->m_unscaled_size.x),
|
||||||
std::max(rt_again->m_unscaled_size.y, src->m_unscaled_size.y));
|
std::max(rt_again->m_unscaled_size.y, src->m_unscaled_size.y));
|
||||||
rt_again->ResizeTexture(new_size.x, new_size.y);
|
rt_again->ResizeTexture(new_size.x, new_size.y);
|
||||||
rt = rt_again->m_texture;
|
rt = rt_again->m_texture;
|
||||||
rt_size = new_size;
|
rt_size = new_size;
|
||||||
|
rt_again->UpdateDrawn(GSVector4i::loadh(rt_size));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1318,6 +1320,9 @@ static bool GetMoveTargetPair(GSRendererHW& r, GSTextureCache::Target** src, GIF
|
||||||
|
|
||||||
*src = tsrc;
|
*src = tsrc;
|
||||||
*dst = tdst;
|
*dst = tdst;
|
||||||
|
|
||||||
|
tdst->UpdateDrawn(tdst->m_valid);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2274,7 +2274,7 @@ void GSRendererHW::Draw()
|
||||||
const bool is_square = (t_size.y == t_size.x) && m_r.w >= 1023 && PrimitiveCoversWithoutGaps();
|
const bool is_square = (t_size.y == t_size.x) && m_r.w >= 1023 && PrimitiveCoversWithoutGaps();
|
||||||
const bool is_clear = is_possible_mem_clear && is_square;
|
const bool is_clear = is_possible_mem_clear && is_square;
|
||||||
rt = g_texture_cache->LookupTarget(FRAME_TEX0, t_size, target_scale, GSTextureCache::RenderTarget, true,
|
rt = g_texture_cache->LookupTarget(FRAME_TEX0, t_size, target_scale, GSTextureCache::RenderTarget, true,
|
||||||
fm, false, force_preload, preserve_rt_rgb, preserve_rt_alpha, unclamped_draw_rect);
|
fm, false, force_preload, preserve_rt_rgb, preserve_rt_alpha, unclamped_draw_rect, IsPossibleChannelShuffle());
|
||||||
|
|
||||||
// Draw skipped because it was a clear and there was no target.
|
// Draw skipped because it was a clear and there was no target.
|
||||||
if (!rt)
|
if (!rt)
|
||||||
|
@ -2588,9 +2588,10 @@ void GSRendererHW::Draw()
|
||||||
rt->ResizeDrawn(rt->GetUnscaledRect());
|
rt->ResizeDrawn(rt->GetUnscaledRect());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const GSVector4i update_rect = m_r.rintersect(GSVector4i::loadh(new_size));
|
||||||
// Limit to 2x the vertical height of the resolution (for double buffering)
|
// Limit to 2x the vertical height of the resolution (for double buffering)
|
||||||
rt->UpdateValidity(m_r, can_update_size || (m_r.w <= (resolution.y * 2) && !m_texture_shuffle));
|
rt->UpdateValidity(update_rect, can_update_size || (m_r.w <= (resolution.y * 2) && !m_texture_shuffle));
|
||||||
rt->UpdateDrawn(m_r, can_update_size || (m_r.w <= (resolution.y * 2) && !m_texture_shuffle));
|
rt->UpdateDrawn(update_rect, can_update_size || (m_r.w <= (resolution.y * 2) && !m_texture_shuffle));
|
||||||
// Probably changing to double buffering, so invalidate any old target that was next to it.
|
// Probably changing to double buffering, so invalidate any old target that was next to it.
|
||||||
// This resolves an issue where the PCRTC will find the old target in FMV's causing flashing.
|
// This resolves an issue where the PCRTC will find the old target in FMV's causing flashing.
|
||||||
// Grandia Xtreme, Onimusha Warlord.
|
// Grandia Xtreme, Onimusha Warlord.
|
||||||
|
@ -2781,7 +2782,11 @@ void GSRendererHW::Draw()
|
||||||
// Temporary source *must* be invalidated before normal, because otherwise it'll be double freed.
|
// Temporary source *must* be invalidated before normal, because otherwise it'll be double freed.
|
||||||
g_texture_cache->InvalidateTemporarySource();
|
g_texture_cache->InvalidateTemporarySource();
|
||||||
|
|
||||||
//
|
// Set the RT format back to 32bits after the shuffle.
|
||||||
|
if (rt && m_texture_shuffle && rt->m_32_bits_fmt)
|
||||||
|
{
|
||||||
|
rt->m_TEX0.PSM = PSMCT32;
|
||||||
|
}
|
||||||
|
|
||||||
// Invalidation of old targets when changing to double-buffering.
|
// Invalidation of old targets when changing to double-buffering.
|
||||||
if (old_rt)
|
if (old_rt)
|
||||||
|
@ -5670,6 +5675,7 @@ bool GSRendererHW::DetectDoubleHalfClear(bool& no_rt, bool& no_ds)
|
||||||
const u32 base = clear_depth ? m_cached_ctx.ZBUF.ZBP : m_cached_ctx.FRAME.FBP;
|
const u32 base = clear_depth ? m_cached_ctx.ZBUF.ZBP : m_cached_ctx.FRAME.FBP;
|
||||||
const u32 half = clear_depth ? m_cached_ctx.FRAME.FBP : m_cached_ctx.ZBUF.ZBP;
|
const u32 half = clear_depth ? m_cached_ctx.FRAME.FBP : m_cached_ctx.ZBUF.ZBP;
|
||||||
const bool enough_bits = clear_depth ? (frame_psm.trbpp >= zbuf_psm.trbpp) : (zbuf_psm.trbpp >= frame_psm.trbpp);
|
const bool enough_bits = clear_depth ? (frame_psm.trbpp >= zbuf_psm.trbpp) : (zbuf_psm.trbpp >= frame_psm.trbpp);
|
||||||
|
|
||||||
// Size of the current draw
|
// Size of the current draw
|
||||||
const u32 w_pages = (m_r.z + (frame_psm.pgs.x - 1)) / frame_psm.pgs.x;
|
const u32 w_pages = (m_r.z + (frame_psm.pgs.x - 1)) / frame_psm.pgs.x;
|
||||||
const u32 h_pages = (m_r.w + (frame_psm.pgs.y - 1)) / frame_psm.pgs.y;
|
const u32 h_pages = (m_r.w + (frame_psm.pgs.y - 1)) / frame_psm.pgs.y;
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -479,7 +479,7 @@ public:
|
||||||
Target* FindTargetOverlap(Target* target, int type, int psm);
|
Target* FindTargetOverlap(Target* target, int type, int psm);
|
||||||
Target* LookupTarget(GIFRegTEX0 TEX0, const GSVector2i& size, float scale, int type, bool used = true, u32 fbmask = 0,
|
Target* LookupTarget(GIFRegTEX0 TEX0, const GSVector2i& size, float scale, int type, bool used = true, u32 fbmask = 0,
|
||||||
bool is_frame = false, bool preload = GSConfig.PreloadFrameWithGSData, bool preserve_rgb = true, bool preserve_alpha = true,
|
bool is_frame = false, bool preload = GSConfig.PreloadFrameWithGSData, bool preserve_rgb = true, bool preserve_alpha = true,
|
||||||
const GSVector4i draw_rc = GSVector4i::zero());
|
const GSVector4i draw_rc = GSVector4i::zero(), bool is_shuffle = false);
|
||||||
Target* CreateTarget(GIFRegTEX0 TEX0, const GSVector2i& size, const GSVector2i& valid_size,float scale, int type, bool used = true, u32 fbmask = 0,
|
Target* CreateTarget(GIFRegTEX0 TEX0, const GSVector2i& size, const GSVector2i& valid_size,float scale, int type, bool used = true, u32 fbmask = 0,
|
||||||
bool is_frame = false, bool preload = GSConfig.PreloadFrameWithGSData, bool preserve_target = true,
|
bool is_frame = false, bool preload = GSConfig.PreloadFrameWithGSData, bool preserve_target = true,
|
||||||
const GSVector4i draw_rc = GSVector4i::zero(), GSTextureCache::Source* src = nullptr);
|
const GSVector4i draw_rc = GSVector4i::zero(), GSTextureCache::Source* src = nullptr);
|
||||||
|
|
Loading…
Reference in New Issue