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;
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);

View File

@ -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]++;
}
}