diff --git a/source/base.c b/source/base.c index 24830be..71fc56c 100644 --- a/source/base.c +++ b/source/base.c @@ -8,14 +8,6 @@ C3D_Context __C3D_Context; static aptHookCookie hookCookie; -__attribute__((weak)) void C3Di_RenderQueueWaitDone(void) -{ -} - -__attribute__((weak)) void C3Di_RenderQueueExit(void) -{ -} - __attribute__((weak)) void C3Di_LightEnvUpdate(C3D_LightEnv* env) { (void)env; @@ -102,10 +94,6 @@ bool C3D_Init(size_t cmdBufSize) return false; } - GPUCMD_SetBuffer(ctx->cmdBuf, ctx->cmdBufSize, 0); - GX_BindQueue(&ctx->gxQueue); - gxCmdQueueRun(&ctx->gxQueue); - ctx->flags = C3DiF_Active | C3DiF_TexEnvBuf | C3DiF_TexEnvAll | C3DiF_Effect | C3DiF_TexStatus | C3DiF_TexAll; // TODO: replace with direct struct access @@ -137,6 +125,7 @@ bool C3D_Init(size_t cmdBufSize) ctx->fixedAttribDirty = 0; ctx->fixedAttribEverDirty = 0; + C3Di_RenderQueueInit(); aptHook(&hookCookie, C3Di_AptEventHook, NULL); return true; @@ -348,11 +337,8 @@ void C3D_Fini(void) if (!(ctx->flags & C3DiF_Active)) return; - C3Di_RenderQueueExit(); aptUnhook(&hookCookie); - gxCmdQueueStop(&ctx->gxQueue); - gxCmdQueueWait(&ctx->gxQueue, -1); - GX_BindQueue(NULL); + C3Di_RenderQueueExit(); free(ctx->gxQueue.entries); linearFree(ctx->cmdBuf); ctx->flags = 0; diff --git a/source/internal.h b/source/internal.h index 25b4be6..ff70a24 100644 --- a/source/internal.h +++ b/source/internal.h @@ -140,3 +140,7 @@ void C3Di_LoadShaderUniforms(shaderInstance_s* si); void C3Di_ClearShaderUniforms(GPU_SHADER_TYPE type); bool C3Di_SplitFrame(u32** pBuf, u32* pSize); + +void C3Di_RenderQueueInit(void); +void C3Di_RenderQueueExit(void); +void C3Di_RenderQueueWaitDone(void); diff --git a/source/renderqueue.c b/source/renderqueue.c index 89a6234..0905d51 100644 --- a/source/renderqueue.c +++ b/source/renderqueue.c @@ -8,7 +8,6 @@ static C3D_RenderTarget *linkedTarget[3]; static TickCounter gpuTime, cpuTime; -static bool initialized; static bool inFrame, inSafeTransfer, measureGpuTime; static bool needSwapTop, needSwapBot; static float framerate = 60.0f; @@ -17,6 +16,8 @@ static u32 frameCounter[2]; static void (* frameEndCb)(void*); static void* frameEndCbData; +static void C3Di_RenderTargetDestroy(C3D_RenderTarget* target); + static bool framerateLimit(int id) { framerateCounter[id] -= framerate; @@ -98,63 +99,45 @@ static bool C3Di_WaitAndClearQueue(s64 timeout) return true; } -static void C3Di_RenderQueueInit(void) +void C3Di_RenderQueueInit(void) { + C3D_Context* ctx = C3Di_GetContext(); + gspSetEventCallback(GSPGPU_EVENT_VBlank0, onVBlank0, NULL, false); gspSetEventCallback(GSPGPU_EVENT_VBlank1, onVBlank1, NULL, false); - gxCmdQueueSetCallback(&C3Di_GetContext()->gxQueue, onQueueFinish, NULL); -} -static void C3Di_RenderTargetDestroy(C3D_RenderTarget* target); + GX_BindQueue(&ctx->gxQueue); + gxCmdQueueSetCallback(&ctx->gxQueue, onQueueFinish, NULL); + gxCmdQueueRun(&ctx->gxQueue); +} void C3Di_RenderQueueExit(void) { int i; C3D_RenderTarget *a, *next; - if (!initialized) - return; - C3Di_WaitAndClearQueue(-1); + gxCmdQueueSetCallback(&C3Di_GetContext()->gxQueue, NULL, NULL); + GX_BindQueue(NULL); + + gspSetEventCallback(GSPGPU_EVENT_VBlank0, NULL, NULL, false); + gspSetEventCallback(GSPGPU_EVENT_VBlank1, NULL, NULL, false); + + for (i = 0; i < 3; i ++) + linkedTarget[i] = NULL; + for (a = firstTarget; a; a = next) { next = a->next; C3Di_RenderTargetDestroy(a); } - - gspSetEventCallback(GSPGPU_EVENT_VBlank0, NULL, NULL, false); - gspSetEventCallback(GSPGPU_EVENT_VBlank1, NULL, NULL, false); - gxCmdQueueSetCallback(&C3Di_GetContext()->gxQueue, NULL, NULL); - - for (i = 0; i < 3; i ++) - linkedTarget[i] = NULL; - - initialized = false; } void C3Di_RenderQueueWaitDone(void) { - if (!initialized) - return; C3Di_WaitAndClearQueue(-1); } -static bool checkRenderQueueInit(void) -{ - C3D_Context* ctx = C3Di_GetContext(); - - if (!(ctx->flags & C3DiF_Active)) - return false; - - if (!initialized) - { - C3Di_RenderQueueInit(); - initialized = true; - } - - return true; -} - float C3D_FrameRate(float fps) { float old = framerate; @@ -169,13 +152,17 @@ float C3D_FrameRate(float fps) bool C3D_FrameBegin(u8 flags) { + C3D_Context* ctx = C3Di_GetContext(); if (inFrame) return false; + if (flags & C3D_FRAME_SYNCDRAW) C3D_FrameSync(); if (!C3Di_WaitAndClearQueue((flags & C3D_FRAME_NONBLOCK) ? 0 : -1)) return false; + inFrame = true; osTickCounterStart(&cpuTime); + GPUCMD_SetBuffer(ctx->cmdBuf, ctx->cmdBufSize, 0); return true; } @@ -200,13 +187,15 @@ void C3D_FrameSplit(u8 flags) void C3D_FrameEnd(u8 flags) { C3D_Context* ctx = C3Di_GetContext(); + if (!inFrame) return; if (frameEndCb) frameEndCb(frameEndCbData); C3D_FrameSplit(flags); - inFrame = false; + GPUCMD_SetBuffer(NULL, 0, 0); osTickCounterUpdate(&cpuTime); + inFrame = false; // Flush the entire linear memory if the user did not explicitly mandate to flush the command list if (!(flags & GX_CMDLIST_FLUSH)) @@ -231,7 +220,6 @@ void C3D_FrameEnd(u8 flags) needSwapBot = true; } - GPUCMD_SetBuffer(ctx->cmdBuf, ctx->cmdBufSize, 0); measureGpuTime = true; osTickCounterStart(&gpuTime); gxCmdQueueRun(&ctx->gxQueue); @@ -274,8 +262,6 @@ static void C3Di_RenderTargetFinishInit(C3D_RenderTarget* target) C3D_RenderTarget* C3D_RenderTargetCreate(int width, int height, GPU_COLORBUF colorFmt, C3D_DEPTHTYPE depthFmt) { - if (!checkRenderQueueInit()) goto _fail0; - GPU_DEPTHBUF depthFmtReal = GPU_RB_DEPTH16; void* depthBuf = NULL; void* colorBuf = vramAlloc(C3D_CalcColorBufSize(width,height,colorFmt)); @@ -312,8 +298,6 @@ _fail0: C3D_RenderTarget* C3D_RenderTargetCreateFromTex(C3D_Tex* tex, GPU_TEXFACE face, int level, C3D_DEPTHTYPE depthFmt) { - if (!checkRenderQueueInit()) return NULL; - C3D_RenderTarget* target = C3Di_RenderTargetNew(); if (!target) return NULL;