mirror of https://github.com/PCSX2/pcsx2.git
GS: Compensate for misaligned 24bit partial local->host transfers
This commit is contained in:
parent
fc88d1de85
commit
3a042d8c14
|
@ -460,7 +460,7 @@ public:
|
|||
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);
|
||||
|
||||
|
@ -1123,9 +1123,9 @@ public:
|
|||
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);
|
||||
|
|
|
@ -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);
|
||||
};
|
||||
|
@ -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;
|
||||
|
@ -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:
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
@ -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()
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -123,6 +123,7 @@ private:
|
|||
{
|
||||
int x = 0, y = 0;
|
||||
int start = 0, end = 0, total = 0;
|
||||
int offset = 0;
|
||||
u8* buff = nullptr;
|
||||
GIFRegBITBLTBUF m_blit = {};
|
||||
|
||||
|
|
Loading…
Reference in New Issue