Take advantage of light events in NDSP and GSPGPU code
This commit is contained in:
parent
bbd0fe92d3
commit
da7ecc255b
@ -9,7 +9,7 @@
|
||||
u16 ndspFrameId, ndspBufferCurId, ndspBufferId;
|
||||
void* ndspVars[16][2];
|
||||
|
||||
static bool bComponentLoaded = false, bDspReady = false, bSleeping = false, bNeedsSync = false;
|
||||
static bool bComponentLoaded = false, bDspReady = false, bSleeping = false, bActuallySleeping = false, bNeedsSync = false;
|
||||
static u32 droppedFrames, frameCount;
|
||||
|
||||
static const void* componentBin;
|
||||
@ -19,7 +19,8 @@ static bool componentFree;
|
||||
|
||||
static aptHookCookie aptCookie;
|
||||
|
||||
static Handle irqEvent, dspSem, sleepEvent;
|
||||
static Handle irqEvent, dspSem;
|
||||
static LightEvent sleepEvent;
|
||||
static LightLock ndspMutex;
|
||||
|
||||
static u8 dspVar5Backup[0x1080];
|
||||
@ -305,7 +306,11 @@ static void ndspAptHook(APT_HookType hook, void* param)
|
||||
case APTHOOK_ONWAKEUP:
|
||||
bSleeping = false;
|
||||
ndspInitialize(true);
|
||||
svcSignalEvent(sleepEvent);
|
||||
if (bActuallySleeping)
|
||||
{
|
||||
bActuallySleeping = false;
|
||||
LightEvent_Signal(&sleepEvent);
|
||||
}
|
||||
break;
|
||||
|
||||
case APTHOOK_ONSUSPEND:
|
||||
@ -323,8 +328,8 @@ static void ndspSync(void)
|
||||
{
|
||||
if (bSleeping)
|
||||
{
|
||||
svcWaitSynchronization(sleepEvent, U64_MAX);
|
||||
svcClearEvent(sleepEvent);
|
||||
bActuallySleeping = true;
|
||||
LightEvent_Wait(&sleepEvent);
|
||||
}
|
||||
|
||||
ndspWaitForIrq();
|
||||
@ -455,7 +460,7 @@ Result ndspInit(void)
|
||||
|
||||
if (!componentBin && !ndspFindAndLoadComponent())
|
||||
{
|
||||
rc = MAKERESULT(RL_PERMANENT, RS_NOTFOUND, 41, RD_NOT_FOUND);
|
||||
rc = MAKERESULT(RL_PERMANENT, RS_NOTFOUND, RM_DSP, RD_NOT_FOUND);
|
||||
goto _fail0;
|
||||
}
|
||||
|
||||
@ -479,17 +484,14 @@ Result ndspInit(void)
|
||||
rc = ndspInitialize(false);
|
||||
if (R_FAILED(rc)) goto _fail1;
|
||||
|
||||
rc = svcCreateEvent(&sleepEvent, RESET_STICKY);
|
||||
if (R_FAILED(rc)) goto _fail2;
|
||||
LightEvent_Init(&sleepEvent, RESET_ONESHOT);
|
||||
|
||||
ndspThread = threadCreate(ndspThreadMain, 0x0, NDSP_THREAD_STACK_SIZE, 0x18, -2, true);
|
||||
if (!ndspThread) goto _fail3;
|
||||
if (!ndspThread) goto _fail2;
|
||||
|
||||
aptHook(&aptCookie, ndspAptHook, NULL);
|
||||
return 0;
|
||||
|
||||
_fail3:
|
||||
svcCloseHandle(sleepEvent);
|
||||
_fail2:
|
||||
ndspFinalize(false);
|
||||
_fail1:
|
||||
@ -509,10 +511,12 @@ void ndspExit(void)
|
||||
if (AtomicDecrement(&ndspRefCount)) return;
|
||||
if (!bDspReady) return;
|
||||
ndspThreadRun = false;
|
||||
if (bSleeping)
|
||||
svcSignalEvent(sleepEvent);
|
||||
if (bActuallySleeping)
|
||||
{
|
||||
bActuallySleeping = false;
|
||||
LightEvent_Signal(&sleepEvent);
|
||||
}
|
||||
threadJoin(ndspThread, U64_MAX);
|
||||
svcCloseHandle(sleepEvent);
|
||||
aptUnhook(&aptCookie);
|
||||
if (!bSleeping)
|
||||
ndspFinalize(false);
|
||||
|
@ -14,19 +14,22 @@
|
||||
Handle gspGpuHandle;
|
||||
static int gspRefCount;
|
||||
|
||||
Handle gspEvents[GSPGPU_EVENT_MAX];
|
||||
vu32 gspEventCounts[GSPGPU_EVENT_MAX];
|
||||
ThreadFunc gspEventCb[GSPGPU_EVENT_MAX];
|
||||
void* gspEventCbData[GSPGPU_EVENT_MAX];
|
||||
bool gspEventCbOneShot[GSPGPU_EVENT_MAX];
|
||||
volatile bool gspRunEvents;
|
||||
Thread gspEventThread;
|
||||
static s32 gspLastEvent = -1;
|
||||
static LightEvent gspEvents[GSPGPU_EVENT_MAX];
|
||||
static vu32 gspEventCounts[GSPGPU_EVENT_MAX];
|
||||
static ThreadFunc gspEventCb[GSPGPU_EVENT_MAX];
|
||||
static void* gspEventCbData[GSPGPU_EVENT_MAX];
|
||||
static bool gspEventCbOneShot[GSPGPU_EVENT_MAX];
|
||||
static volatile bool gspRunEvents;
|
||||
static Thread gspEventThread;
|
||||
|
||||
static Handle gspEvent;
|
||||
static vu8* gspEventData;
|
||||
|
||||
static void gspEventThreadMain(void *arg);
|
||||
|
||||
Handle __sync_get_arbiter(void);
|
||||
|
||||
Result gspInit(void)
|
||||
{
|
||||
Result res=0;
|
||||
@ -53,20 +56,10 @@ void gspSetEventCallback(GSPGPU_Event id, ThreadFunc cb, void* data, bool oneSho
|
||||
|
||||
Result gspInitEventHandler(Handle _gspEvent, vu8* _gspSharedMem, u8 gspThreadId)
|
||||
{
|
||||
// Create events
|
||||
// Initialize events
|
||||
int i;
|
||||
for (i = 0; i < GSPGPU_EVENT_MAX; i ++)
|
||||
{
|
||||
Result rc = svcCreateEvent(&gspEvents[i], RESET_STICKY);
|
||||
if (rc != 0)
|
||||
{
|
||||
// Destroy already created events due to failure
|
||||
int j;
|
||||
for (j = 0; j < i; j ++)
|
||||
svcCloseHandle(gspEvents[j]);
|
||||
return rc;
|
||||
}
|
||||
}
|
||||
LightEvent_Init(&gspEvents[i], RESET_STICKY);
|
||||
|
||||
// Start event thread
|
||||
gspEvent = _gspEvent;
|
||||
@ -82,11 +75,6 @@ void gspExitEventHandler(void)
|
||||
gspRunEvents = false;
|
||||
svcSignalEvent(gspEvent);
|
||||
threadJoin(gspEventThread, U64_MAX);
|
||||
|
||||
// Free events
|
||||
int i;
|
||||
for (i = 0; i < GSPGPU_EVENT_MAX; i ++)
|
||||
svcCloseHandle(gspEvents[i]);
|
||||
}
|
||||
|
||||
void gspWaitForEvent(GSPGPU_Event id, bool nextEvent)
|
||||
@ -94,19 +82,30 @@ void gspWaitForEvent(GSPGPU_Event id, bool nextEvent)
|
||||
if(id>= GSPGPU_EVENT_MAX)return;
|
||||
|
||||
if (nextEvent)
|
||||
svcClearEvent(gspEvents[id]);
|
||||
svcWaitSynchronization(gspEvents[id], U64_MAX);
|
||||
LightEvent_Clear(&gspEvents[id]);
|
||||
LightEvent_Wait(&gspEvents[id]);
|
||||
if (!nextEvent)
|
||||
svcClearEvent(gspEvents[id]);
|
||||
LightEvent_Clear(&gspEvents[id]);
|
||||
}
|
||||
|
||||
GSPGPU_Event gspWaitForAnyEvent(void)
|
||||
{
|
||||
s32 which = 0;
|
||||
Result rc = svcWaitSynchronizationN(&which, gspEvents, GSPGPU_EVENT_MAX, false, U64_MAX);
|
||||
if (R_FAILED(rc)) return -1;
|
||||
svcClearEvent(gspEvents[which]);
|
||||
return which;
|
||||
s32 x;
|
||||
do
|
||||
{
|
||||
do
|
||||
{
|
||||
x = __ldrex(&gspLastEvent);
|
||||
if (x < 0)
|
||||
{
|
||||
__clrex();
|
||||
break;
|
||||
}
|
||||
} while (__strex(&gspLastEvent, -1));
|
||||
if (x < 0)
|
||||
svcArbitrateAddress(__sync_get_arbiter(), (u32)&gspLastEvent, ARBITRATION_WAIT_IF_LESS_THAN, 0, 0);
|
||||
} while (x < 0);
|
||||
return (GSPGPU_Event)x;
|
||||
}
|
||||
|
||||
static int popInterrupt()
|
||||
@ -168,7 +167,11 @@ void gspEventThreadMain(void *arg)
|
||||
gspEventCb[curEvt] = NULL;
|
||||
func(gspEventCbData[curEvt]);
|
||||
}
|
||||
svcSignalEvent(gspEvents[curEvt]);
|
||||
LightEvent_Signal(&gspEvents[curEvt]);
|
||||
do
|
||||
__ldrex(&gspLastEvent);
|
||||
while (__strex(&gspLastEvent, curEvt));
|
||||
svcArbitrateAddress(__sync_get_arbiter(), (u32)&gspLastEvent, ARBITRATION_SIGNAL, 1, 0);
|
||||
gspEventCounts[curEvt]++;
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user