From d8374c2883787c3187a3e6272bf9283877592f47 Mon Sep 17 00:00:00 2001 From: fincs Date: Sun, 26 Mar 2017 19:37:25 +0200 Subject: [PATCH] Refactor gpu.h/gpu.c, see details: - Added GPUCMD_Split for splitting the command buffer (and beginning a new command list within the same buffer) - Deprecated GPUCMD_Finalize/Run/FlushAndRun: - Use GPUCMD_Split + GX_ProcessCommandList instead - Turned GPUCMD_SetBuffer/SetBufferOffset/GetBuffer into inlines - GPUCMD_Add: svcBreak on cmdbuf overflow --- libctru/include/3ds/gpu/gpu.h | 36 ++++++++++++++++++++++++++-------- libctru/source/gpu/gpu.c | 37 ++++++++++++++++------------------- 2 files changed, 45 insertions(+), 28 deletions(-) diff --git a/libctru/include/3ds/gpu/gpu.h b/libctru/include/3ds/gpu/gpu.h index 38d0fca..d43b0a0 100644 --- a/libctru/include/3ds/gpu/gpu.h +++ b/libctru/include/3ds/gpu/gpu.h @@ -20,21 +20,34 @@ extern u32 gpuCmdBufOffset; ///< GPU command buffer offset. * @param size Size of the command buffer. * @param offset Offset of the command buffer. */ -void GPUCMD_SetBuffer(u32* adr, u32 size, u32 offset); +static inline void GPUCMD_SetBuffer(u32* adr, u32 size, u32 offset) +{ + gpuCmdBuf=adr; + gpuCmdBufSize=size; + gpuCmdBufOffset=offset; +} /** * @brief Sets the offset of the GPU command buffer. * @param offset Offset of the command buffer. */ -void GPUCMD_SetBufferOffset(u32 offset); +static inline void GPUCMD_SetBufferOffset(u32 offset) +{ + gpuCmdBufOffset=offset; +} /** * @brief Gets the current GPU command buffer. - * @param adr Pointer to output the command buffer to. - * @param size Pointer to output the size of the command buffer to. + * @param addr Pointer to output the command buffer to. + * @param size Pointer to output the size (in words) of the command buffer to. * @param offset Pointer to output the offset of the command buffer to. */ -void GPUCMD_GetBuffer(u32** adr, u32* size, u32* offset); +static inline void GPUCMD_GetBuffer(u32** addr, u32* size, u32* offset) +{ + if(addr)*addr=gpuCmdBuf; + if(size)*size=gpuCmdBufSize; + if(offset)*offset=gpuCmdBufOffset; +} /** * @brief Adds raw GPU commands to the current command buffer. @@ -44,10 +57,10 @@ void GPUCMD_GetBuffer(u32** adr, u32* size, u32* offset); void GPUCMD_AddRawCommands(const u32* cmd, u32 size); /// Executes the GPU command buffer. -void GPUCMD_Run(void); +DEPRECATED void GPUCMD_Run(void); /// Flushes linear memory and executes the GPU command buffer. -void GPUCMD_FlushAndRun(void); +DEPRECATED void GPUCMD_FlushAndRun(void); /** * @brief Adds a GPU command to the current command buffer. @@ -57,8 +70,15 @@ void GPUCMD_FlushAndRun(void); */ void GPUCMD_Add(u32 header, const u32* param, u32 paramlength); +/** + * @brief Splits the current GPU command buffer. + * @param addr Pointer to output the command buffer to. + * @param size Pointer to output the size (in words) of the command buffer to. + */ +void GPUCMD_Split(u32** addr, u32* size); + /// Finalizes the GPU command buffer. -void GPUCMD_Finalize(void); +DEPRECATED void GPUCMD_Finalize(void); /** * @brief Converts a 32-bit float to a 16-bit float. diff --git a/libctru/source/gpu/gpu.c b/libctru/source/gpu/gpu.c index e7b748c..db77129 100644 --- a/libctru/source/gpu/gpu.c +++ b/libctru/source/gpu/gpu.c @@ -5,6 +5,7 @@ #include #include #include <3ds/types.h> +#include <3ds/svc.h> #include <3ds/gpu/gpu.h> #include <3ds/gpu/gx.h> #include <3ds/gpu/shbin.h> @@ -13,25 +14,6 @@ u32* gpuCmdBuf; u32 gpuCmdBufSize; u32 gpuCmdBufOffset; -void GPUCMD_SetBuffer(u32* adr, u32 size, u32 offset) -{ - gpuCmdBuf=adr; - gpuCmdBufSize=size; - gpuCmdBufOffset=offset; -} - -void GPUCMD_SetBufferOffset(u32 offset) -{ - gpuCmdBufOffset=offset; -} - -void GPUCMD_GetBuffer(u32** adr, u32* size, u32* offset) -{ - if(adr)*adr=gpuCmdBuf; - if(size)*size=gpuCmdBufSize; - if(offset)*offset=gpuCmdBufOffset; -} - void GPUCMD_AddRawCommands(const u32* cmd, u32 size) { if(!cmd || !size)return; @@ -58,7 +40,8 @@ void GPUCMD_FlushAndRun(void) void GPUCMD_Add(u32 header, const u32* param, u32 paramlength) { if(!paramlength)paramlength=1; - if(!gpuCmdBuf || gpuCmdBufOffset+paramlength+1>gpuCmdBufSize)return; + if(!gpuCmdBuf || gpuCmdBufOffset+paramlength+1>gpuCmdBufSize) + svcBreak(USERBREAK_PANIC); // Shouldn't happen. paramlength--; header|=(paramlength&0x7ff)<<20; @@ -77,6 +60,20 @@ void GPUCMD_Add(u32 header, const u32* param, u32 paramlength) if(paramlength&1)gpuCmdBuf[gpuCmdBufOffset++]=0x00000000; //alignment } +void GPUCMD_Split(u32** addr, u32* size) +{ + GPUCMD_AddWrite(GPUREG_FINALIZE, 0x12345678); + if (gpuCmdBufOffset & 3) + GPUCMD_AddWrite(GPUREG_FINALIZE, 0x12345678); // 16-byte align the buffer + + if (addr) *addr = gpuCmdBuf; + if (size) *size = gpuCmdBufOffset; + + gpuCmdBuf += gpuCmdBufOffset; + gpuCmdBufSize -= gpuCmdBufOffset; + gpuCmdBufOffset = 0; +} + void GPUCMD_Finalize(void) { GPUCMD_AddMaskedWrite(GPUREG_PRIMITIVE_CONFIG, 0x8, 0x00000000);