mirror of https://github.com/PCSX2/pcsx2.git
GS/HW: Allow finding targets offset behind FBP for tex-in-rt
This commit is contained in:
parent
bb42353c81
commit
5e3e988846
|
@ -953,7 +953,7 @@ GSTextureCache::Source* GSTextureCache::LookupSource(const GIFRegTEX0& TEX0, con
|
||||||
if (can_translate)
|
if (can_translate)
|
||||||
{
|
{
|
||||||
const bool swizzle_match = GSLocalMemory::m_psm[psm].depth == GSLocalMemory::m_psm[t->m_TEX0.PSM].depth;
|
const bool swizzle_match = GSLocalMemory::m_psm[psm].depth == GSLocalMemory::m_psm[t->m_TEX0.PSM].depth;
|
||||||
const GSVector2i page_size = GSLocalMemory::m_psm[t->m_TEX0.PSM].pgs;
|
const GSVector2i& page_size = GSLocalMemory::m_psm[t->m_TEX0.PSM].pgs;
|
||||||
const GSVector4i page_mask(GSVector4i((page_size.x - 1), (page_size.y - 1)).xyxy());
|
const GSVector4i page_mask(GSVector4i((page_size.x - 1), (page_size.y - 1)).xyxy());
|
||||||
GSVector4i rect = r & ~page_mask;
|
GSVector4i rect = r & ~page_mask;
|
||||||
|
|
||||||
|
@ -968,7 +968,7 @@ GSTextureCache::Source* GSTextureCache::LookupSource(const GIFRegTEX0& TEX0, con
|
||||||
// If it's not page aligned, grab the whole pages it covers, to be safe.
|
// If it's not page aligned, grab the whole pages it covers, to be safe.
|
||||||
if (GSLocalMemory::m_psm[psm].bpp != GSLocalMemory::m_psm[t->m_TEX0.PSM].bpp)
|
if (GSLocalMemory::m_psm[psm].bpp != GSLocalMemory::m_psm[t->m_TEX0.PSM].bpp)
|
||||||
{
|
{
|
||||||
const GSVector2i dst_page_size = GSLocalMemory::m_psm[psm].pgs;
|
const GSVector2i& dst_page_size = GSLocalMemory::m_psm[psm].pgs;
|
||||||
rect = GSVector4i(rect.x / page_size.x, rect.y / page_size.y, (rect.z + (page_size.x - 1)) / page_size.x, (rect.w + (page_size.y - 1)) / page_size.y);
|
rect = GSVector4i(rect.x / page_size.x, rect.y / page_size.y, (rect.z + (page_size.x - 1)) / page_size.x, (rect.w + (page_size.y - 1)) / page_size.y);
|
||||||
rect = GSVector4i(rect.x * dst_page_size.x, rect.y * dst_page_size.y, rect.z * dst_page_size.x, rect.w * dst_page_size.y);
|
rect = GSVector4i(rect.x * dst_page_size.x, rect.y * dst_page_size.y, rect.z * dst_page_size.x, rect.w * dst_page_size.y);
|
||||||
}
|
}
|
||||||
|
@ -1031,16 +1031,47 @@ GSTextureCache::Source* GSTextureCache::LookupSource(const GIFRegTEX0& TEX0, con
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (GSConfig.UserHacks_TextureInsideRt >= GSTextureInRtMode::MergeTargets && !tex_merge_rt)
|
else
|
||||||
{
|
{
|
||||||
dst = t;
|
// Some games, such as Tomb Raider: Underworld, and Destroy All Humans shift the texture pointer
|
||||||
x_offset = 0;
|
// back behind the framebuffer, but then offset their texture coordinates to compensate. Why they
|
||||||
y_offset = 0;
|
// do this, I have no idea... but it's usually only a page wide/high of an offset. Thankfully,
|
||||||
tex_merge_rt = true;
|
// they also seem to set region clamp with the offset as well, so we can use that to find the target
|
||||||
|
// that they're expecting to read from. Example from Tomb Raider: TBP0 0xee0 with a TBW of 8, MINU/V
|
||||||
|
// of 64,32, which means 9 pages down, or 0x1000, which lines up with the main framebuffer. Originally
|
||||||
|
// I had a check on the end block too, but since the game's a bit rude, it channel shuffles into new
|
||||||
|
// targets that it never regularly draws to, which means the end block for them won't be correct.
|
||||||
|
// Omitting that check here seemed less risky than blowing CS targets out...
|
||||||
|
const GSVector2i& page_size = GSLocalMemory::m_psm[psm].pgs;
|
||||||
|
const GSOffset offset(GSLocalMemory::m_psm[psm].info, bp, bw, psm);
|
||||||
|
if (bp < t->m_TEX0.TBP0 && region.HasX() && region.HasY() &&
|
||||||
|
(region.GetMinX() & (page_size.x - 1)) == 0 && (region.GetMinY() & (page_size.y - 1)) == 0 &&
|
||||||
|
offset.bn(region.GetMinX(), region.GetMinY()) == t->m_TEX0.TBP0)
|
||||||
|
{
|
||||||
|
GL_CACHE("TC: Target 0x%x detected in front of TBP 0x%x with %d,%d offset (%d pages)",
|
||||||
|
t->m_TEX0.TBP0, TEX0.TBP0, region.GetMinX(), region.GetMinY(),
|
||||||
|
(region.GetMinY() / page_size.y) * TEX0.TBW + (region.GetMinX() / page_size.x));
|
||||||
|
x_offset = -region.GetMinX();
|
||||||
|
y_offset = -region.GetMinY();
|
||||||
|
dst = t;
|
||||||
|
tex_merge_rt = false;
|
||||||
|
found_t = true;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
// Prefer a target inside over a target outside.
|
// Strictly speaking this path is no longer needed, but I'm leaving it here for now because Guitar
|
||||||
found_t = false;
|
// Hero III needs it to merge crowd textures.
|
||||||
continue;
|
else if (GSConfig.UserHacks_TextureInsideRt >= GSTextureInRtMode::MergeTargets && !tex_merge_rt)
|
||||||
|
{
|
||||||
|
dst = t;
|
||||||
|
x_offset = 0;
|
||||||
|
y_offset = 0;
|
||||||
|
tex_merge_rt = true;
|
||||||
|
|
||||||
|
// Prefer a target inside over a target outside.
|
||||||
|
found_t = false;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2909,8 +2940,14 @@ GSTextureCache::Source* GSTextureCache::CreateSource(const GIFRegTEX0& TEX0, con
|
||||||
GL_CACHE("TC: Sample offset (%d,%d) reduced region directly from target: %dx%d -> %dx%d @ %d,%d",
|
GL_CACHE("TC: Sample offset (%d,%d) reduced region directly from target: %dx%d -> %dx%d @ %d,%d",
|
||||||
dst->m_texture->GetWidth(), x_offset, y_offset, dst->m_texture->GetHeight(), w, h, x_offset, y_offset);
|
dst->m_texture->GetWidth(), x_offset, y_offset, dst->m_texture->GetHeight(), w, h, x_offset, y_offset);
|
||||||
|
|
||||||
src->m_region.SetX(x_offset, x_offset + tw);
|
if (x_offset < 0)
|
||||||
src->m_region.SetY(y_offset, y_offset + th);
|
src->m_region.SetX(x_offset, region.GetMaxX() + x_offset);
|
||||||
|
else
|
||||||
|
src->m_region.SetX(x_offset, x_offset + tw);
|
||||||
|
if (y_offset < 0)
|
||||||
|
src->m_region.SetY(y_offset, region.GetMaxY() + y_offset);
|
||||||
|
else
|
||||||
|
src->m_region.SetY(y_offset, y_offset + th);
|
||||||
src->m_texture = dst->m_texture;
|
src->m_texture = dst->m_texture;
|
||||||
src->m_unscaled_size = dst->m_unscaled_size;
|
src->m_unscaled_size = dst->m_unscaled_size;
|
||||||
src->m_shared_texture = true;
|
src->m_shared_texture = true;
|
||||||
|
|
Loading…
Reference in New Issue