Skip to content

Commit

Permalink
Implement render queue system
Browse files Browse the repository at this point in the history
  • Loading branch information
fincs committed Jan 5, 2016
1 parent f74c7b1 commit 39a71a5
Show file tree
Hide file tree
Showing 5 changed files with 435 additions and 9 deletions.
42 changes: 42 additions & 0 deletions include/c3d/renderqueue.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
#pragma once
#include "renderbuffer.h"

typedef struct C3D_RenderTarget_tag C3D_RenderTarget;

struct C3D_RenderTarget_tag
{
C3D_RenderTarget *next, *prev, *link, *frame[2];
C3D_RenderBuf renderBuf;
u32 transferFlags;

u8 clearBits;
bool drawOk, transferOk;

bool linked;
gfxScreen_t screen;
gfx3dSide_t side;
};

// Flags for C3D_FrameBegin
enum
{
C3D_FRAME_SYNCDRAW = BIT(0), // Do not render the frame until the previous has finished rendering
C3D_FRAME_NONBLOCK = BIT(1), // Return false instead of waiting for the GPU to finish rendering
};

bool C3D_FrameBegin(u8 flags);
bool C3D_FrameDrawOn(C3D_RenderTarget* target);
void C3D_FrameEnd(u8 flags);

// Flags for C3D_RenderTargetSetClear (only C3D_CLEAR_ALL implemented atm)
enum
{
C3D_CLEAR_COLOR = BIT(0),
C3D_CLEAR_DEPTH = BIT(1),
C3D_CLEAR_ALL = C3D_CLEAR_COLOR | C3D_CLEAR_DEPTH,
};

C3D_RenderTarget* C3D_RenderTargetCreate(int width, int height, int colorFmt, int depthFmt);
void C3D_RenderTargetDelete(C3D_RenderTarget* target);
void C3D_RenderTargetSetClear(C3D_RenderTarget* target, u32 clearBits, u32 clearColor, u32 clearDepth);
void C3D_RenderTargetSetOutput(C3D_RenderTarget* target, gfxScreen_t screen, gfx3dSide_t side, u32 transferFlags);
1 change: 1 addition & 0 deletions include/citro3d.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ extern "C" {
#include "c3d/light.h"

#include "c3d/renderbuffer.h"
#include "c3d/renderqueue.h"

#ifdef __cplusplus
}
Expand Down
40 changes: 32 additions & 8 deletions source/base.c
Original file line number Diff line number Diff line change
Expand Up @@ -73,13 +73,14 @@ bool C3D_Init(size_t cmdBufSize)
if (ctx->flags & C3DiF_Active)
return false;

ctx->cmdBufSize = cmdBufSize;
ctx->cmdBuf = linearAlloc(cmdBufSize);
ctx->cmdBufSize = cmdBufSize/8; // Half of the size of the cmdbuf, in words
ctx->cmdBuf = (u32*)linearAlloc(cmdBufSize);
if (!ctx->cmdBuf) return false;

GPUCMD_SetBuffer(ctx->cmdBuf, ctx->cmdBufSize, 0);

ctx->flags = C3DiF_Active | C3DiF_TexEnvBuf | C3DiF_TexEnvAll | C3DiF_Effect | C3DiF_TexAll;
ctx->renderQueueExit = NULL;

// TODO: replace with direct struct access
C3D_DepthMap(-1.0f, 0.0f);
Expand Down Expand Up @@ -149,6 +150,7 @@ void C3Di_UpdateContext(void)
{
ctx->flags &= ~C3DiF_DrawUsed;
GPUCMD_AddWrite(GPUREG_FRAMEBUFFER_FLUSH, 1);
GPUCMD_AddWrite(GPUREG_EARLYDEPTH_CLEAR, 1);
}
C3Di_RenderBufBind(ctx->rb);
}
Expand Down Expand Up @@ -251,13 +253,10 @@ void C3Di_UpdateContext(void)
C3D_UpdateUniforms(GPU_GEOMETRY_SHADER);
}

void C3D_FlushAsync(void)
void C3Di_FinalizeFrame(u32** pBuf, u32* pSize)
{
C3D_Context* ctx = C3Di_GetContext();

if (!(ctx->flags & C3DiF_Active))
return;

if (ctx->flags & C3DiF_DrawUsed)
{
ctx->flags &= ~C3DiF_DrawUsed;
Expand All @@ -267,8 +266,30 @@ void C3D_FlushAsync(void)
}

GPUCMD_Finalize();
GPUCMD_FlushAndRun();
GPUCMD_SetBuffer(ctx->cmdBuf, ctx->cmdBufSize, 0);
GPUCMD_GetBuffer(pBuf, NULL, pSize);
*pSize *= 4;

ctx->flags ^= C3DiF_CmdBuffer;
u32* buf = ctx->cmdBuf;
if (ctx->flags & C3DiF_CmdBuffer)
buf += ctx->cmdBufSize;
GPUCMD_SetBuffer(buf, ctx->cmdBufSize, 0);
}

void C3D_FlushAsync(void)
{
if (!(C3Di_GetContext()->flags & C3DiF_Active))
return;

u32* cmdBuf;
u32 cmdBufSize;
C3Di_FinalizeFrame(&cmdBuf, &cmdBufSize);

//take advantage of GX_FlushCacheRegions to flush gsp heap
extern u32 __ctru_linear_heap;
extern u32 __ctru_linear_heap_size;
GX_FlushCacheRegions(cmdBuf, cmdBufSize, (u32 *) __ctru_linear_heap, __ctru_linear_heap_size, NULL, 0);
GX_ProcessCommandList(cmdBuf, cmdBufSize, 0x0);
}

void C3D_Fini(void)
Expand All @@ -278,6 +299,9 @@ void C3D_Fini(void)
if (!(ctx->flags & C3DiF_Active))
return;

if (ctx->renderQueueExit)
ctx->renderQueueExit();

aptUnhook(&hookCookie);
linearFree(ctx->cmdBuf);
ctx->flags = 0;
Expand Down
7 changes: 6 additions & 1 deletion source/context.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ typedef struct

typedef struct
{
void* cmdBuf;
u32* cmdBuf;
size_t cmdBufSize;

u32 flags;
Expand All @@ -49,6 +49,8 @@ typedef struct
u16 fixedAttribDirty, fixedAttribEverDirty;
C3D_FVec fixedAttribs[12];

void (* renderQueueExit)(void);

} C3D_Context;

enum
Expand All @@ -66,6 +68,7 @@ enum
C3DiF_LightEnv = BIT(10),
C3DiF_VshCode = BIT(11),
C3DiF_GshCode = BIT(12),
C3DiF_CmdBuffer = BIT(13),

#define C3DiF_Tex(n) BIT(23+(n))
C3DiF_TexAll = 7 << 23,
Expand All @@ -91,3 +94,5 @@ void C3Di_LightMtlBlend(C3D_Light* light);
void C3Di_DirtyUniforms(GPU_SHADER_TYPE type);
void C3Di_LoadShaderUniforms(shaderInstance_s* si);
void C3Di_ClearShaderUniforms(GPU_SHADER_TYPE type);

void C3Di_FinalizeFrame(u32** pBuf, u32* pSize);

0 comments on commit 39a71a5

Please sign in to comment.