From f57018317aa1bbb19f4c8275b3bbba7eb61da7f9 Mon Sep 17 00:00:00 2001 From: Matthew Date: Mon, 14 Apr 2025 16:37:47 +1000 Subject: [PATCH] big clean up --- build.sh | 10 +- src/allocators.c | 122 ++++++++-- src/allocators.h | 74 ++++-- src/assets.h | 2 + src/ds.c | 9 +- src/ds.h | 14 +- src/entry_linux.c | 6 +- src/game.c | 201 +++++++++------- src/game.h | 30 ++- src/packer.c | 112 +++------ src/packer.h | 62 ++--- src/platform/platform.c | 33 --- src/platform/platform.h | 95 ++------ src/platform/platform_linux.c | 75 ++---- src/platform/platform_linux.h | 53 +++-- src/platform/platform_linux_public.c | 165 +++++++++---- src/platform/platform_windows.c | 6 +- src/platform/platform_windows.h | 25 +- src/renderer.h | 47 ++-- src/renderer_vulkan.c | 340 +++++++++++++++------------ src/renderer_vulkan.h | 145 +++++------- src/renderer_vulkan_public.c | 65 ++--- src/shared_types.h | 116 +++++---- src/util.c | 227 ++++++++---------- src/util.h | 78 ++---- 25 files changed, 1081 insertions(+), 1031 deletions(-) diff --git a/build.sh b/build.sh index e324a24..33c6948 100755 --- a/build.sh +++ b/build.sh @@ -32,7 +32,7 @@ packer_out_name="Packer" # vma flags vma_source_files="../external/vma/vma.cpp" -vma_compile_flags="-std=c++20 -I../external/vma -c" +vma_compile_flags="-std=c++20 -D_USE_MATH_DEFINES -I../external/vma -c -Wno-everything -static" vma_out="-o" vma_obj="vma.o" @@ -47,14 +47,14 @@ glsl_stage_geom="-fshader-stage=geom" glsl_stage_comp="-fshader-stage=comp" glsl_out="-o./shaders/glsl/" -clang_common="${include_flags} ${render_flag} -g -Xclang -flto-visibility-public-std -Wno-unknown-warning-option -fdiagnostics-absolute-paths -Wall -Wno-missing-braces -Wno-unused-function -Wno-writable-strings -Wno-unused-value -Wno-unused-variable -Wno-unused-local-typedef -Wno-deprecated-register -Wno-deprecated-declarations -Wno-unused-but-set-variable -Wno-single-bit-bitfield-constant-conversion -Wno-compare-distinct-pointer-types -Wno-initializer-overrides -Wno-incompatible-pointer-types-discards-qualifiers -Wno-for-loop-analysis -DVMA_STATIC_VULKAN_FUNCTIONS=0" +clang_common="${include_flags} ${render_flag} -DCOMPILER_CLANG -fuse-ld=mold -Xclang -flto-visibility-public-std -Wno-unknown-warning-option -fdiagnostics-absolute-paths -Wall -Wno-missing-braces -Wno-unused-function -Wno-writable-strings -Wno-unused-value -Wno-unused-variable -Wno-unused-local-typedef -Wno-deprecated-register -Wno-deprecated-declarations -Wno-unused-but-set-variable -Wno-single-bit-bitfield-constant-conversion -Wno-compare-distinct-pointer-types -Wno-initializer-overrides -Wno-incompatible-pointer-types-discards-qualifiers -Wno-for-loop-analysis -DVMA_STATIC_VULKAN_FUNCTIONS=0" clang_debug="$compiler -g -O0 -DBUILD_DEBUG=1 ${clang_common}" -clang_release="$compiler -g -O2 ${clang_common}" +clang_release="$compiler -O2 ${clang_common}" clang_test="$compiler -O2 -DBUILD_TEST=1 ${clang_common}" -clang_link="-lpthread -lm -lrt -ldl -l:libvma.a" +clang_link="-lpthread -lm -lrt -ldl ${render_link} -lstdc++" clang_out="-o" -gcc_common="${include_flags} ${render_flag} -std=c99 -fuse-ld=mold -g -Wno-unknown-warning-option -Wall -Wno-missing-braces -Wno-unused-function -Wno-attributes -Wno-unused-value -Wno-unused-variable -Wno-unused-local-typedef -Wno-deprecated-declarations -Wno-unused-but-set-variable -Wno-compare-distinct-pointer-types -D_USE_MATH_DEFINES -Dstrdup=_strdup -Dgnu_printf=printf -DVMA_STATIC_VULKAN_FUNCTIONS=0" +gcc_common="${include_flags} ${render_flag} -DCOMPILER_GCC -std=c99 -fuse-ld=mold -g -Wno-unknown-warning-option -Wall -Wno-missing-braces -Wno-unused-function -Wno-attributes -Wno-unused-value -Wno-unused-variable -Wno-unused-local-typedef -Wno-deprecated-declarations -Wno-unused-but-set-variable -Wno-compare-distinct-pointer-types -D_USE_MATH_DEFINES -Dstrdup=_strdup -Dgnu_printf=printf -DVMA_STATIC_VULKAN_FUNCTIONS=0" gcc_debug="$compiler -g -O0 -DBUILD_DEBUG=1 ${gcc_common}" gcc_release="$compiler -O2 ${gcc_common} ${render_flag}" gcc_test="$compiler -O2 -DBUILD_TEST=1 ${gcc_common} ${render_flag}" diff --git a/src/allocators.c b/src/allocators.c index 1573c42..e0c0b14 100644 --- a/src/allocators.c +++ b/src/allocators.c @@ -1,6 +1,37 @@ +// ::Allocator::Globals:: + +Allocator g_alloc; +read_only FLNode FL_NIL_NODE = {}; + +// ::Allocator::Util::Header:: + +usize CalcPaddingWithHeader(uintptr ptr, uintptr alignment, usize header_size) +{ + Assert(IsPow2(alignment), "Alignment provided to CalcPaddingWithHeader is not a power of two"); + + uintptr modulo = ptr & (alignment-1); + uintptr padding = 0; + uintptr needed_space = (uintptr)header_size; + + if (modulo != 0) + padding = alignment - modulo; + + if (padding < needed_space) + { + needed_space -= padding; + + if ((needed_space & (alignment-1)) != 0) + padding += alignment * (1 + (needed_space/alignment)); + else + padding += alignment * (needed_space/alignment); + } + + return (usize)padding; +} + // ::Allocator::Arena::Start:: -static Arena *CreateArena(rawptr buffer, isize length) +static Arena *CreateArena(rawptr buffer, usize length) { Arena *arena = (Arena *)buffer; buffer = PtrAdd(buffer, ARENA_HEADER_SIZE); @@ -12,7 +43,7 @@ static Arena *CreateArena(rawptr buffer, isize length) return arena; } -static rawptr ArenaAllocAlign(Arena *arena, isize size, isize align) +static rawptr ArenaAllocAlign(Arena *arena, usize size, usize align) { rawptr ptr = NULL; @@ -34,7 +65,7 @@ static rawptr ArenaAllocAlign(Arena *arena, isize size, isize align) return ptr; } -static rawptr ArenaAlloc(Arena *arena, isize size) +static rawptr ArenaAlloc(Arena *arena, usize size) { return ArenaAllocAlign(arena, size, DEFAULT_ALIGNMENT); } @@ -55,7 +86,7 @@ static void DeallocArena(Arena *arena) MemFree(arena, arena->length); } -static Arena * CreateArenaDebug(rawptr buffer, isize length, u32 init_line_no) +static Arena * CreateArenaDebug(rawptr buffer, usize length, u32 init_line_no) { Arena *arena = CreateArena(buffer, length); arena->init_line_no = init_line_no; @@ -64,17 +95,17 @@ static Arena * CreateArenaDebug(rawptr buffer, isize length, u32 init_line_no) // ::Allocator::Arena::End:: -// ::Allocator::FreeList::Start:: +// ::Allocator::GlobalAlloc::Start:: -static Alloc *CreateFreeListAlloc(isize init_size, isize grow_size) +static void InitAllocator(usize init_size, usize grow_size) { - isize size = init_size + sizeof(Alloc) + sizeof(FreeListBuffer) + sizeof(rawptr) + sizeof(RBNode); + usize size = init_size + sizeof(Allocator) + sizeof(FreeListBuffer) + sizeof(rawptr) + sizeof(RBNode); u8 *mem = (u8 *)MemAllocZeroed(size); - Alloc *fl_alloc = (Alloc *)mem; + Allocator *fl_alloc = (Allocator *)mem; u8 *pre_mem = mem; mem = (u8 *)PtrAdd(mem, sizeof(Alloc)); - isize rem_size = (size) - (pre_mem - mem); + usize rem_size = (size) - (pre_mem - mem); fl_alloc->buf_len = 1; fl_alloc->grow_size = grow_size; @@ -94,35 +125,86 @@ static Alloc *CreateFreeListAlloc(isize init_size, isize grow_size) fl_alloc->buffers[0].size = (u32)size; fl_alloc->buffers[0].free_size = (u32)rem_size; - return fl_alloc; } -static void DeallocFreeListAlloc(Alloc *alloc) +static void DeinitAlloc() { - for (u8 i = alloc->buf_len-1; i >= 0; i--) + for (u8 i = g_alloc.buf_len-1; i >= 0; i--) { - if (i == 0) - MemFree(alloc, alloc->buffers[i].size); - else - MemFree(alloc->buffers[i].buf, alloc->buffers[i].size); + MemFree(g_alloc.buffers[i].buf, g_alloc.buffers[i].size); } } -static rawptr FLAlloc(Alloc *alloc, isize size) +static rawptr Alloc(usize size) { return NULL; } -static void FLFree(Alloc *alloc, rawptr ptr) +static void Free(rawptr ptr) { } -static void FreeListGrow(Alloc *alloc) +static void AllocGrow() { - u8 *mem = (u8 *)MemAllocZeroed(alloc->grow_size); + u8 *mem = (u8 *)MemAllocZeroed(g_alloc.grow_size); } // ::Allocator::FreeList::End:: + +static void FLAllocInit(FLAlloc *alloc, usize size) +{ + alloc->data = MemAllocZeroed(size); + alloc->size = size; + alloc->nil = &FL_NIL_NODE; + FLAllocFreeAll(alloc); +} + +static void FLAllocFreeAll(FLAlloc *alloc) +{ + FLNode *node = (FLNode *)alloc->data; + node->size = alloc->size; + node->next = alloc->nil; + + alloc->used = 0; + alloc->head = node; +} + +static FLNode *FreeListSearch(FLAlloc *alloc, usize size, u32 alignment, u32 *out_padding, FLNode **prev_node) +{ + FLNode *node = alloc->head; + FLNode *prev = alloc->nil; + + usize padding = 0; + + while (node != alloc->nil) + { + padding = CalcPaddingWithHeader((uintptr)node, (uintptr)alignment, sizeof(FLNode)); + usize required_size = size + padding; + if (node->size >= required_size) + break; + + prev = node; + node = node->next; + } + + if (out_padding) + *out_padding = padding; + + if (prev_node) + *prev_node = prev; + + return node; +} + +static rawptr FreeListAlloc(FLAlloc *alloc, usize size, u32 alignment) +{ + usize padding = 0; + FLNode *prev_node = alloc->nil; + + + + return NULL; +} diff --git a/src/allocators.h b/src/allocators.h index 090cd08..76b21d9 100644 --- a/src/allocators.h +++ b/src/allocators.h @@ -1,55 +1,85 @@ #pragma once +// ::Allocator::Util::Header:: + +usize CalcPaddingWithHeader(uintptr ptr, uintptr alignment, usize header_size); + // ::Allocator::Arena::Header:: #define ARENA_HEADER_SIZE 64 -typedef struct Arena_t +typedef struct Arena { u8 *buffer; - isize length; - isize pos; + usize length; + usize pos; u32 init_line_no; } Arena; -typedef struct TempArena_t +typedef struct TempArena { Arena *arena; u64 pos; } TempArena; -static Arena *CreateArena(rawptr buffer, isize length); -static rawptr ArenaAllocAlign(Arena *arena, isize size, isize align); -static rawptr ArenaAlloc(Arena *arena, isize size); +static Arena *CreateArena(rawptr buffer, usize length); +static rawptr ArenaAllocAlign(Arena *arena, usize size, usize align); +static rawptr ArenaAlloc(Arena *arena, usize size); static void ArenaFree(Arena *arena); static void ArenaFreeZeroed(Arena *arena); static void DeallocArena(Arena *arena); -static Arena *CreateArenaDebug(rawptr buffer, isize length, u32 init_line_no); +static Arena *CreateArenaDebug(rawptr buffer, usize length, u32 init_line_no); -// ::Allocator::FreeList::Header:: +// ::Allocator::GlobalAlloc::Header:: -typedef struct FreeListBuffer_t +typedef struct FreeListBuffer { rawptr buf; u32 size; u32 free_size; } FreeListBuffer; -typedef struct Alloc_t +typedef struct Allocator { RBNode *head; RBNode *nil; FreeListBuffer *buffers; - isize grow_size; + usize grow_size; u8 buf_len; -} Alloc; +} Allocator; -static Alloc *CreateFreeListAlloc(isize init_size, isize grow_size); -static void DeallocFreeListAlloc(Alloc *alloc); -static void FreeListGrow(Alloc *alloc); -static rawptr FLAlloc(Alloc *alloc, isize size); -static void FLFree(Alloc *alloc, rawptr ptr); -static inline b32 FLNodeInsert(Alloc *alloc, RBNode *node); -static inline void FLNodeDelete(RBNode *node); -static inline void FLNodeLeftRotate(RBNode *node); -static inline void FLNodeRightRotate(RBNode *node); +static void InitAllocator(usize init_size, usize grow_size); +static void DeinitAlloc(); +static void AllocGrow(); +static rawptr Alloc(usize size); +static void Free(rawptr ptr); + +// ::Allocator::FreeList::Header:: + +typedef struct FLAllocHeader +{ + usize block_size; + usize padding; +} FLAllocHeader; + +typedef struct FLNode FLNode; + +typedef struct FLNode +{ + FLNode *next; + usize size; +} FLNode; + +typedef struct FLAlloc +{ + rawptr data; + FLNode *head; + FLNode *nil; + usize size; + usize used; +} FLAlloc; + +static void FLAllocInit(FLAlloc *alloc, usize size); +static void FLAllocFreeAll(FLAlloc *alloc); +static FLNode *FreeListSearch(FLAlloc *alloc, usize size, u32 alignment, u32 *out_padding, FLNode **prev_node); +static rawptr FreeListAlloc(FLAlloc *alloc, usize size, u32 alignment); diff --git a/src/assets.h b/src/assets.h index a2e7b80..273d943 100644 --- a/src/assets.h +++ b/src/assets.h @@ -1,5 +1,7 @@ #pragma once +// ::Assets::Types::Header:: + typedef enum AssetType_e { SHADER_ASSET, diff --git a/src/ds.c b/src/ds.c index 304f60a..ae565d7 100644 --- a/src/ds.c +++ b/src/ds.c @@ -1,6 +1,13 @@ +// ::DataStructures::Globals::Start:: RBNode RB_NIL = { .color = RB_BLACK }; +// ::DataStructures::Globals::End:: + + + +// ::DataStructures::RedBlackTree::Functions::Start:: + static void CreateRBTree(RBTree *tree) { Assert(tree != NULL, "RBTree is null"); @@ -319,4 +326,4 @@ static void RBTreeRightRotate(RBTree *tree, RBNode *node) node->parent = left; } - +// ::DataStructures::RedBlackTree::Functions::Start:: diff --git a/src/ds.h b/src/ds.h index d992e5c..73bbad4 100644 --- a/src/ds.h +++ b/src/ds.h @@ -1,5 +1,7 @@ #pragma once +// ::DataStructures::Types::Header:: + typedef enum RBNodeColor_e { RB_RED, @@ -12,9 +14,9 @@ typedef enum RBNodeDir_e RB_RIGHT, } RBNodeDir; -typedef struct RBNode_t RBNode; +typedef struct RBNode RBNode; -typedef struct RBNode_t +typedef struct RBNode { RBNode *parent; union @@ -31,17 +33,21 @@ typedef struct RBNode_t RBNodeColor color; } RBNode; -typedef struct RBTree_t +typedef struct RBTree { RBNode *root; RBNode *nil; } RBTree; +// ::DataStructures::Macros::Header:: + #define NodeDir(node) (node == node->parent->left ? RB_LEFT : RB_RIGHT) +// ::DataStructures::RedBlackTree::Functions::Header:: + static void CreateRBTree(RBTree *tree); static void RBTreeInsert(RBTree *tree, RBNode *node); -static b32 RBTreeSearch(RBTree *tree, i32 value, RBNode **out_node); +static b32 RBTreeSearch(RBTree *tree, i32 value, RBNode **node); static void RBTreeDelete(RBTree *tree, i32 value); static void RBTreeLeftRotate(RBTree *tree, RBNode *node); static void RBTreeRightRotate(RBTree *tree, RBNode *node); diff --git a/src/entry_linux.c b/src/entry_linux.c index 1b9a676..3109e1b 100644 --- a/src/entry_linux.c +++ b/src/entry_linux.c @@ -89,13 +89,11 @@ int main(int argc, char **argv) Traverse(&tree); - return 0; - u8 *mem = (u8 *)MemAllocZeroed(MB(64)); Arena *arena = CreateArenaDebug(mem, MB(64), __LINE__); - isize renderer_mem_size = MB(16); - isize game_mem_size = MB(16); + usize renderer_mem_size = MB(16); + usize game_mem_size = MB(16); rawptr renderer_mem = ArenaAlloc(arena, renderer_mem_size); Arena *renderer_arena = CreateArenaDebug(renderer_mem, renderer_mem_size, 2); diff --git a/src/game.c b/src/game.c index 598b6e7..0c5ffa2 100644 --- a/src/game.c +++ b/src/game.c @@ -1,3 +1,21 @@ +// ::Game::Globals::Start:: + +// TEMP + +u32 selected_rect = 0; +b8 mouse_pressed = false; +b8 mouse_clicked = false; +i16 mouse_prev_pos_x = 0; +i16 mouse_prev_pos_y = 0; +i16 mouse_pos_x = 0; +i16 mouse_pos_y = 0; + +// ::Game::Globals::End:: + + + +// ::Game::Init::Functions::Start:: + static void InitializeGame(Arena *arena, GameContext *ctx, Arena *ctx_arena) { Assert(InitRenderer(arena), "Failed to initialize the renderer"); @@ -22,13 +40,89 @@ static void DestroyGame() DestroyRenderer(); } -u32 selected_rect = 0; -b8 mouse_pressed = false; -b8 mouse_clicked = false; -i16 mouse_prev_pos_x = 0; -i16 mouse_prev_pos_y = 0; -i16 mouse_pos_x = 0; -i16 mouse_pos_y = 0; +// ::Game::Init::Functions::End:: + + + +// ::Game::GameLoop::Functions::Start:: + +static void RunCycle(GameContext *ctx, GameInput *inputs, u32 i_count) +{ + __atomic_store_n(&renderer.vk.imm.job_count, 0, __ATOMIC_RELEASE); + __atomic_store_n(&renderer.vk.imm.remaining_count, 0, __ATOMIC_RELEASE); + + PrepareGUICtx(ctx); + + HandleInputs(inputs, i_count); + + if (UIButton(ctx, "Show 2", 150.0f, 150.0f, 200.0f, 200.0f)) + { + UIWindow(ctx, "Window 2", 500.0f, 500.0f, 600.0f, 600.0f); + } + + if (UIButton(ctx, "Show 1", 50.0f, 50.0f, 100.0f, 100.0f)) + { + UIWindow(ctx, "Window 1", 200.0f, 200.0f, 400.0f, 400.0f); + } + + if (UIButton(ctx, "Show 3", 150.0f, 300.0f, 200.0f, 350.0f)) + { + UIWindow(ctx, "Window 3", 250.0f, 500.0f, 400.0f, 650.0f); + } + + + GetViewportSize(&ctx->pc.res); + + + RenderBuffer *vertex_buffer = MakeArray(ctx->arena, RenderBuffer, 1); + vertex_buffer->type = RENDER_BUFFER_TYPE_VERTEX; + vertex_buffer->size = sizeof(GUIVertex) * ctx->gui.vertices_len; + + RenderBuffer *index_buffer = MakeArray(ctx->arena, RenderBuffer, 1); + index_buffer->type = RENDER_BUFFER_TYPE_INDEX, + index_buffer->size = sizeof(u32) * ctx->gui.indices_len, + + CreateAndUploadToBuffer(vertex_buffer, ctx->gui.vertices); + CreateAndUploadToBuffer(index_buffer, ctx->gui.indices); + + for (u32 i = 0; i < renderer.vk_conf.avail_threads; i++) + { + pthread_cond_signal(&cond); + } + + i32 count = -1; + while (count != 0) + { + __atomic_load(&renderer.vk.imm.remaining_count, &count, __ATOMIC_SEQ_CST); + } + + BeginFrame(); + + BindPipeline(PIPELINE_GUI, PIPELINE_TYPE_GRAPHICS); + + SetPushConstants(&ctx->pc); + + BindVertexBuffer(vertex_buffer); + BindIndexBuffer(index_buffer); + + DrawIndexed(6, ctx->gui.instance_count); + + FinishFrame(); + + FreeBuffers(vertex_buffer, 1); + FreeBuffers(index_buffer, 1); + + ctx->gui.vertices_len = 0; + ctx->gui.indices_len = 0; + ctx->gui.instance_count = 0; + ArenaFree(ctx->arena); +} + +// ::Game::GameLoop::Functions::End:: + + + +// ::Game::Inputs::Functions::Start:: static void HandleInputs(GameInput *inputs, u32 count) { @@ -78,25 +172,21 @@ static void HandleInputs(GameInput *inputs, u32 count) } } +// ::Game::Inputs::Functions::End:: + + + +// ::Game::GUI::Functions::Start:: + static inline void PrepareGUICtx(GameContext *ctx) { ctx->gui.has_grabbed = false; } -static inline u32 StrToU32(char *str) -{ - u32 result = 0; - for (; *str != '\0'; str++) - { - result += (u32)(*str); - } - return result; -} - static b32 UIButton(GameContext *ctx, char *label, f32 x0, f32 y0, f32 x1, f32 y1) { GUIButton *btn = NULL; - u32 id = StrToU32(label) + (u32)(x0 + y0 + x1 + y1); + u64 id = HashFromString(Str8L(label)); if (ctx->btn_len == 0) { ctx->buttons[0].p0.x = x0; @@ -156,7 +246,7 @@ static b32 UIButton(GameContext *ctx, char *label, f32 x0, f32 y0, f32 x1, f32 y static b32 UIWindow(GameContext *ctx, char *title, f32 x0, f32 y0, f32 x1, f32 y1) { GUIWindow *win = NULL; - u32 id = StrToU32(title) + (u32)(x0 + y0 + x1 + y1); + u32 id = HashFromString(Str8L(title)); if (ctx->window_len == 0) { ctx->windows[0].p0.x = x0; @@ -233,77 +323,6 @@ static b32 UIWindow(GameContext *ctx, char *title, f32 x0, f32 y0, f32 x1, f32 y return true; } -static void RunCycle(GameContext *ctx, GameInput *inputs, u32 i_count) -{ - __atomic_store_n(&renderer.vk.imm.job_count, 0, __ATOMIC_RELEASE); - __atomic_store_n(&renderer.vk.imm.remaining_count, 0, __ATOMIC_RELEASE); - - PrepareGUICtx(ctx); - - HandleInputs(inputs, i_count); - - if (UIButton(ctx, "Show 2", 150.0f, 150.0f, 200.0f, 200.0f)) - { - UIWindow(ctx, "Window 2", 500.0f, 500.0f, 600.0f, 600.0f); - } - - if (UIButton(ctx, "Show 1", 50.0f, 50.0f, 100.0f, 100.0f)) - { - UIWindow(ctx, "Window 1", 200.0f, 200.0f, 400.0f, 400.0f); - } - - if (UIButton(ctx, "Show 3", 150.0f, 300.0f, 200.0f, 350.0f)) - { - UIWindow(ctx, "Window 3", 250.0f, 500.0f, 400.0f, 650.0f); - } - - - GetViewportSize(&ctx->pc.res); - - - RenderBuffer *vertex_buffer = MakeArray(ctx->arena, RenderBuffer, 1); - vertex_buffer->type = RENDER_BUFFER_TYPE_VERTEX; - vertex_buffer->size = sizeof(GUIVertex) * ctx->gui.vertices_len; - - RenderBuffer *index_buffer = MakeArray(ctx->arena, RenderBuffer, 1); - index_buffer->type = RENDER_BUFFER_TYPE_INDEX, - index_buffer->size = sizeof(u32) * ctx->gui.indices_len, - - CreateAndUploadToBuffer(vertex_buffer, ctx->gui.vertices); - CreateAndUploadToBuffer(index_buffer, ctx->gui.indices); - - for (u32 i = 0; i < renderer.vk_conf.avail_threads; i++) - { - pthread_cond_signal(&cond); - } - - u32 count = -1; - while (count != 0) - { - __atomic_load(&renderer.vk.imm.remaining_count, &count, __ATOMIC_SEQ_CST); - } - - BeginFrame(); - - BindPipeline(PIPELINE_GUI, PIPELINE_TYPE_GRAPHICS); - - SetPushConstants(&ctx->pc); - - BindVertexBuffer(vertex_buffer); - BindIndexBuffer(index_buffer); - - DrawIndexed(6, ctx->gui.instance_count); - - FinishFrame(); - - FreeBuffers(vertex_buffer, 1); - FreeBuffers(index_buffer, 1); - - ctx->gui.vertices_len = 0; - ctx->gui.indices_len = 0; - ctx->gui.instance_count = 0; - ArenaFree(ctx->arena); -} static void DrawRect(GUIContext *ctx, Vec2 p0, Vec2 p1, Vec4 col) { @@ -324,3 +343,5 @@ static void DrawRect(GUIContext *ctx, Vec2 p0, Vec2 p1, Vec4 col) ctx->instance_count += 1; } + +// ::Game::GUI::Functions::End:: diff --git a/src/game.h b/src/game.h index df80eb7..ac7e1d9 100644 --- a/src/game.h +++ b/src/game.h @@ -1,24 +1,26 @@ #pragma once -typedef struct GUIWindow_t +// ::Game::Types::Header:: + +typedef struct GUIWindow { Vec2 p0; Vec2 p1; Vec2 grabbed_pos; - u32 id; + u64 id; b8 grabbed; } GUIWindow; -typedef struct GUIButton_t +typedef struct GUIButton { Vec2 p0; Vec2 p1; - u32 id; + u64 id; b8 pressed; b8 pressed_prev; } GUIButton; -typedef struct GameContext_t +typedef struct GameContext { GUIContext gui; PushConst pc; @@ -29,8 +31,22 @@ typedef struct GameContext_t u32 btn_len; } GameContext; -static void RunCycle(GameContext *ctx, GameInput *inputs, u32 i_count); +// ::Game::Init::Functions::Header:: + static void InitializeGame(Arena *arena, GameContext *ctx, Arena *ctx_arena); static void DestroyGame(); -static void DrawRect(GUIContext *ctx, Vec2 p0, Vec2 p1, Vec4 col); + +// ::Game::GameLoop::Functions::Header:: + +static void RunCycle(GameContext *ctx, GameInput *inputs, u32 i_count); + +// ::Game::Inputs::Functions::Header:: + static void HandleInputs(GameInput *inputs, u32 count); + +// ::Game::GUI::Functions::Header:: + +static inline void PrepareGUICtx(GameContext *ctx); +static void DrawRect(GUIContext *ctx, Vec2 p0, Vec2 p1, Vec4 col); +static b32 UIWindow(GameContext *ctx, c8 *title, f32 x0, f32 y0, f32 x1, f32 y1); +static b32 UIButton(GameContext *ctx, c8 *label, f32 x0, f32 y0, f32 x1, f32 y1); diff --git a/src/packer.c b/src/packer.c index c558bed..8c9965f 100644 --- a/src/packer.c +++ b/src/packer.c @@ -1,3 +1,5 @@ +// ::Packer::Includes::CFiles::Start:: + #include "packer.h" #include "xxhash/xxhash.c" @@ -10,76 +12,33 @@ #include "renderer.c" #include "game.c" -#define FWrite(buf, size, count, file) ((size) * (fwrite(buf, size, count, file))) -#define FRead(buf, size, count, file) ((size) * (fread(buf, size, count, file))) +// ::Packer::Includes::CFiles::End:: -#if __linux__ -b32 ChangeDir(c8 *dir) -{ - return chdir(dir); -} -u8 **GetFileNamesInDir(Arena *arena, u32 *count) -{ - struct dirent *dir; - DIR *d = opendir("."); +// ::Packer::Globals::Start:: - *count = 0; - if (d) - { - while ((dir = readdir(d)) != NULL) - { - if (!StrEq(dir->d_name, ".") && !StrEq(dir->d_name, "..")) - *count += 1; - } - } +const FileMapping g_Shader_File_Map[] = { + { .file_name = "quad.frag.spv", .ix = QUAD_FRAG_SPIRV_SHADER }, + { .file_name = "quad.vert.spv", .ix = QUAD_VERT_SPIRV_SHADER }, + { .file_name = "gui.frag.spv", .ix = GUI_FRAG_SPIRV_SHADER }, + { .file_name = "gui.vert.spv", .ix = GUI_VERT_SPIRV_SHADER }, +}; - c8 **file_names = MakeArray(arena, u8*, *count); +const FileMapping g_Texture_File_Map[] = { + { .file_name = "pattermon.png", .ix = PATTERMON_OBESE }, + { .file_name = "patamon.png", .ix = PATTERMON_ORIENTAL }, + { .file_name = "purplemon.png", .ix = PATTERMON_PURPLOID }, +}; - d = opendir("."); - *count = 0; - if (d) - { - while ((dir = readdir(d)) != NULL) - { - if (!StrEq(dir->d_name, ".") && !StrEq(dir->d_name, "..")) - { - i32 str_len = StrLen(dir->d_name); - file_names[*count] = MakeArray(arena, u8, str_len); - MemCpy(file_names[*count], dir->d_name, str_len); - *count += 1; - } - } - } +c8 *g_Shader_File_Names[SHADER_ASSET_MAX] = {}; +c8 *g_Texture_File_Names[TEXTURE_ASSET_MAX] = {}; - return (u8 **)file_names; -} +// ::Packer::Globals::End:: -b8 DirVisible(c8 *dir_name) -{ - b8 found = false; - struct dirent *dir; - DIR *d = opendir("."); - if (d) - { - while ((dir = readdir(d)) != NULL) - { - if (StrEq(dir_name, dir->d_name) && dir->d_type == DT_DIR) - { - found = true; - break; - } - } - } - - return found; -} -#elif _WIN32 -# error Not yet implemented -#endif +// ::Packer::Files::Functions::Start:: u64 FileLength(FILE *file) { @@ -113,6 +72,12 @@ void CloseFile(FILE *file) Assert(fclose(file) != EOF, "Error closing file"); } +// ::Packer::Files::Functions::End:: + + + +// ::Packer::Packing::Functions::Start:: + void SetArrayLookups() { for (i32 i = 0; i < Len(g_Shader_File_Map); i++) @@ -298,22 +263,11 @@ void PackFiles(Arena *arena, FileHeader *header) ChangeDir(return_dir); } -void PrintBytes(u8 *bytes, u64 len) -{ - u32 count = 0; - while (count + 8 < len) - { - Printfln("%#02X %#02X %#02X %#02X %#02X %#02X %#02X %#02X", bytes[count], bytes[count+1], bytes[count+2], bytes[count+3], - bytes[count+4], bytes[count+5], bytes[count+6], bytes[count+7]); - count += 8; - } +// ::Packer::Packing::Functions::End:: - while (count < len) - { - Printf("%u", bytes[count]); - count += 1; - } -} + + +// ::Packer::Tests::Functions::Start:: static inline void TestAssetIsCorrect(Arena *arena, c8 *file_name, AssetFile *file_info, FILE *file) { @@ -408,6 +362,12 @@ void TestAssetPack(Arena *arena) } } +// ::Packer::Tests::Functions::End:: + + + +// ::Packer::Main::Functions::Start:: + int main(int argc, c8 **argv) { Printfln("Header: %d", sizeof(FileHeader)); @@ -429,3 +389,5 @@ int main(int argc, c8 **argv) TestAssetPack(arena); } + +// ::Packer::Main::Functions::End:: diff --git a/src/packer.h b/src/packer.h index 2aede4f..fa8cc67 100644 --- a/src/packer.h +++ b/src/packer.h @@ -1,5 +1,7 @@ #pragma once +// ::Packer::Includes::Header:: + #if __linux__ # define _GNU_SOURCE #elif _WIN32 @@ -25,27 +27,31 @@ #include -#if __linux__ -# include -# include -#endif +// ::Packer::Macros::Header:: #define CreateMagicValue(a, b, c, d) ((u32)(d << 24) | (u32)(c << 16) | (u32)(b << 8) | (u32)(a)) +#define FWrite(buf, size, count, file) ((size) * (fwrite(buf, size, count, file))) +#define FRead(buf, size, count, file) ((size) * (fread(buf, size, count, file))) + +// ::Packer::Defines::Header:: + #define FILE_VERSION 0 -typedef struct AssetTag_t +// ::Packer::Types::Header:: + +typedef struct AssetTag { u32 tag_id; f32 value; } AssetTag; -typedef struct AssetFile_t +typedef struct AssetFile { u64 data_offset; u64 len; } AssetFile; -typedef struct AssetHeader_t +typedef struct AssetHeader { AssetTag *tags; AssetFile *assets; @@ -53,7 +59,7 @@ typedef struct AssetHeader_t u32 asset_count; } AssetHeader; -typedef struct FileHeader_t +typedef struct FileHeader { u32 magic_num; u32 version; @@ -65,36 +71,34 @@ typedef struct FileHeader_t u64 asset_offsets[ASSET_TYPE_MAX]; } FileHeader; -typedef struct FileMapping_t +typedef struct FileMapping { c8 *file_name; u32 ix; } FileMapping; -const FileMapping g_Shader_File_Map[] = { - { .file_name = "quad.frag.spv", .ix = QUAD_FRAG_SPIRV_SHADER }, - { .file_name = "quad.vert.spv", .ix = QUAD_VERT_SPIRV_SHADER }, - { .file_name = "gui.frag.spv", .ix = GUI_FRAG_SPIRV_SHADER }, - { .file_name = "gui.vert.spv", .ix = GUI_VERT_SPIRV_SHADER }, -}; +// ::Packer::Files::Functions::Header:: -const FileMapping g_Texture_File_Map[] = { - { .file_name = "pattermon.png", .ix = PATTERMON_OBESE }, - { .file_name = "patamon.png", .ix = PATTERMON_ORIENTAL }, - { .file_name = "purplemon.png", .ix = PATTERMON_PURPLOID }, -}; - -c8 *g_Shader_File_Names[SHADER_ASSET_MAX] = {}; -c8 *g_Texture_File_Names[TEXTURE_ASSET_MAX] = {}; - -b32 ChangeDir(c8 *dir); -u8 **GetFileNamesInDir(Arena *arena, u32 *count); -b8 DirVisible(c8 *dir); -void InitHeader(FileHeader *header); -i32 WriteHeader(FILE *file, FileHeader *header); FILE *OpenFile(c8 *name, c8 *mode); void CloseFile(FILE *file); u64 FileLength(FILE *file); u64 WriteData(void *buf, u64 pos, u64 size, FILE *file); u64 ReadData(void *buf, u64 pos, u64 size, FILE *file); + +// ::Packer::Packing::Functions::Header:: + +void SetArrayLookups(); +void InitHeader(FileHeader *header); +i32 WriteHeader(FILE *file, FileHeader *header); +void PackFiles(Arena *arena, FileHeader *header); +void MoveToTextureDir(c8 **return_dir); +void MoveToShaderDir(c8 **return_dir); + +// ::Packer::Tests::Functions::Header:: + +void TestAssetPack(Arena *arena); static inline void TestAssetIsCorrect(Arena *arena, c8 *file_name, AssetFile *file_info, FILE *file); + +// ::Packer::Main::Functions::Header:: + +int main(int argc, char **argv); diff --git a/src/platform/platform.c b/src/platform/platform.c index 50ed91c..05a1051 100644 --- a/src/platform/platform.c +++ b/src/platform/platform.c @@ -14,36 +14,3 @@ #error Not yet implemented #endif -i32 Printf(const char *fmt, ...) -{ - va_list arg; - - va_start(arg, fmt); - i32 result = _Printf(fmt, arg); - va_end(arg); - - return result; -} - -i32 Printfln(const char *fmt, ...) -{ - va_list arg; - - va_start(arg, fmt); - i32 result = _Printfln(fmt, arg); - va_end(arg); - - return result; -} - -i32 EPrintf(const char *fmt, ...) -{ - va_list arg; - - va_start(arg, fmt); - i32 result = _EPrintf(fmt, arg); - va_end(arg); - - return result; -} - diff --git a/src/platform/platform.h b/src/platform/platform.h index 3b10eea..58d7fad 100644 --- a/src/platform/platform.h +++ b/src/platform/platform.h @@ -2,57 +2,8 @@ // ::Platform::Types::Header:: -typedef enum Event_e Event_e; -typedef struct WindowEvent WindowEvent; -typedef struct WindowSize WindowSize; - -enum Event_e -{ - EVENT_NONE = 0, - EVENT_QUIT, - EVENT_RESIZE, - EVENT_MINIMIZE, - EVENT_SHOW, -}; - -struct WindowSize -{ - u16 w; - u16 h; -}; - -struct WindowEvent -{ - union - { - WindowSize resize; - }; - Event_e type; -}; - -#if __linux__ - -typedef struct { - void *lib; -} Library; - -typedef struct { - void *fn; -} Function; - -#elif _WIN32 - -typedef struct -{ - HMODULE module; -} Library; - -typedef struct -{ - FARPROC fn; -} Function; - -#endif +typedef struct Library Library; +typedef struct Function Function; // ::Platform::Includes::Header:: @@ -72,39 +23,43 @@ typedef struct #error Not yet implemented #endif -// ::Platform::Functions::Header:: +// ::Platform::Types::Header:: -// ::Platform::Functions::Init::Header:: +typedef struct WindowSize +{ + u16 h, w; +} WindowSize; + +// ::Platform::ConsoleOut::Functions::Header:: + +i32 WriteStdOut(void *buf, i32 len); +i32 WriteStdErr(void *buf, i32 len); + +// ::Platform::Library::Functions::Header:: b32 LoadLib(const char *name, Library *out_lib); b32 LoadFn(const char *name, Library *lib, Function *out_fn); -// ::Platform::Functions::Memory::Header:: +// ::Platform::Memory::Functions::Header:: -rawptr MemAlloc(isize size); -rawptr MemAllocZeroed(isize size); -void MemFree(rawptr ptr, isize size); -isize GetPageSize(); +rawptr MemAlloc(usize size); +rawptr MemAllocZeroed(usize size); +void MemFree(rawptr ptr, usize size); +usize GetPageSize(); -// ::Platform::Functions::Print::Header:: - -i32 EPrint(void const *str); -i32 Printf(const char *fmt, ...); -i32 Printfln(const char *fmt, ...); -i32 EPrintf(const char *fmt, ...); - -// ::Platform::Functions::Window::Header:: +// ::Platform::Window::Functions::Header:: b32 CreatePlatformWindow(const char *window_name); WindowSize GetWindowSize(); b32 ShouldQuit(); PlatformWindow *GetPlatformWindow(); -// ::Platform::Functions::SystemInfo::Header:: +// ::Platform::SystemInfo::Functions::Header:: u32 AvailableCPUCount(); -// ::Platform::Functions::Directory::Header:: +// ::Platform::FileSystem::Functions::Header:: -b32 ChangeWorkingDir(const char *); -u8 *OSOpenFile(const char *); +b32 ChangeDir(c8 *dir); +c8 **GetFileNamesInDir(Arena *arena, u32 *count); +b8 DirVisible(c8 *dir_name); diff --git a/src/platform/platform_linux.c b/src/platform/platform_linux.c index 33994b7..1f7037c 100644 --- a/src/platform/platform_linux.c +++ b/src/platform/platform_linux.c @@ -1,4 +1,4 @@ -// TODO(MA): Do stuff for general unix platforms some day +// ::Platform::Linux::Globals::Start:: static PlatformWindow linux_window = { .w = 1920, @@ -7,29 +7,21 @@ static PlatformWindow linux_window = { b32 global_quit = false; -// Init +// ::Platform::Linux::Globals::End:: +// ::Platform::Linux::Print::Functions::Start:: -// Init End - -b32 CheckSyscallErr(void *ptr) +i32 WriteStdOut(rawptr buf, i32 len) { - return (isize)ptr == SYS_ERR ? true : false; + return (i32)write(STDOUT, buf, len); } -i32 Write(int fd, void const *str, isize count) +i32 WriteStdErr(rawptr buf, i32 len) { - i32 result = (i32)write(fd, str, count); - return result; + return (i32)write(STDERR, buf, len); } -WindowSize _GetWindowSize() -{ - return (WindowSize) { - .w = linux_window.w, - .h = linux_window.h, - }; -} +// ::Platform::Linux::Window::Functions::Start:: void GetWindowEvents(GameInput *inputs, u32 *i_count) { @@ -69,15 +61,6 @@ void HandleWindowEvent(GameInput *inputs, u32 *i_count, b32 wait_for_event) if (msg->data.data32[0] == linux_window.close_event) global_quit = true; - -#ifndef STG_NO_RENDERER - if (msg->type == XCB_ATOM_NOTICE) - SetRenderResolution(linux_window.w, linux_window.h); -#endif - } break; - case XCB_EXPOSE: - { - RepaintWindow(); } break; case XCB_CONFIGURE_NOTIFY: { @@ -162,19 +145,6 @@ void HandleWindowEvent(GameInput *inputs, u32 *i_count, b32 wait_for_event) } while(!wait_for_event && !has_max_inputs); } -void RepaintWindow() -{ - xcb_client_message_event_t client_message = { - .response_type = XCB_CLIENT_MESSAGE, - .format = 32, - .window = linux_window.window, - .type = XCB_ATOM_NOTICE, - }; - - xcb_send_event(linux_window.connection, 0, linux_window.window, 0, (char *)&client_message); - xcb_flush(linux_window.connection); -} - KeyboardInput ConvertInputEvent(u32 x_key) { switch (x_key) @@ -311,30 +281,21 @@ KeyboardInput ConvertInputEvent(u32 x_key) } } -b32 ChangeWorkingDir(const char *) -{ - b32 success = false; +// ::Platform::Linux::Window::Functions::Start:: - return success; + + +// ::Platform::Linux::Utils::Functions::Start:: + +b32 CheckSyscallErr(void *ptr) +{ + return (isize)ptr == SYS_ERR ? true : false; } -u8 *OSOpenFile(const char *) -{ - u8 *bytes = NULL; +// ::Platform::Linux::Utils::Functions::End:: - return bytes; -} -b32 ShouldQuit() -{ - return false; -} -u32 AvailableCPUCount() -{ - cpu_set_t cpu_set; - sched_getaffinity(0, sizeof(cpu_set), &cpu_set); - return CPU_COUNT(&cpu_set); -} +// ::Platform::Linux::Includes::CFile:: #include "platform_linux_public.c" diff --git a/src/platform/platform_linux.h b/src/platform/platform_linux.h index 0bd9749..0be15a9 100644 --- a/src/platform/platform_linux.h +++ b/src/platform/platform_linux.h @@ -20,22 +20,20 @@ #include #include #include - -#ifndef STG_NO_WINDOW - -#endif - #include +#include +#include + +// ::Platform::Linux::Defines::Header:: -// syscall defines #define SYS_ERR -1 -// syscall write defines -#define _STDIN 0 -#define _STDOUT 1 -#define _STDERR 2 +#define STDIN 0 +#define STDOUT 1 +#define STDERR 2 + +// ::Platform::Linux::Macros::Header:: -// xcb defines #define XCB_CHECK_CURRENT_ERROR(window, error, message) do { \ error = xcb_request_check(window->connection, cookie); \ if (error != NULL) { \ @@ -50,7 +48,10 @@ XCB_CHECK_CURRENT_ERROR(window, error, message); \ } while (0) -typedef struct { +// ::Platform::Linux::Types::Header + +typedef struct PlatformWindow +{ Display *display; xcb_connection_t *connection; xcb_window_t window; @@ -59,26 +60,28 @@ typedef struct { u16 w, h; } PlatformWindow; -// ::Platform::Linux::Functions::Header:: +typedef struct Library +{ + void *lib; +} Library; -// Print Functions -i32 _EPrint(void const *str); -i32 _Printf(const char *fmt, va_list arg); -i32 _Printfln(const char *fmt, va_list arg); -i32 _EPrintf(const char *fmt, va_list arg); +typedef struct Function +{ + void *fn; +} Function; + +// ::Platform::Linux::Print::Functions::Header:: + +i32 Write(int fd, void const *str, isize count); + +// ::Platform::Linux::Window::Functions::Header:: -// Window Functions void GetWindowEvents(GameInput *inputs, u32 *i_count); b32 WaitForWindowEvent(GameInput *input); void HandleWindowEvent(GameInput *inputs, u32 *input_count, b32 wait_for_event); KeyboardInput ConvertInputEvent(u32 x_key); -void RepaintWindow(); -// Platform API END +// ::Platform::Linux::Utils::Functions::Header:: -// General Utils b32 CheckSyscallErr(void *ptr); -// Write Utils -i32 Write(int fd, void const *str, isize count); - diff --git a/src/platform/platform_linux_public.c b/src/platform/platform_linux_public.c index 294d112..f728171 100644 --- a/src/platform/platform_linux_public.c +++ b/src/platform/platform_linux_public.c @@ -1,4 +1,4 @@ -// ::Platform::Functions::Start:: +// ::Platform::Functions::Library::Start:: b32 LoadLib(const char *name, Library *out_lib) { @@ -29,61 +29,20 @@ b32 LoadFn(const char *name, Library *lib, Function *out_fn) return true; } +// ::Platform::Functions::Library::End:: -i32 EPrint(void const *str) -{ - return Write(_STDERR, str, (isize)StrLen(str)); -} -i32 _EPrintf(const char *fmt, va_list arg) -{ - char buffer[1024]; +// ::Platform::Functions::Print::Start:: - int sprf_res = stbsp_vsnprintf(&buffer[0], 1024, fmt, arg); - if (sprf_res < 0) return sprf_res; - - return EPrint(&buffer); -} +// ::Platform::Functions::Print::End:: -i32 _Printf(const char *fmt, va_list arg) -{ - char buffer[1024]; - - int sprf_res = stbsp_vsnprintf(&buffer[0], 1024, fmt, arg); - - i32 pr_res; - if (sprf_res < 0) - pr_res = sprf_res; - else - pr_res = Write(_STDOUT, &buffer, sprf_res); - return pr_res; -} -i32 _Printfln(const char *fmt, va_list arg) -{ - char buffer[1024]; +// ::Platform::Functions::Memory::Start:: - int sprf_res = stbsp_vsnprintf(&buffer[0], 1023, fmt, arg); - - i32 pr_res; - if (sprf_res < 0) - { - pr_res = sprf_res; - } - else - { - buffer[sprf_res] = '\n'; - buffer[sprf_res+1] = '\0'; - pr_res = Write(_STDOUT, &buffer, sprf_res+1); - } - - return pr_res; -} - -rawptr MemAlloc(isize size) +rawptr MemAlloc(usize size) { void *addr = mmap( NULL, @@ -99,23 +58,29 @@ rawptr MemAlloc(isize size) return addr; } -rawptr MemAllocZeroed(isize size) +rawptr MemAllocZeroed(usize size) { rawptr ptr = MemAlloc(size); MemZero(ptr, size); return ptr; } -void MemFree(rawptr ptr, isize size) +void MemFree(rawptr ptr, usize size) { Assert(munmap(ptr, size) == 0, "munmap failed"); } -isize GetPageSize() +usize GetPageSize() { - return (isize)sysconf(_SC_PAGESIZE); + return (usize)sysconf(_SC_PAGESIZE); } +// ::Platform::Functions::Memory::End:: + + + +// ::Platform::Functions::Window::Start:: + b32 CreatePlatformWindow(const char *window_name) { PlatformWindow *window = &linux_window; @@ -224,7 +189,105 @@ b32 CreatePlatformWindow(const char *window_name) return true; } +WindowSize GetWindowSize() +{ + return (WindowSize) { + .w = linux_window.w, + .h = linux_window.h, + }; +} + PlatformWindow *GetPlatformWindow() { return &linux_window; } + +b32 ShouldQuit() +{ + return false; +} + +// ::Platform::Functions::Window::End:: + + + +// ::Platform::Functions::SystemInfo::Start:: + +u32 AvailableCPUCount() +{ + cpu_set_t cpu_set; + sched_getaffinity(0, sizeof(cpu_set), &cpu_set); + return CPU_COUNT(&cpu_set); +} + +// ::Platform::Functions::SystemInfo::StarEnd:: + + + +// ::Platform::Functions::Directory::Start:: + +b32 ChangeDir(c8 *dir) +{ + return chdir(dir); +} + +c8 **GetFileNamesInDir(Arena *arena, u32 *count) +{ + struct dirent *dir; + + DIR *d = opendir("."); + + *count = 0; + if (d) + { + while ((dir = readdir(d)) != NULL) + { + if (!StrEq(dir->d_name, ".") && !StrEq(dir->d_name, "..")) + *count += 1; + } + } + + c8 **file_names = MakeArray(arena, u8*, *count); + + d = opendir("."); + *count = 0; + if (d) + { + while ((dir = readdir(d)) != NULL) + { + if (!StrEq(dir->d_name, ".") && !StrEq(dir->d_name, "..")) + { + i32 str_len = StrLen(dir->d_name); + file_names[*count] = MakeArray(arena, u8, str_len); + MemCpy(file_names[*count], dir->d_name, str_len); + *count += 1; + } + } + } + + return (c8 **)file_names; +} + +b8 DirVisible(c8 *dir_name) +{ + b8 found = false; + + struct dirent *dir; + DIR *d = opendir("."); + + if (d) + { + while ((dir = readdir(d)) != NULL) + { + if (StrEq(dir_name, dir->d_name) && dir->d_type == DT_DIR) + { + found = true; + break; + } + } + } + + return found; +} + +// ::Platform::Functions::Directory::End:: diff --git a/src/platform/platform_windows.c b/src/platform/platform_windows.c index 18cac73..086afa2 100644 --- a/src/platform/platform_windows.c +++ b/src/platform/platform_windows.c @@ -56,17 +56,17 @@ b32 LoadFn(const char *name, Library *lib, Function *out_fn) return success; } -rawptr _MemAlloc(isize size) +rawptr MemAlloc(isize size) { return (rawptr)VirtualAlloc(0, size, MEM_RESERVE|MEM_COMMIT, PAGE_READWRITE); } -rawptr _MemAllocZeroed(isize size) +rawptr MemAllocZeroed(isize size) { return _MemAlloc(size); } -isize _GetPageSize() +isize GetPageSize() { return 0; } diff --git a/src/platform/platform_windows.h b/src/platform/platform_windows.h index f20b475..02b6d28 100644 --- a/src/platform/platform_windows.h +++ b/src/platform/platform_windows.h @@ -1,12 +1,16 @@ #pragma once -#include +#include #include #include +// ::Platform::Windows::Defines::Header:: + #define WINDOW_CLASS_NAME "GearsWindowClass" -typedef struct +// ::Platform::Windows::Types::Header:: + +typedef struct PlatformWindow { HINSTANCE instance; HWND handle; @@ -14,14 +18,21 @@ typedef struct b32 resize_requested; } PlatformWindow; +typedef struct Library +{ + HMODULE module; +} Library; + +typedef struct +{ + FARPROC fn; +} Function; + +// ::Platform::Windows::Functions::::Header:: + rawptr _MemAlloc(isize size); rawptr _MemAllocZeroed(isize size); isize _GetPageSize(); -i32 _EPrint(void const *str); -i32 _Printf(const char *fmt, va_list arg); -i32 _Printfln(const char *fmt, va_list arg); -i32 _EPrintf(const char *fmt, va_list arg); - void GetWindowEvents(); void WaitForWindowEvent(); diff --git a/src/renderer.h b/src/renderer.h index 9584376..8a0f251 100644 --- a/src/renderer.h +++ b/src/renderer.h @@ -1,5 +1,17 @@ #pragma once +// ::Renderer::Declarations::Header:: + +typedef u16 DescHandle; + +// @requirement RenderBuffer type; +// @requirement u32 size; +typedef struct RenderBuffer RenderBuffer; +typedef struct PushConst PushConst; +typedef struct ShaderGlobals ShaderGlobals; + +// ::Renderer::Enums::Header:: + typedef enum Pipeline_e { PIPELINE_CUBE, @@ -30,34 +42,21 @@ typedef enum VertexAttrType_e VERTEX_ATTRIBUTE_TYPE_COLOR = 1, } VertexAttrType; -// Renderer Front End Types +// ::Renderer::Types::Header:: -// Declarations - -typedef u16 DescHandle; - -// @requirement RenderBuffer type; -// @requirement u32 size; -typedef struct RenderBuffer_t RenderBuffer; -typedef struct PushConst_t PushConst; -typedef struct ShaderGlobals_t ShaderGlobals; - -// Types -typedef struct RenderBuffers_t +typedef struct RenderBuffers { RenderBuffer *buffers; u32 len; } RenderBuffers; -// Renderer Front End Types END +// ::Renderer::Initialization::Header:: -// Back End API - -// ::Initialization::Header:: b32 InitRenderer(Arena *arena); void DestroyRenderer(); -// ::Buffers::Header:: +// ::Renderer::Buffers::Header:: + static b32 CreateBuffer(RenderBuffer *buffer); static void FreeBuffers(RenderBuffer *buffers, u32 buffer_count); static b32 UploadToBuffer(RenderBuffer **buffer, rawptr *ptr, u32 count, u8 thr_ix); @@ -65,22 +64,28 @@ static void CreateAndUploadToBuffer(RenderBuffer *buffer, rawptr ptr); static void BindVertexBuffer(RenderBuffer *buffer); static void BindIndexBuffer(RenderBuffer *buffer); -// ::Uniforms::Header:: ::PushConstants::Header:: +// ::Renderer::Uniforms::Header:: +// ::Renderer::PushConstants::Header:: + static void GetViewportSize(Vec2 *size); static void SetGlobalUniform(ShaderGlobals *globals); static void SetPushConstants(PushConst *pc); static DescHandle UploadImageUniform(); -// ::Config::Header:: +// ::Renderer::Config::Header:: + static void SetRenderResolution(u32 x, u32 y); static void SetRendererAvailableThreads(u32 n); -// ::Rendering::Header:: +// ::Renderer::Rendering::Header:: + static b32 BeginFrame(); static b32 FinishFrame(); static void DrawIndexed(u32 index_count, u32 instance_count); static void BindPipeline(PipelineHandle handle, PipelineType type); +// ::Renderer::Includes::Header:: + #if STG_VULKAN_RENDERER #include "renderer_vulkan.h" #endif diff --git a/src/renderer_vulkan.c b/src/renderer_vulkan.c index 4776400..adf712d 100644 --- a/src/renderer_vulkan.c +++ b/src/renderer_vulkan.c @@ -1,11 +1,44 @@ -/** - * BACK END API - */ +// ::Vulkan::Globals::Start:: -// TODO(MA): Make separate functions for debug/non debug builds for readability +static Renderer renderer = { + .vk = { + .queues = { + .graphics = -1, + .transfer = -1, + }, + .sc = { + .format = INT_MAX, + .color_space = INT_MAX, + .present_mode = INT_MAX, + }, + .imm = { + .next_ticket = 1, + }, + } +}; + +static u32 vk_thread_indices[10] = {}; + +#if __linux__ +pthread_cond_t cond; +#elif _WIN32 +# error threading not yet implemented +#endif + +// ::Vulkan::Globals::End:: + + + +// ::Vulkan::Includes::CFiles::Start:: #include "renderer_vulkan_public.c" +// ::Vulkan::Includes::CFiles::End:: + + + +// ::Vulkan::Util::Functions::Start:: + static inline u32 GetFrameIndex() { return renderer.frame_state.frame_cnt % FRAME_OVERLAP; @@ -41,6 +74,87 @@ static inline RenderBuffer *GetFrameRenderBuffers() return renderer.vk.frame.buffer_destroy_queues[GetFrameIndex()]; } +static inline void CopyImageToImage(VkCommandBuffer cmd, VkImage src, VkImage dst, VkExtent2D src_ext, VkExtent2D dst_ext) +{ + VkImageBlit2 blit = { + .sType = STYPE(IMAGE_BLIT_2), + .srcOffsets = { + {0}, + { .x = (i32)src_ext.width, .y = (i32)src_ext.height, .z = 1 }, + }, + .dstOffsets = { + {0}, + { .x = (i32)dst_ext.width, .y = (i32)dst_ext.height, .z = 1 }, + }, + .srcSubresource = { + .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT, + .baseArrayLayer = 0, + .layerCount = 1, + .mipLevel = 0, + }, + .dstSubresource = { + .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT, + .baseArrayLayer = 0, + .layerCount = 1, + .mipLevel = 0, + }, + }; + + VkBlitImageInfo2 blit_info = { + .sType = STYPE(BLIT_IMAGE_INFO_2), + .srcImage = src, + .srcImageLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, + .dstImage = dst, + .dstImageLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, + .filter = VK_FILTER_LINEAR, + .regionCount = 1, + .pRegions = &blit, + }; + + vkCmdBlitImage2(cmd, &blit_info); +} + +static inline void TransitionImageLayout(VkCommandBuffer cmd, VkImage img, VkImageLayout curr, VkImageLayout new) +{ + VkImageMemoryBarrier2 barrier = { + .sType = STYPE(IMAGE_MEMORY_BARRIER_2), + .srcStageMask = VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT, + .srcAccessMask = VK_ACCESS_2_MEMORY_WRITE_BIT, + .dstStageMask = VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT, + .dstAccessMask = VK_ACCESS_2_MEMORY_WRITE_BIT | VK_ACCESS_2_MEMORY_READ_BIT, + .oldLayout = curr, + .newLayout = new, + .image = img, + .subresourceRange = { + .aspectMask = new == VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL ? VK_IMAGE_ASPECT_DEPTH_BIT : VK_IMAGE_ASPECT_COLOR_BIT, + .baseMipLevel = 0, + .levelCount = VK_REMAINING_MIP_LEVELS, + .baseArrayLayer = 0, + .layerCount = VK_REMAINING_ARRAY_LAYERS, + }, + }; + + VkDependencyInfo dep_info = { + .sType = STYPE(DEPENDENCY_INFO), + .imageMemoryBarrierCount = 1, + .pImageMemoryBarriers = &barrier, + }; + + vkCmdPipelineBarrier2(cmd, &dep_info); +} + +static inline void TransitionImage(VkCommandBuffer cmd, Image *img, VkImageLayout new) +{ + TransitionImageLayout(cmd, img->img, img->curr_layout, new); + img->curr_layout = new; +} + +// ::Vulkan::Util::Functions::End:: + + + +// ::Vulkan::Rendering::Functions::Start:: + static void BeginRendering() { VkCommandBuffer cmd = GetFrameCmdBuf(); @@ -87,26 +201,11 @@ static void BeginRendering() vkCmdBindDescriptorSets(cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, renderer.vk.pipe.pipeline_layout, 0, DESC_TYPE_MAX, renderer.vk.pipe.sets, 0, NULL); } -void ClearScreen() -{ - -} - -static void DrawGUI(GUIContext *ctx) -{ - if (!renderer.frame_state.begin_rendering) - BeginRendering(); - - VkCommandBuffer cmd = GetFrameCmdBuf(); - - if (renderer.frame_state.last_pipeline != PIPELINE_GUI) - { - vkCmdBindPipeline(cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, renderer.vk.pipe.pipelines[PIPELINE_GUI]); - renderer.frame_state.last_pipeline = PIPELINE_GUI; - } +// ::Vulkan::Rendering::Functions::End:: -} + +// ::Vulkan::ImmediateSubmit::Functions::Start:: static b32 BeginImmSubmit(VkDevice device, VkFence *fence, VkCommandBuffer cmd) { @@ -192,23 +291,12 @@ static b32 FinishImmSubmit(VkDevice device, VkFence *fence, VkCommandBuffer cmd, return success; } - -static b32 UploadGUIBuffer(MeshBuffer *buf, GUIContext *ctx) -{ - b32 success = true; - return success; -} +// ::Vulkan::ImmediateSubmit::Functions::End:: -/** - * BACK END API END - */ -/** - * INTERNAL API - */ +// ::Vulkan::Swapchain::Functions::Start:: -// Swapchain static void ResizeSwapchain() { vkDeviceWaitIdle(renderer.vk.device); @@ -226,84 +314,11 @@ static void ResizeSwapchain() renderer.pending.resized = false; } -// UTIL +// ::Vulkan::Swapchain::Functions::End:: -static void CopyImageToImage(VkCommandBuffer cmd, VkImage src, VkImage dst, VkExtent2D src_ext, VkExtent2D dst_ext) -{ - VkImageBlit2 blit = { - .sType = STYPE(IMAGE_BLIT_2), - .srcOffsets = { - {0}, - { .x = (i32)src_ext.width, .y = (i32)src_ext.height, .z = 1 }, - }, - .dstOffsets = { - {0}, - { .x = (i32)dst_ext.width, .y = (i32)dst_ext.height, .z = 1 }, - }, - .srcSubresource = { - .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT, - .baseArrayLayer = 0, - .layerCount = 1, - .mipLevel = 0, - }, - .dstSubresource = { - .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT, - .baseArrayLayer = 0, - .layerCount = 1, - .mipLevel = 0, - }, - }; - VkBlitImageInfo2 blit_info = { - .sType = STYPE(BLIT_IMAGE_INFO_2), - .srcImage = src, - .srcImageLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, - .dstImage = dst, - .dstImageLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, - .filter = VK_FILTER_LINEAR, - .regionCount = 1, - .pRegions = &blit, - }; - vkCmdBlitImage2(cmd, &blit_info); -} - -static void TransitionImageLayout(VkCommandBuffer cmd, VkImage img, VkImageLayout curr, VkImageLayout new) -{ - VkImageMemoryBarrier2 barrier = { - .sType = STYPE(IMAGE_MEMORY_BARRIER_2), - .srcStageMask = VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT, - .srcAccessMask = VK_ACCESS_2_MEMORY_WRITE_BIT, - .dstStageMask = VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT, - .dstAccessMask = VK_ACCESS_2_MEMORY_WRITE_BIT | VK_ACCESS_2_MEMORY_READ_BIT, - .oldLayout = curr, - .newLayout = new, - .image = img, - .subresourceRange = { - .aspectMask = new == VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL ? VK_IMAGE_ASPECT_DEPTH_BIT : VK_IMAGE_ASPECT_COLOR_BIT, - .baseMipLevel = 0, - .levelCount = VK_REMAINING_MIP_LEVELS, - .baseArrayLayer = 0, - .layerCount = VK_REMAINING_ARRAY_LAYERS, - }, - }; - - VkDependencyInfo dep_info = { - .sType = STYPE(DEPENDENCY_INFO), - .imageMemoryBarrierCount = 1, - .pImageMemoryBarriers = &barrier, - }; - - vkCmdPipelineBarrier2(cmd, &dep_info); -} - -static void TransitionImage(VkCommandBuffer cmd, Image *img, VkImageLayout new) -{ - TransitionImageLayout(cmd, img->img, img->curr_layout, new); - img->curr_layout = new; -} - -// INIT +// ::Vulkan::Init::Functions::Start:: static b32 CreateVmaAllocator() { @@ -719,27 +734,6 @@ static b32 LoadVulkanLib() return lib_found; } -static b32 VLayersSupported() -{ - b32 success; - - u32 count; - vkEnumerateInstanceLayerProperties(&count, NULL); - Assert(count, "VLayersSupported(): vkEnumerateInstanceLayerProperties returned a count of 0"); - - VkLayerProperties *layers = ArenaAlloc(renderer.arena, sizeof(VkLayerProperties) * count); - vkEnumerateInstanceLayerProperties(&count, layers); - - for (u32 i = 0; i < count; i++) { - if (StrEq(layers[i].layerName, _VK_VALIDATION)) { - success = true; - break; - } - } - - return success; -} - static b32 CreateFrameStructures() { b32 success = true; @@ -1170,9 +1164,36 @@ static b32 CreateShaderModule(u8 *bytes, u32 len, VkShaderModule *module) return success; } -#ifdef __linux__ +#if __linux__ -pthread_cond_t cond; +static void StartVkLoaderThreads() +{ + if (renderer.vk_conf.avail_threads == 0) + return; + + u32 count = renderer.vk_conf.avail_threads; + pthread_t *threads = ArenaAlloc(renderer.perm_arena, sizeof(pthread_t) * count); + + for (u32 i = 0; i < count; i++) + { + vk_thread_indices[i] = i; + pthread_create(&threads[i], NULL, VkLoaderStart, &vk_thread_indices[i]); + } +} + +#elif _WIN32 + +# error Threading not yet implemented + +#endif + +// ::Vulkan::Init::Functions::End:: + + + +// ::Vulkan::Async::Functions::Start:: + +#ifdef __linux__ void *VkLoaderStart(void *i) { @@ -1226,20 +1247,6 @@ void *VkLoaderStart(void *i) } } -static void StartVkLoaderThreads() -{ - if (renderer.vk_conf.avail_threads == 0) - return; - - u32 count = renderer.vk_conf.avail_threads; - pthread_t *threads = ArenaAlloc(renderer.perm_arena, sizeof(pthread_t) * count); - - for (u32 i = 0; i < count; i++) - { - vk_thread_indices[i] = i; - pthread_create(&threads[i], NULL, VkLoaderStart, &vk_thread_indices[i]); - } -} #elif _WIN32 @@ -1247,6 +1254,12 @@ static void StartVkLoaderThreads() #endif +// ::Vulkan::Async::Functions::End:: + + + +// ::Vulkan::CleanUp::Functions::Start:: + static void DestroySwapchain() { for (u32 i = 0; i < renderer.vk.sc.img_count; i++) @@ -1270,6 +1283,12 @@ static void DestroyDrawImages() vmaDestroyImage(vma_alloc, sc->depth_img.img, sc->depth_img.alloc); } +// ::Vulkan::CleanUp::Functions::End:: + + + +// ::Vulkan::Logging::Functions::Start:: + void VkInfo(const char *str) { Printfln("[INFO] %s", str); @@ -1285,6 +1304,12 @@ void VkError(const char *str) Printfln("[ERROR] %s", str); } +// ::Vulkan::Logging::Functions::End:: + + + +// ::Vulkan::Debug::Functions::Start:: + const char *VkResultStr(VkResult result) { switch (result) @@ -1456,4 +1481,25 @@ static VKAPI_ATTR VkBool32 DebugCallback( return VK_FALSE; } +static b32 VLayersSupported() +{ + b32 success = false; + u32 count; + vkEnumerateInstanceLayerProperties(&count, NULL); + Assert(count, "VLayersSupported(): vkEnumerateInstanceLayerProperties returned a count of 0"); + + VkLayerProperties *layers = ArenaAlloc(renderer.arena, sizeof(VkLayerProperties) * count); + vkEnumerateInstanceLayerProperties(&count, layers); + + for (u32 i = 0; i < count; i++) { + if (StrEq(layers[i].layerName, _VK_VALIDATION)) { + success = true; + break; + } + } + + return success; +} + +// ::Vulkan::Debug::Functions::End:: diff --git a/src/renderer_vulkan.h b/src/renderer_vulkan.h index 584d618..cfcb2a3 100644 --- a/src/renderer_vulkan.h +++ b/src/renderer_vulkan.h @@ -16,6 +16,27 @@ #include "file_data/spv.c" +// ::Vulkan::Constants::Header:: + +static const char *_VK_VALIDATION = "VK_LAYER_KHRONOS_validation"; + +#if __linux__ +static char *vulkan_libs[] = { + "libvulkan.so.1", + "libvulkan.so" +}; +#endif + +#if _WIN32 +static char *vulkan_libs[] = { + "vulkan-1.dll", +}; +#endif + +#if __unix__ && !__linux__ +#error Not yet implemented +#endif + // ::Vulkan::Macros::Header:: #define VK_DECLARE(fn) static PFN_##fn fn = NULL @@ -158,12 +179,12 @@ typedef enum DescType_e DESC_TYPE_MAX, } DescType; -typedef struct ShaderGlobals_t +typedef struct ShaderGlobals { Vec2 res; } ShaderGlobals; -typedef struct RenderBuffer_t +typedef struct RenderBuffer { RenderBufferType type; VkBuffer buffer; @@ -173,18 +194,18 @@ typedef struct RenderBuffer_t i32 mem_index; // TODO(MA): use this } RenderBuffer; -typedef struct +typedef struct MeshBuffer { RenderBuffer index_buf, vertex_buf; u32 index_count; } MeshBuffer; -typedef struct +typedef struct GlobalUniforms { f32 res[2]; } GlobalUniforms; -typedef struct +typedef struct DescBindings { u16 *free; u16 free_count; @@ -193,7 +214,7 @@ typedef struct DescHandle *handle_indices; } DescBindings; -typedef struct +typedef struct PipelineStructures { VkPipelineLayout pipeline_layout; VkDescriptorPool pool; @@ -204,12 +225,12 @@ typedef struct VkPipeline pipelines[PIPELINE_MAX]; } PipelineStructures; -typedef struct PushConst_t +typedef struct PushConst { Vec2 res; } PushConst; -typedef struct +typedef struct FrameStructures { VkCommandPool *pools; VkCommandBuffer *buffers; @@ -220,7 +241,7 @@ typedef struct u32 *buffer_counts; } FrameStructures; -typedef struct +typedef struct ImmediateStructures { VkCommandPool *pools; VkCommandBuffer *cmds; @@ -233,13 +254,15 @@ typedef struct u32 volatile next_ticket; } ImmediateStructures; -typedef struct { +typedef struct DeviceQueues +{ i32 graphics, transfer; VkQueue graphics_queue, transfer_queue; b8 single_queue; } DeviceQueues; -typedef struct { +typedef struct Image +{ VkImage img; VkImageView view; VmaAllocation alloc; @@ -247,7 +270,8 @@ typedef struct { VkImageLayout curr_layout; } Image; -typedef struct { +typedef struct SwapchainStructures +{ VkFormat format; VkColorSpaceKHR color_space; VkPresentModeKHR present_mode; @@ -259,7 +283,8 @@ typedef struct { Image depth_img; } SwapchainStructures; -typedef struct { +typedef struct FrameState +{ u32 img_ix; u64 frame_cnt; u64 prev_frame; @@ -269,7 +294,8 @@ typedef struct { u32 prev_buffer_count; } FrameState; -typedef struct { +typedef struct Vulkan +{ Library lib; VkInstance inst; VkSurfaceKHR surface; @@ -285,15 +311,16 @@ typedef struct { #ifdef BUILD_DEBUG VkDebugUtilsMessengerEXT debug; #endif -} Vulkan_t; +} Vulkan; -typedef struct { +typedef struct PendingUpdates +{ u16 render_width; u16 render_height; b8 resized; } PendingUpdates; -typedef struct VulkanConfig_t +typedef struct VulkanConfig { u8 avail_threads; #ifdef __linux__ @@ -303,9 +330,9 @@ typedef struct VulkanConfig_t #endif } VulkanConfig; -typedef struct Renderer_t +typedef struct Renderer { - Vulkan_t vk; + Vulkan vk; VulkanConfig vk_conf; FrameState frame_state; PendingUpdates pending; @@ -313,9 +340,7 @@ typedef struct Renderer_t Arena *perm_arena; } Renderer; -// ::Vulkan::Functions::Header:: - -// ::Vulkan::Debug::Header:: +// ::Vulkan::Debug::Functions::Header:: static b32 VLayersSupported(); static VKAPI_ATTR VkBool32 DebugCallback( @@ -326,7 +351,7 @@ static VKAPI_ATTR VkBool32 DebugCallback( ); const char *VkResultStr(VkResult result); -// ::Vulkan::Init::Header:: +// ::Vulkan::Init::Functions::Header:: static b32 LoadVulkanLib(); static b32 InitVkInstanceFunctions(); @@ -349,7 +374,7 @@ static b32 CreatePipelines(); static b32 CreateShaderModule(u8 *bytes, u32 len, VkShaderModule *module); static void StartVkLoaderThreads(); -// ::Vulkan::Util::Header:: +// ::Vulkan::Util::Functions::Header:: static inline VkCommandBuffer GetFrameCmdBuf(); static inline VkFence *GetFrameRenderFence(); @@ -359,42 +384,36 @@ static inline u32 GetFrameIndex(); static inline VkImage GetFrameSwapImage(); static inline u32 *GetFrameBufferCount(); static inline RenderBuffer *GetFrameRenderBuffers(); -static void BeginRendering(); +static inline void TransitionImage(VkCommandBuffer cmd, Image *img, VkImageLayout new); +static inline void TransitionImageLayout(VkCommandBuffer cmd, VkImage img, VkImageLayout curr, VkImageLayout new); +static inline void CopyImageToImage(VkCommandBuffer cmd, VkImage src, VkImage dst, VkExtent2D src_ext, VkExtent2D dst_ext); -// ::Vulkan::Async::Header:: +// ::Vulkan::Async::Functions::Header:: #ifdef __linux__ void *VkLoaderStart(void *thread_data); #elif _WIN32 #error not yet implemented #endif -// ::Vulkan::ImmediateSubmit::Header:: +// ::Vulkan::ImmediateSubmit::Functions::Header:: static b32 BeginImmSubmit(VkDevice device, VkFence *fence, VkCommandBuffer cmd); static b32 FinishImmSubmit(VkDevice device, VkFence *fence, VkCommandBuffer cmd, VkQueue queue); -// ::Vulkan::Buffers::Header:: +// ::Vulkan::Rendering::Functions::Header:: -static b32 UploadGUIBuffer(MeshBuffer *buf, GUIContext *ctx); +static void BeginRendering(); -// ::Vulkan::Destroy::Header:: +// ::Vulkan::CleanUp::Functions::Header:: static void DestroySwapchain(); static void DestroyDrawImages(); -// ::Vulkan::Util::Header:: +// ::Vulkan::Swapchain::Functions::Header:: -static void TransitionImage(VkCommandBuffer cmd, Image *img, VkImageLayout new); -static void TransitionImageLayout(VkCommandBuffer cmd, VkImage img, VkImageLayout curr, VkImageLayout new); -static void CopyImageToImage(VkCommandBuffer cmd, VkImage src, VkImage dst, VkExtent2D src_ext, VkExtent2D dst_ext); - -// ::Vulkan::Swapchain::Header:: - -static VkExtent2D SelectSwapchainExtent(VkSurfaceCapabilitiesKHR *capabilities); -static VkSurfaceFormatKHR SelectSwapchainFormat(VkSurfaceFormatKHR *formats); static void ResizeSwapchain(); -// ::Vulkan::Logging::Header:: +// ::Vulkan::Logging::Functions::Header:: static void VkInfo(const char *str); static void VkWarn(const char *str); @@ -402,50 +421,4 @@ static void VkError(const char *str); #include "vulkan_config.c" -// ::Vulkan::Globals::Header:: - -static Renderer renderer = { - .vk = { - .queues = { - .graphics = -1, - .transfer = -1, - }, - .sc = { - .format = INT_MAX, - .color_space = INT_MAX, - .present_mode = INT_MAX, - }, - .imm = { - .next_ticket = 1, - }, - } -}; - -static u32 vk_thread_indices[10] = {}; - -// ::Vulkan::Constants::Header:: - -static const char *_VK_VALIDATION = "VK_LAYER_KHRONOS_validation"; - -#if __linux__ -static char *vulkan_libs[] = { - "libvulkan.so.1", - "libvulkan.so" -}; -#endif - -#if _WIN32 -static char *vulkan_libs[] = { - "vulkan-1.dll", -}; -#endif - -#if __APPLE__ || __MACH__ -#error Not yet implemented -#endif - -#if __unix__ && !__linux__ -#error Not yet implemented -#endif - diff --git a/src/renderer_vulkan_public.c b/src/renderer_vulkan_public.c index 4554b7f..b5d5cf3 100644 --- a/src/renderer_vulkan_public.c +++ b/src/renderer_vulkan_public.c @@ -1,6 +1,5 @@ -/* - * ::Initialization::Start:: - */ +// ::Vulkan::Renderer::Initialization::Functions::Start:: + b32 InitRenderer(Arena *arena) { SetRendererAvailableThreads(AvailableCPUCount()); @@ -114,13 +113,11 @@ void DestroyRenderer() ArenaFree(renderer.perm_arena); } -/* - * ::Initialization::End:: - */ +// ::Vulkan::Renderer::Initialization::Functions::End:: -/* - * ::Buffers::Start:: - */ + + +// ::Vulkan::Renderer::Buffers::Functions::Start:: static b32 CreateBuffer(RenderBuffer *buffer) { @@ -320,20 +317,6 @@ static void CreateAndUploadToBuffer(RenderBuffer *buffer, rawptr ptr) __atomic_add_fetch(&renderer.vk.imm.next_ticket, 1, __ATOMIC_SEQ_CST); } -/* TODO: DELETE -static b32 CreateAndUploadToBuffer(RenderBuffer *buffer, rawptr ptr) -{ - b32 success = true; - - success = CreateBuffer(buffer); - - if (success) - success = UploadToBuffer(buffer, ptr, 0); // TODO: DELETE this - - return success; -} -*/ - static void FreeBuffers(RenderBuffer *buffers, u32 buffer_count) { VkDevice device = renderer.vk.device; @@ -370,13 +353,12 @@ static void BindIndexBuffer(RenderBuffer *buffer) vkCmdBindIndexBuffer(cmd, buffer->buffer, 0, VK_INDEX_TYPE_UINT32); } -/* - * ::Buffers::End:: - */ +// ::Vulkan::Renderer::Buffers::Functions::End:: -/* - * ::Uniforms::Start:: ::PushConstants::Start:: - */ + + +// ::Vulkan::Renderer::Uniforms::Functions::Start:: +// ::Vulkan::Renderer::PushConstants::Functions::Start:: static void GetViewportSize(Vec2 *size) { @@ -401,13 +383,12 @@ static void SetPushConstants(PushConst *pc) pc); } -/* - * ::Uniforms::End:: ::PushConstants::End:: - */ +// ::Vulkan::Renderer::Uniforms::Functions::End:: +// ::Vulkan::Renderer::PushConstants::Functions::End:: -/* - * ::Config::Start:: - */ + + +// ::Vulkan::Renderer::Config::Functions::Start:: static void SetRenderResolution(u32 x, u32 y) { @@ -421,13 +402,11 @@ static void SetRendererAvailableThreads(u32 n) renderer.vk_conf.avail_threads = n; } -/* - * ::Config::End:: - */ +// ::Vulkan::Renderer::Config::Functions::End:: -/* - * ::Rendering::Start:: - */ + + +// ::Vulkan::Renderer::Rendering::Functions::Start:: b32 BeginFrame() { @@ -651,6 +630,4 @@ static void BindPipeline(PipelineHandle handle, PipelineType type) vkCmdSetScissor(cmd, 0, 1, &scissor); } -/* - * ::Rendering::End:: - */ +// ::Vulkan::Renderer::Rendering::Functions::End:: diff --git a/src/shared_types.h b/src/shared_types.h index 90c1f03..285d7a2 100644 --- a/src/shared_types.h +++ b/src/shared_types.h @@ -6,53 +6,24 @@ #include #endif -typedef int8_t i8; -typedef int16_t i16; -typedef int32_t i32; -typedef int64_t i64; +// ::SharedTypes::Declarations::Header:: -typedef uint8_t u8; -typedef uint16_t u16; -typedef uint32_t u32; -typedef uint64_t u64; +typedef struct Arena Arena; -typedef char c8; - -typedef intptr_t intptr; -typedef uintptr_t uintptr; - -typedef float f32; -typedef double f64; - -typedef uint8_t b8; -typedef uint32_t b32; - -typedef void * rawptr; - -#ifdef __linux__ - -typedef ssize_t isize; -typedef size_t usize; - -#elif _WIN32 - -#if defined ( _WIN64 ) - -typedef int64_t isize; -typedef uint64_t usize; - -#elif defined ( _WIN32 ) - -typedef int32_t isize; -typedef uint32_t usize; +// ::SharedTypes::Attributes::Header:: +#if COMPILER_MSVC || (COMPILER_CLANG && _WIN32) +# pragma section(".rdata$", read) +# define read_only __declspec(allocate(".rdata$")) +#elif (COMPILER_CLANG && __linux__) +# define read_only __attribute__((section(".rodata"))) +#elif (COMPILER_GCC && __linux__) +# define read_only +#else +# error read_only not implemented for compiler/target #endif -#elif __APPLE__ || __MACH__ - -#else // unix - -#endif +// ::SharedTypes::Enums::Header:: typedef enum KeyboardInput_e { @@ -181,6 +152,59 @@ typedef enum GameInputType_e GI_GAMEPAD, } GameInputType; +// ::SharedTypes::Types::Header:: + +typedef int8_t i8; +typedef int16_t i16; +typedef int32_t i32; +typedef int64_t i64; + +typedef uint8_t u8; +typedef uint16_t u16; +typedef uint32_t u32; +typedef uint64_t u64; + +typedef char c8; + +typedef intptr_t intptr; +typedef uintptr_t uintptr; + +typedef float f32; +typedef double f64; + +typedef uint8_t b8; +typedef uint32_t b32; + +typedef void * rawptr; + +typedef struct Str8 +{ + u32 len; + u8 *value; +} Str8; + +#ifdef __linux__ + +typedef ssize_t isize; +typedef size_t usize; + +#elif _WIN32 + +#if defined ( _WIN64 ) + +typedef int64_t isize; +typedef uint64_t usize; + +#elif defined ( _WIN32 ) +typedef int32_t isize; +typedef uint32_t usize; + +#endif + +#else // unix + +#endif + typedef union { struct { f32 r, g; }; @@ -225,13 +249,13 @@ typedef f64 dMat2[4]; typedef f64 dMat3[9]; typedef f64 dMat4[16]; -typedef struct MouseMotionEvent_t +typedef struct MouseMotionEvent { i16 x; i16 y; } MouseMotionEvent; -typedef struct +typedef struct GameInput { union { @@ -243,14 +267,14 @@ typedef struct GameInputType type; } GameInput; // TODO: add gamepad input -typedef struct +typedef struct GUIVertex { Vec2 p0; Vec2 p1; Vec4 col; } GUIVertex; -typedef struct +typedef struct GUIContext { GUIVertex *vertices; u32 vertices_len; diff --git a/src/util.c b/src/util.c index 9e18635..571ca41 100644 --- a/src/util.c +++ b/src/util.c @@ -72,6 +72,10 @@ Str8 PreSplitNewStr8(Arena *arena, Str8 string, Str8 delimiter) // ::Util::Strings::Functions::End:: + + +// ::Util::Memory::Functions::Start:: + void MemZero(void *ptr, isize size) { if (!size || !ptr) return; @@ -146,6 +150,12 @@ void MemCpy(rawptr dst, rawptr src, usize size) } } +// ::Util::Memory::Functions::End:: + + + +// ::Util::Math::Functions::Start:: + u32 u32Min(u32 l, u32 r) { return l >= r ? r : l; @@ -176,133 +186,9 @@ u32 u32Clamp(u32 v, u32 min, u32 max) return i32Min(max, i32Max(v, min)); } -u32 inline ReadBit(BitWriter *bw) -{ - u32 r = bw->bits >> 31; - bw->bits <<= 1; - bw->pos += 1; - return r; -} +// ::Util::Math::Functions::End:: -void static inline RefillBits(BitWriter *bw) -{ - while (bw->pos >= 0) - { - bw->bits |= (bw->current < bw->end ? *bw->current : 0) << bw->pos; - bw->pos -= 8; - bw->current += 1; - } -} -void static inline FlushBits(BitWriter *bw) -{ - while (bw->pos >= 8) - { - bw->pos -= 8; - *bw->current = (bw->bits >> bw->pos) & 0xFF; - *bw->current += 1; - } -} - -void static inline WriteBit(BitWriter *bw, u32 v) -{ - bw->bits = (bw->bits << 1) | v; - bw->pos += 1; - if (bw->pos >= 8) - FlushBits(bw); -} - -void static inline HMScan1(HMNode *nodes, u8 symbol) -{ - nodes[symbol].freq += 1; -} - -void static inline HMScan2(HMNode *nodes, u8 symbol1, u8 symbol2) -{ - nodes[symbol1].freq += 1; - nodes[symbol2].freq += 1; -} - -void static inline HMScan3(HMNode *nodes, u8 symbol1, u8 symbol2, u8 symbol3) -{ - nodes[symbol1].freq += 1; - nodes[symbol2].freq += 1; - nodes[symbol3].freq += 1; -} - -void static inline HMScan4(HMNode *nodes, u8 symbol1, u8 symbol2, u8 symbol3, u8 symbol4) -{ - nodes[symbol1].freq += 1; - nodes[symbol2].freq += 1; - nodes[symbol3].freq += 1; - nodes[symbol4].freq += 1; -} - -void static inline HMQuicksort(HMNode *nodes, u32 low, u32 high) -{ - if (low < high) - { - u32 pi = low - 1; - HMNode *p = &nodes[high]; - HMNode temp; - for (u32 i = low; i < high; i++) - { - if (nodes[i].freq < p->freq) - { - pi += 1; - temp = nodes[pi]; - nodes[pi] = nodes[i]; - nodes[i] = temp; - } - } - - pi += 1; - temp = nodes[pi]; - nodes[pi] = nodes[high]; - nodes[high] = temp; - - HMQuicksort(nodes, low, pi-1); - HMQuicksort(nodes, pi+1, high); - } -} - -void static inline HMBuildTable(HMNode *nodes) -{ - HMNode *q[256]; - HMNode *p[256]; - u32 num_symbols = 0; - for (u32 i = 0; i < HM_MAX_SYMBOLS; i++) - { - if (nodes[i].freq) - { - nodes[num_symbols] = nodes[i]; - q[num_symbols] = &nodes[num_symbols]; - num_symbols += 1; - } - } - - // TODO: also finish this trash - - HMQuicksort(nodes, 0, num_symbols); -} - -b32 HMCompressData(u8 *data, u32 len, u8 *out) -{ - b32 success = true; - - BitWriter bw = { - .current = data, - .end = &data[len-1], - .bits = 0, - .pos = 24, - }; - - // TODO: finish this trash - - u32 iterations; - - return success; -} // ::Util::Hashing::Functions::Start:: @@ -312,3 +198,94 @@ u64 static inline HashFromString(Str8 string) } // ::Util::Hashing::Functions::End:: + + + +// ::Util::Print::Functions::Start:: + +i32 Printf(char *fmt, ...) +{ + va_list arg; + + va_start(arg, fmt); + i32 result = _Printf(fmt, arg); + va_end(arg); + + return result; +} + +i32 Printfln(char *fmt, ...) +{ + va_list arg; + + va_start(arg, fmt); + i32 result = _Printfln(fmt, arg); + va_end(arg); + + return result; +} + +i32 EPrintf(char *fmt, ...) +{ + va_list arg; + + va_start(arg, fmt); + i32 result = _EPrintf(fmt, arg); + va_end(arg); + + return result; +} + +i32 EPrint(void *str) +{ + return WriteStdErr(str, (isize)StrLen(str)); +} + +i32 _EPrintf(char *fmt, va_list arg) +{ + char buffer[1024]; + + int sprf_res = stbsp_vsnprintf(&buffer[0], 1024, fmt, arg); + + if (sprf_res < 0) return sprf_res; + + return EPrint(&buffer); +} + +i32 _Printf(char *fmt, va_list arg) +{ + char buffer[1024]; + + int sprf_res = stbsp_vsnprintf(&buffer[0], 1024, fmt, arg); + + i32 pr_res; + if (sprf_res < 0) + pr_res = sprf_res; + else + pr_res = WriteStdOut(&buffer, sprf_res); + + return pr_res; +} + +i32 _Printfln(char *fmt, va_list arg) +{ + char buffer[1024]; + + int sprf_res = stbsp_vsnprintf(&buffer[0], 1023, fmt, arg); + + i32 pr_res; + if (sprf_res < 0) + { + pr_res = sprf_res; + } + else + { + buffer[sprf_res] = '\n'; + buffer[sprf_res+1] = '\0'; + pr_res = WriteStdOut(&buffer, sprf_res+1); + } + + return pr_res; +} + +// ::Util::Print::Functions::End:: diff --git a/src/util.h b/src/util.h index 25024eb..1312bac 100644 --- a/src/util.h +++ b/src/util.h @@ -2,71 +2,34 @@ #include -typedef struct Arena_t Arena; +typedef struct Arena Arena; + +// ::Util::Macros::Header:: #define Assert(condition, message) do { assert((condition) && (message)); } while(0) -// ::Util::Size::Defines:: - #define KB(n) n * 1024LL #define MB(n) KB(n) * 1024LL #define GB(n) MB(n) * 1024LL #define TB(n) GB(n) * 1024LL -// ::Util::Memory::Defines:: - -#define DEFAULT_ALIGNMENT (2*sizeof(rawptr)) - #define BitEq(var, bits) (((var) & (bits)) == (bits)) #define AlignPow2(x, b) (((x) + (b) - 1) & (~((b) - 1))) #define IsPow2(x) ((x) != 0 && ((x) &((x) - 1)) == 0) #define PtrAdd(ptr, add) (((char *)ptr) + add) -// ::Util::Array::Defines:: - #define MakeArray(arena, type, count) ArenaAlloc(arena, (isize)(sizeof(type)) * (isize)(count)) #define Len(x) ((sizeof(x)/sizeof(0[x])) / ((size_t)(!(sizeof(x) % sizeof(0[x]))))) -// ::Util::Compression::Defines:: - -#define HM_MAX_SYMBOLS 256 - -// ::Util::Strings::Defines:: -#define Str8L(x) (Str8){ .len = Len(x), .value = (u8 *)x } +#define Str8L(x) (Str8){ .len = StrLen(x), .value = (u8 *)x } #define MakeString(x) #x -// ::Util::Hashing::Defines:: +// ::Util::Defines::Header:: + +#define HM_MAX_SYMBOLS 256 +#define DEFAULT_ALIGNMENT (2*sizeof(rawptr)) #define HASH_SEED 5995 -typedef struct HMEnc_t -{ - u8 length[256]; - u32 code[256]; -} HMEnc; - -typedef struct HMNode_t HMNode; -typedef struct HMNode_t -{ - u32 freq; - u32 sym; - HMNode *l; - HMNode *r; -} HMNode; - -typedef struct BitWriter_t -{ - u32 bits; - i32 pos; - u8 *current; - u8 *end; -} BitWriter; - -typedef struct Str8_t -{ - u32 len; - u8 *value; -} Str8; - // ::Util::Strings::Functions::Header:: u32 StrLen(const char *str); @@ -90,20 +53,17 @@ i32 i32Max(i32 l, i32 r); i32 i32Clamp(i32 v, i32 min, i32 max); u32 u32Clamp(u32 v, u32 min, u32 max); -// ::Util::Compression::Functions::Header:: - -b32 HMCompressData(u8 *data, u32 len, u8 *out); -u32 static inline ReadBit(BitWriter *bw); -void static inline RefillBits(BitWriter *bw); -void static inline FlushBits(BitWriter *bw); -void static inline WriteBit(BitWriter *bw, u32 v); -void static inline HMScan1(HMNode *nodes, u8 symbol); -void static inline HMScan2(HMNode *nodes, u8 symbol1, u8 symbol2); -void static inline HMScan3(HMNode *nodes, u8 symbol1, u8 symbol2, u8 symbol3); -void static inline HMScan4(HMNode *nodes, u8 symbol1, u8 symbol2, u8 symbol3, u8 symbol4); -void static inline HMBuildTable(HMNode *nodes); -void static inline HMQuicksort(HMNode *nodes, u32 low, u32 high); - // ::Util::Hashing::Functions::Header:: u64 static inline HashFromString(Str8 string); + +// ::Util::Print::Functions::Header:: + +i32 EPrint(void *str); +i32 Printf(char *fmt, ...); +i32 Printfln(char *fmt, ...); +i32 EPrintf(char *fmt, ...); +i32 _EPrint(void *str); +i32 _Printf(char *fmt, va_list arg); +i32 _Printfln(char *fmt, va_list arg); +i32 _EPrintf(char *fmt, va_list arg);