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;
|
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);
|
||||||
|
@ -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]++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user