Skip to content

Commit 7eb743c

Browse files
GS/TC: Correct some preload behaviour on merging targets
1 parent 28abbc6 commit 7eb743c

File tree

1 file changed

+62
-17
lines changed

1 file changed

+62
-17
lines changed

pcsx2/GS/Renderers/HW/GSTextureCache.cpp

Lines changed: 62 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -3815,23 +3815,54 @@ bool GSTextureCache::PreloadTarget(GIFRegTEX0 TEX0, const GSVector2i& size, cons
38153815
if (GSConfig.UserHacks_TextureInsideRt >= GSTextureInRtMode::InsideTargets && t->Inside(dst->m_TEX0.TBP0, dst->m_TEX0.TBW, dst->m_TEX0.PSM, dst->m_valid) &&
38163816
GSLocalMemory::m_psm[t->m_TEX0.PSM].bpp == GSLocalMemory::m_psm[dst->m_TEX0.PSM].bpp)
38173817
{
3818-
dst->m_TEX0.TBP0 = t->m_TEX0.TBP0;
3819-
dst->m_valid = t->m_valid;
3820-
dst->m_drawn_since_read = t->m_drawn_since_read;
3821-
dst->m_end_block = t->m_end_block;
3822-
dst->m_valid_rgb = true;
3823-
t->m_valid_rgb = false;
3824-
t->m_was_dst_matched = true;
3818+
// if this part is dirty, then let's break it in two.
3819+
GSVector4i dirty_rect = t->m_dirty.GetTotalRect(t->m_TEX0, t->m_unscaled_size);
3820+
if (GSLocalMemory::GetStartBlockAddress(t->m_TEX0.TBP0, t->m_TEX0.TBW, t->m_TEX0.PSM, dirty_rect) >= dst->m_TEX0.TBP0)
3821+
{
3822+
t->m_valid.w = dirty_rect.y;
38253823

3826-
dst->ResizeTexture(t->m_unscaled_size.x, t->m_unscaled_size.y);
3824+
if (t->m_valid.rempty())
3825+
{
3826+
if (src && src->m_target && src->m_from_target == t)
3827+
{
3828+
src->m_from_target = nullptr;
3829+
src->m_texture = t->m_texture;
3830+
src->m_target_direct = false;
3831+
src->m_shared_texture = false;
38273832

3828-
const ShaderConvert shader = (GSLocalMemory::m_psm[dst->m_TEX0.PSM].trbpp == 16) ? ShaderConvert::RGB5A1_TO_FLOAT16 :
3829-
(GSLocalMemory::m_psm[dst->m_TEX0.PSM].trbpp == 32) ? ShaderConvert::RGBA8_TO_FLOAT32 :
3830-
ShaderConvert::RGBA8_TO_FLOAT24;
3833+
t->m_texture = nullptr;
3834+
i = list.erase(j);
3835+
delete t;
3836+
}
3837+
else
3838+
{
3839+
InvalidateSourcesFromTarget(t);
3840+
i = list.erase(j);
3841+
delete t;
3842+
}
3843+
}
3844+
else
3845+
t->UpdateValidity(t->m_valid, true);
3846+
}
3847+
else
3848+
{
3849+
dst->m_TEX0.TBP0 = t->m_TEX0.TBP0;
3850+
dst->m_valid = t->m_valid;
3851+
dst->m_drawn_since_read = t->m_drawn_since_read;
3852+
dst->m_end_block = t->m_end_block;
3853+
dst->m_valid_rgb = true;
3854+
t->m_valid_rgb = false;
3855+
t->m_was_dst_matched = true;
38313856

3832-
g_gs_device->StretchRect(t->m_texture, GSVector4(0, 0, 1, 1),
3833-
dst->m_texture, GSVector4(t->GetUnscaledRect()) * GSVector4(dst->GetScale()), shader, false);
3857+
dst->ResizeTexture(t->m_unscaled_size.x, t->m_unscaled_size.y);
38343858

3859+
const ShaderConvert shader = (GSLocalMemory::m_psm[dst->m_TEX0.PSM].trbpp == 16) ? ShaderConvert::RGB5A1_TO_FLOAT16 :
3860+
(GSLocalMemory::m_psm[dst->m_TEX0.PSM].trbpp == 32) ? ShaderConvert::RGBA8_TO_FLOAT32 :
3861+
ShaderConvert::RGBA8_TO_FLOAT24;
3862+
3863+
g_gs_device->StretchRect(t->m_texture, GSVector4(0, 0, 1, 1),
3864+
dst->m_texture, GSVector4(t->GetUnscaledRect()) * GSVector4(dst->GetScale()), shader, false);
3865+
}
38353866
break;
38363867
}
38373868
else
@@ -3858,7 +3889,18 @@ bool GSTextureCache::PreloadTarget(GIFRegTEX0 TEX0, const GSVector2i& size, cons
38583889

38593890
if (height_adjust < t->m_unscaled_size.y)
38603891
{
3861-
t->m_TEX0.TBP0 = GSLocalMemory::GetStartBlockAddress(t->m_TEX0.TBP0, t->m_TEX0.TBW, t->m_TEX0.PSM, GSVector4i(0, height_adjust, t->m_valid.z, t->m_valid.w));
3892+
u32 new_base_tbp = GSLocalMemory::GetStartBlockAddress(t->m_TEX0.TBP0, t->m_TEX0.TBW, t->m_TEX0.PSM, GSVector4i(0, height_adjust, t->m_valid.z, t->m_valid.w));
3893+
if (t->m_dirty.size() > 0)
3894+
{
3895+
u32 dirty_end = GSLocalMemory::GetEndBlockAddress(t->m_TEX0.TBP0, t->m_TEX0.TBW, t->m_TEX0.PSM, t->m_dirty.GetTotalRect(t->m_TEX0, t->m_unscaled_size));
3896+
3897+
if (new_base_tbp >= dirty_end)
3898+
t->m_dirty.clear();
3899+
else
3900+
t->Update(true);
3901+
}
3902+
3903+
t->m_TEX0.TBP0 = new_base_tbp;
38623904
t->m_valid.w -= height_adjust;
38633905
t->ResizeValidity(t->m_valid);
38643906

@@ -4368,16 +4410,19 @@ void GSTextureCache::InvalidateContainedTargets(u32 start_bp, u32 end_bp, u32 wr
43684410
const u32 end_width = write_bw * 64;
43694411
const u32 end_height = ((end_page_offset / std::max(write_bw, 1U)) * GSLocalMemory::m_psm[write_psm].pgs.y) + GSLocalMemory::m_psm[write_psm].pgs.y;
43704412
const GSVector4i r = GSVector4i(0, 0, end_width, end_height);
4371-
const GSVector4i invalidate_r = TranslateAlignedRectByPage(t, start_bp, write_psm, write_bw, r, false).rintersect(t->m_valid); // it is invalidation but we need a real rect.
4413+
const GSVector4i invalidate_r = TranslateAlignedRectByPage(t, start_bp, write_psm, write_bw, r, true).rintersect(t->m_valid); // it is invalidation but we need a real rect.
43724414

43734415
if (offset == 0 || dirty_rect.rempty() || !dirty_rect.rintersect(invalidate_r).rempty())
43744416
{
43754417
if (write_bw == t->m_TEX0.TBW && GSLocalMemory::m_psm[t->m_TEX0.PSM].bpp == GSLocalMemory::m_psm[write_psm].bpp)
43764418
{
4377-
43784419
RGBAMask mask;
43794420
mask._u32 = GSUtil::GetChannelMask(write_psm, fb_mask);
4380-
AddDirtyRectTarget(t, invalidate_r, t->m_TEX0.PSM, t->m_TEX0.TBW, mask, false);
4421+
4422+
if (write_bw != t->m_TEX0.TBW)
4423+
DirtyRectByPage(start_bp, write_psm, write_bw, t, r);
4424+
else
4425+
AddDirtyRectTarget(t, invalidate_r, t->m_TEX0.PSM, t->m_TEX0.TBW, mask, false);
43814426
}
43824427

43834428
++i;

0 commit comments

Comments
 (0)