From 75ee45cc65b35d40355178f48ef0c2d90040b863 Mon Sep 17 00:00:00 2001 From: 3gg <3gg@shellblade.net> Date: Sun, 28 Dec 2025 12:57:52 -0800 Subject: Move memory allocation to the client --- include/swgfx.h | 14 +++----------- src/swgfx.c | 47 ++++++++++++++++++++++++++--------------------- 2 files changed, 29 insertions(+), 32 deletions(-) diff --git a/include/swgfx.h b/include/swgfx.h index 94eb359..005359b 100644 --- a/include/swgfx.h +++ b/include/swgfx.h @@ -39,13 +39,13 @@ typedef struct sgPixel { uint8_t r, g, b, a; } sgPixel; typedef struct swgfx swgfx; -swgfx* sgNew(); +size_t sgMem(int width, int height); // Get memory requirements. +swgfx* sgNew(int width, int height, void* mem); void sgDel(swgfx**); // TODO: Write client app first, then implement the functions below in the C file. -void sgColourBuffer(swgfx*, sgVec2i dimensions, sgPixel* buffer); -void sgPresent (swgfx*, sgVec2i dimensions, sgPixel* screen); +void sgPresent(swgfx*, sgVec2i dimensions, sgPixel* screen); void sgModelId (swgfx*); void sgModel (swgfx*, sgVec3 position, sgVec3 right, sgVec3 up, sgVec3 forward); @@ -66,11 +66,3 @@ void sgTrianglesIndexed(swgfx*, size_t numIndices, const sgIdx* indices, const s void sgTrianglesIndexedNonUniform(swgfx*, size_t numTris, const sgTriIdx* tris, const sgVec3* positions); void sgCheck(swgfx*); - -// Memory -#define SG_ALIGN 64 -#define SG_ALIGN_PTR(P) ((uintptr_t)(P) & (~(SG_ALIGN-1))) -#define SG_ALIGN_ALLOC(COUNT, TYPE) (TYPE*)sgAlloc(1, COUNT * sizeof(TYPE)) -#define SG_FREE(PP) sgFree((void**)PP) -void* sgAlloc(size_t count, size_t size); -void sgFree(void**); diff --git a/src/swgfx.c b/src/swgfx.c index 3b9ce29..54f7432 100644 --- a/src/swgfx.c +++ b/src/swgfx.c @@ -17,7 +17,6 @@ Coordinate systems: #include #include // sqrt #include -#include #include static constexpr sgVec3 Up3 = (sgVec3){0,1,0}; @@ -361,47 +360,53 @@ static void DrawTriangle3(swgfx* gfx, const sgTri3* tri) { } #define is_pow2_or_0(X) ((X & (X - 1)) == 0) +#define SG_ALIGN 64 +#define SG_ALLOC(PP_MEM, COUNT, TYPE) (TYPE*)Alloc(PP_MEM, COUNT, sizeof(TYPE)) -static size_t align(size_t size) { +static void* AlignPtr(void* address) { + assert(is_pow2_or_0(SG_ALIGN)); + constexpr size_t mask = SG_ALIGN - 1; + return (void*)(((uintptr_t)address + mask) & ~mask); +} + +static size_t Align(size_t size) { static_assert(is_pow2_or_0(SG_ALIGN)); constexpr size_t mask = SG_ALIGN - 1; return (size + mask) & (~mask); } -void* sgAlloc(size_t count, size_t size) { - const size_t total = align(count * size); - void* const ptr = aligned_alloc(SG_ALIGN, total); +static void* Alloc(void** ppMem, size_t count, size_t size) { + assert(ppMem); + assert(*ppMem); + assert(*ppMem == AlignPtr(*ppMem)); // Should already be aligned. + const size_t total = Align(count * size); + void* ptr = *ppMem; + *ppMem = ptr + total; memset(ptr, 0, total); return ptr; } -void sgFree(void** pp) { - assert(pp); - if (*pp) { - free(*pp); - *pp = nullptr; - } +size_t sgMem(int width, int height) { + return Align(sizeof(swgfx)) + + Align(width * height * sizeof(sgPixel)) + + (SG_ALIGN - 1); // To make room to align allocations within the buffer. } -swgfx* sgNew() { - swgfx* gfx = SG_ALIGN_ALLOC(1, swgfx); +swgfx* sgNew(int width, int height, void* mem) { + void* aligned = AlignPtr(mem); // Uses the extra room we made in sgMem(). + swgfx* gfx = SG_ALLOC(&aligned, 1, swgfx); + gfx->dims = (sgVec2i){width, height}; + gfx->colour = SG_ALLOC(&aligned, width * height, sgPixel); return gfx; } void sgDel(swgfx** ppSwgfx) { assert(ppSwgfx); if (*ppSwgfx) { - free(*ppSwgfx); - *ppSwgfx = 0; + *ppSwgfx = nullptr; } } -void sgColourBuffer(swgfx* gfx, sgVec2i dimensions, sgPixel* buffer) { - assert(gfx); - gfx->dims = dimensions; - gfx->colour = buffer; -} - void sgPresent(swgfx* gfx, sgVec2i dimensions, sgPixel* screen) { assert(gfx); assert(screen); -- cgit v1.2.3