GS/HW: Make regions signed, and use compatible bits for tex-in-rt

This commit is contained in:
Stenzek 2023-05-04 00:09:03 +10:00 committed by refractionpcsx2
parent 61740fc9ed
commit bb42353c81
3 changed files with 25 additions and 21 deletions

View File

@ -33,4 +33,8 @@
<DisplayString Condition="m_type == 0">{{ RT @ BP={m_TEX0.TBP0,X}-{m_end_block,X} BW={m_TEX0.TBW} PSM={m_TEX0.PSM,X} {m_unscaled_size.x}x{m_unscaled_size.y} {m_valid.z},{m_valid.w} }}</DisplayString>
<DisplayString Condition="m_type == 1">{{ Depth @ BP={m_TEX0.TBP0,X}-{m_end_block,X} BW={m_TEX0.TBW} PSM={m_TEX0.PSM,X} {m_unscaled_size.x}x{m_unscaled_size.y} {m_valid.z},{m_valid.w} }}</DisplayString>
</Type>
<Type Name="GSTextureCache::SourceRegion">
<DisplayString>{{ Min=({(s16)(bits &amp; 0xFFFF)},{(s16)((bits >> 32) &amp; 0xFFFF)}} Max={(s16)((bits >> 16) &amp; 0xFFFF)},{(s16)((bits >> 48) &amp; 0xFFFF)}) }}</DisplayString>
</Type>
</AutoVisualizer>

View File

@ -937,8 +937,8 @@ GSTextureCache::Source* GSTextureCache::LookupSource(const GIFRegTEX0& TEX0, con
// Make sure the texture actually is INSIDE the RT, it's possibly not valid if it isn't.
// Also check BP >= TBP, create source isn't equpped to expand it backwards and all data comes from the target. (GH3)
else if (GSConfig.UserHacks_TextureInsideRt >= GSTextureInRtMode::InsideTargets && psm >= PSMCT32 &&
psm <= PSMCT16S && t->m_TEX0.PSM == psm && (t->Overlaps(bp, bw, psm, r) || t->Wraps()) &&
t->m_age <= 1 && !found_t)
psm <= PSMCT16S && GSUtil::HasCompatibleBits(t->m_TEX0.PSM, psm) && (t->Overlaps(bp, bw, psm, r) || t->Wraps()) &&
t->m_age <= 1 && (!found_t || dst->m_TEX0.TBW < bw))
{
// PSM equality needed because CreateSource does not handle PSM conversion.
// Only inclusive hit to limit false hits.
@ -3311,7 +3311,7 @@ GSTextureCache::Source* GSTextureCache::CreateMergedSource(GIFRegTEX0 TEX0, GIFR
for (auto i = m_dst[RenderTarget].begin(); i != m_dst[RenderTarget].end(); ++i)
{
Target* const t = *i;
if (this_start_block >= t->m_TEX0.TBP0 && this_end_block <= t->m_end_block && t->m_TEX0.PSM == TEX0.PSM)
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);
@ -4221,8 +4221,8 @@ void GSTextureCache::Source::Flush(u32 count, int layer, const GSOffset& off)
const SourceRegion region((layer == 0) ? m_region : m_region.AdjustForMipmap(layer));
// For the invalid tex0 case, the region might be larger than TEX0.TW/TH.
const int tw = std::max(region.GetWidth(), 1u << m_TEX0.TW);
const int th = std::max(region.GetHeight(), 1u << m_TEX0.TH);
const int tw = std::max(region.GetWidth(), 1 << m_TEX0.TW);
const int th = std::max(region.GetHeight(), 1 << m_TEX0.TH);
const GSVector4i tex_r(region.GetRect(tw, th));
int pitch = std::max(tw, psm.bs.x) * sizeof(u32);
@ -5120,12 +5120,12 @@ bool GSTextureCache::SourceRegion::IsFixedTEX0(int tw, int th) const
bool GSTextureCache::SourceRegion::IsFixedTEX0W(int tw) const
{
return (GetMaxX() > static_cast<u32>(tw));
return (GetMaxX() > tw);
}
bool GSTextureCache::SourceRegion::IsFixedTEX0H(int th) const
{
return (GetMaxY() > static_cast<u32>(th));
return (GetMaxY() > th);
}
GSVector2i GSTextureCache::SourceRegion::GetSize(int tw, int th) const
@ -5140,8 +5140,8 @@ GSVector4i GSTextureCache::SourceRegion::GetRect(int tw, int th) const
GSVector4i GSTextureCache::SourceRegion::GetOffset(int tw, int th) const
{
const int xoffs = (GetMaxX() > static_cast<u32>(tw)) ? static_cast<int>(GetMinX()) : 0;
const int yoffs = (GetMaxY() > static_cast<u32>(th)) ? static_cast<int>(GetMinY()) : 0;
const int xoffs = (GetMaxX() > tw) ? GetMinX() : 0;
const int yoffs = (GetMaxY() > th) ? GetMinY() : 0;
return GSVector4i(xoffs, yoffs, xoffs, yoffs);
}
@ -5151,14 +5151,14 @@ GSTextureCache::SourceRegion GSTextureCache::SourceRegion::AdjustForMipmap(u32 l
SourceRegion ret = {};
if (HasX())
{
const u32 new_minx = GetMinX() >> level;
const u32 new_maxx = new_minx + std::max(GetWidth() >> level, 1u);
const s32 new_minx = GetMinX() >> level;
const s32 new_maxx = new_minx + std::max(GetWidth() >> level, 1);
ret.SetX(new_minx, new_maxx);
}
if (HasY())
{
const u32 new_miny = GetMinY() >> level;
const u32 new_maxy = new_miny + std::max(GetHeight() >> level, 1u);
const s32 new_miny = GetMinY() >> level;
const s32 new_maxy = new_miny + std::max(GetHeight() >> level, 1);
ret.SetY(new_miny, new_maxy);
}
return ret;

View File

@ -52,16 +52,16 @@ public:
bool HasY() const { return static_cast<u32>(bits >> 32) != 0; }
bool HasEither() const { return (bits != 0); }
void SetX(u32 min, u32 max) { bits |= (min | (max << 16)); }
void SetY(u32 min, u32 max) { bits |= ((static_cast<u64>(min) << 32) | (static_cast<u64>(max) << 48)); }
void SetX(s32 min, s32 max) { bits |= (static_cast<u64>(static_cast<u16>(min)) | (static_cast<u64>(static_cast<u16>(max) << 16))); }
void SetY(s32 min, s32 max) { bits |= ((static_cast<u64>(static_cast<u16>(min)) << 32) | (static_cast<u64>(static_cast<u16>(max)) << 48)); }
u32 GetMinX() const { return static_cast<u32>(bits) & 0xFFFFu; }
u32 GetMaxX() const { return static_cast<u32>(bits >> 16) & 0xFFFFu; }
u32 GetMinY() const { return static_cast<u32>(bits >> 32) & 0xFFFFu; }
u32 GetMaxY() const { return static_cast<u32>(bits >> 48); }
s32 GetMinX() const { return static_cast<s16>(bits); }
s32 GetMaxX() const { return static_cast<s16>((bits >> 16) & 0xFFFFu); }
s32 GetMinY() const { return static_cast<s16>((bits >> 32) & 0xFFFFu); }
s32 GetMaxY() const { return static_cast<s16>(bits >> 48); }
u32 GetWidth() const { return (GetMaxX() - GetMinX()); }
u32 GetHeight() const { return (GetMaxY() - GetMinY()); }
s32 GetWidth() const { return (GetMaxX() - GetMinX()); }
s32 GetHeight() const { return (GetMaxY() - GetMinY()); }
/// Returns true if the area of the region exceeds the TW/TH size (i.e. "fixed tex0").
bool IsFixedTEX0(GIFRegTEX0 TEX0) const;