diff --git a/include/c3d/renderbuffer.h b/include/c3d/renderbuffer.h index 74f9e50..40e6ff8 100644 --- a/include/c3d/renderbuffer.h +++ b/include/c3d/renderbuffer.h @@ -1,12 +1,12 @@ #pragma once #include "types.h" +#include "texture.h" typedef struct { - void *colorBuf, *depthBuf; - u16 colorFmt, depthFmt; - u16 width, height; + C3D_Tex colorBuf, depthBuf; u32 clearColor, clearDepth; + int depthFmt; } C3D_RenderBuf; bool C3D_RenderBufInit(C3D_RenderBuf* rb, int width, int height, int colorFmt, int depthFmt); diff --git a/source/effect.c b/source/effect.c index be39418..3489bb3 100644 --- a/source/effect.c +++ b/source/effect.c @@ -81,7 +81,7 @@ void C3Di_EffectBind(C3D_Effect* e) GPUCMD_AddWrite(GPUREG_BLEND_COLOR, e->blendClr); GPUCMD_AddWrite(GPUREG_BLEND_CONFIG, e->alphaBlend); GPUCMD_AddWrite(GPUREG_LOGICOP_CONFIG, e->clrLogicOp); - GPUCMD_AddMaskedWrite(GPUREG_BLEND_ENABLE, 2, e->fragOpMode); + GPUCMD_AddMaskedWrite(GPUREG_BLEND_ENABLE, 7, e->fragOpMode); // Disable early depth test? GPUCMD_AddMaskedWrite(GPUREG_0062, 1, 0); diff --git a/source/renderbuffer.c b/source/renderbuffer.c index 8892152..6101080 100644 --- a/source/renderbuffer.c +++ b/source/renderbuffer.c @@ -1,64 +1,76 @@ #include "context.h" +#include static const u8 colorFmtSizes[] = {2,1,0,0,0}; static const u8 depthFmtSizes[] = {0,0,1,2}; -static inline u32 calcColorBufSize(u32 width, u32 height, u32 fmt) +static inline u16 getColorBufFillFlag(int fmt) { - return width*height*(colorFmtSizes[fmt]+2); + if (fmt < 0) return 0; + return BIT(0) | ((u32)colorFmtSizes[fmt] << 8); } -static inline u32 calcDepthBufSize(u32 width, u32 height, u32 fmt) +static inline u16 getDepthBufFillFlag(int fmt) { - return width*height*(depthFmtSizes[fmt]+2); + if (fmt < 0) return 0; + return BIT(0) | ((u32)depthFmtSizes[fmt] << 8); +} + +static inline u32 getColorBufFormatReg(int fmt) +{ + return (fmt << 16) | colorFmtSizes[fmt]; +} + +static inline GPU_TEXCOLOR colorFmtFromDepthFmt(int fmt) +{ + switch (fmt) + { + case GPU_RB_DEPTH16: + return GPU_RGB565; + case GPU_RB_DEPTH24: + return GPU_RGB8; + case GPU_RB_DEPTH24_STENCIL8: + return GPU_RGBA8; + default: + return 0; + } } bool C3D_RenderBufInit(C3D_RenderBuf* rb, int width, int height, int colorFmt, int depthFmt) { - if (rb->colorBuf || rb->depthBuf) return false; + memset(rb, 0, sizeof(*rb)); - rb->colorFmt = colorFmt; rb->depthFmt = depthFmt; - rb->width = width; - rb->height = height; rb->clearColor = rb->clearDepth = 0; - if (colorFmt >= 0) - { - rb->colorBuf = vramAlloc(calcColorBufSize(width, height, colorFmt)); - if (!rb->colorBuf) return false; - } else - rb->colorFmt = GPU_RB_RGBA8; + if (colorFmt < 0) + return false; + if (!C3D_TexInitVRAM(&rb->colorBuf, width, height, colorFmt)) + return false; if (depthFmt >= 0) { - rb->depthBuf = vramAlloc(calcDepthBufSize(width, height, depthFmt)); - if (!rb->depthBuf) + if (!C3D_TexInitVRAM(&rb->depthBuf, width, height, colorFmtFromDepthFmt(depthFmt))) { - if (rb->colorBuf) - vramFree(rb->colorBuf); - rb->colorBuf = NULL; + C3D_TexDelete(&rb->colorBuf); return false; } - } else - rb->depthFmt = GPU_RB_DEPTH16; + } return true; } void C3D_RenderBufClearAsync(C3D_RenderBuf* rb) { - u32 colorBufSize = calcColorBufSize(rb->width, rb->height, rb->colorFmt); - u32 depthBufSize = calcDepthBufSize(rb->width, rb->height, rb->depthFmt); GX_MemoryFill( - (u32*)rb->colorBuf, rb->clearColor, (u32*)((u8*)rb->colorBuf+colorBufSize), BIT(0) | ((u32)colorFmtSizes[rb->colorFmt] << 8), - (u32*)rb->depthBuf, rb->clearDepth, (u32*)((u8*)rb->depthBuf+depthBufSize), BIT(0) | ((u32)depthFmtSizes[rb->depthFmt] << 8)); + (u32*)rb->colorBuf.data, rb->clearColor, (u32*)((u8*)rb->colorBuf.data+rb->colorBuf.size), getColorBufFillFlag(rb->colorBuf.fmt), + (u32*)rb->depthBuf.data, rb->clearDepth, (u32*)((u8*)rb->depthBuf.data+rb->depthBuf.size), getDepthBufFillFlag(rb->depthFmt)); } void C3D_RenderBufTransferAsync(C3D_RenderBuf* rb, u32* frameBuf, u32 flags) { - u32 dim = GX_BUFFER_DIM((u32)rb->width, (u32)rb->height); - GX_DisplayTransfer((u32*)rb->colorBuf, dim, frameBuf, dim, flags); + u32 dim = GX_BUFFER_DIM((u32)rb->colorBuf.width, (u32)rb->colorBuf.height); + GX_DisplayTransfer((u32*)rb->colorBuf.data, dim, frameBuf, dim, flags); } void C3D_RenderBufBind(C3D_RenderBuf* rb) @@ -66,7 +78,7 @@ void C3D_RenderBufBind(C3D_RenderBuf* rb) C3D_Context* ctx = C3Di_GetContext(); ctx->flags |= C3DiF_RenderBuf; ctx->rb = rb; - C3D_SetViewport(0, 0, rb->width, rb->height); + C3D_SetViewport(0, 0, rb->colorBuf.width, rb->colorBuf.height); } void C3Di_RenderBufBind(C3D_RenderBuf* rb) @@ -75,35 +87,24 @@ void C3Di_RenderBufBind(C3D_RenderBuf* rb) GPUCMD_AddWrite(GPUREG_FRAMEBUFFER_INVALIDATE, 1); - param[0] = osConvertVirtToPhys(rb->depthBuf) >> 3; - param[1] = osConvertVirtToPhys(rb->colorBuf) >> 3; - param[2] = 0x01000000 | (((u32)(rb->height-1) & 0xFFF) << 12) | (rb->width & 0xFFF); + param[0] = osConvertVirtToPhys(rb->depthBuf.data) >> 3; + param[1] = osConvertVirtToPhys(rb->colorBuf.data) >> 3; + param[2] = 0x01000000 | (((u32)(rb->colorBuf.height-1) & 0xFFF) << 12) | (rb->colorBuf.width & 0xFFF); GPUCMD_AddIncrementalWrites(GPUREG_DEPTHBUFFER_LOC, param, 3); GPUCMD_AddWrite(GPUREG_FRAMEBUFFER_DIM2, param[2]); //? - GPUCMD_AddWrite(GPUREG_DEPTHBUFFER_FORMAT, rb->depthFmt); - GPUCMD_AddWrite(GPUREG_COLORBUFFER_FORMAT, ((u32)rb->colorFmt << 16) | colorFmtSizes[rb->colorFmt]); + GPUCMD_AddWrite(GPUREG_DEPTHBUFFER_FORMAT, rb->depthFmt >= 0 ? rb->depthFmt : GPU_RB_DEPTH16); + GPUCMD_AddWrite(GPUREG_COLORBUFFER_FORMAT, getColorBufFormatReg(rb->colorBuf.fmt)); GPUCMD_AddWrite(GPUREG_FRAMEBUFFER_BLOCK32, 0x00000000); //? - // "Enable depth buffer" (?) - if (rb->colorBuf) - param[0] = param[1] = 0xF; - if (rb->depthBuf) - param[2] = param[3] = 0x2; + // Enable or disable color/depth buffers + param[0] = param[1] = rb->colorBuf.data ? 0xF : 0; + param[2] = param[3] = rb->depthBuf.data ? 0x2 : 0; GPUCMD_AddIncrementalWrites(GPUREG_COLORBUFFER_READ, param, 4); } void C3D_RenderBufDelete(C3D_RenderBuf* rb) { - if (rb->colorBuf) - { - vramFree(rb->colorBuf); - rb->colorBuf = NULL; - } - - if (rb->depthBuf) - { - vramFree(rb->depthBuf); - rb->depthBuf = NULL; - } + C3D_TexDelete(&rb->colorBuf); + C3D_TexDelete(&rb->depthBuf); }