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; }
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; }
int Interpreter::SingleStepInner() { if (HandleFunctionHooking(PC)) { UpdatePC(); return PPCTables::GetOpInfo(m_prev_inst)->numCycles; } #ifdef USE_GDBSTUB if (gdb_active() && gdb_bp_x(PC)) { Host_UpdateDisasmDialog(); gdb_signal(GDB_SIGTRAP); gdb_handle_exception(); } #endif NPC = PC + sizeof(UGeckoInstruction); m_prev_inst.hex = PowerPC::Read_Opcode(PC); // Uncomment to trace the interpreter // if ((PC & 0xffffff)>=0x0ab54c && (PC & 0xffffff)<=0x0ab624) // startTrace = 1; // else // startTrace = 0; if (startTrace) { Trace(m_prev_inst); } if (m_prev_inst.hex != 0) { if (IsInvalidPairedSingleExecution(m_prev_inst)) { GenerateProgramException(); CheckExceptions(); } else if (MSR.FP) { m_op_table[m_prev_inst.OPCD](m_prev_inst); if (PowerPC::ppcState.Exceptions & EXCEPTION_DSI) { CheckExceptions(); } } else { // check if we have to generate a FPU unavailable exception or a program exception. if (PPCTables::UsesFPU(m_prev_inst)) { PowerPC::ppcState.Exceptions |= EXCEPTION_FPU_UNAVAILABLE; CheckExceptions(); } else { m_op_table[m_prev_inst.OPCD](m_prev_inst); if (PowerPC::ppcState.Exceptions & EXCEPTION_DSI) { CheckExceptions(); } } } } else { // Memory exception on instruction fetch CheckExceptions(); } UpdatePC(); return PPCTables::GetOpInfo(m_prev_inst)->numCycles; }