Refactor renderbuffer code to create and use texture objects

This commit is contained in:
fincs 2015-11-28 15:53:06 +01:00
parent 209de933de
commit 912e9b152c
3 changed files with 54 additions and 53 deletions

View File

@ -1,12 +1,12 @@
#pragma once #pragma once
#include "types.h" #include "types.h"
#include "texture.h"
typedef struct typedef struct
{ {
void *colorBuf, *depthBuf; C3D_Tex colorBuf, depthBuf;
u16 colorFmt, depthFmt;
u16 width, height;
u32 clearColor, clearDepth; u32 clearColor, clearDepth;
int depthFmt;
} C3D_RenderBuf; } C3D_RenderBuf;
bool C3D_RenderBufInit(C3D_RenderBuf* rb, int width, int height, int colorFmt, int depthFmt); bool C3D_RenderBufInit(C3D_RenderBuf* rb, int width, int height, int colorFmt, int depthFmt);

View File

@ -81,7 +81,7 @@ void C3Di_EffectBind(C3D_Effect* e)
GPUCMD_AddWrite(GPUREG_BLEND_COLOR, e->blendClr); GPUCMD_AddWrite(GPUREG_BLEND_COLOR, e->blendClr);
GPUCMD_AddWrite(GPUREG_BLEND_CONFIG, e->alphaBlend); GPUCMD_AddWrite(GPUREG_BLEND_CONFIG, e->alphaBlend);
GPUCMD_AddWrite(GPUREG_LOGICOP_CONFIG, e->clrLogicOp); 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? // Disable early depth test?
GPUCMD_AddMaskedWrite(GPUREG_0062, 1, 0); GPUCMD_AddMaskedWrite(GPUREG_0062, 1, 0);

View File

@ -1,64 +1,76 @@
#include "context.h" #include "context.h"
#include <string.h>
static const u8 colorFmtSizes[] = {2,1,0,0,0}; static const u8 colorFmtSizes[] = {2,1,0,0,0};
static const u8 depthFmtSizes[] = {0,0,1,2}; 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) 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->depthFmt = depthFmt;
rb->width = width;
rb->height = height;
rb->clearColor = rb->clearDepth = 0; rb->clearColor = rb->clearDepth = 0;
if (colorFmt >= 0) if (colorFmt < 0)
{ return false;
rb->colorBuf = vramAlloc(calcColorBufSize(width, height, colorFmt)); if (!C3D_TexInitVRAM(&rb->colorBuf, width, height, colorFmt))
if (!rb->colorBuf) return false; return false;
} else
rb->colorFmt = GPU_RB_RGBA8;
if (depthFmt >= 0) if (depthFmt >= 0)
{ {
rb->depthBuf = vramAlloc(calcDepthBufSize(width, height, depthFmt)); if (!C3D_TexInitVRAM(&rb->depthBuf, width, height, colorFmtFromDepthFmt(depthFmt)))
if (!rb->depthBuf)
{ {
if (rb->colorBuf) C3D_TexDelete(&rb->colorBuf);
vramFree(rb->colorBuf);
rb->colorBuf = NULL;
return false; return false;
} }
} else }
rb->depthFmt = GPU_RB_DEPTH16;
return true; return true;
} }
void C3D_RenderBufClearAsync(C3D_RenderBuf* rb) 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( GX_MemoryFill(
(u32*)rb->colorBuf, rb->clearColor, (u32*)((u8*)rb->colorBuf+colorBufSize), BIT(0) | ((u32)colorFmtSizes[rb->colorFmt] << 8), (u32*)rb->colorBuf.data, rb->clearColor, (u32*)((u8*)rb->colorBuf.data+rb->colorBuf.size), getColorBufFillFlag(rb->colorBuf.fmt),
(u32*)rb->depthBuf, rb->clearDepth, (u32*)((u8*)rb->depthBuf+depthBufSize), BIT(0) | ((u32)depthFmtSizes[rb->depthFmt] << 8)); (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) void C3D_RenderBufTransferAsync(C3D_RenderBuf* rb, u32* frameBuf, u32 flags)
{ {
u32 dim = GX_BUFFER_DIM((u32)rb->width, (u32)rb->height); u32 dim = GX_BUFFER_DIM((u32)rb->colorBuf.width, (u32)rb->colorBuf.height);
GX_DisplayTransfer((u32*)rb->colorBuf, dim, frameBuf, dim, flags); GX_DisplayTransfer((u32*)rb->colorBuf.data, dim, frameBuf, dim, flags);
} }
void C3D_RenderBufBind(C3D_RenderBuf* rb) void C3D_RenderBufBind(C3D_RenderBuf* rb)
@ -66,7 +78,7 @@ void C3D_RenderBufBind(C3D_RenderBuf* rb)
C3D_Context* ctx = C3Di_GetContext(); C3D_Context* ctx = C3Di_GetContext();
ctx->flags |= C3DiF_RenderBuf; ctx->flags |= C3DiF_RenderBuf;
ctx->rb = rb; 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) void C3Di_RenderBufBind(C3D_RenderBuf* rb)
@ -75,35 +87,24 @@ void C3Di_RenderBufBind(C3D_RenderBuf* rb)
GPUCMD_AddWrite(GPUREG_FRAMEBUFFER_INVALIDATE, 1); GPUCMD_AddWrite(GPUREG_FRAMEBUFFER_INVALIDATE, 1);
param[0] = osConvertVirtToPhys(rb->depthBuf) >> 3; param[0] = osConvertVirtToPhys(rb->depthBuf.data) >> 3;
param[1] = osConvertVirtToPhys(rb->colorBuf) >> 3; param[1] = osConvertVirtToPhys(rb->colorBuf.data) >> 3;
param[2] = 0x01000000 | (((u32)(rb->height-1) & 0xFFF) << 12) | (rb->width & 0xFFF); param[2] = 0x01000000 | (((u32)(rb->colorBuf.height-1) & 0xFFF) << 12) | (rb->colorBuf.width & 0xFFF);
GPUCMD_AddIncrementalWrites(GPUREG_DEPTHBUFFER_LOC, param, 3); GPUCMD_AddIncrementalWrites(GPUREG_DEPTHBUFFER_LOC, param, 3);
GPUCMD_AddWrite(GPUREG_FRAMEBUFFER_DIM2, param[2]); //? GPUCMD_AddWrite(GPUREG_FRAMEBUFFER_DIM2, param[2]); //?
GPUCMD_AddWrite(GPUREG_DEPTHBUFFER_FORMAT, rb->depthFmt); GPUCMD_AddWrite(GPUREG_DEPTHBUFFER_FORMAT, rb->depthFmt >= 0 ? rb->depthFmt : GPU_RB_DEPTH16);
GPUCMD_AddWrite(GPUREG_COLORBUFFER_FORMAT, ((u32)rb->colorFmt << 16) | colorFmtSizes[rb->colorFmt]); GPUCMD_AddWrite(GPUREG_COLORBUFFER_FORMAT, getColorBufFormatReg(rb->colorBuf.fmt));
GPUCMD_AddWrite(GPUREG_FRAMEBUFFER_BLOCK32, 0x00000000); //? GPUCMD_AddWrite(GPUREG_FRAMEBUFFER_BLOCK32, 0x00000000); //?
// "Enable depth buffer" (?) // Enable or disable color/depth buffers
if (rb->colorBuf) param[0] = param[1] = rb->colorBuf.data ? 0xF : 0;
param[0] = param[1] = 0xF; param[2] = param[3] = rb->depthBuf.data ? 0x2 : 0;
if (rb->depthBuf)
param[2] = param[3] = 0x2;
GPUCMD_AddIncrementalWrites(GPUREG_COLORBUFFER_READ, param, 4); GPUCMD_AddIncrementalWrites(GPUREG_COLORBUFFER_READ, param, 4);
} }
void C3D_RenderBufDelete(C3D_RenderBuf* rb) void C3D_RenderBufDelete(C3D_RenderBuf* rb)
{ {
if (rb->colorBuf) C3D_TexDelete(&rb->colorBuf);
{ C3D_TexDelete(&rb->depthBuf);
vramFree(rb->colorBuf);
rb->colorBuf = NULL;
}
if (rb->depthBuf)
{
vramFree(rb->depthBuf);
rb->depthBuf = NULL;
}
} }