OpcodeDecoder: Skip recursiv display lists

This commit is contained in:
degasus 2014-11-15 16:24:06 +01:00
parent e47bfc2788
commit 90613a1bda
3 changed files with 25 additions and 16 deletions

View File

@ -251,7 +251,7 @@ static void ReadDataFromFifoOnCPU(u32 readPtr)
}
}
Memory::CopyFromEmu(s_video_buffer_write_ptr, readPtr, len);
OpcodeDecoder_Preprocess(write_ptr + len);
OpcodeDecoder_Preprocess(write_ptr + len, false);
// This would have to be locked if the GPU thread didn't spin.
s_video_buffer_write_ptr = write_ptr + len;
}
@ -289,7 +289,7 @@ void RunGpuLoop()
// See comment in SyncGPU
if (write_ptr > seen_ptr)
{
OpcodeDecoder_Run(write_ptr);
OpcodeDecoder_Run(write_ptr, false);
{
std::lock_guard<std::mutex> vblk(s_video_buffer_lock);
@ -325,7 +325,7 @@ void RunGpuLoop()
u8* write_ptr = s_video_buffer_write_ptr;
cyclesExecuted = OpcodeDecoder_Run(write_ptr);
cyclesExecuted = OpcodeDecoder_Run(write_ptr, false);
if (SConfig::GetInstance().m_LocalCoreStartupParameter.bSyncGPU && Common::AtomicLoad(CommandProcessor::VITicks) >= cyclesExecuted)
@ -399,7 +399,7 @@ void RunGpu()
FPURoundMode::SaveSIMDState();
FPURoundMode::LoadDefaultSIMDState();
ReadDataFromFifo(fifo.CPReadPointer);
OpcodeDecoder_Run(s_video_buffer_write_ptr);
OpcodeDecoder_Run(s_video_buffer_write_ptr, false);
FPURoundMode::LoadSIMDState();
}

View File

@ -55,7 +55,7 @@ static u32 InterpretDisplayList(u32 address, u32 size)
Statistics::SwapDL();
u8 *end = g_video_buffer_read_ptr + size;
cycles = OpcodeDecoder_Run(end);
cycles = OpcodeDecoder_Run(end, true);
INCSTAT(stats.thisFrame.numDListsCalled);
// un-swap
@ -80,7 +80,7 @@ static void InterpretDisplayListPreprocess(u32 address, u32 size)
g_video_buffer_pp_read_ptr = startAddress;
u8 *end = startAddress + size;
OpcodeDecoder_Preprocess(end);
OpcodeDecoder_Preprocess(end, true);
}
g_video_buffer_pp_read_ptr = old_read_ptr;
@ -126,7 +126,7 @@ static void UnknownOpcode(u8 cmd_byte, void *buffer, bool preprocess)
}
template <bool is_preprocess, u8** bufp>
static u32 Decode(u8* end)
static u32 Decode(u8* end, bool in_display_list)
{
u8 *opcodeStart = *bufp;
if (*bufp == end)
@ -205,10 +205,19 @@ static u32 Decode(u8* end)
return 0;
u32 address = DataRead<u32>(bufp);
u32 count = DataRead<u32>(bufp);
if (is_preprocess)
InterpretDisplayListPreprocess(address, count);
if (in_display_list)
{
cycles = 6;
WARN_LOG(VIDEO,"recursive display list detected");
}
else
cycles = 6 + InterpretDisplayList(address, count);
{
if (is_preprocess)
InterpretDisplayListPreprocess(address, count);
else
cycles = 6 + InterpretDisplayList(address, count);
}
}
break;
@ -297,13 +306,13 @@ void OpcodeDecoder_Shutdown()
{
}
u32 OpcodeDecoder_Run(u8* end)
u32 OpcodeDecoder_Run(u8* end, bool in_display_list)
{
u32 totalCycles = 0;
while (true)
{
u8* old = g_video_buffer_read_ptr;
u32 cycles = Decode</*is_preprocess*/ false, &g_video_buffer_read_ptr>(end);
u32 cycles = Decode</*is_preprocess*/ false, &g_video_buffer_read_ptr>(end, in_display_list);
if (cycles == 0)
{
g_video_buffer_read_ptr = old;
@ -314,12 +323,12 @@ u32 OpcodeDecoder_Run(u8* end)
return totalCycles;
}
void OpcodeDecoder_Preprocess(u8 *end)
void OpcodeDecoder_Preprocess(u8 *end, bool in_display_list)
{
while (true)
{
u8* old = g_video_buffer_pp_read_ptr;
u32 cycles = Decode</*is_preprocess*/ true, &g_video_buffer_pp_read_ptr>(end);
u32 cycles = Decode</*is_preprocess*/ true, &g_video_buffer_pp_read_ptr>(end, in_display_list);
if (cycles == 0)
{
g_video_buffer_pp_read_ptr = old;

View File

@ -40,5 +40,5 @@ extern bool g_bRecordFifoData;
void OpcodeDecoder_Init();
void OpcodeDecoder_Shutdown();
u32 OpcodeDecoder_Run(u8* end);
void OpcodeDecoder_Preprocess(u8* write_ptr);
u32 OpcodeDecoder_Run(u8* end, bool in_display_list);
void OpcodeDecoder_Preprocess(u8* end, bool in_display_list);