u32 sceUmdCancelWaitDriveStat() { DEBUG_LOG(HLE, "0=sceUmdCancelWaitDriveStat()"); __KernelTriggerWait(WAITTYPE_UMD, 1, SCE_KERNEL_ERROR_WAIT_CANCEL, "umd stat ready", true); // TODO: We should call UnscheduleEvent() event here? // But it's not often used anyway, and worst-case it will just do nothing unless it waits again. return 0; }
void hleEnterVblank(u64 userdata, int cyclesLate) { int vbCount = userdata; DEBUG_LOG(HLE, "Enter VBlank %i", vbCount); isVblank = 1; // Wake up threads waiting for VBlank __KernelTriggerWait(WAITTYPE_VBLANK, 0, true); // Trigger VBlank interrupt handlers. __TriggerInterrupt(PSP_VBLANK_INTR); CoreTiming::ScheduleEvent(msToCycles(vblankMs) - cyclesLate, leaveVblankEvent, vbCount+1); // TODO: Should this be done here or in hleLeaveVblank? if (framebufIsLatched) { DEBUG_LOG(HLE, "Setting latched framebuffer %08x (prev: %08x)", latchedFramebuf.topaddr, framebuf.topaddr); framebuf = latchedFramebuf; framebufIsLatched = false; } // Yeah, this has to be the right moment to end the frame. Should possibly blit the right buffer // depending on what's set in sceDisplaySetFramebuf, in order to support half-framerate games - // an initial hack could be to NOT end the frame if the buffer didn't change? that should work okay. { host->EndFrame(); host->BeginFrame(); if (g_Config.bDisplayFramebuffer) { INFO_LOG(HLE, "Drawing the framebuffer"); DisplayDrawer_DrawFramebuffer(framebuf.pspframebuf, framebuf.pspFramebufFormat, framebuf.pspFramebufLinesize); } shaderManager.DirtyShader(); shaderManager.DirtyUniform(DIRTY_ALL); } // TODO: Find a way to tell the CPU core to stop emulating here, when running on Android. }
u32 GPUCommon::DequeueList(int listid) { if (listid < 0 || listid >= DisplayListMaxCount || dls[listid].state == PSP_GE_DL_STATE_NONE) return SCE_KERNEL_ERROR_INVALID_ID; if (dls[listid].state == PSP_GE_DL_STATE_RUNNING || dls[listid].state == PSP_GE_DL_STATE_PAUSED) return 0x80000021; dls[listid].state = PSP_GE_DL_STATE_NONE; if (listid == dlQueue.front()) PopDLQueue(); else dlQueue.remove(listid); dls[listid].shouldWait = false; __KernelTriggerWait(WAITTYPE_GELISTSYNC, listid, 0, "GeListSync"); CheckDrawSync(); return 0; }
bool GPUCommon::ProcessDLQueue() { startingTicks = CoreTiming::GetTicks(); cyclesExecuted = 0; DisplayListQueue::iterator iter = dlQueue.begin(); while (iter != dlQueue.end()) { DisplayList &l = dls[*iter]; DEBUG_LOG(G3D,"Okay, starting DL execution at %08x - stall = %08x", l.pc, l.stall); if (!InterpretList(l)) { return false; } else { //At the end, we can remove it from the queue and continue dlQueue.erase(iter); //this invalidated the iterator, let's fix it iter = dlQueue.begin(); } } currentList = NULL; drawComplete = true; if (__KernelTriggerWait(WAITTYPE_GEDRAWSYNC, 1, 0, "GeDrawSync")) { 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 true; //no more lists! }