mirror of
https://github.com/hrydgard/ppsspp.git
synced 2025-02-11 00:56:37 +00:00
Merge pull request #3873 from unknownbrackets/ge-minor
Improve sceGeBreak and offsetAddr handling
This commit is contained in:
commit
c69852444b
@ -403,11 +403,28 @@ int sceGeContinue()
|
||||
return gpu->Continue();
|
||||
}
|
||||
|
||||
int sceGeBreak(u32 mode)
|
||||
int sceGeBreak(u32 mode, u32 unknownPtr)
|
||||
{
|
||||
if (mode > 1)
|
||||
{
|
||||
WARN_LOG(SCEGE, "sceGeBreak(mode=%d, unknown=%08x): invalid mode", mode, unknownPtr);
|
||||
return SCE_KERNEL_ERROR_INVALID_MODE;
|
||||
}
|
||||
// Not sure what this is supposed to be for...
|
||||
if ((int)unknownPtr < 0 || (int)unknownPtr + 16 < 0)
|
||||
{
|
||||
WARN_LOG_REPORT(SCEGE, "sceGeBreak(mode=%d, unknown=%08x): invalid ptr", mode, unknownPtr);
|
||||
return 0x80000023;
|
||||
}
|
||||
else if (unknownPtr != 0)
|
||||
WARN_LOG_REPORT(SCEGE, "sceGeBreak(mode=%d, unknown=%08x): unknown ptr (%s)", mode, unknownPtr, Memory::IsValidAddress(unknownPtr) ? "valid" : "invalid");
|
||||
|
||||
//mode => 0 : current dlist 1: all drawing
|
||||
DEBUG_LOG(SCEGE, "sceGeBreak(mode=%d)", mode);
|
||||
return gpu->Break(mode);
|
||||
DEBUG_LOG(SCEGE, "sceGeBreak(mode=%d, unknown=%08x)", mode, unknownPtr);
|
||||
int result = gpu->Break(mode);
|
||||
if (result >= 0 && mode == 0)
|
||||
return 0x35000000 ^ result;
|
||||
return result;
|
||||
}
|
||||
|
||||
u32 sceGeSetCallback(u32 structAddr)
|
||||
@ -481,7 +498,7 @@ u32 sceGeSaveContext(u32 ctxAddr)
|
||||
DEBUG_LOG(SCEGE, "sceGeSaveContext(%08x)", ctxAddr);
|
||||
gpu->SyncThread();
|
||||
|
||||
if (gpu->DrawSync(1) != PSP_GE_LIST_COMPLETED)
|
||||
if (gpu->BusyDrawing())
|
||||
{
|
||||
WARN_LOG(SCEGE, "sceGeSaveContext(%08x): lists in process, aborting", ctxAddr);
|
||||
// Real error code.
|
||||
@ -504,7 +521,7 @@ u32 sceGeRestoreContext(u32 ctxAddr)
|
||||
DEBUG_LOG(SCEGE, "sceGeRestoreContext(%08x)", ctxAddr);
|
||||
gpu->SyncThread();
|
||||
|
||||
if (gpu->DrawSync(1) != PSP_GE_LIST_COMPLETED)
|
||||
if (gpu->BusyDrawing())
|
||||
{
|
||||
WARN_LOG(SCEGE, "sceGeRestoreContext(%08x): lists in process, aborting", ctxAddr);
|
||||
return SCE_KERNEL_ERROR_BUSY;
|
||||
@ -601,7 +618,7 @@ const HLEFunction sceGe_user[] =
|
||||
{0xE0D68148, WrapI_UU<sceGeListUpdateStallAddr>, "sceGeListUpdateStallAddr"},
|
||||
{0x03444EB4, WrapI_UU<sceGeListSync>, "sceGeListSync"},
|
||||
{0xB287BD61, WrapU_U<sceGeDrawSync>, "sceGeDrawSync"},
|
||||
{0xB448EC0D, WrapI_U<sceGeBreak>, "sceGeBreak"},
|
||||
{0xB448EC0D, WrapI_UU<sceGeBreak>, "sceGeBreak"},
|
||||
{0x4C06E472, WrapI_V<sceGeContinue>, "sceGeContinue"},
|
||||
{0xA4FC06A4, WrapU_U<sceGeSetCallback>, "sceGeSetCallback"},
|
||||
{0x05DB22CE, WrapI_U<sceGeUnsetCallback>, "sceGeUnsetCallback"},
|
||||
|
@ -48,6 +48,17 @@ void GPUCommon::PopDLQueue() {
|
||||
}
|
||||
}
|
||||
|
||||
bool GPUCommon::BusyDrawing() {
|
||||
u32 state = DrawSync(1);
|
||||
if (state == PSP_GE_LIST_DRAWING || state == PSP_GE_LIST_STALLING) {
|
||||
lock_guard guard(listLock);
|
||||
if (currentList && currentList->state != PSP_GE_DL_STATE_PAUSED) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
u32 GPUCommon::DrawSync(int mode) {
|
||||
// FIXME: Workaround for displaylists sometimes hanging unprocessed. Not yet sure of the cause.
|
||||
if (g_Config.bSeparateCPUThread) {
|
||||
@ -252,6 +263,7 @@ u32 GPUCommon::EnqueueList(u32 listpc, u32 stall, int subIntrBase, PSPPointer<Ps
|
||||
dl.waitTicks = (u64)-1;
|
||||
dl.interruptsEnabled = interruptsEnabled_;
|
||||
dl.started = false;
|
||||
dl.offsetAddr = 0;
|
||||
if (args.IsValid() && args->context.IsValid())
|
||||
dl.context = args->context;
|
||||
else
|
||||
@ -377,7 +389,7 @@ u32 GPUCommon::Break(int mode) {
|
||||
return SCE_KERNEL_ERROR_INVALID_MODE;
|
||||
|
||||
if (!currentList)
|
||||
return 0x80000020;
|
||||
return SCE_KERNEL_ERROR_ALREADY;
|
||||
|
||||
if (mode == 1)
|
||||
{
|
||||
@ -410,9 +422,9 @@ u32 GPUCommon::Break(int mode) {
|
||||
ERROR_LOG_REPORT(G3D, "sceGeBreak: can't break signal-pausing list");
|
||||
}
|
||||
else
|
||||
return 0x80000020;
|
||||
return SCE_KERNEL_ERROR_ALREADY;
|
||||
}
|
||||
return 0x80000021;
|
||||
return SCE_KERNEL_ERROR_BUSY;
|
||||
}
|
||||
|
||||
if (currentList->state == PSP_GE_DL_STATE_QUEUED)
|
||||
@ -456,10 +468,7 @@ bool GPUCommon::InterpretList(DisplayList &list) {
|
||||
}
|
||||
list.started = true;
|
||||
|
||||
// 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;
|
||||
gstate_c.offsetAddr = list.offsetAddr;
|
||||
|
||||
if (!Memory::IsValidAddress(list.pc)) {
|
||||
ERROR_LOG_REPORT(G3D, "DL PC = %08x WTF!!!!", list.pc);
|
||||
@ -514,6 +523,8 @@ bool GPUCommon::InterpretList(DisplayList &list) {
|
||||
UpdatePC(list.pc - 4, list.pc);
|
||||
}
|
||||
|
||||
list.offsetAddr = gstate_c.offsetAddr;
|
||||
|
||||
if (g_Config.bShowDebugStats) {
|
||||
time_update();
|
||||
gpuStats.msProcessingDisplayLists += time_now_d() - start;
|
||||
|
@ -44,6 +44,7 @@ public:
|
||||
SyncThread();
|
||||
return true;
|
||||
}
|
||||
virtual bool BusyDrawing();
|
||||
virtual u32 Continue();
|
||||
virtual u32 Break(int mode);
|
||||
virtual void ReapplyGfxState();
|
||||
|
@ -134,6 +134,7 @@ struct DisplayList
|
||||
bool pendingInterrupt;
|
||||
bool started;
|
||||
u32_le *context;
|
||||
u32 offsetAddr;
|
||||
};
|
||||
|
||||
enum GPUInvalidationType {
|
||||
@ -237,6 +238,7 @@ public:
|
||||
virtual void Resized() = 0;
|
||||
virtual bool FramebufferDirty() = 0;
|
||||
virtual bool FramebufferReallyDirty() = 0;
|
||||
virtual bool BusyDrawing() = 0;
|
||||
|
||||
// Debugging
|
||||
virtual void DumpNextFrame() = 0;
|
||||
|
@ -56,14 +56,12 @@ void NullGPU::ExecuteOp(u32 op, u32 diff)
|
||||
DEBUG_LOG(G3D,"DL BASE: %06x", data);
|
||||
break;
|
||||
|
||||
case GE_CMD_VADDR: /// <<8????
|
||||
gstate_c.vertexAddr = ((gstate.base & 0x00FF0000) << 8)|data;
|
||||
DEBUG_LOG(G3D,"DL VADDR: %06x", gstate_c.vertexAddr);
|
||||
case GE_CMD_VADDR:
|
||||
gstate_c.vertexAddr = gstate_c.getRelativeAddress(data);
|
||||
break;
|
||||
|
||||
case GE_CMD_IADDR:
|
||||
gstate_c.indexAddr = ((gstate.base & 0x00FF0000) << 8)|data;
|
||||
DEBUG_LOG(G3D,"DL IADDR: %06x", gstate_c.indexAddr);
|
||||
gstate_c.indexAddr = gstate_c.getRelativeAddress(data);
|
||||
break;
|
||||
|
||||
case GE_CMD_PRIM:
|
||||
|
Loading…
x
Reference in New Issue
Block a user