bool GPUCommon::InterpretList(DisplayList &list) { // Initialized to avoid a race condition with bShowDebugStats changing. double start = 0.0; if (g_Config.bShowDebugStats) { time_update(); start = time_now_d(); } easy_guard guard(listLock); // TODO: This has to be right... but it freezes right now? //if (list.state == PSP_GE_DL_STATE_PAUSED) // return false; currentList = &list; // I don't know if this is the correct place to zero this, but something // need to do it. See Sol Trigger title screen. // TODO: Maybe this is per list? Should a stalled list remember the old value? gstate_c.offsetAddr = 0; if (!Memory::IsValidAddress(list.pc)) { ERROR_LOG_REPORT(G3D, "DL PC = %08x WTF!!!!", list.pc); return true; } #if defined(USING_QT_UI) if (host->GpuStep()) { host->SendGPUStart(); } #endif cycleLastPC = list.pc; downcount = list.stall == 0 ? 0x0FFFFFFF : (list.stall - list.pc) / 4; list.state = PSP_GE_DL_STATE_RUNNING; list.interrupted = false; gpuState = list.pc == list.stall ? GPUSTATE_STALL : GPUSTATE_RUNNING; guard.unlock(); const bool dumpThisFrame = dumpThisFrame_; // TODO: Add check for displaylist debugger. const bool useFastRunLoop = !dumpThisFrame; while (gpuState == GPUSTATE_RUNNING) { { easy_guard innerGuard(listLock); if (list.pc == list.stall) { gpuState = GPUSTATE_STALL; downcount = 0; } } if (useFastRunLoop) { FastRunLoop(list); } else { SlowRunLoop(list); } { easy_guard innerGuard(listLock); downcount = list.stall == 0 ? 0x0FFFFFFF : (list.stall - list.pc) / 4; if (gpuState == GPUSTATE_STALL && list.stall != list.pc) { // Unstalled. gpuState = GPUSTATE_RUNNING; } } } // We haven't run the op at list.pc, so it shouldn't count. if (cycleLastPC != list.pc) { UpdatePC(list.pc - 4, list.pc); } if (g_Config.bShowDebugStats) { time_update(); gpuStats.msProcessingDisplayLists += time_now_d() - start; } return gpuState == GPUSTATE_DONE || gpuState == GPUSTATE_ERROR; }
bool GPUCommon::InterpretList(DisplayList &list) { // Initialized to avoid a race condition with bShowDebugStats changing. double start = 0.0; if (g_Config.bShowDebugStats) { time_update(); start = time_now_d(); } easy_guard guard(listLock); // TODO: This has to be right... but it freezes right now? //if (list.state == PSP_GE_DL_STATE_PAUSED) // return false; currentList = &list; if (!list.started && list.context != NULL) { gstate.Save(list.context); } list.started = true; gstate_c.offsetAddr = list.offsetAddr; if (!Memory::IsValidAddress(list.pc)) { ERROR_LOG_REPORT(G3D, "DL PC = %08x WTF!!!!", list.pc); return true; } // TODO: Use new interface. #if defined(USING_QT_UI) if (host->GpuStep()) { host->SendGPUStart(); } #endif cycleLastPC = list.pc; downcount = list.stall == 0 ? 0x0FFFFFFF : (list.stall - list.pc) / 4; list.state = PSP_GE_DL_STATE_RUNNING; list.interrupted = false; gpuState = list.pc == list.stall ? GPUSTATE_STALL : GPUSTATE_RUNNING; guard.unlock(); const bool useDebugger = host->GPUDebuggingActive(); const bool useFastRunLoop = !dumpThisFrame_ && !useDebugger; while (gpuState == GPUSTATE_RUNNING) { { easy_guard innerGuard(listLock); if (list.pc == list.stall) { gpuState = GPUSTATE_STALL; downcount = 0; } } if (useFastRunLoop) { FastRunLoop(list); } else { SlowRunLoop(list); } { easy_guard innerGuard(listLock); downcount = list.stall == 0 ? 0x0FFFFFFF : (list.stall - list.pc) / 4; if (gpuState == GPUSTATE_STALL && list.stall != list.pc) { // Unstalled. gpuState = GPUSTATE_RUNNING; } } } // We haven't run the op at list.pc, so it shouldn't count. if (cycleLastPC != list.pc) { UpdatePC(list.pc - 4, list.pc); } list.offsetAddr = gstate_c.offsetAddr; if (g_Config.bShowDebugStats) { time_update(); gpuStats.msProcessingDisplayLists += time_now_d() - start; } return gpuState == GPUSTATE_DONE || gpuState == GPUSTATE_ERROR; }