mirror of https://github.com/PCSX2/pcsx2.git
GS: Read local memory without sync when readbacks are disabled
This commit is contained in:
parent
4fd06b5ea8
commit
edd735ce80
|
@ -257,6 +257,9 @@ GraphicsSettingsWidget::GraphicsSettingsWidget(SettingsDialog* dialog, QWidget*
|
||||||
connect(m_ui.enableHWFixes, &QCheckBox::stateChanged, this, &GraphicsSettingsWidget::onEnableHardwareFixesChanged);
|
connect(m_ui.enableHWFixes, &QCheckBox::stateChanged, this, &GraphicsSettingsWidget::onEnableHardwareFixesChanged);
|
||||||
updateRendererDependentOptions();
|
updateRendererDependentOptions();
|
||||||
|
|
||||||
|
// only allow disabling readbacks for per-game settings, it's too dangerous
|
||||||
|
m_ui.disableHardwareReadbacks->setEnabled(m_dialog->isPerGameSettings());
|
||||||
|
|
||||||
dialog->registerWidgetHelp(m_ui.enableHWFixes, tr("Manual Hardware Renderer Fixes"), tr("Unchecked"),
|
dialog->registerWidgetHelp(m_ui.enableHWFixes, tr("Manual Hardware Renderer Fixes"), tr("Unchecked"),
|
||||||
tr("Enabling this option gives you the ability to change the renderer and upscaling fixes "
|
tr("Enabling this option gives you the ability to change the renderer and upscaling fixes "
|
||||||
"to your games. However IF you have ENABLED this, you WILL DISABLE AUTOMATIC "
|
"to your games. However IF you have ENABLED this, you WILL DISABLE AUTOMATIC "
|
||||||
|
@ -271,6 +274,10 @@ GraphicsSettingsWidget::GraphicsSettingsWidget(SettingsDialog* dialog, QWidget*
|
||||||
tr("Detects when idle frames are being presented in 25/30fps games, and skips presenting those frames. The frame is still rendered, it just means "
|
tr("Detects when idle frames are being presented in 25/30fps games, and skips presenting those frames. The frame is still rendered, it just means "
|
||||||
"the GPU has more time to complete it (this is NOT frame skipping). Can smooth our frame time fluctuations when the CPU/GPU are near maximum "
|
"the GPU has more time to complete it (this is NOT frame skipping). Can smooth our frame time fluctuations when the CPU/GPU are near maximum "
|
||||||
"utilization, but makes frame pacing more inconsistent and can increase input lag."));
|
"utilization, but makes frame pacing more inconsistent and can increase input lag."));
|
||||||
|
dialog->registerWidgetHelp(m_ui.disableHardwareReadbacks, tr("Disable Hardware Readbacks"), tr("Unchecked"),
|
||||||
|
tr("Skips synchronizing with the GS thread and host GPU for GS downloads. "
|
||||||
|
"Can result in a large speed boost on slower systems, at the cost of many broken graphical effects. "
|
||||||
|
"If games are broken and you have this option enabled, please disable it first."));
|
||||||
}
|
}
|
||||||
|
|
||||||
GraphicsSettingsWidget::~GraphicsSettingsWidget() = default;
|
GraphicsSettingsWidget::~GraphicsSettingsWidget() = default;
|
||||||
|
|
|
@ -423,6 +423,11 @@ void GSInitAndReadFIFO(u8* mem, u32 size)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void GSReadLocalMemoryUnsync(u8* mem, u32 qwc, u64 BITBLITBUF, u64 TRXPOS, u64 TRXREG)
|
||||||
|
{
|
||||||
|
g_gs_renderer->ReadLocalMemoryUnsync(mem, qwc, GIFRegBITBLTBUF{BITBLITBUF}, GIFRegTRXPOS{TRXPOS}, GIFRegTRXREG{TRXREG});
|
||||||
|
}
|
||||||
|
|
||||||
void GSgifTransfer(const u8* mem, u32 size)
|
void GSgifTransfer(const u8* mem, u32 size)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
|
|
|
@ -62,6 +62,7 @@ void GSclose();
|
||||||
void GSgifSoftReset(u32 mask);
|
void GSgifSoftReset(u32 mask);
|
||||||
void GSwriteCSR(u32 csr);
|
void GSwriteCSR(u32 csr);
|
||||||
void GSInitAndReadFIFO(u8* mem, u32 size);
|
void GSInitAndReadFIFO(u8* mem, u32 size);
|
||||||
|
void GSReadLocalMemoryUnsync(u8* mem, u32 qwc, u64 BITBLITBUF, u64 TRXPOS, u64 TRXREG);
|
||||||
void GSgifTransfer(const u8* mem, u32 size);
|
void GSgifTransfer(const u8* mem, u32 size);
|
||||||
void GSgifTransfer1(u8* mem, u32 addr);
|
void GSgifTransfer1(u8* mem, u32 addr);
|
||||||
void GSgifTransfer2(u8* mem, u32 size);
|
void GSgifTransfer2(u8* mem, u32 size);
|
||||||
|
|
|
@ -2091,6 +2091,25 @@ void GSState::ReadFIFO(u8* mem, int size)
|
||||||
m_dump->ReadFIFO(size);
|
m_dump->ReadFIFO(size);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void GSState::ReadLocalMemoryUnsync(u8* mem, int qwc, GIFRegBITBLTBUF BITBLTBUF, GIFRegTRXPOS TRXPOS, GIFRegTRXREG TRXREG)
|
||||||
|
{
|
||||||
|
const int sx = TRXPOS.SSAX;
|
||||||
|
const int sy = TRXPOS.SSAY;
|
||||||
|
const int w = TRXREG.RRW;
|
||||||
|
const int h = TRXREG.RRH;
|
||||||
|
|
||||||
|
const u16 bpp = GSLocalMemory::m_psm[BITBLTBUF.SPSM].trbpp;
|
||||||
|
|
||||||
|
GSTransferBuffer tb;
|
||||||
|
tb.Init(TRXPOS.SSAX, TRXPOS.SSAY, BITBLTBUF);
|
||||||
|
|
||||||
|
int len = qwc * 16;
|
||||||
|
if (!tb.Update(w, h, bpp, len))
|
||||||
|
return;
|
||||||
|
|
||||||
|
m_mem.ReadImageX(tb.x, tb.y, mem, len, BITBLTBUF, TRXPOS, TRXREG);
|
||||||
|
}
|
||||||
|
|
||||||
template void GSState::Transfer<0>(const u8* mem, u32 size);
|
template void GSState::Transfer<0>(const u8* mem, u32 size);
|
||||||
template void GSState::Transfer<1>(const u8* mem, u32 size);
|
template void GSState::Transfer<1>(const u8* mem, u32 size);
|
||||||
template void GSState::Transfer<2>(const u8* mem, u32 size);
|
template void GSState::Transfer<2>(const u8* mem, u32 size);
|
||||||
|
|
|
@ -322,6 +322,7 @@ public:
|
||||||
void SoftReset(u32 mask);
|
void SoftReset(u32 mask);
|
||||||
void WriteCSR(u32 csr) { m_regs->CSR.U32[1] = csr; }
|
void WriteCSR(u32 csr) { m_regs->CSR.U32[1] = csr; }
|
||||||
void ReadFIFO(u8* mem, int size);
|
void ReadFIFO(u8* mem, int size);
|
||||||
|
void ReadLocalMemoryUnsync(u8* mem, int qwc, GIFRegBITBLTBUF BITBLTBUF, GIFRegTRXPOS TRXPOS, GIFRegTRXREG TRXREG);
|
||||||
template<int index> void Transfer(const u8* mem, u32 size);
|
template<int index> void Transfer(const u8* mem, u32 size);
|
||||||
int Freeze(freezeData* fd, bool sizeonly);
|
int Freeze(freezeData* fd, bool sizeonly);
|
||||||
int Defrost(const freezeData* fd);
|
int Defrost(const freezeData* fd);
|
||||||
|
|
|
@ -27,15 +27,11 @@ bool Gif_HandlerAD(u8* pMem)
|
||||||
{
|
{
|
||||||
u32 reg = pMem[8];
|
u32 reg = pMem[8];
|
||||||
u32* data = (u32*)pMem;
|
u32* data = (u32*)pMem;
|
||||||
if (reg == 0x50)
|
if (reg >= GIF_A_D_REG_BITBLTBUF && reg <= GIF_A_D_REG_TRXREG)
|
||||||
{
|
{
|
||||||
vif1.BITBLTBUF._u64 = *(u64*)pMem;
|
vif1.transfer_registers[reg - GIF_A_D_REG_BITBLTBUF] = *(u64*)pMem;
|
||||||
}
|
}
|
||||||
else if (reg == 0x52)
|
else if (reg == GIF_A_D_REG_TRXDIR)
|
||||||
{
|
|
||||||
vif1.TRXREG._u64 = *(u64*)pMem;
|
|
||||||
}
|
|
||||||
else if (reg == 0x53)
|
|
||||||
{ // TRXDIR
|
{ // TRXDIR
|
||||||
if ((pMem[0] & 3) == 1)
|
if ((pMem[0] & 3) == 1)
|
||||||
{ // local -> host
|
{ // local -> host
|
||||||
|
@ -63,7 +59,7 @@ bool Gif_HandlerAD(u8* pMem)
|
||||||
vif1.GSLastDownloadSize = vif1.TRXREG.RRW * vif1.TRXREG.RRH * bpp >> 7;
|
vif1.GSLastDownloadSize = vif1.TRXREG.RRW * vif1.TRXREG.RRH * bpp >> 7;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (reg == 0x60)
|
else if (reg == GIF_A_D_REG_SIGNAL)
|
||||||
{ // SIGNAL
|
{ // SIGNAL
|
||||||
if (CSRreg.SIGNAL)
|
if (CSRreg.SIGNAL)
|
||||||
{ // Time to ignore all subsequent drawing operations.
|
{ // Time to ignore all subsequent drawing operations.
|
||||||
|
@ -85,12 +81,12 @@ bool Gif_HandlerAD(u8* pMem)
|
||||||
CSRreg.SIGNAL = true;
|
CSRreg.SIGNAL = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (reg == 0x61)
|
else if (reg == GIF_A_D_REG_FINISH)
|
||||||
{ // FINISH
|
{ // FINISH
|
||||||
GUNIT_WARN("GIF Handler - FINISH");
|
GUNIT_WARN("GIF Handler - FINISH");
|
||||||
CSRreg.FINISH = true;
|
CSRreg.FINISH = true;
|
||||||
}
|
}
|
||||||
else if (reg == 0x62)
|
else if (reg == GIF_A_D_REG_LABEL)
|
||||||
{ // LABEL
|
{ // LABEL
|
||||||
GUNIT_WARN("GIF Handler - LABEL");
|
GUNIT_WARN("GIF Handler - LABEL");
|
||||||
GSSIGLBLID.LBLID = (GSSIGLBLID.LBLID & ~data[1]) | (data[0] & data[1]);
|
GSSIGLBLID.LBLID = (GSSIGLBLID.LBLID & ~data[1]) | (data[0] & data[1]);
|
||||||
|
@ -108,7 +104,7 @@ bool Gif_HandlerAD_MTVU(u8* pMem)
|
||||||
u32 reg = pMem[8];
|
u32 reg = pMem[8];
|
||||||
u32* data = (u32*)pMem;
|
u32* data = (u32*)pMem;
|
||||||
|
|
||||||
if (reg == 0x60)
|
if (reg == GIF_A_D_REG_SIGNAL)
|
||||||
{ // SIGNAL
|
{ // SIGNAL
|
||||||
GUNIT_WARN("GIF Handler - SIGNAL");
|
GUNIT_WARN("GIF Handler - SIGNAL");
|
||||||
if (vu1Thread.mtvuInterrupts.load(std::memory_order_acquire) & VU_Thread::InterruptFlagSignal)
|
if (vu1Thread.mtvuInterrupts.load(std::memory_order_acquire) & VU_Thread::InterruptFlagSignal)
|
||||||
|
@ -116,14 +112,14 @@ bool Gif_HandlerAD_MTVU(u8* pMem)
|
||||||
vu1Thread.gsSignal.store(((u64)data[1] << 32) | data[0], std::memory_order_relaxed);
|
vu1Thread.gsSignal.store(((u64)data[1] << 32) | data[0], std::memory_order_relaxed);
|
||||||
vu1Thread.mtvuInterrupts.fetch_or(VU_Thread::InterruptFlagSignal, std::memory_order_release);
|
vu1Thread.mtvuInterrupts.fetch_or(VU_Thread::InterruptFlagSignal, std::memory_order_release);
|
||||||
}
|
}
|
||||||
else if (reg == 0x61)
|
else if (reg == GIF_A_D_REG_FINISH)
|
||||||
{ // FINISH
|
{ // FINISH
|
||||||
GUNIT_WARN("GIF Handler - FINISH");
|
GUNIT_WARN("GIF Handler - FINISH");
|
||||||
u32 old = vu1Thread.mtvuInterrupts.fetch_or(VU_Thread::InterruptFlagFinish, std::memory_order_relaxed);
|
u32 old = vu1Thread.mtvuInterrupts.fetch_or(VU_Thread::InterruptFlagFinish, std::memory_order_relaxed);
|
||||||
if (old & VU_Thread::InterruptFlagFinish)
|
if (old & VU_Thread::InterruptFlagFinish)
|
||||||
Console.Error("GIF Handler MTVU - Double FINISH Not Handled");
|
Console.Error("GIF Handler MTVU - Double FINISH Not Handled");
|
||||||
}
|
}
|
||||||
else if (reg == 0x62)
|
else if (reg == GIF_A_D_REG_LABEL)
|
||||||
{ // LABEL
|
{ // LABEL
|
||||||
GUNIT_WARN("GIF Handler - LABEL");
|
GUNIT_WARN("GIF Handler - LABEL");
|
||||||
// It's okay to coalesce label updates
|
// It's okay to coalesce label updates
|
||||||
|
|
|
@ -244,7 +244,10 @@ void SysMtgsThread::PostVsyncStart(bool registers_written)
|
||||||
void SysMtgsThread::InitAndReadFIFO(u8* mem, u32 qwc)
|
void SysMtgsThread::InitAndReadFIFO(u8* mem, u32 qwc)
|
||||||
{
|
{
|
||||||
if (GSConfig.HWDisableReadbacks && GSConfig.UseHardwareRenderer())
|
if (GSConfig.HWDisableReadbacks && GSConfig.UseHardwareRenderer())
|
||||||
|
{
|
||||||
|
GSReadLocalMemoryUnsync(mem, qwc, vif1.BITBLTBUF._u64, vif1.TRXPOS._u64, vif1.TRXREG._u64);
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
SendPointerPacket(GS_RINGTYPE_INIT_AND_READ_FIFO, qwc, mem);
|
SendPointerPacket(GS_RINGTYPE_INIT_AND_READ_FIFO, qwc, mem);
|
||||||
WaitGS(false, false, false);
|
WaitGS(false, false, false);
|
||||||
|
|
|
@ -44,9 +44,27 @@ union tBITBLTBUF {
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
union tTRXREG {
|
union tTRXPOS {
|
||||||
u64 _u64;
|
u64 _u64;
|
||||||
struct {
|
struct {
|
||||||
|
u32 SSAX : 11;
|
||||||
|
u32 _PAD1 : 5;
|
||||||
|
u32 SSAY : 11;
|
||||||
|
u32 _PAD2 : 5;
|
||||||
|
u32 DSAX : 11;
|
||||||
|
u32 _PAD3 : 5;
|
||||||
|
u32 DSAY : 11;
|
||||||
|
u32 DIRY : 1;
|
||||||
|
u32 DIRX : 1;
|
||||||
|
u32 _PAD4 : 3;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
union tTRXREG
|
||||||
|
{
|
||||||
|
u64 _u64;
|
||||||
|
struct
|
||||||
|
{
|
||||||
u32 RRW : 12;
|
u32 RRW : 12;
|
||||||
u32 _pad12 : 20;
|
u32 _pad12 : 20;
|
||||||
u32 RRH : 12;
|
u32 RRH : 12;
|
||||||
|
@ -83,8 +101,17 @@ struct vifStruct {
|
||||||
int unpackcalls;
|
int unpackcalls;
|
||||||
// GS registers used for calculating the size of the last local->host transfer initiated on the GS
|
// GS registers used for calculating the size of the last local->host transfer initiated on the GS
|
||||||
// Transfer size calculation should be restricted to GS emulation in the future
|
// Transfer size calculation should be restricted to GS emulation in the future
|
||||||
tBITBLTBUF BITBLTBUF;
|
union
|
||||||
tTRXREG TRXREG;
|
{
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
tBITBLTBUF BITBLTBUF;
|
||||||
|
tTRXPOS TRXPOS;
|
||||||
|
tTRXREG TRXREG;
|
||||||
|
};
|
||||||
|
u64 transfer_registers[3];
|
||||||
|
};
|
||||||
|
|
||||||
u32 GSLastDownloadSize;
|
u32 GSLastDownloadSize;
|
||||||
|
|
||||||
tVIF_CTRL irqoffset; // 32bit offset where next vif code is
|
tVIF_CTRL irqoffset; // 32bit offset where next vif code is
|
||||||
|
|
Loading…
Reference in New Issue