u32 GPUCommon::UpdateStall(int listid, u32 newstall) { if (listid < 0 || listid >= DisplayListMaxCount || dls[listid].state == PSP_GE_DL_STATE_NONE) return SCE_KERNEL_ERROR_INVALID_ID; dls[listid].stall = newstall & 0xFFFFFFF; ProcessDLQueue(); return 0; }
u32 GLES_GPU::EnqueueList(u32 listpc, u32 stall) { DisplayList dl; dl.id = dlIdGenerator++; dl.listpc = listpc&0xFFFFFFF; dl.stall = stall&0xFFFFFFF; dlQueue.push_back(dl); if (!ProcessDLQueue()) return dl.id; else return 0; }
void GPUCommon::UpdateStall(int listid, u32 newstall) { for (auto iter = dlQueue.begin(); iter != dlQueue.end(); ++iter) { DisplayList &cur = *iter; if (cur.id == listid) { cur.stall = newstall & 0xFFFFFFF; } } ProcessDLQueue(); }
void GLES_GPU::UpdateStall(int listid, u32 newstall) { // this needs improvement.... for (std::vector<DisplayList>::iterator iter = dlQueue.begin(); iter != dlQueue.end(); iter++) { DisplayList &l = *iter; if (l.id == listid) { l.stall = newstall & 0xFFFFFFF; } } ProcessDLQueue(); }
u32 GPUCommon::UpdateStall(int listid, u32 newstall) { if (listid < 0 || listid >= DisplayListMaxCount || dls[listid].state == PSP_GE_DL_STATE_NONE) return SCE_KERNEL_ERROR_INVALID_ID; dls[listid].stall = newstall & 0xFFFFFFF; if (dls[listid].signal == PSP_GE_SIGNAL_HANDLER_PAUSE) dls[listid].signal = PSP_GE_SIGNAL_HANDLER_SUSPEND; ProcessDLQueue(); return 0; }
u32 GPUCommon::EnqueueList(u32 listpc, u32 stall, int subIntrBase, bool head) { DisplayList dl; dl.id = dlIdGenerator++; dl.pc = listpc & 0xFFFFFFF; dl.stall = stall & 0xFFFFFFF; dl.status = PSP_GE_LIST_QUEUED; dl.subIntrBase = subIntrBase; if(head) dlQueue.push_front(dl); else dlQueue.push_back(dl); ProcessDLQueue(); return dl.id; }
u32 GPUCommon::UpdateStall(int listid, u32 newstall) { easy_guard guard(listLock); if (listid < 0 || listid >= DisplayListMaxCount || dls[listid].state == PSP_GE_DL_STATE_NONE) return SCE_KERNEL_ERROR_INVALID_ID; auto &dl = dls[listid]; if (dl.state == PSP_GE_DL_STATE_COMPLETED) return SCE_KERNEL_ERROR_ALREADY; dl.stall = newstall & 0x0FFFFFFF; if (dl.signal == PSP_GE_SIGNAL_HANDLER_PAUSE) dl.signal = PSP_GE_SIGNAL_HANDLER_SUSPEND; guard.unlock(); ProcessDLQueue(); return 0; }
u32 GPUCommon::Continue() { easy_guard guard(listLock); if (!currentList) return 0; if (currentList->state == PSP_GE_DL_STATE_PAUSED) { if (!isbreak) { if (currentList->signal == PSP_GE_SIGNAL_HANDLER_PAUSE) return 0x80000021; currentList->state = PSP_GE_DL_STATE_RUNNING; currentList->signal = PSP_GE_SIGNAL_NONE; // TODO Restore context of DL is necessary // TODO Restore BASE // We have a list now, so it's not complete. drawCompleteTicks = (u64)-1; } else currentList->state = PSP_GE_DL_STATE_QUEUED; } else if (currentList->state == PSP_GE_DL_STATE_RUNNING) { if (sceKernelGetCompiledSdkVersion() >= 0x02000000) return 0x80000020; return -1; } else { if (sceKernelGetCompiledSdkVersion() >= 0x02000000) return 0x80000004; return -1; } guard.unlock(); ProcessDLQueue(); return 0; }
u32 GPUCommon::EnqueueList(u32 listpc, u32 stall, int subIntrBase, bool head) { easy_guard guard(listLock); // TODO Check the stack values in missing arg and ajust the stack depth // Check alignment // TODO Check the context and stack alignement too if (((listpc | stall) & 3) != 0) return 0x80000103; int id = -1; bool oldCompatibility = true; if (sceKernelGetCompiledSdkVersion() > 0x01FFFFFF) { //numStacks = 0; //stack = NULL; oldCompatibility = false; } u64 currentTicks = CoreTiming::GetTicks(); for (int i = 0; i < DisplayListMaxCount; ++i) { if (dls[i].state != PSP_GE_DL_STATE_NONE && dls[i].state != PSP_GE_DL_STATE_COMPLETED) { if (dls[i].pc == listpc && !oldCompatibility) { ERROR_LOG(G3D, "sceGeListEnqueue: can't enqueue, list address %08X already used", listpc); return 0x80000021; } //if(dls[i].stack == stack) { // ERROR_LOG(G3D, "sceGeListEnqueue: can't enqueue, list stack %08X already used", context); // return 0x80000021; //} } if (dls[i].state == PSP_GE_DL_STATE_NONE && !dls[i].pendingInterrupt) { // Prefer a list that isn't used id = i; break; } if (id < 0 && dls[i].state == PSP_GE_DL_STATE_COMPLETED && !dls[i].pendingInterrupt && dls[i].waitTicks < currentTicks) { id = i; } } if (id < 0) { ERROR_LOG_REPORT(G3D, "No DL ID available to enqueue"); for(auto it = dlQueue.begin(); it != dlQueue.end(); ++it) { DisplayList &dl = dls[*it]; DEBUG_LOG(G3D, "DisplayList %d status %d pc %08x stall %08x", *it, dl.state, dl.pc, dl.stall); } return SCE_KERNEL_ERROR_OUT_OF_MEMORY; } DisplayList &dl = dls[id]; dl.id = id; dl.startpc = listpc & 0x0FFFFFFF; dl.pc = listpc & 0x0FFFFFFF; dl.stall = stall & 0x0FFFFFFF; dl.subIntrBase = std::max(subIntrBase, -1); dl.stackptr = 0; dl.signal = PSP_GE_SIGNAL_NONE; dl.interrupted = false; dl.waitTicks = (u64)-1; dl.interruptsEnabled = interruptsEnabled_; if (head) { if (currentList) { if (currentList->state != PSP_GE_DL_STATE_PAUSED) return SCE_KERNEL_ERROR_INVALID_VALUE; currentList->state = PSP_GE_DL_STATE_QUEUED; } dl.state = PSP_GE_DL_STATE_PAUSED; currentList = &dl; dlQueue.push_front(id); } else if (currentList) { dl.state = PSP_GE_DL_STATE_QUEUED; dlQueue.push_back(id); } else { dl.state = PSP_GE_DL_STATE_RUNNING; currentList = &dl; dlQueue.push_front(id); drawCompleteTicks = (u64)-1; // TODO save context when starting the list if param is set guard.unlock(); ProcessDLQueue(); } return id; }