From a68b2c370fda525576a8adeaf3bd5b0b3f12bf19 Mon Sep 17 00:00:00 2001 From: Nico de Poel Date: Sun, 15 Jan 2023 15:15:16 +0100 Subject: [PATCH] Set up some helper functions for memory management, including scratchpad memory. Moved the primitive buffer here too. This will probably have to become inline functions or macros at some point, but for now it's just pure C. --- common.h | 1 + display.c | 18 +----------------- memory.c | 46 ++++++++++++++++++++++++++++++++++++++++++++++ memory.h | 24 ++++++++++++++++++++++++ world.c | 2 +- 5 files changed, 73 insertions(+), 18 deletions(-) create mode 100644 memory.c create mode 100644 memory.h diff --git a/common.h b/common.h index 3bdbc3c..8470319 100644 --- a/common.h +++ b/common.h @@ -8,6 +8,7 @@ #include #include +#include "memory.h" #include "qmath.h" extern VECTOR cam_pos; diff --git a/display.c b/display.c index c101479..9d55a46 100644 --- a/display.c +++ b/display.c @@ -8,13 +8,7 @@ static DISPENV disp[2]; static DRAWENV draw[2]; static int db; -#define PRIMBUFLEN 131072 - static u_long ot[2][OTLEN]; // Ordering tables, two arrays for double buffering. These are basically the buckets for bucket sorting of polygons. - // You can also see them as "layers" in the modern 3D graphics sense, but they serve a more immediate role for polygon ordering. - // Layer 0 is free for overlays, as polygons at depth 0 will be clipped. -static char primbuff[2][PRIMBUFLEN]; // Primitive buffer, just a raw buffer of bytes to use as a pool for primitives -static char *nextpri; const MATRIX identity = { ONE, 0, 0, @@ -151,7 +145,7 @@ void display_start() curOT = ot[db]; ClearOTagR(curOT, OTLEN); - nextpri = primbuff[db]; + mem_prim_reset(db); gte_SetBackColor(48, 48, 48); // Ambient light color gte_SetColorMatrix(&light_cols); // Light color (up to three different lights) @@ -192,13 +186,3 @@ void display_finish() DrawOTag(curOT + OTLEN - 1); // This performs a DMA transfer to quickly send all the primitives off to the GPU } - -void *display_allocPrim(size_t size) -{ - if (nextpri + size > primbuff[db] + PRIMBUFLEN) - return NULL; - - void *prim = nextpri; - nextpri += size; - return prim; -} diff --git a/memory.c b/memory.c new file mode 100644 index 0000000..2e1ac8c --- /dev/null +++ b/memory.c @@ -0,0 +1,46 @@ +#include "common.h" +#include "memory.h" + +#define PRIMBUFLEN 131072 // TODO: optimize this for a typical scene + +static char primbuff[2][PRIMBUFLEN]; // Primitive buffer, just a raw buffer of bytes to use as a pool for primitives +static char *nextpri; +static char *primbuff_bounds; + +static char* const scratch_start = (char*)0x1F800000; +static char *scratch = scratch_start; + +void mem_scratch_reset() +{ + scratch = scratch_start; +} + +char *mem_scratch(unsigned short size) +{ +#if _DEBUG + if (scratch + size > scratch_start + 1024) + return NULL; +#endif + + char *result = scratch; + scratch += size; + return result; +} + +void mem_prim_reset(int db) +{ + nextpri = primbuff[db]; + primbuff_bounds = nextpri + PRIMBUFLEN; +} + +void *mem_prim(size_t size) +{ +#if _DEBUG + if (nextpri + size > primbuff_bounds) + return NULL; // TODO: report error +#endif + + void *prim = nextpri; + nextpri += size; + return prim; +} diff --git a/memory.h b/memory.h new file mode 100644 index 0000000..8afcddc --- /dev/null +++ b/memory.h @@ -0,0 +1,24 @@ +#ifndef __MEMORY_H__ +#define __MEMORY_H__ + +/** + * @brief Allocate memory in the fast scratchpad RAM buffer. + * + * @param size The number of bytes to allocate. Be aware that the scratchpad memory only has 1024 bytes available. + * @return Pointer to the allocated buffer in scratchpad memory. + */ +char *mem_scratch(unsigned short size); + +void mem_scratch_reset(); + +/** + * @brief Allocate a single primitive in the primitive buffer. + * + * @param size Size of the primitive struct to allocate. + * @return Pointer to the allocated struct in memory. + */ +void *mem_prim(size_t size); + +void mem_prim_reset(int db); + +#endif // __MEMORY_H__ diff --git a/world.c b/world.c index ebc2f17..66916a9 100644 --- a/world.c +++ b/world.c @@ -89,7 +89,7 @@ void world_draw(const world_t *world) continue; // Draw a flat-shaded untextured colored triangle - POLY_F3 *poly = (POLY_F3*)display_allocPrim(sizeof(POLY_F3)); + POLY_F3 *poly = (POLY_F3*)mem_prim(sizeof(POLY_F3)); if (poly == NULL) break;