Introduce framebuffer (light renderbuffer) infrastructure
This commit is contained in:
parent
15de0e300e
commit
5c1d037fa2
56
include/c3d/framebuffer.h
Normal file
56
include/c3d/framebuffer.h
Normal file
@ -0,0 +1,56 @@
|
||||
#pragma once
|
||||
#include "texture.h"
|
||||
|
||||
typedef struct
|
||||
{
|
||||
void* colorBuf;
|
||||
void* depthBuf;
|
||||
u16 width;
|
||||
u16 height;
|
||||
GPU_COLORBUF colorFmt;
|
||||
GPU_DEPTHBUF depthFmt;
|
||||
bool block32;
|
||||
u8 colorMask : 4;
|
||||
u8 depthMask : 4;
|
||||
} C3D_FrameBuf;
|
||||
|
||||
C3D_FrameBuf* C3D_GetFrameBuf(void);
|
||||
void C3D_SetFrameBuf(C3D_FrameBuf* fb);
|
||||
void C3D_FrameBufTex(C3D_FrameBuf* fb, C3D_Tex* tex, GPU_TEXFACE face, int level);
|
||||
|
||||
static inline void C3D_FrameBufAttrib(C3D_FrameBuf* fb, u16 width, u16 height, bool block32)
|
||||
{
|
||||
fb->width = width;
|
||||
fb->height = height;
|
||||
fb->block32 = block32;
|
||||
}
|
||||
|
||||
static inline void C3D_FrameBufColor(C3D_FrameBuf* fb, void* buf, GPU_COLORBUF fmt)
|
||||
{
|
||||
if (buf)
|
||||
{
|
||||
fb->colorBuf = buf;
|
||||
fb->colorFmt = fmt;
|
||||
fb->colorMask = 0xF;
|
||||
} else
|
||||
{
|
||||
fb->colorBuf = NULL;
|
||||
fb->colorFmt = GPU_RB_RGBA8;
|
||||
fb->colorMask = 0;
|
||||
}
|
||||
}
|
||||
|
||||
static inline void C3D_FrameBufDepth(C3D_FrameBuf* fb, void* buf, GPU_DEPTHBUF fmt)
|
||||
{
|
||||
if (buf)
|
||||
{
|
||||
fb->depthBuf = buf;
|
||||
fb->depthFmt = fmt;
|
||||
fb->depthMask = fmt == GPU_RB_DEPTH24_STENCIL8 ? 0x3 : 0x2;
|
||||
} else
|
||||
{
|
||||
fb->depthBuf = NULL;
|
||||
fb->depthFmt = GPU_RB_DEPTH24;
|
||||
fb->depthMask = 0;
|
||||
}
|
||||
}
|
@ -24,6 +24,7 @@ extern "C" {
|
||||
#include "c3d/light.h"
|
||||
#include "c3d/lightlut.h"
|
||||
|
||||
#include "c3d/framebuffer.h"
|
||||
#include "c3d/renderbuffer.h"
|
||||
#include "c3d/renderqueue.h"
|
||||
|
||||
|
@ -21,7 +21,7 @@ static void C3Di_AptEventHook(APT_HookType hookType, C3D_UNUSED void* param)
|
||||
}
|
||||
case APTHOOK_ONRESTORE:
|
||||
{
|
||||
ctx->flags |= C3DiF_AttrInfo | C3DiF_BufInfo | C3DiF_Effect | C3DiF_RenderBuf
|
||||
ctx->flags |= C3DiF_AttrInfo | C3DiF_BufInfo | C3DiF_Effect | C3DiF_FrameBuf
|
||||
| C3DiF_Viewport | C3DiF_Scissor | C3DiF_Program | C3DiF_VshCode | C3DiF_GshCode
|
||||
| C3DiF_TexAll | C3DiF_TexEnvBuf | C3DiF_TexEnvAll | C3DiF_LightEnv;
|
||||
|
||||
@ -55,7 +55,7 @@ bool C3D_Init(size_t cmdBufSize)
|
||||
|
||||
GPUCMD_SetBuffer(ctx->cmdBuf, ctx->cmdBufSize, 0);
|
||||
|
||||
ctx->flags = C3DiF_Active | C3DiF_TexEnvBuf | C3DiF_TexEnvAll | C3DiF_Effect | C3DiF_TexAll;
|
||||
ctx->flags = C3DiF_Active | C3DiF_TexEnvBuf | C3DiF_TexEnvAll | C3DiF_Effect | C3DiF_TexStatus | C3DiF_TexAll;
|
||||
ctx->renderQueueExit = NULL;
|
||||
|
||||
// TODO: replace with direct struct access
|
||||
@ -120,16 +120,16 @@ void C3Di_UpdateContext(void)
|
||||
ctx->flags &= ~(C3DiF_Program | C3DiF_VshCode | C3DiF_GshCode);
|
||||
}
|
||||
|
||||
if (ctx->flags & C3DiF_RenderBuf)
|
||||
if (ctx->flags & C3DiF_FrameBuf)
|
||||
{
|
||||
ctx->flags &= ~C3DiF_RenderBuf;
|
||||
ctx->flags &= ~C3DiF_FrameBuf;
|
||||
if (ctx->flags & C3DiF_DrawUsed)
|
||||
{
|
||||
ctx->flags &= ~C3DiF_DrawUsed;
|
||||
GPUCMD_AddWrite(GPUREG_FRAMEBUFFER_FLUSH, 1);
|
||||
GPUCMD_AddWrite(GPUREG_EARLYDEPTH_CLEAR, 1);
|
||||
}
|
||||
C3Di_RenderBufBind(ctx->rb);
|
||||
C3Di_FrameBufBind(&ctx->fb);
|
||||
}
|
||||
|
||||
if (ctx->flags & C3DiF_Viewport)
|
||||
|
55
source/framebuffer.c
Normal file
55
source/framebuffer.c
Normal file
@ -0,0 +1,55 @@
|
||||
#include "internal.h"
|
||||
|
||||
C3D_FrameBuf* C3D_GetFrameBuf(void)
|
||||
{
|
||||
C3D_Context* ctx = C3Di_GetContext();
|
||||
|
||||
if (!(ctx->flags & C3DiF_Active))
|
||||
return NULL;
|
||||
|
||||
ctx->flags |= C3DiF_FrameBuf;
|
||||
return &ctx->fb;
|
||||
}
|
||||
|
||||
void C3D_SetFrameBuf(C3D_FrameBuf* fb)
|
||||
{
|
||||
C3D_Context* ctx = C3Di_GetContext();
|
||||
|
||||
if (!(ctx->flags & C3DiF_Active))
|
||||
return;
|
||||
|
||||
if (fb != &ctx->fb)
|
||||
memcpy(&ctx->fb, fb, sizeof(*fb));
|
||||
ctx->flags |= C3DiF_FrameBuf;
|
||||
}
|
||||
|
||||
void C3D_FrameBufTex(C3D_FrameBuf* fb, C3D_Tex* tex, GPU_TEXFACE face, int level)
|
||||
{
|
||||
C3D_FrameBufAttrib(fb, tex->width, tex->height, false);
|
||||
C3D_FrameBufColor(fb, C3D_TexGetImagePtr(tex,
|
||||
C3Di_TexIs2D(tex) ? tex->data : tex->cube->data[face], level, NULL),
|
||||
(GPU_COLORBUF)tex->fmt);
|
||||
}
|
||||
|
||||
void C3Di_FrameBufBind(C3D_FrameBuf* fb)
|
||||
{
|
||||
static const u8 colorFmtSizes[] = {2,1,0,0,0};
|
||||
u32 param[4] = { 0, 0, 0, 0 };
|
||||
|
||||
GPUCMD_AddWrite(GPUREG_FRAMEBUFFER_INVALIDATE, 1);
|
||||
|
||||
param[0] = osConvertVirtToPhys(fb->depthBuf) >> 3;
|
||||
param[1] = osConvertVirtToPhys(fb->colorBuf) >> 3;
|
||||
param[2] = 0x01000000 | (((u32)(fb->height-1) & 0xFFF) << 12) | (fb->width & 0xFFF);
|
||||
GPUCMD_AddIncrementalWrites(GPUREG_DEPTHBUFFER_LOC, param, 3);
|
||||
|
||||
GPUCMD_AddWrite(GPUREG_RENDERBUF_DIM, param[2]);
|
||||
GPUCMD_AddWrite(GPUREG_DEPTHBUFFER_FORMAT, fb->depthFmt);
|
||||
GPUCMD_AddWrite(GPUREG_COLORBUFFER_FORMAT, colorFmtSizes[fb->colorFmt] | ((u32)fb->colorFmt << 16));
|
||||
GPUCMD_AddWrite(GPUREG_FRAMEBUFFER_BLOCK32, fb->block32 ? 1 : 0);
|
||||
|
||||
// Enable or disable color/depth buffers
|
||||
param[0] = param[1] = fb->colorBuf ? fb->colorMask : 0;
|
||||
param[2] = param[3] = fb->depthBuf ? fb->depthMask : 0;
|
||||
GPUCMD_AddIncrementalWrites(GPUREG_COLORBUFFER_READ, param, 4);
|
||||
}
|
@ -2,7 +2,7 @@
|
||||
#include <c3d/attribs.h>
|
||||
#include <c3d/buffers.h>
|
||||
#include <c3d/light.h>
|
||||
#include <c3d/renderbuffer.h>
|
||||
#include <c3d/framebuffer.h>
|
||||
#include <c3d/texenv.h>
|
||||
|
||||
#define C3D_UNUSED __attribute__((unused))
|
||||
@ -43,7 +43,7 @@ typedef struct
|
||||
|
||||
u32 texEnvBuf, texEnvBufClr;
|
||||
|
||||
C3D_RenderBuf* rb;
|
||||
C3D_FrameBuf fb;
|
||||
u32 viewport[5];
|
||||
u32 scissor[3];
|
||||
|
||||
@ -62,7 +62,7 @@ enum
|
||||
C3DiF_AttrInfo = BIT(2),
|
||||
C3DiF_BufInfo = BIT(3),
|
||||
C3DiF_Effect = BIT(4),
|
||||
C3DiF_RenderBuf = BIT(5),
|
||||
C3DiF_FrameBuf = BIT(5),
|
||||
C3DiF_Viewport = BIT(6),
|
||||
C3DiF_Scissor = BIT(7),
|
||||
C3DiF_Program = BIT(8),
|
||||
@ -84,13 +84,23 @@ static inline C3D_Context* C3Di_GetContext(void)
|
||||
return &__C3D_Context;
|
||||
}
|
||||
|
||||
static inline bool typeIsCube(GPU_TEXTURE_MODE_PARAM type)
|
||||
{
|
||||
return type == GPU_TEX_CUBE_MAP || type == GPU_TEX_SHADOW_CUBE;
|
||||
}
|
||||
|
||||
static inline bool C3Di_TexIs2D(C3D_Tex* tex)
|
||||
{
|
||||
return !typeIsCube(C3D_TexGetType(tex));
|
||||
}
|
||||
|
||||
void C3Di_UpdateContext(void);
|
||||
void C3Di_AttrInfoBind(C3D_AttrInfo* info);
|
||||
void C3Di_BufInfoBind(C3D_BufInfo* info);
|
||||
void C3Di_FrameBufBind(C3D_FrameBuf* fb);
|
||||
void C3Di_TexEnvBind(int id, C3D_TexEnv* env);
|
||||
void C3Di_SetTex(GPU_TEXUNIT unit, C3D_Tex* tex);
|
||||
void C3Di_EffectBind(C3D_Effect* effect);
|
||||
void C3Di_RenderBufBind(C3D_RenderBuf* rb);
|
||||
|
||||
void C3Di_LightMtlBlend(C3D_Light* light);
|
||||
|
||||
|
@ -1,5 +1,6 @@
|
||||
#include "internal.h"
|
||||
#include <c3d/base.h>
|
||||
#include <c3d/renderbuffer.h>
|
||||
|
||||
static const u8 colorFmtSizes[] = {2,1,0,0,0};
|
||||
static const u8 depthFmtSizes[] = {0,0,1,2};
|
||||
@ -16,11 +17,6 @@ static inline u16 getDepthBufFillFlag(int fmt)
|
||||
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)
|
||||
@ -76,33 +72,20 @@ void C3D_RenderBufTransferAsync(C3D_RenderBuf* rb, u32* frameBuf, u32 flags)
|
||||
void C3D_RenderBufBind(C3D_RenderBuf* rb)
|
||||
{
|
||||
C3D_Context* ctx = C3Di_GetContext();
|
||||
ctx->flags |= C3DiF_RenderBuf;
|
||||
ctx->rb = rb;
|
||||
C3D_FrameBuf* fb = &ctx->fb;
|
||||
ctx->flags |= C3DiF_FrameBuf;
|
||||
fb->colorBuf = rb->colorBuf.data;
|
||||
fb->depthBuf = rb->depthBuf.data;
|
||||
fb->width = rb->colorBuf.width;
|
||||
fb->height = rb->colorBuf.height;
|
||||
fb->colorFmt = (GPU_COLORBUF)rb->colorBuf.fmt;
|
||||
fb->depthFmt = rb->depthFmt >= 0 ? (GPU_DEPTHBUF)rb->depthFmt : GPU_RB_DEPTH16;
|
||||
fb->block32 = false;
|
||||
fb->colorMask = 0xF;
|
||||
fb->depthMask = 0x2;
|
||||
C3D_SetViewport(0, 0, rb->colorBuf.width, rb->colorBuf.height);
|
||||
}
|
||||
|
||||
void C3Di_RenderBufBind(C3D_RenderBuf* rb)
|
||||
{
|
||||
u32 param[4] = { 0, 0, 0, 0 };
|
||||
|
||||
GPUCMD_AddWrite(GPUREG_FRAMEBUFFER_INVALIDATE, 1);
|
||||
|
||||
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_RENDERBUF_DIM, param[2]);
|
||||
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 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)
|
||||
{
|
||||
C3D_TexDelete(&rb->colorBuf);
|
||||
|
@ -30,16 +30,6 @@ static inline size_t fmtSize(GPU_TEXCOLOR fmt)
|
||||
}
|
||||
}
|
||||
|
||||
static inline bool typeIsCube(GPU_TEXTURE_MODE_PARAM type)
|
||||
{
|
||||
return type == GPU_TEX_CUBE_MAP || type == GPU_TEX_SHADOW_CUBE;
|
||||
}
|
||||
|
||||
static inline bool C3Di_TexIs2D(C3D_Tex* tex)
|
||||
{
|
||||
return !typeIsCube(C3D_TexGetType(tex));
|
||||
}
|
||||
|
||||
static inline bool addrIsVRAM(const void* addr)
|
||||
{
|
||||
u32 vaddr = (u32)addr;
|
||||
|
Loading…
Reference in New Issue
Block a user