From d4971ddca5a2ffcd89bafe0178eb7cf9f9300b7e Mon Sep 17 00:00:00 2001 From: fincs Date: Sat, 27 Jun 2015 19:17:50 +0200 Subject: [PATCH] Use APT hooks to restore GPU state when returning from homemenu --- examples/gputest/source/main.c | 2 +- include/c3d/base.h | 2 ++ source/base.c | 44 +++++++++++++++++++++++++++++++++- source/context.h | 2 ++ 4 files changed, 48 insertions(+), 2 deletions(-) diff --git a/examples/gputest/source/main.c b/examples/gputest/source/main.c index 006cc49..0e2adb1 100644 --- a/examples/gputest/source/main.c +++ b/examples/gputest/source/main.c @@ -134,7 +134,7 @@ int main() shaderProgramInit(&shader); shaderProgramSetVsh(&shader, &pVsh->DVLE[0]); shaderProgramSetGsh(&shader, &pGsh->DVLE[0], 3*5); // Comment this out to disable the geoshader - shaderProgramUse(&shader); + C3D_BindProgram(&shader); // Configure attributes C3D_AttrInfo* attrInfo = C3D_GetAttrInfo(); diff --git a/include/c3d/base.h b/include/c3d/base.h index a636da2..ea43cb8 100644 --- a/include/c3d/base.h +++ b/include/c3d/base.h @@ -7,6 +7,8 @@ bool C3D_Init(size_t cmdBufSize); void C3D_FlushAsync(void); void C3D_Fini(void); +void C3D_BindProgram(shaderProgram_s* program); + void C3D_SetViewport(u32 x, u32 y, u32 w, u32 h); void C3D_SetScissor(GPU_SCISSORMODE mode, u32 x, u32 y, u32 w, u32 h); diff --git a/source/base.c b/source/base.c index 06086b5..198465f 100644 --- a/source/base.c +++ b/source/base.c @@ -26,7 +26,7 @@ static void C3Di_SetTex(GPU_TEXUNIT unit, C3D_Tex* tex) u32 reg[4]; reg[0] = tex->fmt; reg[1] = osConvertVirtToPhys((u32)tex->data) >> 3; - reg[2] = (u32)tex->width | ((u32)tex->height << 16); + reg[2] = (u32)tex->height | ((u32)tex->width << 16); reg[3] = tex->param; switch (unit) @@ -52,6 +52,28 @@ static void C3Di_SetTex(GPU_TEXUNIT unit, C3D_Tex* tex) } } +static aptHookCookie hookCookie; + +static void C3Di_AptEventHook(int hookType, void* param) +{ + C3D_Context* ctx = C3Di_GetContext(); + + switch (hookType) + { + case APTHOOK_ONSUSPEND: + { + break; + } + case APTHOOK_ONRESTORE: + { + ctx->flags |= C3DiF_AttrBuf | C3DiF_Effect | C3DiF_RenderBuf + | C3DiF_Viewport | C3DiF_Scissor | C3DiF_Program + | C3DiF_TexAll | C3DiF_TexEnvAll; + break; + } + } +} + bool C3D_Init(size_t cmdBufSize) { int i; @@ -85,6 +107,8 @@ bool C3D_Init(size_t cmdBufSize) for (i = 0; i < 6; i ++) TexEnv_Init(&ctx->texEnv[i]); + aptHook(&hookCookie, C3Di_AptEventHook, NULL); + return true; } @@ -121,6 +145,12 @@ void C3Di_UpdateContext(void) //GPU_FinishDrawing(); } + if (ctx->flags & C3DiF_Program) + { + ctx->flags &= ~C3DiF_Program; + shaderProgramUse(ctx->program); + } + if (ctx->flags & C3DiF_RenderBuf) { ctx->flags &= ~C3DiF_RenderBuf; @@ -211,6 +241,18 @@ void C3D_Fini(void) if (!(ctx->flags & C3DiF_Active)) return; + aptUnhook(&hookCookie); linearFree(ctx->cmdBuf); ctx->flags = 0; } + +void C3D_BindProgram(shaderProgram_s* program) +{ + C3D_Context* ctx = C3Di_GetContext(); + + if (!(ctx->flags & C3DiF_Active)) + return; + + ctx->program = program; + ctx->flags |= C3DiF_Program; +} diff --git a/source/context.h b/source/context.h index 9b1f4e4..7d33630 100644 --- a/source/context.h +++ b/source/context.h @@ -27,6 +27,7 @@ typedef struct size_t cmdBufSize; u32 flags; + shaderProgram_s* program; u32 vboPos; C3D_AttrInfo attrInfo; @@ -50,6 +51,7 @@ enum C3DiF_RenderBuf = BIT(4), C3DiF_Viewport = BIT(5), C3DiF_Scissor = BIT(6), + C3DiF_Program = BIT(7), #define C3DiF_Tex(n) BIT(23+(n)) C3DiF_TexAll = 7 << 23,