big clean up
This commit is contained in:
parent
347d6672d9
commit
f57018317a
10
build.sh
10
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}"
|
||||
|
||||
122
src/allocators.c
122
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;
|
||||
}
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -1,5 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
// ::Assets::Types::Header::
|
||||
|
||||
typedef enum AssetType_e
|
||||
{
|
||||
SHADER_ASSET,
|
||||
|
||||
9
src/ds.c
9
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::
|
||||
|
||||
14
src/ds.h
14
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);
|
||||
|
||||
@ -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);
|
||||
|
||||
201
src/game.c
201
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::
|
||||
|
||||
30
src/game.h
30
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);
|
||||
|
||||
112
src/packer.c
112
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::
|
||||
|
||||
62
src/packer.h
62
src/packer.h
@ -1,5 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
// ::Packer::Includes::Header::
|
||||
|
||||
#if __linux__
|
||||
# define _GNU_SOURCE
|
||||
#elif _WIN32
|
||||
@ -25,27 +27,31 @@
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#if __linux__
|
||||
# include <unistd.h>
|
||||
# include <dirent.h>
|
||||
#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);
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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"
|
||||
|
||||
@ -20,22 +20,20 @@
|
||||
#include <dlfcn.h>
|
||||
#include <nmmintrin.h>
|
||||
#include <immintrin.h>
|
||||
|
||||
#ifndef STG_NO_WINDOW
|
||||
|
||||
#endif
|
||||
|
||||
#include <sched.h>
|
||||
#include <unistd.h>
|
||||
#include <dirent.h>
|
||||
|
||||
// ::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);
|
||||
|
||||
|
||||
@ -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;
|
||||
// ::Platform::Functions::Print::End::
|
||||
|
||||
return EPrint(&buffer);
|
||||
}
|
||||
|
||||
i32 _Printf(const char *fmt, va_list arg)
|
||||
{
|
||||
char buffer[1024];
|
||||
|
||||
int sprf_res = stbsp_vsnprintf(&buffer[0], 1024, fmt, arg);
|
||||
// ::Platform::Functions::Memory::Start::
|
||||
|
||||
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];
|
||||
|
||||
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::
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -1,12 +1,16 @@
|
||||
#pragma once
|
||||
#include <windows.h>
|
||||
|
||||
#include <windows.h>
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
// ::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();
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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::
|
||||
|
||||
@ -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
|
||||
|
||||
|
||||
|
||||
@ -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::
|
||||
|
||||
@ -6,53 +6,24 @@
|
||||
#include <sys/types.h>
|
||||
#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;
|
||||
|
||||
227
src/util.c
227
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::
|
||||
|
||||
78
src/util.h
78
src/util.h
@ -2,71 +2,34 @@
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
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);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user