Skip to content

Commit

Permalink
GS: Compensate for misaligned 24bit partial local->host transfers
Browse files Browse the repository at this point in the history
  • Loading branch information
refractionpcsx2 committed Mar 20, 2023
1 parent fc88d1d commit 3a042d8
Show file tree
Hide file tree
Showing 4 changed files with 28 additions and 15 deletions.
6 changes: 3 additions & 3 deletions pcsx2/GS/GSLocalMemory.h
Expand Up @@ -460,7 +460,7 @@ class GSLocalMemory final : public GSAlignedClass<32>
typedef u32 (GSLocalMemory::*readPixelAddr)(u32 addr) const;
typedef u32 (GSLocalMemory::*readTexelAddr)(u32 addr, const GIFRegTEXA& TEXA) const;
typedef void (*writeImage)(GSLocalMemory& mem, int& tx, int& ty, const u8* src, int len, GIFRegBITBLTBUF& BITBLTBUF, GIFRegTRXPOS& TRXPOS, GIFRegTRXREG& TRXREG);
typedef void (*readImage)(const GSLocalMemory& mem, int& tx, int& ty, u8* dst, int len, GIFRegBITBLTBUF& BITBLTBUF, GIFRegTRXPOS& TRXPOS, GIFRegTRXREG& TRXREG);
typedef void (*readImage)(const GSLocalMemory& mem, int& tx, int& ty, int& offset, u8* dst, int len, GIFRegBITBLTBUF& BITBLTBUF, GIFRegTRXPOS& TRXPOS, GIFRegTRXREG& TRXREG);
typedef void (*readTexture)(GSLocalMemory& mem, const GSOffset& off, const GSVector4i& r, u8* dst, int dstpitch, const GIFRegTEXA& TEXA);
typedef void (*readTextureBlock)(const GSLocalMemory& mem, u32 bp, u8* dst, int dstpitch, const GIFRegTEXA& TEXA);

Expand Down Expand Up @@ -1123,9 +1123,9 @@ class GSLocalMemory final : public GSAlignedClass<32>
return ReadTexel16(PixelAddress16SZ(x, y, TEX0.TBP0, TEX0.TBW), TEXA);
}

__forceinline void ReadImageX(int& tx, int& ty, u8* dst, int len, GIFRegBITBLTBUF& BITBLTBUF, GIFRegTRXPOS& TRXPOS, GIFRegTRXREG& TRXREG) const
__forceinline void ReadImageX(int& tx, int& ty, int& offset, u8* dst, int len, GIFRegBITBLTBUF& BITBLTBUF, GIFRegTRXPOS& TRXPOS, GIFRegTRXREG& TRXREG) const
{
m_readImageX(*this, tx, ty, dst, len, BITBLTBUF, TRXPOS, TRXREG);
m_readImageX(*this, tx, ty, offset, dst, len, BITBLTBUF, TRXPOS, TRXREG);
}

void ReadTexture(const GSOffset& off, const GSVector4i& r, u8* dst, int dstpitch, const GIFRegTEXA& TEXA);
Expand Down
27 changes: 17 additions & 10 deletions pcsx2/GS/GSLocalMemoryMultiISA.cpp
Expand Up @@ -87,7 +87,7 @@ class CURRENT_ISA::GSLocalMemoryFunctions
static void ReadTexture(GSLocalMemory& mem, const GSOffset& off, const GSVector4i& r, u8* dst, int dstpitch, const GIFRegTEXA& TEXA);

public:
static void ReadImageX(const GSLocalMemory& mem, int& tx, int& ty, u8* dst, int len, GIFRegBITBLTBUF& BITBLTBUF, GIFRegTRXPOS& TRXPOS, GIFRegTRXREG& TRXREG);
static void ReadImageX(const GSLocalMemory& mem, int& tx, int& ty, int& offset, u8* dst, int len, GIFRegBITBLTBUF& BITBLTBUF, GIFRegTRXPOS& TRXPOS, GIFRegTRXREG& TRXREG);

static void PopulateFunctions(GSLocalMemory& mem);
};
Expand Down Expand Up @@ -931,7 +931,7 @@ void GSLocalMemoryFunctions::WriteImageX(GSLocalMemory& mem, int& tx, int& ty, c

//

void GSLocalMemoryFunctions::ReadImageX(const GSLocalMemory& mem, int& tx, int& ty, u8* dst, int len, GIFRegBITBLTBUF& BITBLTBUF, GIFRegTRXPOS& TRXPOS, GIFRegTRXREG& TRXREG)
void GSLocalMemoryFunctions::ReadImageX(const GSLocalMemory& mem, int& tx, int& ty, int& offset, u8* dst, int len, GIFRegBITBLTBUF& BITBLTBUF, GIFRegTRXPOS& TRXPOS, GIFRegTRXREG& TRXREG)
{
if (len <= 0)
return;
Expand Down Expand Up @@ -1005,16 +1005,23 @@ void GSLocalMemoryFunctions::ReadImageX(const GSLocalMemory& mem, int& tx, int&

case PSM_PSMCT24:
case PSM_PSMZ24:
readWriteHelper(mem.vm32(), tx, ty, len / 3, 1, sx, w, off.assertSizesMatch(GSLocalMemory::swizzle32), [&](auto& pa, int x)
{
const int length = len / 3;
const int aligned_length = (len + 2) / 3;
if (length != aligned_length)
{
u32 c = *pa.value(x);
pb[0] = (u8)(c);
pb[1] = (u8)(c >> 8);
pb[2] = (u8)(c >> 16);
pb += 3;
});
offset = 3 - (len - (length * 3));
}
readWriteHelper(mem.vm32(), tx, ty, aligned_length, 1, sx, w, off.assertSizesMatch(GSLocalMemory::swizzle32), [&](auto& pa, int x)
{
u32 c = *pa.value(x);
pb[0] = (u8)(c);
pb[1] = (u8)(c >> 8);
pb[2] = (u8)(c >> 16);
pb += 3;
});
break;

}
case PSM_PSMCT16:
case PSM_PSMCT16S:
case PSM_PSMZ16:
Expand Down
9 changes: 7 additions & 2 deletions pcsx2/GS/GSState.cpp
Expand Up @@ -1845,7 +1845,9 @@ void GSState::Read(u8* mem, int len)
if (!m_tr.Update(w, h, bpp, len))
return;

m_mem.ReadImageX(m_tr.x, m_tr.y, mem, len, m_env.BITBLTBUF, m_env.TRXPOS, m_env.TRXREG);
mem += m_tr.offset;
len -= m_tr.offset;
m_mem.ReadImageX(m_tr.x, m_tr.y, m_tr.offset, mem, len, m_env.BITBLTBUF, m_env.TRXPOS, m_env.TRXREG);

if (GSConfig.DumpGSData && GSConfig.SaveRT && s_n >= GSConfig.SaveN)
{
Expand Down Expand Up @@ -2136,7 +2138,9 @@ void GSState::ReadLocalMemoryUnsync(u8* mem, int qwc, GIFRegBITBLTBUF BITBLTBUF,
if (!tb.Update(w, h, bpp, len))
return;

m_mem.ReadImageX(tb.x, tb.y, mem, len, BITBLTBUF, TRXPOS, TRXREG);
mem += tb.offset;
len -= tb.offset;
m_mem.ReadImageX(tb.x, tb.y, tb.offset, mem, len, BITBLTBUF, TRXPOS, TRXREG);
}

void GSState::PurgePool()
Expand Down Expand Up @@ -3900,6 +3904,7 @@ void GSState::GSTransferBuffer::Init(int tx, int ty, const GIFRegBITBLTBUF& blit
x = tx;
y = ty;
total = 0;
offset = 0;
m_blit = blit;
}

Expand Down
1 change: 1 addition & 0 deletions pcsx2/GS/GSState.h
Expand Up @@ -123,6 +123,7 @@ class GSState : public GSAlignedClass<32>
{
int x = 0, y = 0;
int start = 0, end = 0, total = 0;
int offset = 0;
u8* buff = nullptr;
GIFRegBITBLTBUF m_blit = {};

Expand Down

0 comments on commit 3a042d8

Please sign in to comment.