Take advantage of light events in NDSP and GSPGPU code

This commit is contained in:
fincs 2016-07-05 22:38:44 +02:00
parent bbd0fe92d3
commit da7ecc255b
2 changed files with 54 additions and 47 deletions

View File

@ -9,7 +9,7 @@
u16 ndspFrameId, ndspBufferCurId, ndspBufferId; u16 ndspFrameId, ndspBufferCurId, ndspBufferId;
void* ndspVars[16][2]; 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 u32 droppedFrames, frameCount;
static const void* componentBin; static const void* componentBin;
@ -19,7 +19,8 @@ static bool componentFree;
static aptHookCookie aptCookie; static aptHookCookie aptCookie;
static Handle irqEvent, dspSem, sleepEvent; static Handle irqEvent, dspSem;
static LightEvent sleepEvent;
static LightLock ndspMutex; static LightLock ndspMutex;
static u8 dspVar5Backup[0x1080]; static u8 dspVar5Backup[0x1080];
@ -305,7 +306,11 @@ static void ndspAptHook(APT_HookType hook, void* param)
case APTHOOK_ONWAKEUP: case APTHOOK_ONWAKEUP:
bSleeping = false; bSleeping = false;
ndspInitialize(true); ndspInitialize(true);
svcSignalEvent(sleepEvent); if (bActuallySleeping)
{
bActuallySleeping = false;
LightEvent_Signal(&sleepEvent);
}
break; break;
case APTHOOK_ONSUSPEND: case APTHOOK_ONSUSPEND:
@ -323,8 +328,8 @@ static void ndspSync(void)
{ {
if (bSleeping) if (bSleeping)
{ {
svcWaitSynchronization(sleepEvent, U64_MAX); bActuallySleeping = true;
svcClearEvent(sleepEvent); LightEvent_Wait(&sleepEvent);
} }
ndspWaitForIrq(); ndspWaitForIrq();
@ -455,7 +460,7 @@ Result ndspInit(void)
if (!componentBin && !ndspFindAndLoadComponent()) 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; goto _fail0;
} }
@ -479,17 +484,14 @@ Result ndspInit(void)
rc = ndspInitialize(false); rc = ndspInitialize(false);
if (R_FAILED(rc)) goto _fail1; if (R_FAILED(rc)) goto _fail1;
rc = svcCreateEvent(&sleepEvent, RESET_STICKY); LightEvent_Init(&sleepEvent, RESET_ONESHOT);
if (R_FAILED(rc)) goto _fail2;
ndspThread = threadCreate(ndspThreadMain, 0x0, NDSP_THREAD_STACK_SIZE, 0x18, -2, true); ndspThread = threadCreate(ndspThreadMain, 0x0, NDSP_THREAD_STACK_SIZE, 0x18, -2, true);
if (!ndspThread) goto _fail3; if (!ndspThread) goto _fail2;
aptHook(&aptCookie, ndspAptHook, NULL); aptHook(&aptCookie, ndspAptHook, NULL);
return 0; return 0;
_fail3:
svcCloseHandle(sleepEvent);
_fail2: _fail2:
ndspFinalize(false); ndspFinalize(false);
_fail1: _fail1:
@ -509,10 +511,12 @@ void ndspExit(void)
if (AtomicDecrement(&ndspRefCount)) return; if (AtomicDecrement(&ndspRefCount)) return;
if (!bDspReady) return; if (!bDspReady) return;
ndspThreadRun = false; ndspThreadRun = false;
if (bSleeping) if (bActuallySleeping)
svcSignalEvent(sleepEvent); {
bActuallySleeping = false;
LightEvent_Signal(&sleepEvent);
}
threadJoin(ndspThread, U64_MAX); threadJoin(ndspThread, U64_MAX);
svcCloseHandle(sleepEvent);
aptUnhook(&aptCookie); aptUnhook(&aptCookie);
if (!bSleeping) if (!bSleeping)
ndspFinalize(false); ndspFinalize(false);

View File

@ -14,19 +14,22 @@
Handle gspGpuHandle; Handle gspGpuHandle;
static int gspRefCount; static int gspRefCount;
Handle gspEvents[GSPGPU_EVENT_MAX]; static s32 gspLastEvent = -1;
vu32 gspEventCounts[GSPGPU_EVENT_MAX]; static LightEvent gspEvents[GSPGPU_EVENT_MAX];
ThreadFunc gspEventCb[GSPGPU_EVENT_MAX]; static vu32 gspEventCounts[GSPGPU_EVENT_MAX];
void* gspEventCbData[GSPGPU_EVENT_MAX]; static ThreadFunc gspEventCb[GSPGPU_EVENT_MAX];
bool gspEventCbOneShot[GSPGPU_EVENT_MAX]; static void* gspEventCbData[GSPGPU_EVENT_MAX];
volatile bool gspRunEvents; static bool gspEventCbOneShot[GSPGPU_EVENT_MAX];
Thread gspEventThread; static volatile bool gspRunEvents;
static Thread gspEventThread;
static Handle gspEvent; static Handle gspEvent;
static vu8* gspEventData; static vu8* gspEventData;
static void gspEventThreadMain(void *arg); static void gspEventThreadMain(void *arg);
Handle __sync_get_arbiter(void);
Result gspInit(void) Result gspInit(void)
{ {
Result res=0; 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) Result gspInitEventHandler(Handle _gspEvent, vu8* _gspSharedMem, u8 gspThreadId)
{ {
// Create events // Initialize events
int i; int i;
for (i = 0; i < GSPGPU_EVENT_MAX; i ++) for (i = 0; i < GSPGPU_EVENT_MAX; i ++)
{ LightEvent_Init(&gspEvents[i], RESET_STICKY);
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;
}
}
// Start event thread // Start event thread
gspEvent = _gspEvent; gspEvent = _gspEvent;
@ -82,11 +75,6 @@ void gspExitEventHandler(void)
gspRunEvents = false; gspRunEvents = false;
svcSignalEvent(gspEvent); svcSignalEvent(gspEvent);
threadJoin(gspEventThread, U64_MAX); 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) 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(id>= GSPGPU_EVENT_MAX)return;
if (nextEvent) if (nextEvent)
svcClearEvent(gspEvents[id]); LightEvent_Clear(&gspEvents[id]);
svcWaitSynchronization(gspEvents[id], U64_MAX); LightEvent_Wait(&gspEvents[id]);
if (!nextEvent) if (!nextEvent)
svcClearEvent(gspEvents[id]); LightEvent_Clear(&gspEvents[id]);
} }
GSPGPU_Event gspWaitForAnyEvent(void) GSPGPU_Event gspWaitForAnyEvent(void)
{ {
s32 which = 0; s32 x;
Result rc = svcWaitSynchronizationN(&which, gspEvents, GSPGPU_EVENT_MAX, false, U64_MAX); do
if (R_FAILED(rc)) return -1; {
svcClearEvent(gspEvents[which]); do
return which; {
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() static int popInterrupt()
@ -168,7 +167,11 @@ void gspEventThreadMain(void *arg)
gspEventCb[curEvt] = NULL; gspEventCb[curEvt] = NULL;
func(gspEventCbData[curEvt]); 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]++; gspEventCounts[curEvt]++;
} }
} }