|
|
|
|
@@ -180,7 +180,7 @@ void GSTextureCache::AddDirtyRectTarget(Target* target, GSVector4i rect, u32 psm
|
|
|
|
|
|
|
|
|
|
if (!skipdirty)
|
|
|
|
|
{
|
|
|
|
|
GL_INS("Dirty rect added for BP %x rect %d,%d->%d->%d", target->m_TEX0.TBP0, rect.x, rect.y, rect.z, rect.w);
|
|
|
|
|
GL_INS("TC: Dirty rect added for BP %x rect %d,%d->%d->%d", target->m_TEX0.TBP0, rect.x, rect.y, rect.z, rect.w);
|
|
|
|
|
target->m_dirty.push_back(GSDirtyRect(rect, psm, bw, rgba, req_linear));
|
|
|
|
|
|
|
|
|
|
if (!target->m_drawn_since_read.rempty())
|
|
|
|
|
@@ -595,7 +595,7 @@ void GSTextureCache::DirtyRectByPage(u32 sbp, u32 spsm, u32 sbw, Target* t, GSVe
|
|
|
|
|
|
|
|
|
|
const u32 start_bp = GSLocalMemory::GetStartBlockAddress(sbp, sbw, spsm, src_r);
|
|
|
|
|
const u32 end_bp = GSLocalMemory::GetEndBlockAddress(sbp, sbw, spsm, src_r);
|
|
|
|
|
GL_INS("Invalidating BP: 0x%x (%x -> %x) BW: %d PSM %s Target BP: 0x%x BW %x PSM %s", sbp, start_bp, end_bp, sbw, psm_str(spsm), t->m_TEX0.TBP0, t->m_TEX0.TBW, psm_str(t->m_TEX0.PSM));
|
|
|
|
|
GL_INS("TC: Invalidating BP: 0x%x (%x -> %x) BW: %d PSM %s Target BP: 0x%x BW %x PSM %s", sbp, start_bp, end_bp, sbw, psm_str(spsm), t->m_TEX0.TBP0, t->m_TEX0.TBW, psm_str(t->m_TEX0.PSM));
|
|
|
|
|
|
|
|
|
|
// If the whole thing is covered, just invalidate the whole rect.
|
|
|
|
|
if (start_bp <= t->m_TEX0.TBP0 && end_bp >= t->UnwrappedEndBlock())
|
|
|
|
|
@@ -1002,7 +1002,7 @@ GSTextureCache::Source* GSTextureCache::LookupDepthSource(const bool is_depth, c
|
|
|
|
|
{
|
|
|
|
|
if (GSConfig.UserHacks_DisableDepthSupport)
|
|
|
|
|
{
|
|
|
|
|
GL_CACHE("LookupDepthSource not supported (0x%x, F:0x%x)", TEX0.TBP0, TEX0.PSM);
|
|
|
|
|
GL_CACHE("TC: LookupDepthSource not supported (0x%x, F:0x%x)", TEX0.TBP0, TEX0.PSM);
|
|
|
|
|
return nullptr;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@@ -1045,7 +1045,7 @@ GSTextureCache::Source* GSTextureCache::LookupDepthSource(const bool is_depth, c
|
|
|
|
|
|
|
|
|
|
if (GSUtil::HasSharedBits(bp, psm, t->m_TEX0.TBP0, t->m_TEX0.PSM))
|
|
|
|
|
{
|
|
|
|
|
GL_INS("Found target in Depth list BP: %x but is RenderTarget", t->m_TEX0.TBP0);
|
|
|
|
|
GL_INS("TC: Found target in Depth list BP: %x but is RenderTarget", t->m_TEX0.TBP0);
|
|
|
|
|
if (t->m_age == 0)
|
|
|
|
|
{
|
|
|
|
|
// Perfect Match
|
|
|
|
|
@@ -1097,7 +1097,7 @@ GSTextureCache::Source* GSTextureCache::LookupDepthSource(const bool is_depth, c
|
|
|
|
|
{
|
|
|
|
|
if (t->m_age <= 1 && t->m_TEX0.TBP0 == bp && t->m_TEX0.TBW == TEX0.TBW && t->HasValidAlpha())
|
|
|
|
|
{
|
|
|
|
|
GL_CACHE("TC depth: Using RT %x instead of depth because of missing alpha", t->m_TEX0.TBP0);
|
|
|
|
|
GL_CACHE("TC: depth: Using RT %x instead of depth because of missing alpha", t->m_TEX0.TBP0);
|
|
|
|
|
|
|
|
|
|
// Have to update here, because this is a source, it won't Update().
|
|
|
|
|
if (FullRectDirty(t, 0x7))
|
|
|
|
|
@@ -1141,7 +1141,7 @@ GSTextureCache::Source* GSTextureCache::LookupDepthSource(const bool is_depth, c
|
|
|
|
|
|
|
|
|
|
if (dst)
|
|
|
|
|
{
|
|
|
|
|
GL_CACHE("TC depth: dst %s hit: (0x%x, %s)", to_string(dst->m_type),
|
|
|
|
|
GL_CACHE("TC: depth: dst %s hit: (0x%x, %s)", to_string(dst->m_type),
|
|
|
|
|
TEX0.TBP0, psm_str(psm));
|
|
|
|
|
|
|
|
|
|
// Create a shared texture source
|
|
|
|
|
@@ -1207,7 +1207,7 @@ GSTextureCache::Source* GSTextureCache::LookupSource(const bool is_color, const
|
|
|
|
|
// Prevent everything going to rubbish if a game somehow sends a TW/TH above 10, and region isn't being used.
|
|
|
|
|
if ((TEX0.TW > 10 && !region.HasX()) || (TEX0.TH > 10 && !region.HasY()))
|
|
|
|
|
{
|
|
|
|
|
GL_CACHE("Invalid TEX0 size %ux%u without region, aborting draw.", TEX0.TW, TEX0.TH);
|
|
|
|
|
GL_CACHE("TC: Invalid TEX0 size %ux%u without region, aborting draw.", TEX0.TW, TEX0.TH);
|
|
|
|
|
return nullptr;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@@ -2135,7 +2135,7 @@ GSTextureCache::Target* GSTextureCache::LookupTarget(GIFRegTEX0 TEX0, const GSVe
|
|
|
|
|
new_size = size.max(tgt->m_unscaled_size);
|
|
|
|
|
new_scaled_size = ScaleRenderTargetSize(new_size, scale);
|
|
|
|
|
dRect = (GSVector4(GSVector4i::loadh(tgt->m_unscaled_size)) * GSVector4(scale)).ceil();
|
|
|
|
|
GL_INS("TC Rescale: %dx%d: %dx%d @ %f -> %dx%d @ %f", tgt->m_unscaled_size.x, tgt->m_unscaled_size.y,
|
|
|
|
|
GL_INS("TC: Rescale: %dx%d: %dx%d @ %f -> %dx%d @ %f", tgt->m_unscaled_size.x, tgt->m_unscaled_size.y,
|
|
|
|
|
tgt->m_texture->GetWidth(), tgt->m_texture->GetHeight(), tgt->m_scale, new_scaled_size.x, new_scaled_size.y,
|
|
|
|
|
scale);
|
|
|
|
|
};
|
|
|
|
|
@@ -2526,7 +2526,7 @@ GSTextureCache::Target* GSTextureCache::LookupTarget(GIFRegTEX0 TEX0, const GSVe
|
|
|
|
|
}
|
|
|
|
|
if (!is_shuffle)
|
|
|
|
|
{
|
|
|
|
|
GL_INS("TC Convert to 16bit: %dx%d: %dx%d @ %f -> %dx%d @ %f", dst->m_unscaled_size.x, dst->m_unscaled_size.y,
|
|
|
|
|
GL_INS("TC: Convert to 16bit: %dx%d: %dx%d @ %f -> %dx%d @ %f", dst->m_unscaled_size.x, dst->m_unscaled_size.y,
|
|
|
|
|
dst->m_texture->GetWidth(), dst->m_texture->GetHeight(), dst->m_scale, new_scaled_size.x, new_scaled_size.y,
|
|
|
|
|
scale);
|
|
|
|
|
|
|
|
|
|
@@ -2738,7 +2738,7 @@ GSTextureCache::Target* GSTextureCache::LookupTarget(GIFRegTEX0 TEX0, const GSVe
|
|
|
|
|
t->m_texture = nullptr;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
GL_CACHE("Deleting Z draw %d", GSState::s_n);
|
|
|
|
|
GL_CACHE("TC: Deleting Z draw %d", GSState::s_n);
|
|
|
|
|
InvalidateSourcesFromTarget(t);
|
|
|
|
|
i = rev_list.erase(i);
|
|
|
|
|
delete t;
|
|
|
|
|
@@ -2759,7 +2759,7 @@ GSTextureCache::Target* GSTextureCache::LookupTarget(GIFRegTEX0 TEX0, const GSVe
|
|
|
|
|
const u32 end_block = GSLocalMemory::GetUnwrappedEndBlockAddress(TEX0.TBP0, TEX0.TBW, TEX0.PSM, draw_rect);
|
|
|
|
|
if (end_block >= t->UnwrappedEndBlock())
|
|
|
|
|
{
|
|
|
|
|
GL_CACHE("Not converting %s at %x TBW %u with end block of %x when we're drawing through %x",
|
|
|
|
|
GL_CACHE("TC: Not converting %s at %x TBW %u with end block of %x when we're drawing through %x",
|
|
|
|
|
to_string(rev_type), t->m_TEX0.TBP0, t->m_TEX0.TBW, t->UnwrappedEndBlock(), end_block);
|
|
|
|
|
remove_target = true;
|
|
|
|
|
}
|
|
|
|
|
@@ -3165,7 +3165,7 @@ bool GSTextureCache::PreloadTarget(GIFRegTEX0 TEX0, const GSVector2i& size, cons
|
|
|
|
|
{
|
|
|
|
|
const GSVector4i save_rect = preserve_target ? newrect : eerect;
|
|
|
|
|
|
|
|
|
|
GL_INS("Preloading the RT DATA from updated GS Memory");
|
|
|
|
|
GL_INS("TC: Preloading the RT DATA from updated GS Memory");
|
|
|
|
|
|
|
|
|
|
AddDirtyRectTarget(dst, save_rect, TEX0.PSM, TEX0.TBW, rgba, GSLocalMemory::m_psm[TEX0.PSM].trbpp >= 16);
|
|
|
|
|
}
|
|
|
|
|
@@ -3182,7 +3182,7 @@ bool GSTextureCache::PreloadTarget(GIFRegTEX0 TEX0, const GSVector2i& size, cons
|
|
|
|
|
GSRendererHW::GetInstance()->m_draw_transfers.pop_back();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
GL_INS("Preloading the RT DATA");
|
|
|
|
|
GL_INS("TC: Preloading the RT DATA");
|
|
|
|
|
|
|
|
|
|
// Don't set valid here, because we have no guarantee this is the data we want.
|
|
|
|
|
AddDirtyRectTarget(dst, newrect, TEX0.PSM, TEX0.TBW, rgba, GSLocalMemory::m_psm[TEX0.PSM].trbpp >= 16);
|
|
|
|
|
@@ -3242,7 +3242,7 @@ bool GSTextureCache::PreloadTarget(GIFRegTEX0 TEX0, const GSVector2i& size, cons
|
|
|
|
|
{
|
|
|
|
|
GSVector4i new_valid = t->m_valid;
|
|
|
|
|
new_valid.w /= 2;
|
|
|
|
|
GL_INS("RT resize buffer for FBP 0x%x, %dx%d => %d,%d", t->m_TEX0.TBP0, t->m_valid.width(), t->m_valid.height(), new_valid.width(), new_valid.height());
|
|
|
|
|
GL_INS("TC: RT resize buffer for FBP 0x%x, %dx%d => %d,%d", t->m_TEX0.TBP0, t->m_valid.width(), t->m_valid.height(), new_valid.width(), new_valid.height());
|
|
|
|
|
t->ResizeValidity(new_valid);
|
|
|
|
|
return hw_clear.value_or(false);
|
|
|
|
|
}
|
|
|
|
|
@@ -3281,7 +3281,7 @@ bool GSTextureCache::PreloadTarget(GIFRegTEX0 TEX0, const GSVector2i& size, cons
|
|
|
|
|
int copy_width = ((t->m_texture->GetWidth()) > (dst->m_texture->GetWidth()) ? (dst->m_texture->GetWidth()) : t->m_texture->GetWidth()) - dst_offset_scaled_width;
|
|
|
|
|
int copy_height = (texture_height - dst_offset_height) * t->m_scale;
|
|
|
|
|
|
|
|
|
|
GL_INS("RT double buffer copy from FBP 0x%x, %dx%d => %d,%d", t->m_TEX0.TBP0, copy_width, copy_height, 0, dst_offset_scaled_height);
|
|
|
|
|
GL_INS("TC: RT double buffer copy from FBP 0x%x, %dx%d => %d,%d", t->m_TEX0.TBP0, copy_width, copy_height, 0, dst_offset_scaled_height);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Clear the dirty first
|
|
|
|
|
@@ -3513,7 +3513,7 @@ void GSTextureCache::Target::ScaleRTAlpha()
|
|
|
|
|
{
|
|
|
|
|
const GSVector2i rtsize(m_texture->GetSize());
|
|
|
|
|
const GSVector4i valid_rect = GSVector4i(GSVector4(m_valid) * GSVector4(m_scale));
|
|
|
|
|
GL_PUSH("ScaleRTAlpha(valid=(%dx%d %d,%d=>%d,%d))", m_valid.width(), m_valid.height(), m_valid.x, m_valid.y, m_valid.z, m_valid.w);
|
|
|
|
|
GL_PUSH("TC: ScaleRTAlpha(valid=(%dx%d %d,%d=>%d,%d))", m_valid.width(), m_valid.height(), m_valid.x, m_valid.y, m_valid.z, m_valid.w);
|
|
|
|
|
|
|
|
|
|
if (GSTexture* temp_rt = g_gs_device->CreateRenderTarget(rtsize.x, rtsize.y, GSTexture::Format::Color, !GSVector4i::loadh(rtsize).eq(valid_rect)))
|
|
|
|
|
{
|
|
|
|
|
@@ -3539,7 +3539,7 @@ void GSTextureCache::Target::UnscaleRTAlpha()
|
|
|
|
|
{
|
|
|
|
|
const GSVector2i rtsize(m_texture->GetSize());
|
|
|
|
|
const GSVector4i valid_rect = GSVector4i(GSVector4(m_valid) * GSVector4(m_scale));
|
|
|
|
|
GL_PUSH("UnscaleRTAlpha(valid=(%dx%d %d,%d=>%d,%d))", valid_rect.width(), valid_rect.height(), valid_rect.x, valid_rect.y, valid_rect.z, valid_rect.w);
|
|
|
|
|
GL_PUSH("TC: UnscaleRTAlpha(valid=(%dx%d %d,%d=>%d,%d))", valid_rect.width(), valid_rect.height(), valid_rect.x, valid_rect.y, valid_rect.z, valid_rect.w);
|
|
|
|
|
|
|
|
|
|
if (GSTexture* temp_rt = g_gs_device->CreateRenderTarget(rtsize.x, rtsize.y, GSTexture::Format::Color, !GSVector4i::loadh(rtsize).eq(valid_rect)))
|
|
|
|
|
{
|
|
|
|
|
@@ -3602,7 +3602,7 @@ void GSTextureCache::ScaleTargetForDisplay(Target* t, const GIFRegTEX0& dispfb,
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
GL_CACHE("Expanding target for display output, target height %d @ 0x%X, display %d @ 0x%X offset %d needed %d",
|
|
|
|
|
GL_CACHE("TC: Expanding target for display output, target height %d @ 0x%X, display %d @ 0x%X offset %d needed %d",
|
|
|
|
|
t->m_unscaled_size.y, t->m_TEX0.TBP0, real_h, dispfb.TBP0, y_offset, needed_height);
|
|
|
|
|
|
|
|
|
|
// Fill the new texture with the old data, and discard the old texture.
|
|
|
|
|
@@ -3772,7 +3772,7 @@ bool GSTextureCache::PrepareDownloadTexture(u32 width, u32 height, GSTexture::Fo
|
|
|
|
|
*tex = g_gs_device->CreateDownloadTexture(new_width, new_height, format);
|
|
|
|
|
if (!tex)
|
|
|
|
|
{
|
|
|
|
|
Console.WriteLn("Failed to create %ux%u download texture", new_width, new_height);
|
|
|
|
|
Console.WriteLn("TC: Failed to create %ux%u download texture", new_width, new_height);
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@@ -4202,7 +4202,7 @@ void GSTextureCache::InvalidateLocalMem(const GSOffset& off, const GSVector4i& r
|
|
|
|
|
{
|
|
|
|
|
if (GSConfig.HWDownloadMode != GSHardwareDownloadMode::Enabled)
|
|
|
|
|
{
|
|
|
|
|
DevCon.Error("Skipping depth readback of %ux%u @ %u,%u", r.width(), r.height(), r.left, r.top);
|
|
|
|
|
DevCon.Error("TC: Skipping depth readback of %ux%u @ %u,%u", r.width(), r.height(), r.left, r.top);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@@ -4472,7 +4472,7 @@ void GSTextureCache::InvalidateLocalMem(const GSOffset& off, const GSVector4i& r
|
|
|
|
|
|
|
|
|
|
if (GSConfig.HWDownloadMode != GSHardwareDownloadMode::Enabled)
|
|
|
|
|
{
|
|
|
|
|
DevCon.Error("Skipping depth readback of %ux%u @ %u,%u", targetr.width(), targetr.height(), targetr.left, targetr.top);
|
|
|
|
|
DevCon.Error("TC: Skipping depth readback of %ux%u @ %u,%u", targetr.width(), targetr.height(), targetr.left, targetr.top);
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@@ -4529,7 +4529,7 @@ bool GSTextureCache::Move(u32 SBP, u32 SBW, u32 SPSM, int sx, int sy, u32 DBP, u
|
|
|
|
|
const GSLocalMemory::psm_t& dpsm_s = GSLocalMemory::m_psm[DPSM];
|
|
|
|
|
if (SPSM != DPSM || ((spsm_s.pal + dpsm_s.pal) != 0 && !alpha_only))
|
|
|
|
|
{
|
|
|
|
|
GL_CACHE("Skipping HW move from 0x%X to 0x%X with SPSM=%s DPSM=%s", SBP, DBP, psm_str(SPSM), psm_str(DPSM));
|
|
|
|
|
GL_CACHE("TC: Skipping HW move from 0x%X to 0x%X with SPSM=%s DPSM=%s", SBP, DBP, psm_str(SPSM), psm_str(DPSM));
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@@ -4554,7 +4554,7 @@ bool GSTextureCache::Move(u32 SBP, u32 SBW, u32 SPSM, int sx, int sy, u32 DBP, u
|
|
|
|
|
dx += rect_offset.x;
|
|
|
|
|
dy += rect_offset.y;
|
|
|
|
|
|
|
|
|
|
GL_INS("Detected striped move, realigning from SBP %x->%x DBP %x->%x", SBP, m_remembered_src_bp, DBP, m_remembered_dst_bp);
|
|
|
|
|
GL_INS("TC: Detected striped move, realigning from SBP %x->%x DBP %x->%x", SBP, m_remembered_src_bp, DBP, m_remembered_dst_bp);
|
|
|
|
|
|
|
|
|
|
SBP = m_remembered_src_bp;
|
|
|
|
|
DBP = m_remembered_dst_bp;
|
|
|
|
|
@@ -4643,7 +4643,7 @@ bool GSTextureCache::Move(u32 SBP, u32 SBW, u32 SPSM, int sx, int sy, u32 DBP, u
|
|
|
|
|
|
|
|
|
|
// We don't recycle the old texture here, because the height cache will track the new size,
|
|
|
|
|
// so the old size won't get created again.
|
|
|
|
|
GL_INS("Resize %dx%d target to %dx%d for move", dst->m_unscaled_size.x, dst->m_unscaled_size.y, dst->m_unscaled_size.x, new_height);
|
|
|
|
|
GL_INS("TC: Resize %dx%d target to %dx%d for move", dst->m_unscaled_size.x, dst->m_unscaled_size.y, dst->m_unscaled_size.x, new_height);
|
|
|
|
|
GetTargetSize(DBP, DBW, DPSM, 0, new_height);
|
|
|
|
|
|
|
|
|
|
if (!dst->ResizeTexture(dst->m_unscaled_size.x, new_height, false))
|
|
|
|
|
@@ -4657,7 +4657,7 @@ bool GSTextureCache::Move(u32 SBP, u32 SBW, u32 SPSM, int sx, int sy, u32 DBP, u
|
|
|
|
|
// Make sure the copy doesn't go out of bounds (it shouldn't).
|
|
|
|
|
if ((scaled_dx + scaled_w) > dst->m_texture->GetWidth() || (scaled_dy + scaled_h) > dst->m_texture->GetHeight())
|
|
|
|
|
return false;
|
|
|
|
|
GL_CACHE("HW Move after draw %d 0x%x[BW:%u PSM:%s] to 0x%x[BW:%u PSM:%s] <%d,%d->%d,%d> -> <%d,%d->%d,%d>", GSState::s_n, SBP, SBW,
|
|
|
|
|
GL_CACHE("TC: HW Move after draw %d 0x%x[BW:%u PSM:%s] to 0x%x[BW:%u PSM:%s] <%d,%d->%d,%d> -> <%d,%d->%d,%d>", GSState::s_n, SBP, SBW,
|
|
|
|
|
psm_str(SPSM), DBP, DBW, psm_str(DPSM), sx, sy, sx + w, sy + h, dx, dy, dx + w, dy + h);
|
|
|
|
|
|
|
|
|
|
const bool cover_whole_target = dst->m_type == RenderTarget && GSVector4i(dx, dy, dx + w, dy + h).rintersect(dst->m_valid).eq(dst->m_valid);
|
|
|
|
|
@@ -4797,7 +4797,7 @@ bool GSTextureCache::ShuffleMove(u32 BP, u32 BW, u32 PSM, int sx, int sy, int dx
|
|
|
|
|
if (PSM != PSMCT16)
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
GL_CACHE("Trying ShuffleMove: BP=%04X BW=%u PSM=%u SX=%d SY=%d DX=%d DY=%d W=%d H=%d", BP, BW, PSM, sx, sy, dx, dy, w, h);
|
|
|
|
|
GL_CACHE("TC: Trying ShuffleMove: BP=%04X BW=%u PSM=%u SX=%d SY=%d DX=%d DY=%d W=%d H=%d", BP, BW, PSM, sx, sy, dx, dy, w, h);
|
|
|
|
|
|
|
|
|
|
GSTextureCache::Target* tgt = nullptr;
|
|
|
|
|
for (auto t : m_dst[RenderTarget])
|
|
|
|
|
@@ -4808,7 +4808,7 @@ bool GSTextureCache::ShuffleMove(u32 BP, u32 BW, u32 PSM, int sx, int sy, int dx
|
|
|
|
|
if (so.is_valid)
|
|
|
|
|
{
|
|
|
|
|
tgt = t;
|
|
|
|
|
GL_CACHE("ShuffleMove: Surface offset %d,%d from BP %04X - %04X", so.b2a_offset.x, so.b2a_offset.y, BP, t->m_TEX0.TBP0);
|
|
|
|
|
GL_CACHE("TC: ShuffleMove: Surface offset %d,%d from BP %04X - %04X", so.b2a_offset.x, so.b2a_offset.y, BP, t->m_TEX0.TBP0);
|
|
|
|
|
sx += so.b2a_offset.x;
|
|
|
|
|
sy += so.b2a_offset.y;
|
|
|
|
|
dx += so.b2a_offset.x;
|
|
|
|
|
@@ -4819,7 +4819,7 @@ bool GSTextureCache::ShuffleMove(u32 BP, u32 BW, u32 PSM, int sx, int sy, int dx
|
|
|
|
|
}
|
|
|
|
|
if (!tgt)
|
|
|
|
|
{
|
|
|
|
|
GL_CACHE("ShuffleMove: No target found");
|
|
|
|
|
GL_CACHE("TC: ShuffleMove: No target found");
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@@ -4827,7 +4827,7 @@ bool GSTextureCache::ShuffleMove(u32 BP, u32 BW, u32 PSM, int sx, int sy, int dx
|
|
|
|
|
const s32 diff_x = (dx - sx);
|
|
|
|
|
if (std::abs(diff_x) != 8 || sy != dy)
|
|
|
|
|
{
|
|
|
|
|
GL_CACHE("ShuffleMove: Difference is not 8 pixels");
|
|
|
|
|
GL_CACHE("TC: ShuffleMove: Difference is not 8 pixels");
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@@ -4879,7 +4879,7 @@ bool GSTextureCache::PageMove(u32 SBP, u32 DBP, u32 BW, u32 PSM, int sx, int sy,
|
|
|
|
|
const u32 dst_page_offset = ((dy / pgs.y) * BW) + (dx / pgs.x);
|
|
|
|
|
const u32 dst_block_end = DBP + (((dst_page_offset + num_pages) * BLOCKS_PER_PAGE) - 1);
|
|
|
|
|
pxAssert(num_pages > 0);
|
|
|
|
|
GL_PUSH("GSTextureCache::PageMove(): %u pages, with offset of %u src %u dst", num_pages, src_page_offset,
|
|
|
|
|
GL_PUSH("TC: GSTextureCache::PageMove(): %u pages, with offset of %u src %u dst", num_pages, src_page_offset,
|
|
|
|
|
dst_page_offset);
|
|
|
|
|
|
|
|
|
|
// Find our targets.
|
|
|
|
|
@@ -4909,14 +4909,14 @@ bool GSTextureCache::PageMove(u32 SBP, u32 DBP, u32 BW, u32 PSM, int sx, int sy,
|
|
|
|
|
}
|
|
|
|
|
if (!stgt || !dtgt)
|
|
|
|
|
{
|
|
|
|
|
GL_INS("Targets not found.");
|
|
|
|
|
GL_INS("TC: Targets not found.");
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Double-check that we're not copying to a non-page-aligned target.
|
|
|
|
|
if (((SBP - stgt->m_TEX0.TBP0) % BLOCKS_PER_PAGE) != 0 || ((DBP - dtgt->m_TEX0.TBP0) % BLOCKS_PER_PAGE) != 0)
|
|
|
|
|
{
|
|
|
|
|
GL_INS("Effective SBP of %x or DBP of %x is not page aligned.", SBP - stgt->m_TEX0.TBP0, DBP - dtgt->m_TEX0.TBP0);
|
|
|
|
|
GL_INS("TC: Effective SBP of %x or DBP of %x is not page aligned.", SBP - stgt->m_TEX0.TBP0, DBP - dtgt->m_TEX0.TBP0);
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@@ -4929,7 +4929,7 @@ bool GSTextureCache::PageMove(u32 SBP, u32 DBP, u32 BW, u32 PSM, int sx, int sy,
|
|
|
|
|
|
|
|
|
|
void GSTextureCache::CopyPages(Target* src, u32 sbw, u32 src_offset, Target* dst, u32 dbw, u32 dst_offset, u32 num_pages, ShaderConvert shader)
|
|
|
|
|
{
|
|
|
|
|
GL_PUSH("GSTextureCache::CopyPages(): %u pages at %x[eff %x] BW %u to %x[eff %x] BW %u", num_pages,
|
|
|
|
|
GL_PUSH("TC: GSTextureCache::CopyPages(): %u pages at %x[eff %x] BW %u to %x[eff %x] BW %u", num_pages,
|
|
|
|
|
src->m_TEX0.TBP0, src->m_TEX0.TBP0 + src_offset, sbw, dst->m_TEX0.TBP0, dst->m_TEX0.TBP0 + dst_offset, dbw);
|
|
|
|
|
|
|
|
|
|
// Create rectangles for the pages.
|
|
|
|
|
@@ -4948,7 +4948,7 @@ void GSTextureCache::CopyPages(Target* src, u32 sbw, u32 src_offset, Target* dst
|
|
|
|
|
const GSVector4i src_rect = page_rc + GSVector4i(src_offset).xyxy();
|
|
|
|
|
const GSVector4i dst_rect = page_rc + GSVector4i(dst_offset).xyxy();
|
|
|
|
|
|
|
|
|
|
GL_INS("Copy page %u @ <%d,%d=>%d,%d> to %u @ <%d,%d=>%d,%d>", src_page_num, src_rect.x, src_rect.y, src_rect.z,
|
|
|
|
|
GL_INS("TC: Copy page %u @ <%d,%d=>%d,%d> to %u @ <%d,%d=>%d,%d>", src_page_num, src_rect.x, src_rect.y, src_rect.z,
|
|
|
|
|
src_rect.w, dst_page_num, dst_rect.x, dst_rect.y, dst_rect.z, dst_rect.w);
|
|
|
|
|
|
|
|
|
|
GSDevice::MultiStretchRect& rc = rects[i];
|
|
|
|
|
@@ -5049,7 +5049,7 @@ GSVector2i GSTextureCache::GetTargetSize(u32 bp, u32 fbw, u32 psm, s32 min_width
|
|
|
|
|
{
|
|
|
|
|
if (elem.width < min_width || elem.height < min_height)
|
|
|
|
|
{
|
|
|
|
|
DbgCon.WriteLn("Expand size at %x %u %u from %ux%u to %ux%u", bp, fbw, psm, elem.width, elem.height,
|
|
|
|
|
DbgCon.WriteLn("TC: Expand size at %x %u %u from %ux%u to %ux%u", bp, fbw, psm, elem.width, elem.height,
|
|
|
|
|
min_width, min_height);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@@ -5063,7 +5063,7 @@ GSVector2i GSTextureCache::GetTargetSize(u32 bp, u32 fbw, u32 psm, s32 min_width
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
DbgCon.WriteLn("New size at %x %u %u: %ux%u draw %d", bp, fbw, psm, min_width, min_height, GSState::s_n);
|
|
|
|
|
DbgCon.WriteLn("TC: New size at %x %u %u: %ux%u draw %d", bp, fbw, psm, min_width, min_height, GSState::s_n);
|
|
|
|
|
m_target_heights.push_front(search);
|
|
|
|
|
return GSVector2i(min_width, min_height);
|
|
|
|
|
}
|
|
|
|
|
@@ -5139,7 +5139,7 @@ void GSTextureCache::InvalidateVideoMemSubTarget(GSTextureCache::Target* rt)
|
|
|
|
|
|
|
|
|
|
if ((t->m_TEX0.TBP0 > rt->m_TEX0.TBP0) && (t->m_end_block < rt->m_end_block) && (t->m_TEX0.TBW == rt->m_TEX0.TBW) && (t->m_TEX0.TBP0 < t->m_end_block))
|
|
|
|
|
{
|
|
|
|
|
GL_INS("InvalidateVideoMemSubTarget: rt 0x%x -> 0x%x, sub rt 0x%x -> 0x%x",
|
|
|
|
|
GL_INS("TC: InvalidateVideoMemSubTarget: rt 0x%x -> 0x%x, sub rt 0x%x -> 0x%x",
|
|
|
|
|
rt->m_TEX0.TBP0, rt->m_end_block, t->m_TEX0.TBP0, t->m_end_block);
|
|
|
|
|
|
|
|
|
|
// Need to also remove any sources which reference this target.
|
|
|
|
|
@@ -5249,7 +5249,7 @@ void GSTextureCache::IncAge()
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
GL_CACHE("Extending life of target for %x", t->m_TEX0.TBP0);
|
|
|
|
|
GL_CACHE("TC: Extending life of target for %x", t->m_TEX0.TBP0);
|
|
|
|
|
t->m_age = 10;
|
|
|
|
|
++i;
|
|
|
|
|
}
|
|
|
|
|
@@ -5443,14 +5443,14 @@ GSTextureCache::Source* GSTextureCache::CreateSource(const GIFRegTEX0& TEX0, con
|
|
|
|
|
const bool is_8bits = TEX0.PSM == PSMT8 && !channel_shuffle;
|
|
|
|
|
if (is_8bits)
|
|
|
|
|
{
|
|
|
|
|
GL_INS("Reading RT as a packed-indexed 8 bits format");
|
|
|
|
|
GL_INS("TC: Reading RT as a packed-indexed 8 bits format");
|
|
|
|
|
shader = ShaderConvert::RGBA_TO_8I;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#ifdef ENABLE_OGL_DEBUG
|
|
|
|
|
if (TEX0.PSM == PSMT4)
|
|
|
|
|
{
|
|
|
|
|
GL_INS("ERROR: Reading RT as a packed-indexed 4 bits format is not supported");
|
|
|
|
|
GL_INS("TC: ERROR: Reading RT as a packed-indexed 4 bits format is not supported");
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
@@ -5612,7 +5612,7 @@ GSTextureCache::Source* GSTextureCache::CreateSource(const GIFRegTEX0& TEX0, con
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
DevCon.Error("Invalid half-right copy with width %d from %dx%d texture", half_width * 2, dst->m_unscaled_size.x, dst->m_unscaled_size.y);
|
|
|
|
|
DevCon.Error("TC: Invalid half-right copy with width %d from %dx%d texture", half_width * 2, dst->m_unscaled_size.x, dst->m_unscaled_size.y);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@@ -5886,7 +5886,7 @@ GSTextureCache::Source* GSTextureCache::CreateMergedSource(GIFRegTEX0 TEX0, GIFR
|
|
|
|
|
|
|
|
|
|
// Compute new end block based on size.
|
|
|
|
|
const u32 end_block = GSLocalMemory::m_psm[TEX0.PSM].info.bn(tex_width - 1, tex_height - 1, TEX0.TBP0, TEX0.TBW);
|
|
|
|
|
GL_PUSH("Merging targets from %x through %x", TEX0.TBP0, end_block);
|
|
|
|
|
GL_PUSH("TC: Merging targets from %x through %x", TEX0.TBP0, end_block);
|
|
|
|
|
|
|
|
|
|
const GSLocalMemory::psm_t& psm = GSLocalMemory::m_psm[TEX0.PSM];
|
|
|
|
|
const int page_width = psm.pgs.x;
|
|
|
|
|
@@ -5971,7 +5971,7 @@ GSTextureCache::Source* GSTextureCache::CreateMergedSource(GIFRegTEX0 TEX0, GIFR
|
|
|
|
|
if (pages_done[page_num / 8] & (1u << (page_num % 8)))
|
|
|
|
|
goto next_page;
|
|
|
|
|
|
|
|
|
|
GL_INS("Searching for block range %x - %x for (%u,%u)", this_start_block, this_end_block, page_x * page_width,
|
|
|
|
|
GL_INS("TC: Searching for block range %x - %x for (%u,%u)", this_start_block, this_end_block, page_x * page_width,
|
|
|
|
|
page_y * page_height);
|
|
|
|
|
|
|
|
|
|
for (auto i = m_dst[RenderTarget].begin(); i != m_dst[RenderTarget].end(); ++i)
|
|
|
|
|
@@ -5979,7 +5979,7 @@ GSTextureCache::Source* GSTextureCache::CreateMergedSource(GIFRegTEX0 TEX0, GIFR
|
|
|
|
|
Target* const t = *i;
|
|
|
|
|
if (this_start_block >= t->m_TEX0.TBP0 && this_end_block <= t->m_end_block && GSUtil::HasCompatibleBits(t->m_TEX0.PSM, TEX0.PSM))
|
|
|
|
|
{
|
|
|
|
|
GL_INS(" Candidate at BP %x BW %d PSM %d", t->m_TEX0.TBP0, t->m_TEX0.TBW, t->m_TEX0.PSM);
|
|
|
|
|
GL_INS("TC: Candidate at BP %x BW %d PSM %d", t->m_TEX0.TBP0, t->m_TEX0.TBW, t->m_TEX0.PSM);
|
|
|
|
|
|
|
|
|
|
// Can't copy multiple pages when we're past the TBW.. only grab one page at a time then.
|
|
|
|
|
GSVector4i src_rect(page_rect);
|
|
|
|
|
@@ -6075,7 +6075,7 @@ GSTextureCache::Source* GSTextureCache::CreateMergedSource(GIFRegTEX0 TEX0, GIFR
|
|
|
|
|
preload_page(dst_x, dst_y);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
GL_INS(" Copy from %d,%d -> %d,%d (%dx%d)", src_x, src_y, dst_x, dst_y, copy_width, copy_height);
|
|
|
|
|
GL_INS("TC: Copy from %d,%d -> %d,%d (%dx%d)", src_x, src_y, dst_x, dst_y, copy_width, copy_height);
|
|
|
|
|
copy_queue[copy_count++] = {
|
|
|
|
|
(GSVector4(src_x, src_y, src_x + copy_width, src_y + copy_height) *
|
|
|
|
|
GSVector4(t->m_scale).xyxy()) /
|
|
|
|
|
@@ -6106,14 +6106,14 @@ GSTextureCache::Source* GSTextureCache::CreateMergedSource(GIFRegTEX0 TEX0, GIFR
|
|
|
|
|
{
|
|
|
|
|
pages_done[page_num / 8] |= (1u << (page_num % 8));
|
|
|
|
|
|
|
|
|
|
GL_INS(" *** NOT FOUND, preloading from local memory");
|
|
|
|
|
GL_INS("TC: *** NOT FOUND, preloading from local memory");
|
|
|
|
|
const int dst_x = page_x * page_width;
|
|
|
|
|
const int dst_y = page_y * page_height;
|
|
|
|
|
preload_page(dst_x, dst_y);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
GL_INS(" *** NOT FOUND");
|
|
|
|
|
GL_INS("TC: *** NOT FOUND");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@@ -6132,7 +6132,7 @@ GSTextureCache::Source* GSTextureCache::CreateMergedSource(GIFRegTEX0 TEX0, GIFR
|
|
|
|
|
// If we didn't find anything, abort.
|
|
|
|
|
if (copy_count == 0)
|
|
|
|
|
{
|
|
|
|
|
GL_INS("No sources found.");
|
|
|
|
|
GL_INS("TC: No sources found.");
|
|
|
|
|
return nullptr;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@@ -6221,7 +6221,7 @@ GSTextureCache::HashCacheEntry* GSTextureCache::LookupHashCache(const GIFRegTEX0
|
|
|
|
|
if (it != m_hash_cache.end())
|
|
|
|
|
{
|
|
|
|
|
// super easy, cache hit. remove paltex if it's a replacement texture.
|
|
|
|
|
GL_CACHE("HC Hit: %" PRIx64 " %" PRIx64 " R-%ux%u", key.TEX0Hash, key.CLUTHash, key.region_width, key.region_height);
|
|
|
|
|
GL_CACHE("TC: HC Hit: %" PRIx64 " %" PRIx64 " R-%ux%u", key.TEX0Hash, key.CLUTHash, key.region_width, key.region_height);
|
|
|
|
|
HashCacheEntry* entry = &it->second;
|
|
|
|
|
paltex &= (entry->texture->GetFormat() == GSTexture::Format::UNorm8);
|
|
|
|
|
entry->refcount++;
|
|
|
|
|
@@ -6229,7 +6229,7 @@ GSTextureCache::HashCacheEntry* GSTextureCache::LookupHashCache(const GIFRegTEX0
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// cache miss.
|
|
|
|
|
GL_CACHE("HC Miss: %" PRIx64 " %" PRIx64 " R-%ux%u", key.TEX0Hash, key.CLUTHash, key.region_width, key.region_height);
|
|
|
|
|
GL_CACHE("TC: HC Miss: %" PRIx64 " %" PRIx64 " R-%ux%u", key.TEX0Hash, key.CLUTHash, key.region_width, key.region_height);
|
|
|
|
|
|
|
|
|
|
// check for a replacement texture with the full clut key
|
|
|
|
|
if (replace)
|
|
|
|
|
@@ -6431,7 +6431,7 @@ GSTexture* GSTextureCache::LookupPaletteSource(u32 CBP, u32 CPSM, u32 CBW, GSVec
|
|
|
|
|
if (t->m_TEX0.PSM != CPSM || (CBW != 0 && t->m_TEX0.TBW != CBW))
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
GL_INS("Exact match on BP 0x%04x BW %u", t->m_TEX0.TBP0, t->m_TEX0.TBW);
|
|
|
|
|
GL_INS("TC: Exact match on BP 0x%04x BW %u", t->m_TEX0.TBP0, t->m_TEX0.TBW);
|
|
|
|
|
this_offset.x = 0;
|
|
|
|
|
this_offset.y = 0;
|
|
|
|
|
}
|
|
|
|
|
@@ -6444,7 +6444,7 @@ GSTexture* GSTextureCache::LookupPaletteSource(u32 CBP, u32 CPSM, u32 CBW, GSVec
|
|
|
|
|
if (!so.is_valid)
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
GL_INS("Match inside RT at BP 0x%04X-0x%04X BW %u", t->m_TEX0.TBP0, t->m_end_block, t->m_TEX0.TBW);
|
|
|
|
|
GL_INS("TC: Match inside RT at BP 0x%04X-0x%04X BW %u", t->m_TEX0.TBP0, t->m_end_block, t->m_TEX0.TBW);
|
|
|
|
|
this_offset.x = so.b2a_offset.left;
|
|
|
|
|
this_offset.y = so.b2a_offset.top;
|
|
|
|
|
}
|
|
|
|
|
@@ -6458,7 +6458,7 @@ GSTexture* GSTextureCache::LookupPaletteSource(u32 CBP, u32 CPSM, u32 CBW, GSVec
|
|
|
|
|
// Otherwise, we'll be using stale data on the CPU.
|
|
|
|
|
if (!t->m_dirty.empty())
|
|
|
|
|
{
|
|
|
|
|
GL_INS("Candidate is dirty, checking");
|
|
|
|
|
GL_INS("TC: Candidate is dirty, checking");
|
|
|
|
|
|
|
|
|
|
const GSVector4i clut_rc(this_offset.x, this_offset.y, this_offset.x + size.x, this_offset.y + size.y);
|
|
|
|
|
bool is_dirty = false;
|
|
|
|
|
@@ -6466,7 +6466,7 @@ GSTexture* GSTextureCache::LookupPaletteSource(u32 CBP, u32 CPSM, u32 CBW, GSVec
|
|
|
|
|
{
|
|
|
|
|
if (!dirty.GetDirtyRect(t->m_TEX0, false).rintersect(clut_rc).rempty())
|
|
|
|
|
{
|
|
|
|
|
GL_INS("Dirty rectangle overlaps CLUT rectangle, skipping");
|
|
|
|
|
GL_INS("TC: Dirty rectangle overlaps CLUT rectangle, skipping");
|
|
|
|
|
is_dirty = true;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
@@ -7078,7 +7078,7 @@ void GSTextureCache::Target::Update(bool cannot_scale)
|
|
|
|
|
if (m_type == DepthStencil && GSConfig.UserHacks_DisableDepthSupport)
|
|
|
|
|
{
|
|
|
|
|
// do the most likely thing a direct write would do, clear it
|
|
|
|
|
GL_INS("ERROR: Update DepthStencil dummy");
|
|
|
|
|
GL_INS("TC: ERROR: Update DepthStencil dummy");
|
|
|
|
|
m_dirty.clear();
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
@@ -7086,7 +7086,7 @@ void GSTextureCache::Target::Update(bool cannot_scale)
|
|
|
|
|
const GSVector4i total_rect = m_dirty.GetTotalRect(m_TEX0, m_unscaled_size);
|
|
|
|
|
if (total_rect.rempty())
|
|
|
|
|
{
|
|
|
|
|
GL_INS("ERROR: Nothing to update?");
|
|
|
|
|
GL_INS("TC: ERROR: Nothing to update?");
|
|
|
|
|
m_dirty.clear();
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
@@ -7182,13 +7182,13 @@ void GSTextureCache::Target::Update(bool cannot_scale)
|
|
|
|
|
// Copy the new GS memory content into the destination texture.
|
|
|
|
|
if (m_type == RenderTarget)
|
|
|
|
|
{
|
|
|
|
|
GL_INS("ERROR: Update RenderTarget 0x%x bw:%d (%d,%d => %d,%d)", m_TEX0.TBP0, m_TEX0.TBW,
|
|
|
|
|
GL_INS("TC: ERROR: Update RenderTarget 0x%x bw:%d (%d,%d => %d,%d)", m_TEX0.TBP0, m_TEX0.TBW,
|
|
|
|
|
update_r.x, update_r.y, update_r.z, update_r.w);
|
|
|
|
|
drect.wmask = static_cast<u8>(m_dirty[i].rgba._u32);
|
|
|
|
|
}
|
|
|
|
|
else if (m_type == DepthStencil)
|
|
|
|
|
{
|
|
|
|
|
GL_INS("ERROR: Update DepthStencil 0x%x", m_TEX0.TBP0);
|
|
|
|
|
GL_INS("TC: ERROR: Update DepthStencil 0x%x", m_TEX0.TBP0);
|
|
|
|
|
drect.wmask = 0xF;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
@@ -7254,7 +7254,7 @@ void GSTextureCache::Target::Update(bool cannot_scale)
|
|
|
|
|
const GSTextureCache::TempZAddress z_address_info = g_texture_cache->GetTemporaryZInfo();
|
|
|
|
|
if (m_TEX0.TBP0 == z_address_info.ZBP)
|
|
|
|
|
{
|
|
|
|
|
//GL_CACHE("RT in RT Updating Z copy on draw %d z_offset %d", s_n, z_address_info.offset);
|
|
|
|
|
//GL_CACHE("TC: RT in RT Updating Z copy on draw %d z_offset %d", s_n, z_address_info.offset);
|
|
|
|
|
const GSVector4i dRect = GSVector4i(total_rect.x * m_scale, (z_address_info.offset + total_rect.y) * m_scale, (total_rect.z + (1.0f / m_scale)) * m_scale, (z_address_info.offset + total_rect.w + (1.0f / m_scale)) * m_scale);
|
|
|
|
|
g_gs_device->StretchRect(m_texture, GSVector4(total_rect.x / static_cast<float>(m_unscaled_size.x), total_rect.y / static_cast<float>(m_unscaled_size.y), (total_rect.z + (1.0f / m_scale)) / static_cast<float>(m_unscaled_size.x), (total_rect.w + (1.0f / m_scale)) / static_cast<float>(m_unscaled_size.y)), g_texture_cache->GetTemporaryZ(), GSVector4(dRect), ShaderConvert::DEPTH_COPY, false);
|
|
|
|
|
g_perfmon.Put(GSPerfMon::TextureCopies, 1);
|
|
|
|
|
@@ -7359,7 +7359,7 @@ void GSTextureCache::Target::ResizeValidity(const GSVector4i& rect)
|
|
|
|
|
|
|
|
|
|
// Else No valid size, so need to resize down.
|
|
|
|
|
|
|
|
|
|
// GL_CACHE("ResizeValidity (0x%x->0x%x) from R:%d,%d Valid: %d,%d", m_TEX0.TBP0, m_end_block, rect.z, rect.w, m_valid.z, m_valid.w);
|
|
|
|
|
// GL_CACHE("TC: ResizeValidity (0x%x->0x%x) from R:%d,%d Valid: %d,%d", m_TEX0.TBP0, m_end_block, rect.z, rect.w, m_valid.z, m_valid.w);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void GSTextureCache::Target::UpdateValidity(const GSVector4i& rect, bool can_resize)
|
|
|
|
|
@@ -7376,7 +7376,7 @@ void GSTextureCache::Target::UpdateValidity(const GSVector4i& rect, bool can_res
|
|
|
|
|
|
|
|
|
|
m_end_block = GSLocalMemory::GetEndBlockAddress(m_TEX0.TBP0, m_TEX0.TBW, m_TEX0.PSM, m_valid);
|
|
|
|
|
}
|
|
|
|
|
// GL_CACHE("UpdateValidity (0x%x->0x%x) from R:%d,%d Valid: %d,%d", m_TEX0.TBP0, m_end_block, rect.z, rect.w, m_valid.z, m_valid.w);
|
|
|
|
|
// GL_CACHE("TC: UpdateValidity (0x%x->0x%x) from R:%d,%d Valid: %d,%d", m_TEX0.TBP0, m_end_block, rect.z, rect.w, m_valid.z, m_valid.w);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool GSTextureCache::Target::ResizeTexture(int new_unscaled_width, int new_unscaled_height, bool recycle_old, bool require_new_rect, GSVector4i new_rect, bool keep_old)
|
|
|
|
|
@@ -7963,7 +7963,7 @@ std::shared_ptr<GSTextureCache::Palette> GSTextureCache::PaletteMap::LookupPalet
|
|
|
|
|
if (map.size() > MAX_SIZE)
|
|
|
|
|
{
|
|
|
|
|
// If the map is too big, try to clean it by disposing and removing unused palettes, before adding the new one
|
|
|
|
|
GL_INS("WARNING, %u-bit PaletteMap (Size %u): Max size %u exceeded, clearing unused palettes.", pal * sizeof(u32), map.size(), MAX_SIZE);
|
|
|
|
|
GL_INS("TC: WARNING, %u-bit PaletteMap (Size %u): Max size %u exceeded, clearing unused palettes.", pal * sizeof(u32), map.size(), MAX_SIZE);
|
|
|
|
|
|
|
|
|
|
const u32 current_size = map.size();
|
|
|
|
|
|
|
|
|
|
@@ -7987,12 +7987,12 @@ std::shared_ptr<GSTextureCache::Palette> GSTextureCache::PaletteMap::LookupPalet
|
|
|
|
|
|
|
|
|
|
if (cleared_palette_count == 0)
|
|
|
|
|
{
|
|
|
|
|
GL_INS("ERROR, %u-bit PaletteMap (Size %u): Max size %u exceeded, could not clear any palette, negative performance impact.", pal * sizeof(u32), map.size(), MAX_SIZE);
|
|
|
|
|
GL_INS("TC: ERROR, %u-bit PaletteMap (Size %u): Max size %u exceeded, could not clear any palette, negative performance impact.", pal * sizeof(u32), map.size(), MAX_SIZE);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
map.reserve(MAX_SIZE); // Ensure map capacity is not modified by the clearing
|
|
|
|
|
GL_INS("INFO, %u-bit PaletteMap (Size %u): Cleared %u palettes.", pal * sizeof(u32), map.size(), cleared_palette_count);
|
|
|
|
|
GL_INS("TC: INFO, %u-bit PaletteMap (Size %u): Cleared %u palettes.", pal * sizeof(u32), map.size(), cleared_palette_count);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@@ -8000,7 +8000,7 @@ std::shared_ptr<GSTextureCache::Palette> GSTextureCache::PaletteMap::LookupPalet
|
|
|
|
|
|
|
|
|
|
map.emplace(palette->GetPaletteKey(), palette);
|
|
|
|
|
|
|
|
|
|
GL_CACHE("TC, %u-bit PaletteMap (Size %u): Added new palette.", pal * sizeof(u32), map.size());
|
|
|
|
|
GL_CACHE("TC: , %u-bit PaletteMap (Size %u): Added new palette.", pal * sizeof(u32), map.size());
|
|
|
|
|
|
|
|
|
|
return palette;
|
|
|
|
|
}
|
|
|
|
|
|