IPU: Improve DMA/IPU call locations to reduce looping

This commit is contained in:
refractionpcsx2 2023-08-05 02:51:17 +01:00
parent f2c032ba07
commit 3e78f8e87d
4 changed files with 46 additions and 37 deletions

View File

@ -95,7 +95,7 @@ __fi void IPUProcessInterrupt()
if (ipuRegs.ctrl.BUSY && !CommandExecuteQueued)
IPUWorker();
if (ipuRegs.ctrl.BUSY)
if (ipuRegs.ctrl.BUSY && !IPU1Status.DataRequested && !(cpuRegs.interrupt & 1 << IPU_PROCESS))
{
CPU_INT(IPU_PROCESS, ProcessedData ? ProcessedData : 64);
}

View File

@ -93,6 +93,8 @@ int IPU_Fifo_Input::write(const u32* pMem, int size)
if (g_BP.IFC == 8)
IPU1Status.DataRequested = false;
CPU_INT(IPU_PROCESS, transfer_size * BIAS);
return transfer_size;
}
@ -106,7 +108,7 @@ int IPU_Fifo_Input::read(void *value)
if(ipu1ch.chcr.STR && cpuRegs.eCycle[4] == 0x9999)
{
CPU_INT( DMAC_TO_IPU, 4);
CPU_INT( DMAC_TO_IPU, std::min(8U, ipu1ch.qwc));
}
if (g_BP.IFC == 0) return 0;
@ -183,7 +185,7 @@ void WriteFIFO_IPUin(const mem128_t* value)
{
if (ipuRegs.ctrl.BUSY && !CommandExecuteQueued)
{
CommandExecuteQueued = true;
CommandExecuteQueued = false;
CPU_INT(IPU_PROCESS, 8);
}
}

View File

@ -983,7 +983,7 @@ __fi static void finishmpeg2sliceIDEC()
__ri static bool mpeg2sliceIDEC()
{
u16 code;
static bool ready_to_decode = true;
switch (ipu_cmd.pos[0])
{
case 0:
@ -1007,6 +1007,13 @@ __ri static bool mpeg2sliceIDEC()
ipu_cmd.pos[0] = 2;
while (1)
{
if (ready_to_decode == true)
{
ready_to_decode = false;
CPU_INT(IPU_PROCESS, 64); // Should probably be much higher, but myst 3 doesn't like it right now.
ipu_cmd.pos[0] = 2;
return false;
}
// 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)
{
@ -1116,15 +1123,13 @@ __ri static bool mpeg2sliceIDEC()
ipu_dither(rgb32, rgb16, decoder.dte);
decoder.SetOutputTo(rgb16);
}
ProcessedData += decoder.ipu0_data;
ipu_cmd.pos[1] = 2;
return false;
[[fallthrough]];
case 2:
{
pxAssert(decoder.ipu0_data > 0);
ready_to_decode = true;
uint read = ipu_fifo.out.write((u32*)decoder.GetIpuDataPtr(), decoder.ipu0_data);
decoder.AdvanceIpuDataBy(read);
@ -1205,6 +1210,7 @@ __ri static bool mpeg2sliceIDEC()
ipu_cmd.pos[1] = 0;
ipu_cmd.pos[2] = 0;
ready_to_decode = true;
}
finish_idec:
@ -1269,6 +1275,7 @@ finish_idec:
__fi static bool mpeg2_slice()
{
int DCT_offset, DCT_stride;
static bool ready_to_decode = true;
macroblock_8& mb8 = decoder.mb8;
macroblock_16& mb16 = decoder.mb16;
@ -1299,7 +1306,12 @@ __fi static bool mpeg2_slice()
case 2:
ipu_cmd.pos[0] = 2;
if (ready_to_decode == true)
{
ready_to_decode = false;
CPU_INT(IPU_PROCESS, 64); // Should probably be much higher, but myst 3 doesn't like it right now.
return false;
}
// 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)
{
@ -1406,23 +1418,23 @@ __fi static bool mpeg2_slice()
{
if (decoder.macroblock_modes & MACROBLOCK_PATTERN)
{
switch(ipu_cmd.pos[1])
switch (ipu_cmd.pos[1])
{
case 0:
{
// Get coded block pattern
const CBPtab* tab;
u16 code = UBITS(16);
{
// Get coded block pattern
const CBPtab* tab;
u16 code = UBITS(16);
if (code >= 0x2000)
tab = CBP_7 + (UBITS(7) - 16);
else
tab = CBP_9 + UBITS(9);
if (code >= 0x2000)
tab = CBP_7 + (UBITS(7) - 16);
else
tab = CBP_9 + UBITS(9);
DUMPBITS(tab->len);
decoder.coded_block_pattern = tab->cbp;
}
[[fallthrough]];
DUMPBITS(tab->len);
decoder.coded_block_pattern = tab->cbp;
}
[[fallthrough]];
case 1:
if (decoder.coded_block_pattern & 0x20)
@ -1490,9 +1502,11 @@ __fi static bool mpeg2_slice()
}
break;
jNO_DEFAULT;
jNO_DEFAULT;
}
}
else
DevCon.Warning("No macroblock mode");
}
// Send The MacroBlock via DmaIpuFrom
@ -1500,14 +1514,11 @@ __fi static bool mpeg2_slice()
coded_block_pattern = decoder.coded_block_pattern;
decoder.SetOutputTo(mb16);
ProcessedData += decoder.ipu0_data;
ipu_cmd.pos[0] = 3;
return false;
[[fallthrough]];
case 3:
{
pxAssert(decoder.ipu0_data > 0);
ready_to_decode = true;
uint read = ipu_fifo.out.write((u32*)decoder.GetIpuDataPtr(), decoder.ipu0_data);
decoder.AdvanceIpuDataBy(read);
@ -1577,6 +1588,7 @@ __fi static bool mpeg2_slice()
break;
}
ready_to_decode = true;
return true;
}

View File

@ -149,12 +149,6 @@ void IPU1dma()
}
}
if (ipuRegs.ctrl.BUSY && !CommandExecuteQueued)
{
CommandExecuteQueued = true;
CPU_INT(IPU_PROCESS, totalqwc * BIAS);
}
IPU_LOG("Completed Call IPU1 DMA QWC Remaining %x Finished %d In Progress %d tadr %x", ipu1ch.qwc, IPU1Status.DMAFinished, IPU1Status.InProgress, ipu1ch.tadr);
}
@ -198,13 +192,14 @@ void IPU0dma()
dmacRegs.stadr.ADDR = ipu0ch.madr;
}
IPU_INT_FROM( readsize * BIAS );
if (!ipu0ch.qwc)
IPU_INT_FROM(readsize * BIAS);
if (ipuRegs.ctrl.BUSY && !CommandExecuteQueued)
{
CommandExecuteQueued = true;
CommandExecuteQueued = false;
CPU_SET_DMASTALL(DMAC_FROM_IPU, true);
CPU_INT(IPU_PROCESS, readsize * BIAS);
IPUProcessInterrupt();
}
}