mirror of https://github.com/PCSX2/pcsx2.git
MTVU/GIF: Clang Formatting
This commit is contained in:
parent
20695d6b15
commit
6066f48d7c
|
@ -24,23 +24,37 @@
|
||||||
Gif_Unit gifUnit;
|
Gif_Unit gifUnit;
|
||||||
|
|
||||||
// Returns true on stalling SIGNAL
|
// Returns true on stalling SIGNAL
|
||||||
bool Gif_HandlerAD(u8* pMem) {
|
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 == 0x50)
|
||||||
|
{
|
||||||
vif1.BITBLTBUF._u64 = *(u64*)pMem;
|
vif1.BITBLTBUF._u64 = *(u64*)pMem;
|
||||||
}
|
}
|
||||||
else if (reg == 0x52) {
|
else if (reg == 0x52)
|
||||||
|
{
|
||||||
vif1.TRXREG._u64 = *(u64*)pMem;
|
vif1.TRXREG._u64 = *(u64*)pMem;
|
||||||
}
|
}
|
||||||
else if (reg == 0x53) { // TRXDIR
|
else if (reg == 0x53)
|
||||||
if ((pMem[0] & 3) == 1) { // local -> host
|
{ // TRXDIR
|
||||||
|
if ((pMem[0] & 3) == 1)
|
||||||
|
{ // local -> host
|
||||||
u8 bpp = 32; // Onimusha does TRXDIR without BLTDIVIDE first, assume 32bit
|
u8 bpp = 32; // Onimusha does TRXDIR without BLTDIVIDE first, assume 32bit
|
||||||
switch(vif1.BITBLTBUF.SPSM & 7) {
|
switch (vif1.BITBLTBUF.SPSM & 7)
|
||||||
case 0: bpp = 32; break;
|
{
|
||||||
case 1: bpp = 24; break;
|
case 0:
|
||||||
case 2: bpp = 16; break;
|
bpp = 32;
|
||||||
case 3: bpp = 8; break;
|
break;
|
||||||
|
case 1:
|
||||||
|
bpp = 24;
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
bpp = 16;
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
bpp = 8;
|
||||||
|
break;
|
||||||
default: // 4 is 4 bit but this is forbidden
|
default: // 4 is 4 bit but this is forbidden
|
||||||
Console.Error("Illegal format for GS upload: SPSM=0%02o", vif1.BITBLTBUF.SPSM);
|
Console.Error("Illegal format for GS upload: SPSM=0%02o", vif1.BITBLTBUF.SPSM);
|
||||||
break;
|
break;
|
||||||
|
@ -50,147 +64,213 @@ 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) { // SIGNAL
|
else if (reg == 0x60)
|
||||||
if (CSRreg.SIGNAL) { // Time to ignore all subsequent drawing operations.
|
{ // SIGNAL
|
||||||
|
if (CSRreg.SIGNAL)
|
||||||
|
{ // Time to ignore all subsequent drawing operations.
|
||||||
GUNIT_WARN(Color_Orange, "GIF Handler - Stalling SIGNAL");
|
GUNIT_WARN(Color_Orange, "GIF Handler - Stalling SIGNAL");
|
||||||
if(!gifUnit.gsSIGNAL.queued) {
|
if (!gifUnit.gsSIGNAL.queued)
|
||||||
gifUnit.gsSIGNAL.queued = true;
|
{
|
||||||
|
gifUnit.gsSIGNAL.queued = true;
|
||||||
gifUnit.gsSIGNAL.data[0] = data[0];
|
gifUnit.gsSIGNAL.data[0] = data[0];
|
||||||
gifUnit.gsSIGNAL.data[1] = data[1];
|
gifUnit.gsSIGNAL.data[1] = data[1];
|
||||||
return true; // Stalling SIGNAL
|
return true; // Stalling SIGNAL
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else
|
||||||
|
{
|
||||||
GUNIT_WARN("GIF Handler - SIGNAL");
|
GUNIT_WARN("GIF Handler - SIGNAL");
|
||||||
GSSIGLBLID.SIGID = (GSSIGLBLID.SIGID&~data[1])|(data[0]&data[1]);
|
GSSIGLBLID.SIGID = (GSSIGLBLID.SIGID & ~data[1]) | (data[0] & data[1]);
|
||||||
if (!GSIMR.SIGMSK) gsIrq();
|
if (!GSIMR.SIGMSK)
|
||||||
|
gsIrq();
|
||||||
CSRreg.SIGNAL = true;
|
CSRreg.SIGNAL = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (reg == 0x61) { // FINISH
|
else if (reg == 0x61)
|
||||||
|
{ // FINISH
|
||||||
GUNIT_WARN("GIF Handler - FINISH");
|
GUNIT_WARN("GIF Handler - FINISH");
|
||||||
CSRreg.FINISH = true;
|
CSRreg.FINISH = true;
|
||||||
}
|
}
|
||||||
else if (reg == 0x62) { // LABEL
|
else if (reg == 0x62)
|
||||||
|
{ // 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]);
|
||||||
}
|
}
|
||||||
else if (reg >= 0x63 && reg != 0x7f) {
|
else if (reg >= 0x63 && reg != 0x7f)
|
||||||
|
{
|
||||||
//DevCon.Warning("GIF Handler - Write to unknown register! [reg=%x]", reg);
|
//DevCon.Warning("GIF Handler - Write to unknown register! [reg=%x]", reg);
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Gif_HandlerAD_MTVU(u8* pMem) {
|
bool Gif_HandlerAD_MTVU(u8* pMem)
|
||||||
u32 reg = pMem[8];
|
{
|
||||||
|
u32 reg = pMem[8];
|
||||||
u32* data = (u32*)pMem;
|
u32* data = (u32*)pMem;
|
||||||
vu1Thread.gsInterrupts &= ~vu1Thread.gsToClear;
|
vu1Thread.gsInterrupts &= ~vu1Thread.gsToClear;
|
||||||
vu1Thread.gsToClear = 0;
|
vu1Thread.gsToClear = 0;
|
||||||
if (reg == 0x50) { Console.Error("GIF Handler Debug - BITBLTBUF"); return 1; }
|
if (reg == 0x50)
|
||||||
else if (reg == 0x52) { Console.Error("GIF Handler Debug - TRXREG"); return 1; }
|
{
|
||||||
else if (reg == 0x53) { Console.Error("GIF Handler Debug - TRXDIR"); return 1; }
|
Console.Error("GIF Handler Debug - BITBLTBUF");
|
||||||
else if (reg == 0x60) { // SIGNAL
|
return 1;
|
||||||
if (CSRreg.SIGNAL) { // Time to ignore all subsequent drawing operations.
|
}
|
||||||
Console.Error("GIF Handler MTVU - Double SIGNAL Not Handled"); return 1;
|
else if (reg == 0x52)
|
||||||
|
{
|
||||||
|
Console.Error("GIF Handler Debug - TRXREG");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
else if (reg == 0x53)
|
||||||
|
{
|
||||||
|
Console.Error("GIF Handler Debug - TRXDIR");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
else if (reg == 0x60)
|
||||||
|
{ // SIGNAL
|
||||||
|
if (CSRreg.SIGNAL)
|
||||||
|
{ // Time to ignore all subsequent drawing operations.
|
||||||
|
Console.Error("GIF Handler MTVU - Double SIGNAL Not Handled");
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
else {
|
else
|
||||||
|
{
|
||||||
GUNIT_WARN("GIF Handler - SIGNAL");
|
GUNIT_WARN("GIF Handler - SIGNAL");
|
||||||
vu1Thread.gsSignal = ((u64)data[1] << 32) | data[0];
|
vu1Thread.gsSignal = ((u64)data[1] << 32) | data[0];
|
||||||
vu1Thread.gsInterrupts |= 2;
|
vu1Thread.gsInterrupts |= 2;
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (reg == 0x61) { // FINISH
|
else if (reg == 0x61)
|
||||||
|
{ // FINISH
|
||||||
GUNIT_WARN("GIF Handler - FINISH");
|
GUNIT_WARN("GIF Handler - FINISH");
|
||||||
vu1Thread.gsInterrupts |= 1;
|
vu1Thread.gsInterrupts |= 1;
|
||||||
}
|
}
|
||||||
else if (reg == 0x62) { // LABEL
|
else if (reg == 0x62)
|
||||||
|
{ // LABEL
|
||||||
GUNIT_WARN("GIF Handler - LABEL");
|
GUNIT_WARN("GIF Handler - LABEL");
|
||||||
vu1Thread.gsLabel = ((u64)data[1] << 32) | data[0];
|
vu1Thread.gsLabel = ((u64)data[1] << 32) | data[0];
|
||||||
vu1Thread.gsInterrupts |= 4;
|
vu1Thread.gsInterrupts |= 4;
|
||||||
}
|
}
|
||||||
else if (reg >= 0x63 && reg != 0x7f) {
|
else if (reg >= 0x63 && reg != 0x7f)
|
||||||
|
{
|
||||||
DevCon.Warning("GIF Handler Debug - Write to unknown register! [reg=%x]", reg);
|
DevCon.Warning("GIF Handler Debug - Write to unknown register! [reg=%x]", reg);
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns true if pcsx2 needed to process the packet...
|
// Returns true if pcsx2 needed to process the packet...
|
||||||
bool Gif_HandlerAD_Debug(u8* pMem) {
|
bool Gif_HandlerAD_Debug(u8* pMem)
|
||||||
u32 reg = pMem[8];
|
{
|
||||||
if (reg == 0x50) { Console.Error("GIF Handler Debug - BITBLTBUF"); return 1; }
|
u32 reg = pMem[8];
|
||||||
else if (reg == 0x52) { Console.Error("GIF Handler Debug - TRXREG"); return 1; }
|
if (reg == 0x50)
|
||||||
else if (reg == 0x53) { Console.Error("GIF Handler Debug - TRXDIR"); return 1; }
|
{
|
||||||
else if (reg == 0x60) { Console.Error("GIF Handler Debug - SIGNAL"); return 1; }
|
Console.Error("GIF Handler Debug - BITBLTBUF");
|
||||||
else if (reg == 0x61) { Console.Error("GIF Handler Debug - FINISH"); return 1; }
|
return 1;
|
||||||
else if (reg == 0x62) { Console.Error("GIF Handler Debug - LABEL"); return 1; }
|
}
|
||||||
else if (reg >= 0x63 && reg != 0x7f) {
|
else if (reg == 0x52)
|
||||||
|
{
|
||||||
|
Console.Error("GIF Handler Debug - TRXREG");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
else if (reg == 0x53)
|
||||||
|
{
|
||||||
|
Console.Error("GIF Handler Debug - TRXDIR");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
else if (reg == 0x60)
|
||||||
|
{
|
||||||
|
Console.Error("GIF Handler Debug - SIGNAL");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
else if (reg == 0x61)
|
||||||
|
{
|
||||||
|
Console.Error("GIF Handler Debug - FINISH");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
else if (reg == 0x62)
|
||||||
|
{
|
||||||
|
Console.Error("GIF Handler Debug - LABEL");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
else if (reg >= 0x63 && reg != 0x7f)
|
||||||
|
{
|
||||||
DevCon.Warning("GIF Handler Debug - Write to unknown register! [reg=%x]", reg);
|
DevCon.Warning("GIF Handler Debug - Write to unknown register! [reg=%x]", reg);
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Gif_FinishIRQ() {
|
void Gif_FinishIRQ()
|
||||||
if (CSRreg.FINISH && !GSIMR.FINISHMSK && !gifUnit.gsFINISH.gsFINISHFired) {
|
{
|
||||||
|
if (CSRreg.FINISH && !GSIMR.FINISHMSK && !gifUnit.gsFINISH.gsFINISHFired)
|
||||||
|
{
|
||||||
gsIrq();
|
gsIrq();
|
||||||
gifUnit.gsFINISH.gsFINISHFired = true;
|
gifUnit.gsFINISH.gsFINISHFired = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Used in MTVU mode... MTVU will later complete a real packet
|
// Used in MTVU mode... MTVU will later complete a real packet
|
||||||
void Gif_AddGSPacketMTVU(GS_Packet& gsPack, GIF_PATH path) {
|
void Gif_AddGSPacketMTVU(GS_Packet& gsPack, GIF_PATH path)
|
||||||
|
{
|
||||||
GetMTGS().SendSimpleGSPacket(GS_RINGTYPE_MTVU_GSPACKET, 0, 0, path);
|
GetMTGS().SendSimpleGSPacket(GS_RINGTYPE_MTVU_GSPACKET, 0, 0, path);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Gif_AddCompletedGSPacket(GS_Packet& gsPack, GIF_PATH path) {
|
void Gif_AddCompletedGSPacket(GS_Packet& gsPack, GIF_PATH path)
|
||||||
|
{
|
||||||
//DevCon.WriteLn("Adding Completed Gif Packet [size=%x]", gsPack.size);
|
//DevCon.WriteLn("Adding Completed Gif Packet [size=%x]", gsPack.size);
|
||||||
if (COPY_GS_PACKET_TO_MTGS) {
|
if (COPY_GS_PACKET_TO_MTGS)
|
||||||
GetMTGS().PrepDataPacket(path, gsPack.size/16);
|
{
|
||||||
MemCopy_WrappedDest((u128*)&gifUnit.gifPath[path].buffer[gsPack.offset], RingBuffer.m_Ring,
|
GetMTGS().PrepDataPacket(path, gsPack.size / 16);
|
||||||
GetMTGS().m_packet_writepos, RingBufferSize, gsPack.size/16);
|
MemCopy_WrappedDest((u128*)&gifUnit.gifPath[path].buffer[gsPack.offset], RingBuffer.m_Ring,
|
||||||
|
GetMTGS().m_packet_writepos, RingBufferSize, gsPack.size / 16);
|
||||||
GetMTGS().SendDataPacket();
|
GetMTGS().SendDataPacket();
|
||||||
}
|
}
|
||||||
else {
|
else
|
||||||
|
{
|
||||||
pxAssertDev(!gsPack.readAmount, "Gif Unit - gsPack.readAmount only valid for MTVU path 1!");
|
pxAssertDev(!gsPack.readAmount, "Gif Unit - gsPack.readAmount only valid for MTVU path 1!");
|
||||||
gifUnit.gifPath[path].readAmount.fetch_add(gsPack.size);
|
gifUnit.gifPath[path].readAmount.fetch_add(gsPack.size);
|
||||||
GetMTGS().SendSimpleGSPacket(GS_RINGTYPE_GSPACKET, gsPack.offset, gsPack.size, path);
|
GetMTGS().SendSimpleGSPacket(GS_RINGTYPE_GSPACKET, gsPack.offset, gsPack.size, path);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Gif_AddBlankGSPacket(u32 size, GIF_PATH path) {
|
void Gif_AddBlankGSPacket(u32 size, GIF_PATH path)
|
||||||
|
{
|
||||||
//DevCon.WriteLn("Adding Blank Gif Packet [size=%x]", size);
|
//DevCon.WriteLn("Adding Blank Gif Packet [size=%x]", size);
|
||||||
gifUnit.gifPath[path].readAmount.fetch_add(size);
|
gifUnit.gifPath[path].readAmount.fetch_add(size);
|
||||||
GetMTGS().SendSimpleGSPacket(GS_RINGTYPE_GSPACKET, ~0u, size, path);
|
GetMTGS().SendSimpleGSPacket(GS_RINGTYPE_GSPACKET, ~0u, size, path);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Gif_MTGS_Wait(bool isMTVU) {
|
void Gif_MTGS_Wait(bool isMTVU)
|
||||||
|
{
|
||||||
GetMTGS().WaitGS(false, true, isMTVU);
|
GetMTGS().WaitGS(false, true, isMTVU);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SaveStateBase::gifPathFreeze(u32 path) {
|
void SaveStateBase::gifPathFreeze(u32 path)
|
||||||
|
{
|
||||||
|
|
||||||
Gif_Path& gifPath = gifUnit.gifPath[path];
|
Gif_Path& gifPath = gifUnit.gifPath[path];
|
||||||
pxAssertDev(!gifPath.readAmount, "Gif Path readAmount should be 0!");
|
pxAssertDev(!gifPath.readAmount, "Gif Path readAmount should be 0!");
|
||||||
pxAssertDev(!gifPath.gsPack.readAmount, "GS Pack readAmount should be 0!");
|
pxAssertDev(!gifPath.gsPack.readAmount, "GS Pack readAmount should be 0!");
|
||||||
pxAssertDev(!gifPath.GetPendingGSPackets(), "MTVU GS Pack Queue should be 0!");
|
pxAssertDev(!gifPath.GetPendingGSPackets(), "MTVU GS Pack Queue should be 0!");
|
||||||
|
|
||||||
if (!gifPath.isMTVU()) { // FixMe: savestate freeze bug (Gust games) with MTVU enabled
|
if (!gifPath.isMTVU())
|
||||||
if (IsSaving()) { // Move all the buffered data to the start of buffer
|
{ // FixMe: savestate freeze bug (Gust games) with MTVU enabled
|
||||||
|
if (IsSaving())
|
||||||
|
{ // Move all the buffered data to the start of buffer
|
||||||
gifPath.RealignPacket(); // May add readAmount which we need to clear on load
|
gifPath.RealignPacket(); // May add readAmount which we need to clear on load
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
u8* bufferPtr = gifPath.buffer; // Backup current buffer ptr
|
u8* bufferPtr = gifPath.buffer; // Backup current buffer ptr
|
||||||
Freeze(gifPath.mtvu.fakePackets);
|
Freeze(gifPath.mtvu.fakePackets);
|
||||||
FreezeMem(&gifPath, sizeof(gifPath) - sizeof(gifPath.mtvu));
|
FreezeMem(&gifPath, sizeof(gifPath) - sizeof(gifPath.mtvu));
|
||||||
FreezeMem(bufferPtr, gifPath.curSize);
|
FreezeMem(bufferPtr, gifPath.curSize);
|
||||||
gifPath.buffer = bufferPtr;
|
gifPath.buffer = bufferPtr;
|
||||||
if(!IsSaving()) {
|
if (!IsSaving())
|
||||||
gifPath.readAmount = 0;
|
{
|
||||||
|
gifPath.readAmount = 0;
|
||||||
gifPath.gsPack.readAmount = 0;
|
gifPath.gsPack.readAmount = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SaveStateBase::gifFreeze() {
|
void SaveStateBase::gifFreeze()
|
||||||
|
{
|
||||||
bool mtvuMode = THREAD_VU1;
|
bool mtvuMode = THREAD_VU1;
|
||||||
pxAssert(vu1Thread.IsDone());
|
pxAssert(vu1Thread.IsDone());
|
||||||
GetMTGS().WaitGS();
|
GetMTGS().WaitGS();
|
||||||
|
@ -203,8 +283,10 @@ void SaveStateBase::gifFreeze() {
|
||||||
gifPathFreeze(GIF_PATH_1);
|
gifPathFreeze(GIF_PATH_1);
|
||||||
gifPathFreeze(GIF_PATH_2);
|
gifPathFreeze(GIF_PATH_2);
|
||||||
gifPathFreeze(GIF_PATH_3);
|
gifPathFreeze(GIF_PATH_3);
|
||||||
if (!IsSaving()) {
|
if (!IsSaving())
|
||||||
if (mtvuMode != THREAD_VU1) {
|
{
|
||||||
|
if (mtvuMode != THREAD_VU1)
|
||||||
|
{
|
||||||
DevCon.Warning("gifUnit: MTVU Mode has switched between save/load state");
|
DevCon.Warning("gifUnit: MTVU Mode has switched between save/load state");
|
||||||
// ToDo: gifUnit.SwitchMTVU(mtvuMode);
|
// ToDo: gifUnit.SwitchMTVU(mtvuMode);
|
||||||
}
|
}
|
||||||
|
|
640
pcsx2/Gif_Unit.h
640
pcsx2/Gif_Unit.h
File diff suppressed because it is too large
Load Diff
110
pcsx2/MTVU.cpp
110
pcsx2/MTVU.cpp
|
@ -22,12 +22,13 @@
|
||||||
__aligned16 VU_Thread vu1Thread(CpuVU1, VU1);
|
__aligned16 VU_Thread vu1Thread(CpuVU1, VU1);
|
||||||
|
|
||||||
#define MTVU_ALWAYS_KICK 0
|
#define MTVU_ALWAYS_KICK 0
|
||||||
#define MTVU_SYNC_MODE 0
|
#define MTVU_SYNC_MODE 0
|
||||||
|
|
||||||
// Rounds up a size in bytes for size in u32's
|
// Rounds up a size in bytes for size in u32's
|
||||||
static __fi u32 size_u32(u32 x) { return (x + 3) >> 2; }
|
static __fi u32 size_u32(u32 x) { return (x + 3) >> 2; }
|
||||||
|
|
||||||
enum MTVU_EVENT {
|
enum MTVU_EVENT
|
||||||
|
{
|
||||||
MTVU_VU_EXECUTE, // Execute VU program
|
MTVU_VU_EXECUTE, // Execute VU program
|
||||||
MTVU_VU_WRITE_MICRO, // Write to VU micro-mem
|
MTVU_VU_WRITE_MICRO, // Write to VU micro-mem
|
||||||
MTVU_VU_WRITE_DATA, // Write to VU data-mem
|
MTVU_VU_WRITE_DATA, // Write to VU data-mem
|
||||||
|
@ -43,8 +44,10 @@ static void MTVU_Unpack(void* data, VIFregisters& vifRegs)
|
||||||
{
|
{
|
||||||
u16 wl = vifRegs.cycle.wl > 0 ? vifRegs.cycle.wl : 256;
|
u16 wl = vifRegs.cycle.wl > 0 ? vifRegs.cycle.wl : 256;
|
||||||
bool isFill = vifRegs.cycle.cl < wl;
|
bool isFill = vifRegs.cycle.cl < wl;
|
||||||
if (newVifDynaRec) dVifUnpack<1>((u8*)data, isFill);
|
if (newVifDynaRec)
|
||||||
else _nVifUnpack(1, (u8*)data, vifRegs.mode, isFill);
|
dVifUnpack<1>((u8*)data, isFill);
|
||||||
|
else
|
||||||
|
_nVifUnpack(1, (u8*)data, vifRegs.mode, isFill);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Called on Saving/Loading states...
|
// Called on Saving/Loading states...
|
||||||
|
@ -52,8 +55,10 @@ void SaveStateBase::mtvuFreeze()
|
||||||
{
|
{
|
||||||
FreezeTag("MTVU");
|
FreezeTag("MTVU");
|
||||||
pxAssert(vu1Thread.IsDone());
|
pxAssert(vu1Thread.IsDone());
|
||||||
if (!IsSaving()) vu1Thread.Reset();
|
if (!IsSaving())
|
||||||
for (size_t i = 0; i < 4; ++i) {
|
vu1Thread.Reset();
|
||||||
|
for (size_t i = 0; i < 4; ++i)
|
||||||
|
{
|
||||||
unsigned int v = vu1Thread.vuCycles[i].load();
|
unsigned int v = vu1Thread.vuCycles[i].load();
|
||||||
Freeze(v);
|
Freeze(v);
|
||||||
}
|
}
|
||||||
|
@ -76,8 +81,9 @@ void SaveStateBase::mtvuFreeze()
|
||||||
Freeze(vu1Thread.vuCycleIdx);
|
Freeze(vu1Thread.vuCycleIdx);
|
||||||
}
|
}
|
||||||
|
|
||||||
VU_Thread::VU_Thread(BaseVUmicroCPU*& _vuCPU, VURegs& _vuRegs) :
|
VU_Thread::VU_Thread(BaseVUmicroCPU*& _vuCPU, VURegs& _vuRegs)
|
||||||
vuCPU(_vuCPU), vuRegs(_vuRegs)
|
: vuCPU(_vuCPU)
|
||||||
|
, vuRegs(_vuRegs)
|
||||||
{
|
{
|
||||||
m_name = L"MTVU";
|
m_name = L"MTVU";
|
||||||
Reset();
|
Reset();
|
||||||
|
@ -85,7 +91,8 @@ VU_Thread::VU_Thread(BaseVUmicroCPU*& _vuCPU, VURegs& _vuRegs) :
|
||||||
|
|
||||||
VU_Thread::~VU_Thread()
|
VU_Thread::~VU_Thread()
|
||||||
{
|
{
|
||||||
try {
|
try
|
||||||
|
{
|
||||||
pxThread::Cancel();
|
pxThread::Cancel();
|
||||||
}
|
}
|
||||||
DESTRUCTOR_CATCHALL
|
DESTRUCTOR_CATCHALL
|
||||||
|
@ -95,12 +102,12 @@ void VU_Thread::Reset()
|
||||||
{
|
{
|
||||||
ScopedLock lock(mtxBusy);
|
ScopedLock lock(mtxBusy);
|
||||||
|
|
||||||
vuCycleIdx = 0;
|
vuCycleIdx = 0;
|
||||||
isBusy = false;
|
isBusy = false;
|
||||||
m_ato_write_pos = 0;
|
m_ato_write_pos = 0;
|
||||||
m_write_pos = 0;
|
m_write_pos = 0;
|
||||||
m_ato_read_pos = 0;
|
m_ato_read_pos = 0;
|
||||||
m_read_pos = 0;
|
m_read_pos = 0;
|
||||||
memzero(vif);
|
memzero(vif);
|
||||||
memzero(vifRegs);
|
memzero(vifRegs);
|
||||||
for (size_t i = 0; i < 4; ++i)
|
for (size_t i = 0; i < 4; ++i)
|
||||||
|
@ -109,42 +116,51 @@ void VU_Thread::Reset()
|
||||||
|
|
||||||
void VU_Thread::ExecuteTaskInThread()
|
void VU_Thread::ExecuteTaskInThread()
|
||||||
{
|
{
|
||||||
PCSX2_PAGEFAULT_PROTECT {
|
PCSX2_PAGEFAULT_PROTECT
|
||||||
|
{
|
||||||
ExecuteRingBuffer();
|
ExecuteRingBuffer();
|
||||||
} PCSX2_PAGEFAULT_EXCEPT;
|
}
|
||||||
|
PCSX2_PAGEFAULT_EXCEPT;
|
||||||
}
|
}
|
||||||
|
|
||||||
void VU_Thread::ExecuteRingBuffer()
|
void VU_Thread::ExecuteRingBuffer()
|
||||||
{
|
{
|
||||||
for(;;) {
|
for (;;)
|
||||||
|
{
|
||||||
semaEvent.WaitWithoutYield();
|
semaEvent.WaitWithoutYield();
|
||||||
ScopedLockBool lock(mtxBusy, isBusy);
|
ScopedLockBool lock(mtxBusy, isBusy);
|
||||||
while (m_ato_read_pos.load(std::memory_order_relaxed) != GetWritePos()) {
|
while (m_ato_read_pos.load(std::memory_order_relaxed) != GetWritePos())
|
||||||
|
{
|
||||||
u32 tag = Read();
|
u32 tag = Read();
|
||||||
switch (tag) {
|
switch (tag)
|
||||||
case MTVU_VU_EXECUTE: {
|
{
|
||||||
|
case MTVU_VU_EXECUTE:
|
||||||
|
{
|
||||||
vuRegs.cycle = 0;
|
vuRegs.cycle = 0;
|
||||||
s32 addr = Read();
|
s32 addr = Read();
|
||||||
vifRegs.top = Read();
|
vifRegs.top = Read();
|
||||||
vifRegs.itop = Read();
|
vifRegs.itop = Read();
|
||||||
|
|
||||||
if (addr != -1) vuRegs.VI[REG_TPC].UL = addr;
|
if (addr != -1)
|
||||||
|
vuRegs.VI[REG_TPC].UL = addr;
|
||||||
vuCPU->SetStartPC(vuRegs.VI[REG_TPC].UL << 3);
|
vuCPU->SetStartPC(vuRegs.VI[REG_TPC].UL << 3);
|
||||||
vuCPU->Execute(vu1RunCycles);
|
vuCPU->Execute(vu1RunCycles);
|
||||||
gifUnit.gifPath[GIF_PATH_1].FinishGSPacketMTVU();
|
gifUnit.gifPath[GIF_PATH_1].FinishGSPacketMTVU();
|
||||||
semaXGkick.Post(); // Tell MTGS a path1 packet is complete
|
semaXGkick.Post(); // Tell MTGS a path1 packet is complete
|
||||||
vuCycles[vuCycleIdx].store(vuRegs.cycle, std::memory_order_release);
|
vuCycles[vuCycleIdx].store(vuRegs.cycle, std::memory_order_release);
|
||||||
vuCycleIdx = (vuCycleIdx + 1) & 3;
|
vuCycleIdx = (vuCycleIdx + 1) & 3;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case MTVU_VU_WRITE_MICRO: {
|
case MTVU_VU_WRITE_MICRO:
|
||||||
|
{
|
||||||
u32 vu_micro_addr = Read();
|
u32 vu_micro_addr = Read();
|
||||||
u32 size = Read();
|
u32 size = Read();
|
||||||
vuCPU->Clear(vu_micro_addr, size);
|
vuCPU->Clear(vu_micro_addr, size);
|
||||||
Read(&vuRegs.Micro[vu_micro_addr], size);
|
Read(&vuRegs.Micro[vu_micro_addr], size);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case MTVU_VU_WRITE_DATA: {
|
case MTVU_VU_WRITE_DATA:
|
||||||
|
{
|
||||||
u32 vu_data_addr = Read();
|
u32 vu_data_addr = Read();
|
||||||
u32 size = Read();
|
u32 size = Read();
|
||||||
Read(&vuRegs.Mem[vu_data_addr], size);
|
Read(&vuRegs.Mem[vu_data_addr], size);
|
||||||
|
@ -156,7 +172,8 @@ void VU_Thread::ExecuteRingBuffer()
|
||||||
case MTVU_VIF_WRITE_ROW:
|
case MTVU_VIF_WRITE_ROW:
|
||||||
Read(&vif.MaskRow, sizeof(vif.MaskRow));
|
Read(&vif.MaskRow, sizeof(vif.MaskRow));
|
||||||
break;
|
break;
|
||||||
case MTVU_VIF_UNPACK: {
|
case MTVU_VIF_UNPACK:
|
||||||
|
{
|
||||||
u32 vif_copy_size = (uptr)&vif.StructEnd - (uptr)&vif.tag;
|
u32 vif_copy_size = (uptr)&vif.StructEnd - (uptr)&vif.tag;
|
||||||
Read(&vif.tag, vif_copy_size);
|
Read(&vif.tag, vif_copy_size);
|
||||||
ReadRegs(&vifRegs);
|
ReadRegs(&vifRegs);
|
||||||
|
@ -168,7 +185,7 @@ void VU_Thread::ExecuteRingBuffer()
|
||||||
case MTVU_NULL_PACKET:
|
case MTVU_NULL_PACKET:
|
||||||
m_read_pos = 0;
|
m_read_pos = 0;
|
||||||
break;
|
break;
|
||||||
jNO_DEFAULT;
|
jNO_DEFAULT;
|
||||||
}
|
}
|
||||||
|
|
||||||
CommitReadPos();
|
CommitReadPos();
|
||||||
|
@ -180,16 +197,19 @@ void VU_Thread::ExecuteRingBuffer()
|
||||||
// Should only be called by ReserveSpace()
|
// Should only be called by ReserveSpace()
|
||||||
__ri void VU_Thread::WaitOnSize(s32 size)
|
__ri void VU_Thread::WaitOnSize(s32 size)
|
||||||
{
|
{
|
||||||
for(;;) {
|
for (;;)
|
||||||
s32 readPos = GetReadPos();
|
{
|
||||||
if (readPos <= m_write_pos) break; // MTVU is reading in back of write_pos
|
s32 readPos = GetReadPos();
|
||||||
|
if (readPos <= m_write_pos)
|
||||||
|
break; // MTVU is reading in back of write_pos
|
||||||
// FIXME greg: there is a bug somewhere in the queue pointer
|
// FIXME greg: there is a bug somewhere in the queue pointer
|
||||||
// management. It creates a deadlock/corruption in SotC intro (before
|
// management. It creates a deadlock/corruption in SotC intro (before
|
||||||
// the first menu). I added a 4KB safety net which seem to avoid to
|
// the first menu). I added a 4KB safety net which seem to avoid to
|
||||||
// trigger the bug.
|
// trigger the bug.
|
||||||
// Note: a wait lock instead of a yield also helps to avoid the bug.
|
// Note: a wait lock instead of a yield also helps to avoid the bug.
|
||||||
if (readPos > m_write_pos + size + _4kb) break; // Enough free front space
|
if (readPos > m_write_pos + size + _4kb)
|
||||||
{ // Let MTVU run to free up buffer space
|
break; // Enough free front space
|
||||||
|
{ // Let MTVU run to free up buffer space
|
||||||
KickStart();
|
KickStart();
|
||||||
// Locking might trigger a full flush of the ring buffer. Yield
|
// Locking might trigger a full flush of the ring buffer. Yield
|
||||||
// will be more aggressive, and only flush the minimal size.
|
// will be more aggressive, and only flush the minimal size.
|
||||||
|
@ -205,10 +225,11 @@ __ri void VU_Thread::WaitOnSize(s32 size)
|
||||||
void VU_Thread::ReserveSpace(s32 size)
|
void VU_Thread::ReserveSpace(s32 size)
|
||||||
{
|
{
|
||||||
pxAssert(m_write_pos < buffer_size);
|
pxAssert(m_write_pos < buffer_size);
|
||||||
pxAssert(size < buffer_size);
|
pxAssert(size < buffer_size);
|
||||||
pxAssert(size > 0);
|
pxAssert(size > 0);
|
||||||
|
|
||||||
if (m_write_pos + size > (buffer_size - 1)) {
|
if (m_write_pos + size > (buffer_size - 1))
|
||||||
|
{
|
||||||
WaitOnSize(1); // Size of MTVU_NULL_PACKET
|
WaitOnSize(1); // Size of MTVU_NULL_PACKET
|
||||||
Write(MTVU_NULL_PACKET);
|
Write(MTVU_NULL_PACKET);
|
||||||
// Reset local write pointer/position
|
// Reset local write pointer/position
|
||||||
|
@ -242,8 +263,10 @@ __fi void VU_Thread::CommitWritePos()
|
||||||
{
|
{
|
||||||
m_ato_write_pos.store(m_write_pos, std::memory_order_release);
|
m_ato_write_pos.store(m_write_pos, std::memory_order_release);
|
||||||
|
|
||||||
if (MTVU_ALWAYS_KICK) KickStart();
|
if (MTVU_ALWAYS_KICK)
|
||||||
if (MTVU_SYNC_MODE) WaitVU();
|
KickStart();
|
||||||
|
if (MTVU_SYNC_MODE)
|
||||||
|
WaitVU();
|
||||||
}
|
}
|
||||||
|
|
||||||
__fi void VU_Thread::CommitReadPos()
|
__fi void VU_Thread::CommitReadPos()
|
||||||
|
@ -307,7 +330,8 @@ u32 VU_Thread::Get_vuCycles()
|
||||||
return (vuCycles[0].load(std::memory_order_acquire) +
|
return (vuCycles[0].load(std::memory_order_acquire) +
|
||||||
vuCycles[1].load(std::memory_order_acquire) +
|
vuCycles[1].load(std::memory_order_acquire) +
|
||||||
vuCycles[2].load(std::memory_order_acquire) +
|
vuCycles[2].load(std::memory_order_acquire) +
|
||||||
vuCycles[3].load(std::memory_order_acquire)) >> 2;
|
vuCycles[3].load(std::memory_order_acquire)) >>
|
||||||
|
2;
|
||||||
}
|
}
|
||||||
|
|
||||||
void VU_Thread::Get_GSChanges()
|
void VU_Thread::Get_GSChanges()
|
||||||
|
@ -369,8 +393,8 @@ void VU_Thread::Get_GSChanges()
|
||||||
|
|
||||||
void VU_Thread::KickStart(bool forceKick)
|
void VU_Thread::KickStart(bool forceKick)
|
||||||
{
|
{
|
||||||
if ((forceKick && !semaEvent.Count())
|
if ((forceKick && !semaEvent.Count()) || (!isBusy.load(std::memory_order_acquire) && GetReadPos() != m_ato_write_pos.load(std::memory_order_relaxed)))
|
||||||
|| (!isBusy.load(std::memory_order_acquire) && GetReadPos() != m_ato_write_pos.load(std::memory_order_relaxed))) semaEvent.Post();
|
semaEvent.Post();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool VU_Thread::IsDone()
|
bool VU_Thread::IsDone()
|
||||||
|
@ -381,8 +405,10 @@ bool VU_Thread::IsDone()
|
||||||
void VU_Thread::WaitVU()
|
void VU_Thread::WaitVU()
|
||||||
{
|
{
|
||||||
MTVU_LOG("MTVU - WaitVU!");
|
MTVU_LOG("MTVU - WaitVU!");
|
||||||
for(;;) {
|
for (;;)
|
||||||
if (IsDone()) break;
|
{
|
||||||
|
if (IsDone())
|
||||||
|
break;
|
||||||
//DevCon.WriteLn("WaitVU()");
|
//DevCon.WriteLn("WaitVU()");
|
||||||
pxAssert(THREAD_VU1);
|
pxAssert(THREAD_VU1);
|
||||||
KickStart();
|
KickStart();
|
||||||
|
|
Loading…
Reference in New Issue