Skip to content

Commit

Permalink
IPU: Adjust DMA timings, improve internal calling
Browse files Browse the repository at this point in the history
[SAVEVERSION+]
  • Loading branch information
refractionpcsx2 committed Sep 14, 2023
1 parent 80ad618 commit 647e61c
Show file tree
Hide file tree
Showing 7 changed files with 94 additions and 68 deletions.
20 changes: 9 additions & 11 deletions pcsx2/IPU/IPU.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
alignas(16) tIPU_cmd ipu_cmd;
alignas(16) tIPU_BP g_BP;
alignas(16) decoder_t decoder;
IPUStatus IPUCoreStatus;

static void (*IPUWorker)();

Expand Down Expand Up @@ -92,15 +93,8 @@ void tIPU_cmd::clear()

__fi void IPUProcessInterrupt()
{
if (ipuRegs.ctrl.BUSY && !CommandExecuteQueued)
if (ipuRegs.ctrl.BUSY)
IPUWorker();

if (ipuRegs.ctrl.BUSY && !IPU1Status.DataRequested && !(cpuRegs.interrupt & 1 << IPU_PROCESS))
{
CPU_INT(IPU_PROCESS, ProcessedData ? ProcessedData : 64);
}
else
ProcessedData = 0;
}

/////////////////////////////////////////////////////////
Expand All @@ -112,6 +106,9 @@ void ipuReset()
std::memset(&ipuRegs, 0, sizeof(ipuRegs));
std::memset(&g_BP, 0, sizeof(g_BP));
std::memset(&decoder, 0, sizeof(decoder));
IPUCoreStatus.DataRequested = false;
IPUCoreStatus.WaitingOnIPUFrom= false;
IPUCoreStatus.WaitingOnIPUTo = false;

decoder.picture_structure = FRAME_PICTURE; //default: progressive...my guess:P

Expand Down Expand Up @@ -149,6 +146,7 @@ bool SaveStateBase::ipuFreeze()
Freeze(coded_block_pattern);
Freeze(decoder);
Freeze(ipu_cmd);
Freeze(IPUCoreStatus);

return IsOkay();
}
Expand Down Expand Up @@ -471,7 +469,6 @@ __fi void IPUCMD_WRITE(u32 val)
{
// don't process anything if currently busy
//if (ipuRegs.ctrl.BUSY) Console.WriteLn("IPU BUSY!"); // wait for thread
ProcessedData = 0;
ipuRegs.ctrl.ECD = 0;
ipuRegs.ctrl.SCD = 0;
ipu_cmd.clear();
Expand Down Expand Up @@ -538,9 +535,10 @@ __fi void IPUCMD_WRITE(u32 val)

// Have a short delay immitating the time it takes to run IDEC/BDEC, other commands are near instant.
// Mana Khemia/Metal Saga start IDEC then change IPU0 expecting there to be a delay before IDEC sends data.
if (!CommandExecuteQueued && (ipu_cmd.CMD == SCE_IPU_IDEC || ipu_cmd.CMD == SCE_IPU_BDEC))
if (ipu_cmd.CMD == SCE_IPU_IDEC || ipu_cmd.CMD == SCE_IPU_BDEC)
{
CommandExecuteQueued = true;
IPUCoreStatus.WaitingOnIPUFrom = false;
IPUCoreStatus.WaitingOnIPUTo = false;
CPU_INT(IPU_PROCESS, 64);
}
else
Expand Down
4 changes: 1 addition & 3 deletions pcsx2/IPU/IPU.h
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ struct alignas(16) tIPU_BP {
// be possible -- so if the fill fails we'll only return 0 if we don't have enough
// remaining bits in the FIFO to fill the request.
// Used to do ((FP!=0) && (BP + bits) <= 128) if we get here there's defo not enough data now though

IPUCoreStatus.WaitingOnIPUTo = true;
return false;
}

Expand Down Expand Up @@ -293,8 +293,6 @@ extern bool EnableFMV;

alignas(16) extern tIPU_cmd ipu_cmd;
extern uint eecount_on_last_vdec;
extern bool CommandExecuteQueued;
extern u32 ProcessedData;

extern void ipuReset();

Expand Down
19 changes: 9 additions & 10 deletions pcsx2/IPU/IPU_Fifo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ void IPU_Fifo_Input::clear()
writepos = 0;

// Because the FIFO is drained it will request more data immediately
IPU1Status.DataRequested = true;
IPUCoreStatus.DataRequested = true;

if (ipu1ch.chcr.STR && cpuRegs.eCycle[4] == 0x9999)
{
Expand Down Expand Up @@ -91,9 +91,7 @@ int IPU_Fifo_Input::write(const u32* pMem, int size)
g_BP.IFC += transfer_size;

if (g_BP.IFC == 8)
IPU1Status.DataRequested = false;

CPU_INT(IPU_PROCESS, transfer_size * BIAS);
IPUCoreStatus.DataRequested = false;

return transfer_size;
}
Expand All @@ -104,7 +102,7 @@ int IPU_Fifo_Input::read(void *value)
if (g_BP.IFC <= 1)
{
// IPU FIFO is empty and DMA is waiting so lets tell the DMA we are ready to put data in the FIFO
IPU1Status.DataRequested = true;
IPUCoreStatus.DataRequested = true;

if(ipu1ch.chcr.STR && cpuRegs.eCycle[4] == 0x9999)
{
Expand Down Expand Up @@ -142,7 +140,7 @@ int IPU_Fifo_Output::write(const u32 *value, uint size)
ipuRegs.ctrl.OFC += transfer_size;

if(ipu0ch.chcr.STR)
IPU_INT_FROM(ipuRegs.ctrl.OFC * BIAS);
IPU_INT_FROM(1);

return transfer_size;
}
Expand Down Expand Up @@ -181,12 +179,13 @@ void WriteFIFO_IPUin(const mem128_t* value)
IPU_LOG( "WriteFIFO/IPUin <- 0x%08X.%08X.%08X.%08X", value->_u32[0], value->_u32[1], value->_u32[2], value->_u32[3]);

//committing every 16 bytes
if( ipu_fifo.in.write(value->_u32, 1) == 0 )
if( ipu_fifo.in.write(value->_u32, 1) > 0 )
{
if (ipuRegs.ctrl.BUSY && !CommandExecuteQueued)
if (ipuRegs.ctrl.BUSY && IPUCoreStatus.WaitingOnIPUTo)
{
CommandExecuteQueued = false;
CPU_INT(IPU_PROCESS, 8);
IPUCoreStatus.WaitingOnIPUFrom = false;
IPUCoreStatus.WaitingOnIPUTo = false;
CPU_INT(IPU_PROCESS, 2 * BIAS);
}
}
}
34 changes: 30 additions & 4 deletions pcsx2/IPU/IPU_MultiISA.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1010,6 +1010,7 @@ __ri static bool mpeg2sliceIDEC()
// IPU0 isn't ready for data, so let's wait for it to be
if ((!ipu0ch.chcr.STR || ipuRegs.ctrl.OFC || ipu0ch.qwc == 0) && ipu_cmd.pos[1] <= 2)
{
IPUCoreStatus.WaitingOnIPUFrom = true;
return false;
}
macroblock_8& mb8 = decoder.mb8;
Expand Down Expand Up @@ -1123,6 +1124,8 @@ __ri static bool mpeg2sliceIDEC()
if (ready_to_decode == true)
{
ready_to_decode = false;
IPUCoreStatus.WaitingOnIPUFrom = false;
IPUCoreStatus.WaitingOnIPUTo = false;
CPU_INT(IPU_PROCESS, 64); // Should probably be much higher, but myst 3 doesn't like it right now.
ipu_cmd.pos[1] = 2;
return false;
Expand All @@ -1134,13 +1137,15 @@ __ri static bool mpeg2sliceIDEC()
if (decoder.ipu0_data != 0)
{
// IPU FIFO filled up -- Will have to finish transferring later.
IPUCoreStatus.WaitingOnIPUFrom = true;
ipu_cmd.pos[1] = 2;
return false;
}

mbaCount = 0;
if (read)
{
IPUCoreStatus.WaitingOnIPUFrom = true;
ipu_cmd.pos[1] = 3;
return false;
}
Expand Down Expand Up @@ -1308,6 +1313,7 @@ __fi static bool mpeg2_slice()
// IPU0 isn't ready for data, so let's wait for it to be
if ((!ipu0ch.chcr.STR || ipuRegs.ctrl.OFC || ipu0ch.qwc == 0) && ipu_cmd.pos[0] <= 3)
{
IPUCoreStatus.WaitingOnIPUFrom = true;
return false;
}

Expand Down Expand Up @@ -1514,6 +1520,8 @@ __fi static bool mpeg2_slice()
{
ipu_cmd.pos[0] = 3;
ready_to_decode = false;
IPUCoreStatus.WaitingOnIPUFrom = false;
IPUCoreStatus.WaitingOnIPUTo = false;
CPU_INT(IPU_PROCESS, 64); // Should probably be much higher, but myst 3 doesn't like it right now.
return false;
}
Expand All @@ -1525,13 +1533,15 @@ __fi static bool mpeg2_slice()
if (decoder.ipu0_data != 0)
{
// IPU FIFO filled up -- Will have to finish transferring later.
IPUCoreStatus.WaitingOnIPUFrom = true;
ipu_cmd.pos[0] = 3;
return false;
}

mbaCount = 0;
if (read)
{
IPUCoreStatus.WaitingOnIPUFrom = true;
ipu_cmd.pos[0] = 4;
return false;
}
Expand Down Expand Up @@ -1801,12 +1811,20 @@ __ri static bool ipuCSC(tIPU_CMD_CSC csc)
if (csc.OFM)
{
ipu_cmd.pos[1] += ipu_fifo.out.write(((u32*) & decoder.rgb16) + 4 * ipu_cmd.pos[1], 32 - ipu_cmd.pos[1]);
if (ipu_cmd.pos[1] < 32) return false;
if (ipu_cmd.pos[1] < 32)
{
IPUCoreStatus.WaitingOnIPUFrom = true;
return false;
}
}
else
{
ipu_cmd.pos[1] += ipu_fifo.out.write(((u32*) & decoder.rgb32) + 4 * ipu_cmd.pos[1], 64 - ipu_cmd.pos[1]);
if (ipu_cmd.pos[1] < 64) return false;
if (ipu_cmd.pos[1] < 64)
{
IPUCoreStatus.WaitingOnIPUFrom = true;
return false;
}
}

ipu_cmd.pos[0] = 0;
Expand Down Expand Up @@ -1834,12 +1852,20 @@ __ri static bool ipuPACK(tIPU_CMD_CSC csc)
if (csc.OFM)
{
ipu_cmd.pos[1] += ipu_fifo.out.write(((u32*) & decoder.rgb16) + 4 * ipu_cmd.pos[1], 32 - ipu_cmd.pos[1]);
if (ipu_cmd.pos[1] < 32) return false;
if (ipu_cmd.pos[1] < 32)
{
IPUCoreStatus.WaitingOnIPUFrom = true;
return false;
}
}
else
{
ipu_cmd.pos[1] += ipu_fifo.out.write(((u32*)g_ipu_indx4) + 4 * ipu_cmd.pos[1], 8 - ipu_cmd.pos[1]);
if (ipu_cmd.pos[1] < 8) return false;
if (ipu_cmd.pos[1] < 8)
{
IPUCoreStatus.WaitingOnIPUFrom = true;
return false;
}
}

ipu_cmd.pos[0] = 0;
Expand Down
Loading

0 comments on commit 647e61c

Please sign in to comment.