3DS: Avoid clearing bottom screen for a little better performance, and don't pointlessly allocate a depth buffer for it

This commit is contained in:
UnknownShadow200 2024-07-16 18:06:28 +10:00
parent f32af27f1b
commit 1f0b1d33e2
2 changed files with 32 additions and 23 deletions

View File

@ -149,12 +149,15 @@ static void InitCitro3D(void) {
C3D_Init(C3D_DEFAULT_CMDBUF_SIZE * 4); C3D_Init(C3D_DEFAULT_CMDBUF_SIZE * 4);
aptHook(&hookCookie, AptEventHook, NULL); 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); 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 // 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. // 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); C3D_RenderTargetSetOutput(&bottomTarget, GFX_BOTTOM, GFX_LEFT, DISPLAY_TRANSFER_FLAGS);
gfxSetDoubleBuffering(GFX_TOP, true); gfxSetDoubleBuffering(GFX_TOP, true);
@ -237,7 +240,9 @@ void Gfx_Set3DRight(struct Matrix* proj, struct Matrix* view) {
Calc3DProjection(+1, proj); Calc3DProjection(+1, proj);
if (!createdTopTargetRight) { 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); C3D_RenderTargetSetOutput(&topTargetRight, GFX_TOP, GFX_RIGHT, DISPLAY_TRANSFER_FLAGS);
createdTopTargetRight = true; createdTopTargetRight = true;
} }
@ -569,7 +574,6 @@ void Gfx_ClearBuffers(GfxBuffers buffers) {
if (buffers & GFX_BUFFER_DEPTH) targets |= C3D_CLEAR_DEPTH; if (buffers & GFX_BUFFER_DEPTH) targets |= C3D_CLEAR_DEPTH;
C3D_RenderTargetClear(&topTargetLeft, targets, clear_color, 0); C3D_RenderTargetClear(&topTargetLeft, targets, clear_color, 0);
C3D_RenderTargetClear(&bottomTarget, targets, 0, 0);
} }
void Gfx_EndFrame(void) { void Gfx_EndFrame(void) {

43
third_party/citro3d.c vendored
View File

@ -332,7 +332,6 @@ static bool C3D_FrameDrawOn(C3D_RenderTarget* target);
static void C3D_FrameSplit(u8 flags); static void C3D_FrameSplit(u8 flags);
static void C3D_FrameEnd(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_RenderTargetDelete(C3D_RenderTarget* target);
static void C3D_RenderTargetSetOutput(C3D_RenderTarget* target, gfxScreen_t screen, gfx3dSide_t side, u32 transferFlags); 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); 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)); 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_FrameBuf* fb = &target->frameBuf;
C3D_FrameBufAttrib(fb, width, height, false); C3D_FrameBufAttrib(fb, width, height, false);
C3D_FrameBufColor(fb, colorBuf, colorFmt); }
C3D_FrameBufDepth(fb, depthBuf, depthFmt);
return;
_fail: static void C3D_RenderTargetColor(C3D_RenderTarget* target, GPU_COLORBUF colorFmt)
if (depthBuf) vramFree(depthBuf); {
if (colorBuf) vramFree(colorBuf); 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) static void C3Di_RenderTargetDestroy(C3D_RenderTarget* target)