mirror of https://github.com/PCSX2/pcsx2.git
GS: Retool downloads to buffer full read
This commit is contained in:
parent
f2229a0007
commit
d4c3501bb8
|
@ -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, int& offset, u8* dst, 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 (*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);
|
||||
|
||||
|
@ -1124,9 +1124,9 @@ public:
|
|||
return ReadTexel16(PixelAddress16SZ(x, y, TEX0.TBP0, TEX0.TBW), TEXA);
|
||||
}
|
||||
|
||||
__forceinline void ReadImageX(int& tx, int& ty, int& offset, u8* dst, int len, GIFRegBITBLTBUF& BITBLTBUF, GIFRegTRXPOS& TRXPOS, GIFRegTRXREG& TRXREG) const
|
||||
__forceinline void ReadImageX(int& tx, int& ty, u8* dst, int len, GIFRegBITBLTBUF& BITBLTBUF, GIFRegTRXPOS& TRXPOS, GIFRegTRXREG& TRXREG) const
|
||||
{
|
||||
m_readImageX(*this, tx, ty, offset, dst, len, BITBLTBUF, TRXPOS, TRXREG);
|
||||
m_readImageX(*this, tx, ty, 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, int& offset, u8* dst, int len, GIFRegBITBLTBUF& BITBLTBUF, GIFRegTRXPOS& TRXPOS, GIFRegTRXREG& TRXREG);
|
||||
static void ReadImageX(const GSLocalMemory& mem, int& tx, int& ty, 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, int& offset, u8* dst, int len, GIFRegBITBLTBUF& BITBLTBUF, GIFRegTRXPOS& TRXPOS, GIFRegTRXREG& TRXREG)
|
||||
void GSLocalMemoryFunctions::ReadImageX(const GSLocalMemory& mem, int& tx, int& ty, u8* dst, int len, GIFRegBITBLTBUF& BITBLTBUF, GIFRegTRXPOS& TRXPOS, GIFRegTRXREG& TRXREG)
|
||||
{
|
||||
if (len <= 0)
|
||||
return;
|
||||
|
@ -1005,22 +1005,15 @@ void GSLocalMemoryFunctions::ReadImageX(const GSLocalMemory& mem, int& tx, int&
|
|||
|
||||
case PSMCT24:
|
||||
case PSMZ24:
|
||||
{
|
||||
const int length = len / 3;
|
||||
if ((length * 3) != len)
|
||||
readWriteHelper(mem.vm32(), tx, ty, len / 3, 1, sx, w, off.assertSizesMatch(GSLocalMemory::swizzle32), [&](auto& pa, int x)
|
||||
{
|
||||
offset = (len - (length * 3));
|
||||
}
|
||||
readWriteHelper(mem.vm32(), tx, ty, 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;
|
||||
});
|
||||
u32 c = *pa.value(x);
|
||||
pb[0] = (u8)(c);
|
||||
pb[1] = (u8)(c >> 8);
|
||||
pb[2] = (u8)(c >> 16);
|
||||
pb += 3;
|
||||
});
|
||||
break;
|
||||
}
|
||||
case PSMCT16:
|
||||
case PSMCT16S:
|
||||
case PSMZ16:
|
||||
|
|
|
@ -106,6 +106,7 @@ GSState::GSState()
|
|||
memset(&m_vertex, 0, sizeof(m_vertex));
|
||||
memset(&m_index, 0, sizeof(m_index));
|
||||
memset(m_mem.m_vm8, 0, m_mem.m_vmsize);
|
||||
|
||||
m_v.RGBAQ.Q = 1.0f;
|
||||
|
||||
GrowVertexBuffer();
|
||||
|
@ -1403,10 +1404,10 @@ void GSState::GIFRegHandlerTRXDIR(const GIFReg* RESTRICT r)
|
|||
switch (m_env.TRXDIR.XDIR)
|
||||
{
|
||||
case 0: // host -> local
|
||||
m_tr.Init(m_env.TRXPOS.DSAX, m_env.TRXPOS.DSAY, m_env.BITBLTBUF);
|
||||
m_tr.Init(m_env.TRXPOS.DSAX, m_env.TRXPOS.DSAY, m_env.BITBLTBUF, true);
|
||||
break;
|
||||
case 1: // local -> host
|
||||
m_tr.Init(m_env.TRXPOS.SSAX, m_env.TRXPOS.SSAY, m_env.BITBLTBUF);
|
||||
m_tr.Init(m_env.TRXPOS.SSAX, m_env.TRXPOS.SSAY, m_env.BITBLTBUF, false);
|
||||
break;
|
||||
case 2: // local -> local
|
||||
Move();
|
||||
|
@ -1463,6 +1464,9 @@ void GSState::Flush(GSFlushReason reason)
|
|||
|
||||
void GSState::FlushWrite()
|
||||
{
|
||||
if (!m_tr.write)
|
||||
return;
|
||||
|
||||
const int len = m_tr.end - m_tr.start;
|
||||
|
||||
if (len <= 0)
|
||||
|
@ -1769,11 +1773,10 @@ void GSState::Write(const u8* mem, int len)
|
|||
|
||||
void GSState::InitReadFIFO(u8* mem, int len)
|
||||
{
|
||||
if (len <= 0)
|
||||
// No size or already a transfer in progress.
|
||||
if (len <= 0 || m_tr.total != 0)
|
||||
return;
|
||||
|
||||
const int sx = m_env.TRXPOS.SSAX;
|
||||
const int sy = m_env.TRXPOS.SSAY;
|
||||
const int w = m_env.TRXREG.RRW;
|
||||
const int h = m_env.TRXREG.RRH;
|
||||
|
||||
|
@ -1782,36 +1785,15 @@ void GSState::InitReadFIFO(u8* mem, int len)
|
|||
if (!m_tr.Update(w, h, bpp, len))
|
||||
return;
|
||||
|
||||
if (m_tr.x == sx && m_tr.y == sy)
|
||||
InvalidateLocalMem(m_env.BITBLTBUF, GSVector4i(sx, sy, sx + w, sy + h));
|
||||
}
|
||||
|
||||
// NOTE: called from outside MTGS
|
||||
void GSState::Read(u8* mem, int len)
|
||||
{
|
||||
if (len <= 0)
|
||||
return;
|
||||
|
||||
const int sx = m_env.TRXPOS.SSAX;
|
||||
const int sy = m_env.TRXPOS.SSAY;
|
||||
const int w = m_env.TRXREG.RRW;
|
||||
const int h = m_env.TRXREG.RRH;
|
||||
|
||||
const GSVector4i r(sx, sy, sx + w, sy + h);
|
||||
|
||||
const u16 bpp = GSLocalMemory::m_psm[m_env.BITBLTBUF.SPSM].trbpp;
|
||||
if (m_tr.x == sx && m_tr.y == sy)
|
||||
InvalidateLocalMem(m_env.BITBLTBUF, r);
|
||||
|
||||
if (!m_tr.Update(w, h, bpp, len))
|
||||
return;
|
||||
|
||||
// If it's 1 QW the destination is likely a register, so don't mess with this, else it can cause stack corruption.
|
||||
// TODO: Change the FIFO downloads to just read off the whole transfer from memory to a temp buffer so we can read it in byte level chunks.
|
||||
if (len > 16)
|
||||
{
|
||||
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);
|
||||
// Read the image all in one go.
|
||||
m_mem.ReadImageX(m_tr.x, m_tr.y, m_tr.buff, m_tr.total, m_env.BITBLTBUF, m_env.TRXPOS, m_env.TRXREG);
|
||||
|
||||
if (GSConfig.DumpGSData && GSConfig.SaveRT && s_n >= GSConfig.SaveN)
|
||||
{
|
||||
|
@ -1824,6 +1806,36 @@ void GSState::Read(u8* mem, int len)
|
|||
}
|
||||
}
|
||||
|
||||
// NOTE: called from outside MTGS
|
||||
void GSState::Read(u8* mem, int len)
|
||||
{
|
||||
if (len <= 0 || m_tr.total == 0)
|
||||
return;
|
||||
|
||||
const int w = m_env.TRXREG.RRW;
|
||||
const int h = m_env.TRXREG.RRH;
|
||||
const u16 bpp = GSLocalMemory::m_psm[m_env.BITBLTBUF.SPSM].trbpp;
|
||||
|
||||
if (!m_tr.Update(w, h, bpp, len))
|
||||
return;
|
||||
|
||||
// If it wraps memory, we need to break it up so we don't read out of bounds.
|
||||
if ((m_tr.end + len) > m_mem.m_vmsize)
|
||||
{
|
||||
const int first_transfer = m_mem.m_vmsize - m_tr.end;
|
||||
const int second_transfer = len - first_transfer;
|
||||
memcpy(mem, &m_tr.buff[m_tr.end], first_transfer);
|
||||
m_tr.end = 0;
|
||||
memcpy(&mem[first_transfer], &m_tr.buff, second_transfer);
|
||||
m_tr.end = second_transfer;
|
||||
}
|
||||
else
|
||||
{
|
||||
memcpy(mem, &m_tr.buff[m_tr.end], len);
|
||||
m_tr.end += len;
|
||||
}
|
||||
}
|
||||
|
||||
void GSState::Move()
|
||||
{
|
||||
// ffxii uses this to move the top/bottom of the scrolling menus offscreen and then blends them back over the text to create a shading effect
|
||||
|
@ -2096,15 +2108,34 @@ void GSState::ReadLocalMemoryUnsync(u8* mem, int qwc, GIFRegBITBLTBUF BITBLTBUF,
|
|||
const u16 bpp = GSLocalMemory::m_psm[BITBLTBUF.SPSM].trbpp;
|
||||
|
||||
GSTransferBuffer tb;
|
||||
tb.Init(TRXPOS.SSAX, TRXPOS.SSAY, BITBLTBUF);
|
||||
|
||||
if(m_tr.end >= m_tr.total || m_tr.write == true)
|
||||
tb.Init(TRXPOS.SSAX, TRXPOS.SSAY, BITBLTBUF, false);
|
||||
|
||||
int len = qwc * 16;
|
||||
if (!tb.Update(w, h, bpp, len))
|
||||
return;
|
||||
|
||||
mem += tb.offset;
|
||||
len -= tb.offset;
|
||||
m_mem.ReadImageX(tb.x, tb.y, tb.offset, mem, len, BITBLTBUF, TRXPOS, TRXREG);
|
||||
if (m_tr.start == 0)
|
||||
{
|
||||
m_mem.ReadImageX(tb.x, tb.y, m_tr.buff, m_tr.total, BITBLTBUF, TRXPOS, TRXREG);
|
||||
m_tr.start += m_tr.total;
|
||||
}
|
||||
|
||||
if ((m_tr.end + len) > m_mem.m_vmsize)
|
||||
{
|
||||
const int masked_end = m_tr.end & 0x3FFFFF; // 4mb.
|
||||
const int first_transfer = m_mem.m_vmsize - masked_end;
|
||||
const int second_transfer = len - first_transfer;
|
||||
memcpy(mem, &m_tr.buff[masked_end], first_transfer);
|
||||
memcpy(&mem[first_transfer], &m_tr.buff, second_transfer);
|
||||
m_tr.end += len;
|
||||
}
|
||||
else
|
||||
{
|
||||
memcpy(mem, &m_tr.buff[m_tr.end], len);
|
||||
m_tr.end += len;
|
||||
}
|
||||
}
|
||||
|
||||
void GSState::PurgePool()
|
||||
|
@ -3862,13 +3893,13 @@ GSState::GSTransferBuffer::~GSTransferBuffer()
|
|||
_aligned_free(buff);
|
||||
}
|
||||
|
||||
void GSState::GSTransferBuffer::Init(int tx, int ty, const GIFRegBITBLTBUF& blit)
|
||||
void GSState::GSTransferBuffer::Init(int tx, int ty, const GIFRegBITBLTBUF& blit, bool is_write)
|
||||
{
|
||||
x = tx;
|
||||
y = ty;
|
||||
total = 0;
|
||||
offset = 0;
|
||||
m_blit = blit;
|
||||
write = is_write;
|
||||
}
|
||||
|
||||
bool GSState::GSTransferBuffer::Update(int tw, int th, int bpp, int& len)
|
||||
|
|
|
@ -123,14 +123,14 @@ private:
|
|||
{
|
||||
int x = 0, y = 0;
|
||||
int start = 0, end = 0, total = 0;
|
||||
int offset = 0;
|
||||
u8* buff = nullptr;
|
||||
GIFRegBITBLTBUF m_blit = {};
|
||||
bool write = false;
|
||||
|
||||
GSTransferBuffer();
|
||||
virtual ~GSTransferBuffer();
|
||||
|
||||
void Init(int tx, int ty, const GIFRegBITBLTBUF& blit);
|
||||
void Init(int tx, int ty, const GIFRegBITBLTBUF& blit, bool write);
|
||||
bool Update(int tw, int th, int bpp, int& len);
|
||||
|
||||
} m_tr;
|
||||
|
|
Loading…
Reference in New Issue