From 1f0b1d33e2c2171ca2642bef9f0d2421c194bb46 Mon Sep 17 00:00:00 2001 From: UnknownShadow200 Date: Tue, 16 Jul 2024 18:06:28 +1000 Subject: [PATCH] 3DS: Avoid clearing bottom screen for a little better performance, and don't pointlessly allocate a depth buffer for it --- src/Graphics_3DS.c | 12 ++++++++---- third_party/citro3d.c | 43 ++++++++++++++++++++++++------------------- 2 files changed, 32 insertions(+), 23 deletions(-) diff --git a/src/Graphics_3DS.c b/src/Graphics_3DS.c index 99f1d0dc6..45cf4c1e5 100644 --- a/src/Graphics_3DS.c +++ b/src/Graphics_3DS.c @@ -149,12 +149,15 @@ static void InitCitro3D(void) { C3D_Init(C3D_DEFAULT_CMDBUF_SIZE * 4); aptHook(&hookCookie, AptEventHook, NULL); - C3D_RenderTargetCreate(&topTargetLeft, 240, 400, GPU_RB_RGBA8, GPU_RB_DEPTH24); + C3D_RenderTargetInit(&topTargetLeft, 240, 400); + C3D_RenderTargetColor(&topTargetLeft, GPU_RB_RGBA8); + C3D_RenderTargetDepth(&topTargetLeft, GPU_RB_DEPTH24); C3D_RenderTargetSetOutput(&topTargetLeft, GFX_TOP, GFX_LEFT, DISPLAY_TRANSFER_FLAGS); // Even though the bottom screen is 320 pixels wide, we use 400 here so that the same ortho matrix // can be used for both screens. The output is clipped to the actual screen width, anyway. - C3D_RenderTargetCreate(&bottomTarget, 240, 400, GPU_RB_RGBA8, GPU_RB_DEPTH24); + C3D_RenderTargetInit(&bottomTarget, 240, 400); + C3D_RenderTargetColor(&bottomTarget, GPU_RB_RGBA8); C3D_RenderTargetSetOutput(&bottomTarget, GFX_BOTTOM, GFX_LEFT, DISPLAY_TRANSFER_FLAGS); gfxSetDoubleBuffering(GFX_TOP, true); @@ -237,7 +240,9 @@ void Gfx_Set3DRight(struct Matrix* proj, struct Matrix* view) { Calc3DProjection(+1, proj); if (!createdTopTargetRight) { - C3D_RenderTargetCreate(&topTargetRight, 240, 400, GPU_RB_RGBA8, GPU_RB_DEPTH24); + C3D_RenderTargetInit(&topTargetRight, 240, 400); + C3D_RenderTargetColor(&topTargetRight, GPU_RB_RGBA8); + C3D_RenderTargetDepth(&topTargetRight, GPU_RB_DEPTH24); C3D_RenderTargetSetOutput(&topTargetRight, GFX_TOP, GFX_RIGHT, DISPLAY_TRANSFER_FLAGS); createdTopTargetRight = true; } @@ -569,7 +574,6 @@ void Gfx_ClearBuffers(GfxBuffers buffers) { if (buffers & GFX_BUFFER_DEPTH) targets |= C3D_CLEAR_DEPTH; C3D_RenderTargetClear(&topTargetLeft, targets, clear_color, 0); - C3D_RenderTargetClear(&bottomTarget, targets, 0, 0); } void Gfx_EndFrame(void) { diff --git a/third_party/citro3d.c b/third_party/citro3d.c index 6ff2908bc..d747dc83e 100644 --- a/third_party/citro3d.c +++ b/third_party/citro3d.c @@ -332,7 +332,6 @@ static bool C3D_FrameDrawOn(C3D_RenderTarget* target); static void C3D_FrameSplit(u8 flags); static void C3D_FrameEnd(u8 flags); -static void C3D_RenderTargetCreate(C3D_RenderTarget* target, int width, int height, GPU_COLORBUF colorFmt, GPU_DEPTHBUF depthFmt); static void C3D_RenderTargetDelete(C3D_RenderTarget* target); static void C3D_RenderTargetSetOutput(C3D_RenderTarget* target, gfxScreen_t screen, gfx3dSide_t side, u32 transferFlags); @@ -1143,30 +1142,36 @@ static void C3D_FrameEnd(u8 flags) gxCmdQueueRun(&ctx->gxQueue); } -void C3D_RenderTargetCreate(C3D_RenderTarget* target, int width, int height, GPU_COLORBUF colorFmt, GPU_DEPTHBUF depthFmt) +static void C3D_RenderTargetInit(C3D_RenderTarget* target, int width, int height) { - size_t colorSize = C3D_CalcColorBufSize(width,height,colorFmt); - size_t depthSize = C3D_CalcDepthBufSize(width,height,depthFmt); memset(target, 0, sizeof(C3D_RenderTarget)); - void* depthBuf = NULL; - void* colorBuf = vramAlloc(colorSize); - if (!colorBuf) goto _fail; - - vramAllocPos vramBank = addrGetVRAMBank(colorBuf); - depthBuf = vramAllocAt(depthSize, vramBank ^ VRAM_ALLOC_ANY); // Attempt opposite bank first... - if (!depthBuf) depthBuf = vramAllocAt(depthSize, vramBank); // ... if that fails, attempt same bank - if (!depthBuf) goto _fail; - C3D_FrameBuf* fb = &target->frameBuf; C3D_FrameBufAttrib(fb, width, height, false); - C3D_FrameBufColor(fb, colorBuf, colorFmt); - C3D_FrameBufDepth(fb, depthBuf, depthFmt); - return; +} -_fail: - if (depthBuf) vramFree(depthBuf); - if (colorBuf) vramFree(colorBuf); +static void C3D_RenderTargetColor(C3D_RenderTarget* target, GPU_COLORBUF colorFmt) +{ + C3D_FrameBuf* fb = &target->frameBuf; + size_t colorSize = C3D_CalcColorBufSize(fb->width, fb->height, colorFmt); + void* colorBuf = vramAlloc(colorSize); + + if (!colorBuf) return; + C3D_FrameBufColor(fb, colorBuf, colorFmt); +} + +static void C3D_RenderTargetDepth(C3D_RenderTarget* target, GPU_DEPTHBUF depthFmt) +{ + C3D_FrameBuf* fb = &target->frameBuf; + size_t depthSize = C3D_CalcDepthBufSize(fb->width, fb->height, depthFmt); + void* depthBuf = NULL; + + vramAllocPos vramBank = addrGetVRAMBank(fb->colorBuf); + depthBuf = vramAllocAt(depthSize, vramBank ^ VRAM_ALLOC_ANY); // Attempt opposite bank first... + if (!depthBuf) depthBuf = vramAllocAt(depthSize, vramBank); // ... if that fails, attempt same bank + if (!depthBuf) return; + + C3D_FrameBufDepth(fb, depthBuf, depthFmt); } static void C3Di_RenderTargetDestroy(C3D_RenderTarget* target)