u32 GPUCommon::DrawSync(int mode) { // FIXME: Workaround for displaylists sometimes hanging unprocessed. Not yet sure of the cause. if (g_Config.bSeparateCPUThread) { // FIXME: Workaround for displaylists sometimes hanging unprocessed. Not yet sure of the cause. ScheduleEvent(GPU_EVENT_PROCESS_QUEUE); // Sync first, because the CPU is usually faster than the emulated GPU. SyncThread(); } easy_guard guard(listLock); if (mode < 0 || mode > 1) return SCE_KERNEL_ERROR_INVALID_MODE; if (mode == 0) { if (!__KernelIsDispatchEnabled()) { return SCE_KERNEL_ERROR_CAN_NOT_WAIT; } if (__IsInInterrupt()) { return SCE_KERNEL_ERROR_ILLEGAL_CONTEXT; } if (drawCompleteTicks > CoreTiming::GetTicks()) { __GeWaitCurrentThread(WAITTYPE_GEDRAWSYNC, 1, "GeDrawSync"); } else { for (int i = 0; i < DisplayListMaxCount; ++i) { if (dls[i].state == PSP_GE_DL_STATE_COMPLETED) { dls[i].state = PSP_GE_DL_STATE_NONE; } } } return 0; } // If there's no current list, it must be complete. DisplayList *top = NULL; for (auto it = dlQueue.begin(), end = dlQueue.end(); it != end; ++it) { if (dls[*it].state != PSP_GE_DL_STATE_COMPLETED) { top = &dls[*it]; break; } } if (!top || top->state == PSP_GE_DL_STATE_COMPLETED) return PSP_GE_LIST_COMPLETED; if (currentList->pc == currentList->stall) return PSP_GE_LIST_STALLING; return PSP_GE_LIST_DRAWING; }
bool DIRECTX9_GPU::FramebufferDirty() { // FIXME: Workaround for displaylists sometimes hanging unprocessed. Not yet sure of the cause. if (g_Config.bSeparateCPUThread) { // FIXME: Workaround for displaylists sometimes hanging unprocessed. Not yet sure of the cause. ScheduleEvent(GPU_EVENT_PROCESS_QUEUE); // Allow it to process fully before deciding if it's dirty. SyncThread(); } VirtualFramebufferDX9 *vfb = framebufferManager_.GetDisplayFBO(); if (vfb) { bool dirty = vfb->dirtyAfterDisplay; vfb->dirtyAfterDisplay = false; return dirty; } return true; }
void AsyncIOManager::DoState(PointerWrap &p) { auto s = p.Section("AsyncIoManager", 1, 2); if (!s) return; SyncThread(); lock_guard guard(resultsLock_); p.Do(resultsPending_); if (s >= 2) { p.Do(results_); } else { std::map<u32, size_t> oldResults; p.Do(oldResults); for (auto it = oldResults.begin(), end = oldResults.end(); it != end; ++it) { results_[it->first] = AsyncIOResult(it->second); } } }
int GPUCommon::ListSync(int listid, int mode) { // FIXME: Workaround for displaylists sometimes hanging unprocessed. Not yet sure of the cause. ScheduleEvent(GPU_EVENT_PROCESS_QUEUE); // Sync first, because the CPU is usually faster than the emulated GPU. SyncThread(); easy_guard guard(listLock); if (listid < 0 || listid >= DisplayListMaxCount) return SCE_KERNEL_ERROR_INVALID_ID; if (mode < 0 || mode > 1) return SCE_KERNEL_ERROR_INVALID_MODE; DisplayList& dl = dls[listid]; if (mode == 1) { switch (dl.state) { case PSP_GE_DL_STATE_QUEUED: if (dl.interrupted) return PSP_GE_LIST_PAUSED; return PSP_GE_LIST_QUEUED; case PSP_GE_DL_STATE_RUNNING: if (dl.pc == dl.stall) return PSP_GE_LIST_STALLING; return PSP_GE_LIST_DRAWING; case PSP_GE_DL_STATE_COMPLETED: return PSP_GE_LIST_COMPLETED; case PSP_GE_DL_STATE_PAUSED: return PSP_GE_LIST_PAUSED; default: return SCE_KERNEL_ERROR_INVALID_ID; } } if (dl.waitTicks > CoreTiming::GetTicks()) { __GeWaitCurrentThread(WAITTYPE_GELISTSYNC, listid, "GeListSync"); } return PSP_GE_LIST_COMPLETED; }