diff options
| author | 3gg <3gg@shellblade.net> | 2025-12-28 12:57:52 -0800 |
|---|---|---|
| committer | 3gg <3gg@shellblade.net> | 2025-12-28 12:57:52 -0800 |
| commit | 75ee45cc65b35d40355178f48ef0c2d90040b863 (patch) | |
| tree | 780f64e0aa6aefe9ec23f5876113fb7a4120155c /src | |
| parent | 07fb91b9571fc0add797cbcd0adcc8711401a2be (diff) | |
Diffstat (limited to 'src')
| -rw-r--r-- | src/swgfx.c | 47 |
1 files changed, 26 insertions, 21 deletions
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: | |||
| 17 | #include <assert.h> | 17 | #include <assert.h> |
| 18 | #include <math.h> // sqrt | 18 | #include <math.h> // sqrt |
| 19 | #include <stdint.h> | 19 | #include <stdint.h> |
| 20 | #include <stdlib.h> | ||
| 21 | #include <string.h> | 20 | #include <string.h> |
| 22 | 21 | ||
| 23 | static constexpr sgVec3 Up3 = (sgVec3){0,1,0}; | 22 | static constexpr sgVec3 Up3 = (sgVec3){0,1,0}; |
| @@ -361,47 +360,53 @@ static void DrawTriangle3(swgfx* gfx, const sgTri3* tri) { | |||
| 361 | } | 360 | } |
| 362 | 361 | ||
| 363 | #define is_pow2_or_0(X) ((X & (X - 1)) == 0) | 362 | #define is_pow2_or_0(X) ((X & (X - 1)) == 0) |
| 363 | #define SG_ALIGN 64 | ||
| 364 | #define SG_ALLOC(PP_MEM, COUNT, TYPE) (TYPE*)Alloc(PP_MEM, COUNT, sizeof(TYPE)) | ||
| 364 | 365 | ||
| 365 | static size_t align(size_t size) { | 366 | static void* AlignPtr(void* address) { |
| 367 | assert(is_pow2_or_0(SG_ALIGN)); | ||
| 368 | constexpr size_t mask = SG_ALIGN - 1; | ||
| 369 | return (void*)(((uintptr_t)address + mask) & ~mask); | ||
| 370 | } | ||
| 371 | |||
| 372 | static size_t Align(size_t size) { | ||
| 366 | static_assert(is_pow2_or_0(SG_ALIGN)); | 373 | static_assert(is_pow2_or_0(SG_ALIGN)); |
| 367 | constexpr size_t mask = SG_ALIGN - 1; | 374 | constexpr size_t mask = SG_ALIGN - 1; |
| 368 | return (size + mask) & (~mask); | 375 | return (size + mask) & (~mask); |
| 369 | } | 376 | } |
| 370 | 377 | ||
| 371 | void* sgAlloc(size_t count, size_t size) { | 378 | static void* Alloc(void** ppMem, size_t count, size_t size) { |
| 372 | const size_t total = align(count * size); | 379 | assert(ppMem); |
| 373 | void* const ptr = aligned_alloc(SG_ALIGN, total); | 380 | assert(*ppMem); |
| 381 | assert(*ppMem == AlignPtr(*ppMem)); // Should already be aligned. | ||
| 382 | const size_t total = Align(count * size); | ||
| 383 | void* ptr = *ppMem; | ||
| 384 | *ppMem = ptr + total; | ||
| 374 | memset(ptr, 0, total); | 385 | memset(ptr, 0, total); |
| 375 | return ptr; | 386 | return ptr; |
| 376 | } | 387 | } |
| 377 | 388 | ||
| 378 | void sgFree(void** pp) { | 389 | size_t sgMem(int width, int height) { |
| 379 | assert(pp); | 390 | return Align(sizeof(swgfx)) + |
| 380 | if (*pp) { | 391 | Align(width * height * sizeof(sgPixel)) + |
| 381 | free(*pp); | 392 | (SG_ALIGN - 1); // To make room to align allocations within the buffer. |
| 382 | *pp = nullptr; | ||
| 383 | } | ||
| 384 | } | 393 | } |
| 385 | 394 | ||
| 386 | swgfx* sgNew() { | 395 | swgfx* sgNew(int width, int height, void* mem) { |
| 387 | swgfx* gfx = SG_ALIGN_ALLOC(1, swgfx); | 396 | void* aligned = AlignPtr(mem); // Uses the extra room we made in sgMem(). |
| 397 | swgfx* gfx = SG_ALLOC(&aligned, 1, swgfx); | ||
| 398 | gfx->dims = (sgVec2i){width, height}; | ||
| 399 | gfx->colour = SG_ALLOC(&aligned, width * height, sgPixel); | ||
| 388 | return gfx; | 400 | return gfx; |
| 389 | } | 401 | } |
| 390 | 402 | ||
| 391 | void sgDel(swgfx** ppSwgfx) { | 403 | void sgDel(swgfx** ppSwgfx) { |
| 392 | assert(ppSwgfx); | 404 | assert(ppSwgfx); |
| 393 | if (*ppSwgfx) { | 405 | if (*ppSwgfx) { |
| 394 | free(*ppSwgfx); | 406 | *ppSwgfx = nullptr; |
| 395 | *ppSwgfx = 0; | ||
| 396 | } | 407 | } |
| 397 | } | 408 | } |
| 398 | 409 | ||
| 399 | void sgColourBuffer(swgfx* gfx, sgVec2i dimensions, sgPixel* buffer) { | ||
| 400 | assert(gfx); | ||
| 401 | gfx->dims = dimensions; | ||
| 402 | gfx->colour = buffer; | ||
| 403 | } | ||
| 404 | |||
| 405 | void sgPresent(swgfx* gfx, sgVec2i dimensions, sgPixel* screen) { | 410 | void sgPresent(swgfx* gfx, sgVec2i dimensions, sgPixel* screen) { |
| 406 | assert(gfx); | 411 | assert(gfx); |
| 407 | assert(screen); | 412 | assert(screen); |
