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 flags
|
||||||
vma_source_files="../external/vma/vma.cpp"
|
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_out="-o"
|
||||||
vma_obj="vma.o"
|
vma_obj="vma.o"
|
||||||
|
|
||||||
@ -47,14 +47,14 @@ glsl_stage_geom="-fshader-stage=geom"
|
|||||||
glsl_stage_comp="-fshader-stage=comp"
|
glsl_stage_comp="-fshader-stage=comp"
|
||||||
glsl_out="-o./shaders/glsl/"
|
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_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_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"
|
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_debug="$compiler -g -O0 -DBUILD_DEBUG=1 ${gcc_common}"
|
||||||
gcc_release="$compiler -O2 ${gcc_common} ${render_flag}"
|
gcc_release="$compiler -O2 ${gcc_common} ${render_flag}"
|
||||||
gcc_test="$compiler -O2 -DBUILD_TEST=1 ${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::
|
// ::Allocator::Arena::Start::
|
||||||
|
|
||||||
static Arena *CreateArena(rawptr buffer, isize length)
|
static Arena *CreateArena(rawptr buffer, usize length)
|
||||||
{
|
{
|
||||||
Arena *arena = (Arena *)buffer;
|
Arena *arena = (Arena *)buffer;
|
||||||
buffer = PtrAdd(buffer, ARENA_HEADER_SIZE);
|
buffer = PtrAdd(buffer, ARENA_HEADER_SIZE);
|
||||||
@ -12,7 +43,7 @@ static Arena *CreateArena(rawptr buffer, isize length)
|
|||||||
return arena;
|
return arena;
|
||||||
}
|
}
|
||||||
|
|
||||||
static rawptr ArenaAllocAlign(Arena *arena, isize size, isize align)
|
static rawptr ArenaAllocAlign(Arena *arena, usize size, usize align)
|
||||||
{
|
{
|
||||||
rawptr ptr = NULL;
|
rawptr ptr = NULL;
|
||||||
|
|
||||||
@ -34,7 +65,7 @@ static rawptr ArenaAllocAlign(Arena *arena, isize size, isize align)
|
|||||||
return ptr;
|
return ptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
static rawptr ArenaAlloc(Arena *arena, isize size)
|
static rawptr ArenaAlloc(Arena *arena, usize size)
|
||||||
{
|
{
|
||||||
return ArenaAllocAlign(arena, size, DEFAULT_ALIGNMENT);
|
return ArenaAllocAlign(arena, size, DEFAULT_ALIGNMENT);
|
||||||
}
|
}
|
||||||
@ -55,7 +86,7 @@ static void DeallocArena(Arena *arena)
|
|||||||
MemFree(arena, arena->length);
|
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 *arena = CreateArena(buffer, length);
|
||||||
arena->init_line_no = init_line_no;
|
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::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);
|
u8 *mem = (u8 *)MemAllocZeroed(size);
|
||||||
Alloc *fl_alloc = (Alloc *)mem;
|
Allocator *fl_alloc = (Allocator *)mem;
|
||||||
|
|
||||||
u8 *pre_mem = mem;
|
u8 *pre_mem = mem;
|
||||||
mem = (u8 *)PtrAdd(mem, sizeof(Alloc));
|
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->buf_len = 1;
|
||||||
fl_alloc->grow_size = grow_size;
|
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].size = (u32)size;
|
||||||
fl_alloc->buffers[0].free_size = (u32)rem_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(g_alloc.buffers[i].buf, g_alloc.buffers[i].size);
|
||||||
MemFree(alloc, alloc->buffers[i].size);
|
|
||||||
else
|
|
||||||
MemFree(alloc->buffers[i].buf, alloc->buffers[i].size);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static rawptr FLAlloc(Alloc *alloc, isize size)
|
static rawptr Alloc(usize size)
|
||||||
{
|
{
|
||||||
return NULL;
|
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::
|
// ::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
|
#pragma once
|
||||||
|
|
||||||
|
// ::Allocator::Util::Header::
|
||||||
|
|
||||||
|
usize CalcPaddingWithHeader(uintptr ptr, uintptr alignment, usize header_size);
|
||||||
|
|
||||||
// ::Allocator::Arena::Header::
|
// ::Allocator::Arena::Header::
|
||||||
|
|
||||||
#define ARENA_HEADER_SIZE 64
|
#define ARENA_HEADER_SIZE 64
|
||||||
|
|
||||||
typedef struct Arena_t
|
typedef struct Arena
|
||||||
{
|
{
|
||||||
u8 *buffer;
|
u8 *buffer;
|
||||||
isize length;
|
usize length;
|
||||||
isize pos;
|
usize pos;
|
||||||
u32 init_line_no;
|
u32 init_line_no;
|
||||||
} Arena;
|
} Arena;
|
||||||
|
|
||||||
typedef struct TempArena_t
|
typedef struct TempArena
|
||||||
{
|
{
|
||||||
Arena *arena;
|
Arena *arena;
|
||||||
u64 pos;
|
u64 pos;
|
||||||
} TempArena;
|
} TempArena;
|
||||||
|
|
||||||
static Arena *CreateArena(rawptr buffer, isize length);
|
static Arena *CreateArena(rawptr buffer, usize length);
|
||||||
static rawptr ArenaAllocAlign(Arena *arena, isize size, isize align);
|
static rawptr ArenaAllocAlign(Arena *arena, usize size, usize align);
|
||||||
static rawptr ArenaAlloc(Arena *arena, isize size);
|
static rawptr ArenaAlloc(Arena *arena, usize size);
|
||||||
static void ArenaFree(Arena *arena);
|
static void ArenaFree(Arena *arena);
|
||||||
static void ArenaFreeZeroed(Arena *arena);
|
static void ArenaFreeZeroed(Arena *arena);
|
||||||
static void DeallocArena(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;
|
rawptr buf;
|
||||||
u32 size;
|
u32 size;
|
||||||
u32 free_size;
|
u32 free_size;
|
||||||
} FreeListBuffer;
|
} FreeListBuffer;
|
||||||
|
|
||||||
typedef struct Alloc_t
|
typedef struct Allocator
|
||||||
{
|
{
|
||||||
RBNode *head;
|
RBNode *head;
|
||||||
RBNode *nil;
|
RBNode *nil;
|
||||||
FreeListBuffer *buffers;
|
FreeListBuffer *buffers;
|
||||||
isize grow_size;
|
usize grow_size;
|
||||||
u8 buf_len;
|
u8 buf_len;
|
||||||
} Alloc;
|
} Allocator;
|
||||||
|
|
||||||
static Alloc *CreateFreeListAlloc(isize init_size, isize grow_size);
|
static void InitAllocator(usize init_size, usize grow_size);
|
||||||
static void DeallocFreeListAlloc(Alloc *alloc);
|
static void DeinitAlloc();
|
||||||
static void FreeListGrow(Alloc *alloc);
|
static void AllocGrow();
|
||||||
static rawptr FLAlloc(Alloc *alloc, isize size);
|
static rawptr Alloc(usize size);
|
||||||
static void FLFree(Alloc *alloc, rawptr ptr);
|
static void Free(rawptr ptr);
|
||||||
static inline b32 FLNodeInsert(Alloc *alloc, RBNode *node);
|
|
||||||
static inline void FLNodeDelete(RBNode *node);
|
// ::Allocator::FreeList::Header::
|
||||||
static inline void FLNodeLeftRotate(RBNode *node);
|
|
||||||
static inline void FLNodeRightRotate(RBNode *node);
|
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
|
#pragma once
|
||||||
|
|
||||||
|
// ::Assets::Types::Header::
|
||||||
|
|
||||||
typedef enum AssetType_e
|
typedef enum AssetType_e
|
||||||
{
|
{
|
||||||
SHADER_ASSET,
|
SHADER_ASSET,
|
||||||
|
|||||||
9
src/ds.c
9
src/ds.c
@ -1,6 +1,13 @@
|
|||||||
|
// ::DataStructures::Globals::Start::
|
||||||
|
|
||||||
RBNode RB_NIL = { .color = RB_BLACK };
|
RBNode RB_NIL = { .color = RB_BLACK };
|
||||||
|
|
||||||
|
// ::DataStructures::Globals::End::
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// ::DataStructures::RedBlackTree::Functions::Start::
|
||||||
|
|
||||||
static void CreateRBTree(RBTree *tree)
|
static void CreateRBTree(RBTree *tree)
|
||||||
{
|
{
|
||||||
Assert(tree != NULL, "RBTree is null");
|
Assert(tree != NULL, "RBTree is null");
|
||||||
@ -319,4 +326,4 @@ static void RBTreeRightRotate(RBTree *tree, RBNode *node)
|
|||||||
node->parent = left;
|
node->parent = left;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ::DataStructures::RedBlackTree::Functions::Start::
|
||||||
|
|||||||
14
src/ds.h
14
src/ds.h
@ -1,5 +1,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
// ::DataStructures::Types::Header::
|
||||||
|
|
||||||
typedef enum RBNodeColor_e
|
typedef enum RBNodeColor_e
|
||||||
{
|
{
|
||||||
RB_RED,
|
RB_RED,
|
||||||
@ -12,9 +14,9 @@ typedef enum RBNodeDir_e
|
|||||||
RB_RIGHT,
|
RB_RIGHT,
|
||||||
} RBNodeDir;
|
} RBNodeDir;
|
||||||
|
|
||||||
typedef struct RBNode_t RBNode;
|
typedef struct RBNode RBNode;
|
||||||
|
|
||||||
typedef struct RBNode_t
|
typedef struct RBNode
|
||||||
{
|
{
|
||||||
RBNode *parent;
|
RBNode *parent;
|
||||||
union
|
union
|
||||||
@ -31,17 +33,21 @@ typedef struct RBNode_t
|
|||||||
RBNodeColor color;
|
RBNodeColor color;
|
||||||
} RBNode;
|
} RBNode;
|
||||||
|
|
||||||
typedef struct RBTree_t
|
typedef struct RBTree
|
||||||
{
|
{
|
||||||
RBNode *root;
|
RBNode *root;
|
||||||
RBNode *nil;
|
RBNode *nil;
|
||||||
} RBTree;
|
} RBTree;
|
||||||
|
|
||||||
|
// ::DataStructures::Macros::Header::
|
||||||
|
|
||||||
#define NodeDir(node) (node == node->parent->left ? RB_LEFT : RB_RIGHT)
|
#define NodeDir(node) (node == node->parent->left ? RB_LEFT : RB_RIGHT)
|
||||||
|
|
||||||
|
// ::DataStructures::RedBlackTree::Functions::Header::
|
||||||
|
|
||||||
static void CreateRBTree(RBTree *tree);
|
static void CreateRBTree(RBTree *tree);
|
||||||
static void RBTreeInsert(RBTree *tree, RBNode *node);
|
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 RBTreeDelete(RBTree *tree, i32 value);
|
||||||
static void RBTreeLeftRotate(RBTree *tree, RBNode *node);
|
static void RBTreeLeftRotate(RBTree *tree, RBNode *node);
|
||||||
static void RBTreeRightRotate(RBTree *tree, RBNode *node);
|
static void RBTreeRightRotate(RBTree *tree, RBNode *node);
|
||||||
|
|||||||
@ -89,13 +89,11 @@ int main(int argc, char **argv)
|
|||||||
|
|
||||||
Traverse(&tree);
|
Traverse(&tree);
|
||||||
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
u8 *mem = (u8 *)MemAllocZeroed(MB(64));
|
u8 *mem = (u8 *)MemAllocZeroed(MB(64));
|
||||||
Arena *arena = CreateArenaDebug(mem, MB(64), __LINE__);
|
Arena *arena = CreateArenaDebug(mem, MB(64), __LINE__);
|
||||||
|
|
||||||
isize renderer_mem_size = MB(16);
|
usize renderer_mem_size = MB(16);
|
||||||
isize game_mem_size = MB(16);
|
usize game_mem_size = MB(16);
|
||||||
|
|
||||||
rawptr renderer_mem = ArenaAlloc(arena, renderer_mem_size);
|
rawptr renderer_mem = ArenaAlloc(arena, renderer_mem_size);
|
||||||
Arena *renderer_arena = CreateArenaDebug(renderer_mem, renderer_mem_size, 2);
|
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)
|
static void InitializeGame(Arena *arena, GameContext *ctx, Arena *ctx_arena)
|
||||||
{
|
{
|
||||||
Assert(InitRenderer(arena), "Failed to initialize the renderer");
|
Assert(InitRenderer(arena), "Failed to initialize the renderer");
|
||||||
@ -22,13 +40,89 @@ static void DestroyGame()
|
|||||||
DestroyRenderer();
|
DestroyRenderer();
|
||||||
}
|
}
|
||||||
|
|
||||||
u32 selected_rect = 0;
|
// ::Game::Init::Functions::End::
|
||||||
b8 mouse_pressed = false;
|
|
||||||
b8 mouse_clicked = false;
|
|
||||||
i16 mouse_prev_pos_x = 0;
|
|
||||||
i16 mouse_prev_pos_y = 0;
|
// ::Game::GameLoop::Functions::Start::
|
||||||
i16 mouse_pos_x = 0;
|
|
||||||
i16 mouse_pos_y = 0;
|
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)
|
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)
|
static inline void PrepareGUICtx(GameContext *ctx)
|
||||||
{
|
{
|
||||||
ctx->gui.has_grabbed = false;
|
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)
|
static b32 UIButton(GameContext *ctx, char *label, f32 x0, f32 y0, f32 x1, f32 y1)
|
||||||
{
|
{
|
||||||
GUIButton *btn = NULL;
|
GUIButton *btn = NULL;
|
||||||
u32 id = StrToU32(label) + (u32)(x0 + y0 + x1 + y1);
|
u64 id = HashFromString(Str8L(label));
|
||||||
if (ctx->btn_len == 0)
|
if (ctx->btn_len == 0)
|
||||||
{
|
{
|
||||||
ctx->buttons[0].p0.x = x0;
|
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)
|
static b32 UIWindow(GameContext *ctx, char *title, f32 x0, f32 y0, f32 x1, f32 y1)
|
||||||
{
|
{
|
||||||
GUIWindow *win = NULL;
|
GUIWindow *win = NULL;
|
||||||
u32 id = StrToU32(title) + (u32)(x0 + y0 + x1 + y1);
|
u32 id = HashFromString(Str8L(title));
|
||||||
if (ctx->window_len == 0)
|
if (ctx->window_len == 0)
|
||||||
{
|
{
|
||||||
ctx->windows[0].p0.x = x0;
|
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;
|
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)
|
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;
|
ctx->instance_count += 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ::Game::GUI::Functions::End::
|
||||||
|
|||||||
30
src/game.h
30
src/game.h
@ -1,24 +1,26 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
typedef struct GUIWindow_t
|
// ::Game::Types::Header::
|
||||||
|
|
||||||
|
typedef struct GUIWindow
|
||||||
{
|
{
|
||||||
Vec2 p0;
|
Vec2 p0;
|
||||||
Vec2 p1;
|
Vec2 p1;
|
||||||
Vec2 grabbed_pos;
|
Vec2 grabbed_pos;
|
||||||
u32 id;
|
u64 id;
|
||||||
b8 grabbed;
|
b8 grabbed;
|
||||||
} GUIWindow;
|
} GUIWindow;
|
||||||
|
|
||||||
typedef struct GUIButton_t
|
typedef struct GUIButton
|
||||||
{
|
{
|
||||||
Vec2 p0;
|
Vec2 p0;
|
||||||
Vec2 p1;
|
Vec2 p1;
|
||||||
u32 id;
|
u64 id;
|
||||||
b8 pressed;
|
b8 pressed;
|
||||||
b8 pressed_prev;
|
b8 pressed_prev;
|
||||||
} GUIButton;
|
} GUIButton;
|
||||||
|
|
||||||
typedef struct GameContext_t
|
typedef struct GameContext
|
||||||
{
|
{
|
||||||
GUIContext gui;
|
GUIContext gui;
|
||||||
PushConst pc;
|
PushConst pc;
|
||||||
@ -29,8 +31,22 @@ typedef struct GameContext_t
|
|||||||
u32 btn_len;
|
u32 btn_len;
|
||||||
} GameContext;
|
} 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 InitializeGame(Arena *arena, GameContext *ctx, Arena *ctx_arena);
|
||||||
static void DestroyGame();
|
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);
|
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 "packer.h"
|
||||||
|
|
||||||
#include "xxhash/xxhash.c"
|
#include "xxhash/xxhash.c"
|
||||||
@ -10,76 +12,33 @@
|
|||||||
#include "renderer.c"
|
#include "renderer.c"
|
||||||
#include "game.c"
|
#include "game.c"
|
||||||
|
|
||||||
#define FWrite(buf, size, count, file) ((size) * (fwrite(buf, size, count, file)))
|
// ::Packer::Includes::CFiles::End::
|
||||||
#define FRead(buf, size, count, file) ((size) * (fread(buf, size, count, file)))
|
|
||||||
|
|
||||||
#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;
|
const FileMapping g_Shader_File_Map[] = {
|
||||||
if (d)
|
{ .file_name = "quad.frag.spv", .ix = QUAD_FRAG_SPIRV_SHADER },
|
||||||
{
|
{ .file_name = "quad.vert.spv", .ix = QUAD_VERT_SPIRV_SHADER },
|
||||||
while ((dir = readdir(d)) != NULL)
|
{ .file_name = "gui.frag.spv", .ix = GUI_FRAG_SPIRV_SHADER },
|
||||||
{
|
{ .file_name = "gui.vert.spv", .ix = GUI_VERT_SPIRV_SHADER },
|
||||||
if (!StrEq(dir->d_name, ".") && !StrEq(dir->d_name, ".."))
|
};
|
||||||
*count += 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
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(".");
|
c8 *g_Shader_File_Names[SHADER_ASSET_MAX] = {};
|
||||||
*count = 0;
|
c8 *g_Texture_File_Names[TEXTURE_ASSET_MAX] = {};
|
||||||
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 (u8 **)file_names;
|
// ::Packer::Globals::End::
|
||||||
}
|
|
||||||
|
|
||||||
b8 DirVisible(c8 *dir_name)
|
|
||||||
{
|
|
||||||
b8 found = false;
|
|
||||||
|
|
||||||
struct dirent *dir;
|
|
||||||
DIR *d = opendir(".");
|
|
||||||
|
|
||||||
if (d)
|
// ::Packer::Files::Functions::Start::
|
||||||
{
|
|
||||||
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
|
|
||||||
|
|
||||||
u64 FileLength(FILE *file)
|
u64 FileLength(FILE *file)
|
||||||
{
|
{
|
||||||
@ -113,6 +72,12 @@ void CloseFile(FILE *file)
|
|||||||
Assert(fclose(file) != EOF, "Error closing file");
|
Assert(fclose(file) != EOF, "Error closing file");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ::Packer::Files::Functions::End::
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// ::Packer::Packing::Functions::Start::
|
||||||
|
|
||||||
void SetArrayLookups()
|
void SetArrayLookups()
|
||||||
{
|
{
|
||||||
for (i32 i = 0; i < Len(g_Shader_File_Map); i++)
|
for (i32 i = 0; i < Len(g_Shader_File_Map); i++)
|
||||||
@ -298,22 +263,11 @@ void PackFiles(Arena *arena, FileHeader *header)
|
|||||||
ChangeDir(return_dir);
|
ChangeDir(return_dir);
|
||||||
}
|
}
|
||||||
|
|
||||||
void PrintBytes(u8 *bytes, u64 len)
|
// ::Packer::Packing::Functions::End::
|
||||||
{
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
while (count < len)
|
|
||||||
{
|
|
||||||
Printf("%u", bytes[count]);
|
// ::Packer::Tests::Functions::Start::
|
||||||
count += 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void TestAssetIsCorrect(Arena *arena, c8 *file_name, AssetFile *file_info, FILE *file)
|
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)
|
int main(int argc, c8 **argv)
|
||||||
{
|
{
|
||||||
Printfln("Header: %d", sizeof(FileHeader));
|
Printfln("Header: %d", sizeof(FileHeader));
|
||||||
@ -429,3 +389,5 @@ int main(int argc, c8 **argv)
|
|||||||
|
|
||||||
TestAssetPack(arena);
|
TestAssetPack(arena);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ::Packer::Main::Functions::End::
|
||||||
|
|||||||
62
src/packer.h
62
src/packer.h
@ -1,5 +1,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
// ::Packer::Includes::Header::
|
||||||
|
|
||||||
#if __linux__
|
#if __linux__
|
||||||
# define _GNU_SOURCE
|
# define _GNU_SOURCE
|
||||||
#elif _WIN32
|
#elif _WIN32
|
||||||
@ -25,27 +27,31 @@
|
|||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
#if __linux__
|
// ::Packer::Macros::Header::
|
||||||
# include <unistd.h>
|
|
||||||
# include <dirent.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define CreateMagicValue(a, b, c, d) ((u32)(d << 24) | (u32)(c << 16) | (u32)(b << 8) | (u32)(a))
|
#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
|
#define FILE_VERSION 0
|
||||||
|
|
||||||
typedef struct AssetTag_t
|
// ::Packer::Types::Header::
|
||||||
|
|
||||||
|
typedef struct AssetTag
|
||||||
{
|
{
|
||||||
u32 tag_id;
|
u32 tag_id;
|
||||||
f32 value;
|
f32 value;
|
||||||
} AssetTag;
|
} AssetTag;
|
||||||
|
|
||||||
typedef struct AssetFile_t
|
typedef struct AssetFile
|
||||||
{
|
{
|
||||||
u64 data_offset;
|
u64 data_offset;
|
||||||
u64 len;
|
u64 len;
|
||||||
} AssetFile;
|
} AssetFile;
|
||||||
|
|
||||||
typedef struct AssetHeader_t
|
typedef struct AssetHeader
|
||||||
{
|
{
|
||||||
AssetTag *tags;
|
AssetTag *tags;
|
||||||
AssetFile *assets;
|
AssetFile *assets;
|
||||||
@ -53,7 +59,7 @@ typedef struct AssetHeader_t
|
|||||||
u32 asset_count;
|
u32 asset_count;
|
||||||
} AssetHeader;
|
} AssetHeader;
|
||||||
|
|
||||||
typedef struct FileHeader_t
|
typedef struct FileHeader
|
||||||
{
|
{
|
||||||
u32 magic_num;
|
u32 magic_num;
|
||||||
u32 version;
|
u32 version;
|
||||||
@ -65,36 +71,34 @@ typedef struct FileHeader_t
|
|||||||
u64 asset_offsets[ASSET_TYPE_MAX];
|
u64 asset_offsets[ASSET_TYPE_MAX];
|
||||||
} FileHeader;
|
} FileHeader;
|
||||||
|
|
||||||
typedef struct FileMapping_t
|
typedef struct FileMapping
|
||||||
{
|
{
|
||||||
c8 *file_name;
|
c8 *file_name;
|
||||||
u32 ix;
|
u32 ix;
|
||||||
} FileMapping;
|
} FileMapping;
|
||||||
|
|
||||||
const FileMapping g_Shader_File_Map[] = {
|
// ::Packer::Files::Functions::Header::
|
||||||
{ .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 },
|
|
||||||
};
|
|
||||||
|
|
||||||
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);
|
FILE *OpenFile(c8 *name, c8 *mode);
|
||||||
void CloseFile(FILE *file);
|
void CloseFile(FILE *file);
|
||||||
u64 FileLength(FILE *file);
|
u64 FileLength(FILE *file);
|
||||||
u64 WriteData(void *buf, u64 pos, u64 size, FILE *file);
|
u64 WriteData(void *buf, u64 pos, u64 size, FILE *file);
|
||||||
u64 ReadData(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);
|
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
|
#error Not yet implemented
|
||||||
#endif
|
#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::
|
// ::Platform::Types::Header::
|
||||||
|
|
||||||
typedef enum Event_e Event_e;
|
typedef struct Library Library;
|
||||||
typedef struct WindowEvent WindowEvent;
|
typedef struct Function Function;
|
||||||
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
|
|
||||||
|
|
||||||
// ::Platform::Includes::Header::
|
// ::Platform::Includes::Header::
|
||||||
|
|
||||||
@ -72,39 +23,43 @@ typedef struct
|
|||||||
#error Not yet implemented
|
#error Not yet implemented
|
||||||
#endif
|
#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 LoadLib(const char *name, Library *out_lib);
|
||||||
b32 LoadFn(const char *name, Library *lib, Function *out_fn);
|
b32 LoadFn(const char *name, Library *lib, Function *out_fn);
|
||||||
|
|
||||||
// ::Platform::Functions::Memory::Header::
|
// ::Platform::Memory::Functions::Header::
|
||||||
|
|
||||||
rawptr MemAlloc(isize size);
|
rawptr MemAlloc(usize size);
|
||||||
rawptr MemAllocZeroed(isize size);
|
rawptr MemAllocZeroed(usize size);
|
||||||
void MemFree(rawptr ptr, isize size);
|
void MemFree(rawptr ptr, usize size);
|
||||||
isize GetPageSize();
|
usize GetPageSize();
|
||||||
|
|
||||||
// ::Platform::Functions::Print::Header::
|
// ::Platform::Window::Functions::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::
|
|
||||||
|
|
||||||
b32 CreatePlatformWindow(const char *window_name);
|
b32 CreatePlatformWindow(const char *window_name);
|
||||||
WindowSize GetWindowSize();
|
WindowSize GetWindowSize();
|
||||||
b32 ShouldQuit();
|
b32 ShouldQuit();
|
||||||
PlatformWindow *GetPlatformWindow();
|
PlatformWindow *GetPlatformWindow();
|
||||||
|
|
||||||
// ::Platform::Functions::SystemInfo::Header::
|
// ::Platform::SystemInfo::Functions::Header::
|
||||||
|
|
||||||
u32 AvailableCPUCount();
|
u32 AvailableCPUCount();
|
||||||
|
|
||||||
// ::Platform::Functions::Directory::Header::
|
// ::Platform::FileSystem::Functions::Header::
|
||||||
|
|
||||||
b32 ChangeWorkingDir(const char *);
|
b32 ChangeDir(c8 *dir);
|
||||||
u8 *OSOpenFile(const char *);
|
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 = {
|
static PlatformWindow linux_window = {
|
||||||
.w = 1920,
|
.w = 1920,
|
||||||
@ -7,29 +7,21 @@ static PlatformWindow linux_window = {
|
|||||||
|
|
||||||
b32 global_quit = false;
|
b32 global_quit = false;
|
||||||
|
|
||||||
// Init
|
// ::Platform::Linux::Globals::End::
|
||||||
|
|
||||||
|
// ::Platform::Linux::Print::Functions::Start::
|
||||||
|
|
||||||
// Init End
|
i32 WriteStdOut(rawptr buf, i32 len)
|
||||||
|
|
||||||
b32 CheckSyscallErr(void *ptr)
|
|
||||||
{
|
{
|
||||||
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 (i32)write(STDERR, buf, len);
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
WindowSize _GetWindowSize()
|
// ::Platform::Linux::Window::Functions::Start::
|
||||||
{
|
|
||||||
return (WindowSize) {
|
|
||||||
.w = linux_window.w,
|
|
||||||
.h = linux_window.h,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
void GetWindowEvents(GameInput *inputs, u32 *i_count)
|
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)
|
if (msg->data.data32[0] == linux_window.close_event)
|
||||||
global_quit = true;
|
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;
|
} break;
|
||||||
case XCB_CONFIGURE_NOTIFY:
|
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);
|
} 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)
|
KeyboardInput ConvertInputEvent(u32 x_key)
|
||||||
{
|
{
|
||||||
switch (x_key)
|
switch (x_key)
|
||||||
@ -311,30 +281,21 @@ KeyboardInput ConvertInputEvent(u32 x_key)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
b32 ChangeWorkingDir(const char *)
|
// ::Platform::Linux::Window::Functions::Start::
|
||||||
{
|
|
||||||
b32 success = false;
|
|
||||||
|
|
||||||
return success;
|
|
||||||
|
|
||||||
|
// ::Platform::Linux::Utils::Functions::Start::
|
||||||
|
|
||||||
|
b32 CheckSyscallErr(void *ptr)
|
||||||
|
{
|
||||||
|
return (isize)ptr == SYS_ERR ? true : false;
|
||||||
}
|
}
|
||||||
|
|
||||||
u8 *OSOpenFile(const char *)
|
// ::Platform::Linux::Utils::Functions::End::
|
||||||
{
|
|
||||||
u8 *bytes = NULL;
|
|
||||||
|
|
||||||
return bytes;
|
|
||||||
}
|
|
||||||
|
|
||||||
b32 ShouldQuit()
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
u32 AvailableCPUCount()
|
// ::Platform::Linux::Includes::CFile::
|
||||||
{
|
|
||||||
cpu_set_t cpu_set;
|
|
||||||
sched_getaffinity(0, sizeof(cpu_set), &cpu_set);
|
|
||||||
return CPU_COUNT(&cpu_set);
|
|
||||||
}
|
|
||||||
|
|
||||||
#include "platform_linux_public.c"
|
#include "platform_linux_public.c"
|
||||||
|
|||||||
@ -20,22 +20,20 @@
|
|||||||
#include <dlfcn.h>
|
#include <dlfcn.h>
|
||||||
#include <nmmintrin.h>
|
#include <nmmintrin.h>
|
||||||
#include <immintrin.h>
|
#include <immintrin.h>
|
||||||
|
|
||||||
#ifndef STG_NO_WINDOW
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <sched.h>
|
#include <sched.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <dirent.h>
|
||||||
|
|
||||||
|
// ::Platform::Linux::Defines::Header::
|
||||||
|
|
||||||
// syscall defines
|
|
||||||
#define SYS_ERR -1
|
#define SYS_ERR -1
|
||||||
|
|
||||||
// syscall write defines
|
#define STDIN 0
|
||||||
#define _STDIN 0
|
#define STDOUT 1
|
||||||
#define _STDOUT 1
|
#define STDERR 2
|
||||||
#define _STDERR 2
|
|
||||||
|
// ::Platform::Linux::Macros::Header::
|
||||||
|
|
||||||
// xcb defines
|
|
||||||
#define XCB_CHECK_CURRENT_ERROR(window, error, message) do { \
|
#define XCB_CHECK_CURRENT_ERROR(window, error, message) do { \
|
||||||
error = xcb_request_check(window->connection, cookie); \
|
error = xcb_request_check(window->connection, cookie); \
|
||||||
if (error != NULL) { \
|
if (error != NULL) { \
|
||||||
@ -50,7 +48,10 @@
|
|||||||
XCB_CHECK_CURRENT_ERROR(window, error, message); \
|
XCB_CHECK_CURRENT_ERROR(window, error, message); \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
typedef struct {
|
// ::Platform::Linux::Types::Header
|
||||||
|
|
||||||
|
typedef struct PlatformWindow
|
||||||
|
{
|
||||||
Display *display;
|
Display *display;
|
||||||
xcb_connection_t *connection;
|
xcb_connection_t *connection;
|
||||||
xcb_window_t window;
|
xcb_window_t window;
|
||||||
@ -59,26 +60,28 @@ typedef struct {
|
|||||||
u16 w, h;
|
u16 w, h;
|
||||||
} PlatformWindow;
|
} PlatformWindow;
|
||||||
|
|
||||||
// ::Platform::Linux::Functions::Header::
|
typedef struct Library
|
||||||
|
{
|
||||||
|
void *lib;
|
||||||
|
} Library;
|
||||||
|
|
||||||
// Print Functions
|
typedef struct Function
|
||||||
i32 _EPrint(void const *str);
|
{
|
||||||
i32 _Printf(const char *fmt, va_list arg);
|
void *fn;
|
||||||
i32 _Printfln(const char *fmt, va_list arg);
|
} Function;
|
||||||
i32 _EPrintf(const char *fmt, va_list arg);
|
|
||||||
|
// ::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);
|
void GetWindowEvents(GameInput *inputs, u32 *i_count);
|
||||||
b32 WaitForWindowEvent(GameInput *input);
|
b32 WaitForWindowEvent(GameInput *input);
|
||||||
void HandleWindowEvent(GameInput *inputs, u32 *input_count, b32 wait_for_event);
|
void HandleWindowEvent(GameInput *inputs, u32 *input_count, b32 wait_for_event);
|
||||||
KeyboardInput ConvertInputEvent(u32 x_key);
|
KeyboardInput ConvertInputEvent(u32 x_key);
|
||||||
void RepaintWindow();
|
|
||||||
|
|
||||||
// Platform API END
|
// ::Platform::Linux::Utils::Functions::Header::
|
||||||
|
|
||||||
// General Utils
|
|
||||||
b32 CheckSyscallErr(void *ptr);
|
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)
|
b32 LoadLib(const char *name, Library *out_lib)
|
||||||
{
|
{
|
||||||
@ -29,61 +29,20 @@ b32 LoadFn(const char *name, Library *lib, Function *out_fn)
|
|||||||
return true;
|
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)
|
// ::Platform::Functions::Print::Start::
|
||||||
{
|
|
||||||
char buffer[1024];
|
|
||||||
|
|
||||||
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;
|
rawptr MemAlloc(usize size)
|
||||||
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)
|
|
||||||
{
|
{
|
||||||
void *addr = mmap(
|
void *addr = mmap(
|
||||||
NULL,
|
NULL,
|
||||||
@ -99,23 +58,29 @@ rawptr MemAlloc(isize size)
|
|||||||
return addr;
|
return addr;
|
||||||
}
|
}
|
||||||
|
|
||||||
rawptr MemAllocZeroed(isize size)
|
rawptr MemAllocZeroed(usize size)
|
||||||
{
|
{
|
||||||
rawptr ptr = MemAlloc(size);
|
rawptr ptr = MemAlloc(size);
|
||||||
MemZero(ptr, size);
|
MemZero(ptr, size);
|
||||||
return ptr;
|
return ptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MemFree(rawptr ptr, isize size)
|
void MemFree(rawptr ptr, usize size)
|
||||||
{
|
{
|
||||||
Assert(munmap(ptr, size) == 0, "munmap failed");
|
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)
|
b32 CreatePlatformWindow(const char *window_name)
|
||||||
{
|
{
|
||||||
PlatformWindow *window = &linux_window;
|
PlatformWindow *window = &linux_window;
|
||||||
@ -224,7 +189,105 @@ b32 CreatePlatformWindow(const char *window_name)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
WindowSize GetWindowSize()
|
||||||
|
{
|
||||||
|
return (WindowSize) {
|
||||||
|
.w = linux_window.w,
|
||||||
|
.h = linux_window.h,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
PlatformWindow *GetPlatformWindow()
|
PlatformWindow *GetPlatformWindow()
|
||||||
{
|
{
|
||||||
return &linux_window;
|
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;
|
return success;
|
||||||
}
|
}
|
||||||
|
|
||||||
rawptr _MemAlloc(isize size)
|
rawptr MemAlloc(isize size)
|
||||||
{
|
{
|
||||||
return (rawptr)VirtualAlloc(0, size, MEM_RESERVE|MEM_COMMIT, PAGE_READWRITE);
|
return (rawptr)VirtualAlloc(0, size, MEM_RESERVE|MEM_COMMIT, PAGE_READWRITE);
|
||||||
}
|
}
|
||||||
|
|
||||||
rawptr _MemAllocZeroed(isize size)
|
rawptr MemAllocZeroed(isize size)
|
||||||
{
|
{
|
||||||
return _MemAlloc(size);
|
return _MemAlloc(size);
|
||||||
}
|
}
|
||||||
|
|
||||||
isize _GetPageSize()
|
isize GetPageSize()
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,12 +1,16 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include <windows.h>
|
|
||||||
|
|
||||||
|
#include <windows.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
|
|
||||||
|
// ::Platform::Windows::Defines::Header::
|
||||||
|
|
||||||
#define WINDOW_CLASS_NAME "GearsWindowClass"
|
#define WINDOW_CLASS_NAME "GearsWindowClass"
|
||||||
|
|
||||||
typedef struct
|
// ::Platform::Windows::Types::Header::
|
||||||
|
|
||||||
|
typedef struct PlatformWindow
|
||||||
{
|
{
|
||||||
HINSTANCE instance;
|
HINSTANCE instance;
|
||||||
HWND handle;
|
HWND handle;
|
||||||
@ -14,14 +18,21 @@ typedef struct
|
|||||||
b32 resize_requested;
|
b32 resize_requested;
|
||||||
} PlatformWindow;
|
} PlatformWindow;
|
||||||
|
|
||||||
|
typedef struct Library
|
||||||
|
{
|
||||||
|
HMODULE module;
|
||||||
|
} Library;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
FARPROC fn;
|
||||||
|
} Function;
|
||||||
|
|
||||||
|
// ::Platform::Windows::Functions::::Header::
|
||||||
|
|
||||||
rawptr _MemAlloc(isize size);
|
rawptr _MemAlloc(isize size);
|
||||||
rawptr _MemAllocZeroed(isize size);
|
rawptr _MemAllocZeroed(isize size);
|
||||||
isize _GetPageSize();
|
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 GetWindowEvents();
|
||||||
void WaitForWindowEvent();
|
void WaitForWindowEvent();
|
||||||
|
|||||||
@ -1,5 +1,17 @@
|
|||||||
#pragma once
|
#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
|
typedef enum Pipeline_e
|
||||||
{
|
{
|
||||||
PIPELINE_CUBE,
|
PIPELINE_CUBE,
|
||||||
@ -30,34 +42,21 @@ typedef enum VertexAttrType_e
|
|||||||
VERTEX_ATTRIBUTE_TYPE_COLOR = 1,
|
VERTEX_ATTRIBUTE_TYPE_COLOR = 1,
|
||||||
} VertexAttrType;
|
} VertexAttrType;
|
||||||
|
|
||||||
// Renderer Front End Types
|
// ::Renderer::Types::Header::
|
||||||
|
|
||||||
// Declarations
|
typedef struct RenderBuffers
|
||||||
|
|
||||||
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
|
|
||||||
{
|
{
|
||||||
RenderBuffer *buffers;
|
RenderBuffer *buffers;
|
||||||
u32 len;
|
u32 len;
|
||||||
} RenderBuffers;
|
} RenderBuffers;
|
||||||
|
|
||||||
// Renderer Front End Types END
|
// ::Renderer::Initialization::Header::
|
||||||
|
|
||||||
// Back End API
|
|
||||||
|
|
||||||
// ::Initialization::Header::
|
|
||||||
b32 InitRenderer(Arena *arena);
|
b32 InitRenderer(Arena *arena);
|
||||||
void DestroyRenderer();
|
void DestroyRenderer();
|
||||||
|
|
||||||
// ::Buffers::Header::
|
// ::Renderer::Buffers::Header::
|
||||||
|
|
||||||
static b32 CreateBuffer(RenderBuffer *buffer);
|
static b32 CreateBuffer(RenderBuffer *buffer);
|
||||||
static void FreeBuffers(RenderBuffer *buffers, u32 buffer_count);
|
static void FreeBuffers(RenderBuffer *buffers, u32 buffer_count);
|
||||||
static b32 UploadToBuffer(RenderBuffer **buffer, rawptr *ptr, u32 count, u8 thr_ix);
|
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 BindVertexBuffer(RenderBuffer *buffer);
|
||||||
static void BindIndexBuffer(RenderBuffer *buffer);
|
static void BindIndexBuffer(RenderBuffer *buffer);
|
||||||
|
|
||||||
// ::Uniforms::Header:: ::PushConstants::Header::
|
// ::Renderer::Uniforms::Header::
|
||||||
|
// ::Renderer::PushConstants::Header::
|
||||||
|
|
||||||
static void GetViewportSize(Vec2 *size);
|
static void GetViewportSize(Vec2 *size);
|
||||||
static void SetGlobalUniform(ShaderGlobals *globals);
|
static void SetGlobalUniform(ShaderGlobals *globals);
|
||||||
static void SetPushConstants(PushConst *pc);
|
static void SetPushConstants(PushConst *pc);
|
||||||
static DescHandle UploadImageUniform();
|
static DescHandle UploadImageUniform();
|
||||||
|
|
||||||
// ::Config::Header::
|
// ::Renderer::Config::Header::
|
||||||
|
|
||||||
static void SetRenderResolution(u32 x, u32 y);
|
static void SetRenderResolution(u32 x, u32 y);
|
||||||
static void SetRendererAvailableThreads(u32 n);
|
static void SetRendererAvailableThreads(u32 n);
|
||||||
|
|
||||||
// ::Rendering::Header::
|
// ::Renderer::Rendering::Header::
|
||||||
|
|
||||||
static b32 BeginFrame();
|
static b32 BeginFrame();
|
||||||
static b32 FinishFrame();
|
static b32 FinishFrame();
|
||||||
static void DrawIndexed(u32 index_count, u32 instance_count);
|
static void DrawIndexed(u32 index_count, u32 instance_count);
|
||||||
static void BindPipeline(PipelineHandle handle, PipelineType type);
|
static void BindPipeline(PipelineHandle handle, PipelineType type);
|
||||||
|
|
||||||
|
// ::Renderer::Includes::Header::
|
||||||
|
|
||||||
#if STG_VULKAN_RENDERER
|
#if STG_VULKAN_RENDERER
|
||||||
#include "renderer_vulkan.h"
|
#include "renderer_vulkan.h"
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@ -1,11 +1,44 @@
|
|||||||
/**
|
// ::Vulkan::Globals::Start::
|
||||||
* BACK END API
|
|
||||||
*/
|
|
||||||
|
|
||||||
// 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"
|
#include "renderer_vulkan_public.c"
|
||||||
|
|
||||||
|
// ::Vulkan::Includes::CFiles::End::
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// ::Vulkan::Util::Functions::Start::
|
||||||
|
|
||||||
static inline u32 GetFrameIndex()
|
static inline u32 GetFrameIndex()
|
||||||
{
|
{
|
||||||
return renderer.frame_state.frame_cnt % FRAME_OVERLAP;
|
return renderer.frame_state.frame_cnt % FRAME_OVERLAP;
|
||||||
@ -41,6 +74,87 @@ static inline RenderBuffer *GetFrameRenderBuffers()
|
|||||||
return renderer.vk.frame.buffer_destroy_queues[GetFrameIndex()];
|
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()
|
static void BeginRendering()
|
||||||
{
|
{
|
||||||
VkCommandBuffer cmd = GetFrameCmdBuf();
|
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);
|
vkCmdBindDescriptorSets(cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, renderer.vk.pipe.pipeline_layout, 0, DESC_TYPE_MAX, renderer.vk.pipe.sets, 0, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ClearScreen()
|
// ::Vulkan::Rendering::Functions::End::
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
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::ImmediateSubmit::Functions::Start::
|
||||||
|
|
||||||
static b32 BeginImmSubmit(VkDevice device, VkFence *fence, VkCommandBuffer cmd)
|
static b32 BeginImmSubmit(VkDevice device, VkFence *fence, VkCommandBuffer cmd)
|
||||||
{
|
{
|
||||||
@ -192,23 +291,12 @@ static b32 FinishImmSubmit(VkDevice device, VkFence *fence, VkCommandBuffer cmd,
|
|||||||
return success;
|
return success;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ::Vulkan::ImmediateSubmit::Functions::End::
|
||||||
static b32 UploadGUIBuffer(MeshBuffer *buf, GUIContext *ctx)
|
|
||||||
{
|
|
||||||
b32 success = true;
|
|
||||||
return success;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* BACK END API END
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
// ::Vulkan::Swapchain::Functions::Start::
|
||||||
* INTERNAL API
|
|
||||||
*/
|
|
||||||
|
|
||||||
// Swapchain
|
|
||||||
static void ResizeSwapchain()
|
static void ResizeSwapchain()
|
||||||
{
|
{
|
||||||
vkDeviceWaitIdle(renderer.vk.device);
|
vkDeviceWaitIdle(renderer.vk.device);
|
||||||
@ -226,84 +314,11 @@ static void ResizeSwapchain()
|
|||||||
renderer.pending.resized = false;
|
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);
|
// ::Vulkan::Init::Functions::Start::
|
||||||
}
|
|
||||||
|
|
||||||
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
|
|
||||||
|
|
||||||
static b32 CreateVmaAllocator()
|
static b32 CreateVmaAllocator()
|
||||||
{
|
{
|
||||||
@ -719,27 +734,6 @@ static b32 LoadVulkanLib()
|
|||||||
return lib_found;
|
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()
|
static b32 CreateFrameStructures()
|
||||||
{
|
{
|
||||||
b32 success = true;
|
b32 success = true;
|
||||||
@ -1170,9 +1164,36 @@ static b32 CreateShaderModule(u8 *bytes, u32 len, VkShaderModule *module)
|
|||||||
return success;
|
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)
|
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
|
#elif _WIN32
|
||||||
|
|
||||||
@ -1247,6 +1254,12 @@ static void StartVkLoaderThreads()
|
|||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// ::Vulkan::Async::Functions::End::
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// ::Vulkan::CleanUp::Functions::Start::
|
||||||
|
|
||||||
static void DestroySwapchain()
|
static void DestroySwapchain()
|
||||||
{
|
{
|
||||||
for (u32 i = 0; i < renderer.vk.sc.img_count; i++)
|
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);
|
vmaDestroyImage(vma_alloc, sc->depth_img.img, sc->depth_img.alloc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ::Vulkan::CleanUp::Functions::End::
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// ::Vulkan::Logging::Functions::Start::
|
||||||
|
|
||||||
void VkInfo(const char *str)
|
void VkInfo(const char *str)
|
||||||
{
|
{
|
||||||
Printfln("[INFO] %s", str);
|
Printfln("[INFO] %s", str);
|
||||||
@ -1285,6 +1304,12 @@ void VkError(const char *str)
|
|||||||
Printfln("[ERROR] %s", str);
|
Printfln("[ERROR] %s", str);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ::Vulkan::Logging::Functions::End::
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// ::Vulkan::Debug::Functions::Start::
|
||||||
|
|
||||||
const char *VkResultStr(VkResult result)
|
const char *VkResultStr(VkResult result)
|
||||||
{
|
{
|
||||||
switch (result)
|
switch (result)
|
||||||
@ -1456,4 +1481,25 @@ static VKAPI_ATTR VkBool32 DebugCallback(
|
|||||||
return VK_FALSE;
|
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"
|
#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::
|
// ::Vulkan::Macros::Header::
|
||||||
|
|
||||||
#define VK_DECLARE(fn) static PFN_##fn fn = NULL
|
#define VK_DECLARE(fn) static PFN_##fn fn = NULL
|
||||||
@ -158,12 +179,12 @@ typedef enum DescType_e
|
|||||||
DESC_TYPE_MAX,
|
DESC_TYPE_MAX,
|
||||||
} DescType;
|
} DescType;
|
||||||
|
|
||||||
typedef struct ShaderGlobals_t
|
typedef struct ShaderGlobals
|
||||||
{
|
{
|
||||||
Vec2 res;
|
Vec2 res;
|
||||||
} ShaderGlobals;
|
} ShaderGlobals;
|
||||||
|
|
||||||
typedef struct RenderBuffer_t
|
typedef struct RenderBuffer
|
||||||
{
|
{
|
||||||
RenderBufferType type;
|
RenderBufferType type;
|
||||||
VkBuffer buffer;
|
VkBuffer buffer;
|
||||||
@ -173,18 +194,18 @@ typedef struct RenderBuffer_t
|
|||||||
i32 mem_index; // TODO(MA): use this
|
i32 mem_index; // TODO(MA): use this
|
||||||
} RenderBuffer;
|
} RenderBuffer;
|
||||||
|
|
||||||
typedef struct
|
typedef struct MeshBuffer
|
||||||
{
|
{
|
||||||
RenderBuffer index_buf, vertex_buf;
|
RenderBuffer index_buf, vertex_buf;
|
||||||
u32 index_count;
|
u32 index_count;
|
||||||
} MeshBuffer;
|
} MeshBuffer;
|
||||||
|
|
||||||
typedef struct
|
typedef struct GlobalUniforms
|
||||||
{
|
{
|
||||||
f32 res[2];
|
f32 res[2];
|
||||||
} GlobalUniforms;
|
} GlobalUniforms;
|
||||||
|
|
||||||
typedef struct
|
typedef struct DescBindings
|
||||||
{
|
{
|
||||||
u16 *free;
|
u16 *free;
|
||||||
u16 free_count;
|
u16 free_count;
|
||||||
@ -193,7 +214,7 @@ typedef struct
|
|||||||
DescHandle *handle_indices;
|
DescHandle *handle_indices;
|
||||||
} DescBindings;
|
} DescBindings;
|
||||||
|
|
||||||
typedef struct
|
typedef struct PipelineStructures
|
||||||
{
|
{
|
||||||
VkPipelineLayout pipeline_layout;
|
VkPipelineLayout pipeline_layout;
|
||||||
VkDescriptorPool pool;
|
VkDescriptorPool pool;
|
||||||
@ -204,12 +225,12 @@ typedef struct
|
|||||||
VkPipeline pipelines[PIPELINE_MAX];
|
VkPipeline pipelines[PIPELINE_MAX];
|
||||||
} PipelineStructures;
|
} PipelineStructures;
|
||||||
|
|
||||||
typedef struct PushConst_t
|
typedef struct PushConst
|
||||||
{
|
{
|
||||||
Vec2 res;
|
Vec2 res;
|
||||||
} PushConst;
|
} PushConst;
|
||||||
|
|
||||||
typedef struct
|
typedef struct FrameStructures
|
||||||
{
|
{
|
||||||
VkCommandPool *pools;
|
VkCommandPool *pools;
|
||||||
VkCommandBuffer *buffers;
|
VkCommandBuffer *buffers;
|
||||||
@ -220,7 +241,7 @@ typedef struct
|
|||||||
u32 *buffer_counts;
|
u32 *buffer_counts;
|
||||||
} FrameStructures;
|
} FrameStructures;
|
||||||
|
|
||||||
typedef struct
|
typedef struct ImmediateStructures
|
||||||
{
|
{
|
||||||
VkCommandPool *pools;
|
VkCommandPool *pools;
|
||||||
VkCommandBuffer *cmds;
|
VkCommandBuffer *cmds;
|
||||||
@ -233,13 +254,15 @@ typedef struct
|
|||||||
u32 volatile next_ticket;
|
u32 volatile next_ticket;
|
||||||
} ImmediateStructures;
|
} ImmediateStructures;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct DeviceQueues
|
||||||
|
{
|
||||||
i32 graphics, transfer;
|
i32 graphics, transfer;
|
||||||
VkQueue graphics_queue, transfer_queue;
|
VkQueue graphics_queue, transfer_queue;
|
||||||
b8 single_queue;
|
b8 single_queue;
|
||||||
} DeviceQueues;
|
} DeviceQueues;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct Image
|
||||||
|
{
|
||||||
VkImage img;
|
VkImage img;
|
||||||
VkImageView view;
|
VkImageView view;
|
||||||
VmaAllocation alloc;
|
VmaAllocation alloc;
|
||||||
@ -247,7 +270,8 @@ typedef struct {
|
|||||||
VkImageLayout curr_layout;
|
VkImageLayout curr_layout;
|
||||||
} Image;
|
} Image;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct SwapchainStructures
|
||||||
|
{
|
||||||
VkFormat format;
|
VkFormat format;
|
||||||
VkColorSpaceKHR color_space;
|
VkColorSpaceKHR color_space;
|
||||||
VkPresentModeKHR present_mode;
|
VkPresentModeKHR present_mode;
|
||||||
@ -259,7 +283,8 @@ typedef struct {
|
|||||||
Image depth_img;
|
Image depth_img;
|
||||||
} SwapchainStructures;
|
} SwapchainStructures;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct FrameState
|
||||||
|
{
|
||||||
u32 img_ix;
|
u32 img_ix;
|
||||||
u64 frame_cnt;
|
u64 frame_cnt;
|
||||||
u64 prev_frame;
|
u64 prev_frame;
|
||||||
@ -269,7 +294,8 @@ typedef struct {
|
|||||||
u32 prev_buffer_count;
|
u32 prev_buffer_count;
|
||||||
} FrameState;
|
} FrameState;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct Vulkan
|
||||||
|
{
|
||||||
Library lib;
|
Library lib;
|
||||||
VkInstance inst;
|
VkInstance inst;
|
||||||
VkSurfaceKHR surface;
|
VkSurfaceKHR surface;
|
||||||
@ -285,15 +311,16 @@ typedef struct {
|
|||||||
#ifdef BUILD_DEBUG
|
#ifdef BUILD_DEBUG
|
||||||
VkDebugUtilsMessengerEXT debug;
|
VkDebugUtilsMessengerEXT debug;
|
||||||
#endif
|
#endif
|
||||||
} Vulkan_t;
|
} Vulkan;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct PendingUpdates
|
||||||
|
{
|
||||||
u16 render_width;
|
u16 render_width;
|
||||||
u16 render_height;
|
u16 render_height;
|
||||||
b8 resized;
|
b8 resized;
|
||||||
} PendingUpdates;
|
} PendingUpdates;
|
||||||
|
|
||||||
typedef struct VulkanConfig_t
|
typedef struct VulkanConfig
|
||||||
{
|
{
|
||||||
u8 avail_threads;
|
u8 avail_threads;
|
||||||
#ifdef __linux__
|
#ifdef __linux__
|
||||||
@ -303,9 +330,9 @@ typedef struct VulkanConfig_t
|
|||||||
#endif
|
#endif
|
||||||
} VulkanConfig;
|
} VulkanConfig;
|
||||||
|
|
||||||
typedef struct Renderer_t
|
typedef struct Renderer
|
||||||
{
|
{
|
||||||
Vulkan_t vk;
|
Vulkan vk;
|
||||||
VulkanConfig vk_conf;
|
VulkanConfig vk_conf;
|
||||||
FrameState frame_state;
|
FrameState frame_state;
|
||||||
PendingUpdates pending;
|
PendingUpdates pending;
|
||||||
@ -313,9 +340,7 @@ typedef struct Renderer_t
|
|||||||
Arena *perm_arena;
|
Arena *perm_arena;
|
||||||
} Renderer;
|
} Renderer;
|
||||||
|
|
||||||
// ::Vulkan::Functions::Header::
|
// ::Vulkan::Debug::Functions::Header::
|
||||||
|
|
||||||
// ::Vulkan::Debug::Header::
|
|
||||||
|
|
||||||
static b32 VLayersSupported();
|
static b32 VLayersSupported();
|
||||||
static VKAPI_ATTR VkBool32 DebugCallback(
|
static VKAPI_ATTR VkBool32 DebugCallback(
|
||||||
@ -326,7 +351,7 @@ static VKAPI_ATTR VkBool32 DebugCallback(
|
|||||||
);
|
);
|
||||||
const char *VkResultStr(VkResult result);
|
const char *VkResultStr(VkResult result);
|
||||||
|
|
||||||
// ::Vulkan::Init::Header::
|
// ::Vulkan::Init::Functions::Header::
|
||||||
|
|
||||||
static b32 LoadVulkanLib();
|
static b32 LoadVulkanLib();
|
||||||
static b32 InitVkInstanceFunctions();
|
static b32 InitVkInstanceFunctions();
|
||||||
@ -349,7 +374,7 @@ static b32 CreatePipelines();
|
|||||||
static b32 CreateShaderModule(u8 *bytes, u32 len, VkShaderModule *module);
|
static b32 CreateShaderModule(u8 *bytes, u32 len, VkShaderModule *module);
|
||||||
static void StartVkLoaderThreads();
|
static void StartVkLoaderThreads();
|
||||||
|
|
||||||
// ::Vulkan::Util::Header::
|
// ::Vulkan::Util::Functions::Header::
|
||||||
|
|
||||||
static inline VkCommandBuffer GetFrameCmdBuf();
|
static inline VkCommandBuffer GetFrameCmdBuf();
|
||||||
static inline VkFence *GetFrameRenderFence();
|
static inline VkFence *GetFrameRenderFence();
|
||||||
@ -359,42 +384,36 @@ static inline u32 GetFrameIndex();
|
|||||||
static inline VkImage GetFrameSwapImage();
|
static inline VkImage GetFrameSwapImage();
|
||||||
static inline u32 *GetFrameBufferCount();
|
static inline u32 *GetFrameBufferCount();
|
||||||
static inline RenderBuffer *GetFrameRenderBuffers();
|
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__
|
#ifdef __linux__
|
||||||
void *VkLoaderStart(void *thread_data);
|
void *VkLoaderStart(void *thread_data);
|
||||||
#elif _WIN32
|
#elif _WIN32
|
||||||
#error not yet implemented
|
#error not yet implemented
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// ::Vulkan::ImmediateSubmit::Header::
|
// ::Vulkan::ImmediateSubmit::Functions::Header::
|
||||||
|
|
||||||
static b32 BeginImmSubmit(VkDevice device, VkFence *fence, VkCommandBuffer cmd);
|
static b32 BeginImmSubmit(VkDevice device, VkFence *fence, VkCommandBuffer cmd);
|
||||||
static b32 FinishImmSubmit(VkDevice device, VkFence *fence, VkCommandBuffer cmd, VkQueue queue);
|
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 DestroySwapchain();
|
||||||
static void DestroyDrawImages();
|
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();
|
static void ResizeSwapchain();
|
||||||
|
|
||||||
// ::Vulkan::Logging::Header::
|
// ::Vulkan::Logging::Functions::Header::
|
||||||
|
|
||||||
static void VkInfo(const char *str);
|
static void VkInfo(const char *str);
|
||||||
static void VkWarn(const char *str);
|
static void VkWarn(const char *str);
|
||||||
@ -402,50 +421,4 @@ static void VkError(const char *str);
|
|||||||
|
|
||||||
#include "vulkan_config.c"
|
#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 @@
|
|||||||
/*
|
// ::Vulkan::Renderer::Initialization::Functions::Start::
|
||||||
* ::Initialization::Start::
|
|
||||||
*/
|
|
||||||
b32 InitRenderer(Arena *arena)
|
b32 InitRenderer(Arena *arena)
|
||||||
{
|
{
|
||||||
SetRendererAvailableThreads(AvailableCPUCount());
|
SetRendererAvailableThreads(AvailableCPUCount());
|
||||||
@ -114,13 +113,11 @@ void DestroyRenderer()
|
|||||||
ArenaFree(renderer.perm_arena);
|
ArenaFree(renderer.perm_arena);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// ::Vulkan::Renderer::Initialization::Functions::End::
|
||||||
* ::Initialization::End::
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* ::Buffers::Start::
|
|
||||||
*/
|
// ::Vulkan::Renderer::Buffers::Functions::Start::
|
||||||
|
|
||||||
static b32 CreateBuffer(RenderBuffer *buffer)
|
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);
|
__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)
|
static void FreeBuffers(RenderBuffer *buffers, u32 buffer_count)
|
||||||
{
|
{
|
||||||
VkDevice device = renderer.vk.device;
|
VkDevice device = renderer.vk.device;
|
||||||
@ -370,13 +353,12 @@ static void BindIndexBuffer(RenderBuffer *buffer)
|
|||||||
vkCmdBindIndexBuffer(cmd, buffer->buffer, 0, VK_INDEX_TYPE_UINT32);
|
vkCmdBindIndexBuffer(cmd, buffer->buffer, 0, VK_INDEX_TYPE_UINT32);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// ::Vulkan::Renderer::Buffers::Functions::End::
|
||||||
* ::Buffers::End::
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* ::Uniforms::Start:: ::PushConstants::Start::
|
|
||||||
*/
|
// ::Vulkan::Renderer::Uniforms::Functions::Start::
|
||||||
|
// ::Vulkan::Renderer::PushConstants::Functions::Start::
|
||||||
|
|
||||||
static void GetViewportSize(Vec2 *size)
|
static void GetViewportSize(Vec2 *size)
|
||||||
{
|
{
|
||||||
@ -401,13 +383,12 @@ static void SetPushConstants(PushConst *pc)
|
|||||||
pc);
|
pc);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// ::Vulkan::Renderer::Uniforms::Functions::End::
|
||||||
* ::Uniforms::End:: ::PushConstants::End::
|
// ::Vulkan::Renderer::PushConstants::Functions::End::
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* ::Config::Start::
|
|
||||||
*/
|
// ::Vulkan::Renderer::Config::Functions::Start::
|
||||||
|
|
||||||
static void SetRenderResolution(u32 x, u32 y)
|
static void SetRenderResolution(u32 x, u32 y)
|
||||||
{
|
{
|
||||||
@ -421,13 +402,11 @@ static void SetRendererAvailableThreads(u32 n)
|
|||||||
renderer.vk_conf.avail_threads = n;
|
renderer.vk_conf.avail_threads = n;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// ::Vulkan::Renderer::Config::Functions::End::
|
||||||
* ::Config::End::
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* ::Rendering::Start::
|
|
||||||
*/
|
// ::Vulkan::Renderer::Rendering::Functions::Start::
|
||||||
|
|
||||||
b32 BeginFrame()
|
b32 BeginFrame()
|
||||||
{
|
{
|
||||||
@ -651,6 +630,4 @@ static void BindPipeline(PipelineHandle handle, PipelineType type)
|
|||||||
vkCmdSetScissor(cmd, 0, 1, &scissor);
|
vkCmdSetScissor(cmd, 0, 1, &scissor);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// ::Vulkan::Renderer::Rendering::Functions::End::
|
||||||
* ::Rendering::End::
|
|
||||||
*/
|
|
||||||
|
|||||||
@ -6,53 +6,24 @@
|
|||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
typedef int8_t i8;
|
// ::SharedTypes::Declarations::Header::
|
||||||
typedef int16_t i16;
|
|
||||||
typedef int32_t i32;
|
|
||||||
typedef int64_t i64;
|
|
||||||
|
|
||||||
typedef uint8_t u8;
|
typedef struct Arena Arena;
|
||||||
typedef uint16_t u16;
|
|
||||||
typedef uint32_t u32;
|
|
||||||
typedef uint64_t u64;
|
|
||||||
|
|
||||||
typedef char c8;
|
// ::SharedTypes::Attributes::Header::
|
||||||
|
|
||||||
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;
|
|
||||||
|
|
||||||
|
#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
|
#endif
|
||||||
|
|
||||||
#elif __APPLE__ || __MACH__
|
// ::SharedTypes::Enums::Header::
|
||||||
|
|
||||||
#else // unix
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
typedef enum KeyboardInput_e
|
typedef enum KeyboardInput_e
|
||||||
{
|
{
|
||||||
@ -181,6 +152,59 @@ typedef enum GameInputType_e
|
|||||||
GI_GAMEPAD,
|
GI_GAMEPAD,
|
||||||
} GameInputType;
|
} 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
|
typedef union
|
||||||
{
|
{
|
||||||
struct { f32 r, g; };
|
struct { f32 r, g; };
|
||||||
@ -225,13 +249,13 @@ typedef f64 dMat2[4];
|
|||||||
typedef f64 dMat3[9];
|
typedef f64 dMat3[9];
|
||||||
typedef f64 dMat4[16];
|
typedef f64 dMat4[16];
|
||||||
|
|
||||||
typedef struct MouseMotionEvent_t
|
typedef struct MouseMotionEvent
|
||||||
{
|
{
|
||||||
i16 x;
|
i16 x;
|
||||||
i16 y;
|
i16 y;
|
||||||
} MouseMotionEvent;
|
} MouseMotionEvent;
|
||||||
|
|
||||||
typedef struct
|
typedef struct GameInput
|
||||||
{
|
{
|
||||||
union
|
union
|
||||||
{
|
{
|
||||||
@ -243,14 +267,14 @@ typedef struct
|
|||||||
GameInputType type;
|
GameInputType type;
|
||||||
} GameInput; // TODO: add gamepad input
|
} GameInput; // TODO: add gamepad input
|
||||||
|
|
||||||
typedef struct
|
typedef struct GUIVertex
|
||||||
{
|
{
|
||||||
Vec2 p0;
|
Vec2 p0;
|
||||||
Vec2 p1;
|
Vec2 p1;
|
||||||
Vec4 col;
|
Vec4 col;
|
||||||
} GUIVertex;
|
} GUIVertex;
|
||||||
|
|
||||||
typedef struct
|
typedef struct GUIContext
|
||||||
{
|
{
|
||||||
GUIVertex *vertices;
|
GUIVertex *vertices;
|
||||||
u32 vertices_len;
|
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::Strings::Functions::End::
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// ::Util::Memory::Functions::Start::
|
||||||
|
|
||||||
void MemZero(void *ptr, isize size)
|
void MemZero(void *ptr, isize size)
|
||||||
{
|
{
|
||||||
if (!size || !ptr) return;
|
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)
|
u32 u32Min(u32 l, u32 r)
|
||||||
{
|
{
|
||||||
return l >= r ? r : l;
|
return l >= r ? r : l;
|
||||||
@ -176,133 +186,9 @@ u32 u32Clamp(u32 v, u32 min, u32 max)
|
|||||||
return i32Min(max, i32Max(v, min));
|
return i32Min(max, i32Max(v, min));
|
||||||
}
|
}
|
||||||
|
|
||||||
u32 inline ReadBit(BitWriter *bw)
|
// ::Util::Math::Functions::End::
|
||||||
{
|
|
||||||
u32 r = bw->bits >> 31;
|
|
||||||
bw->bits <<= 1;
|
|
||||||
bw->pos += 1;
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
|
|
||||||
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::
|
// ::Util::Hashing::Functions::Start::
|
||||||
|
|
||||||
@ -312,3 +198,94 @@ u64 static inline HashFromString(Str8 string)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ::Util::Hashing::Functions::End::
|
// ::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>
|
#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)
|
#define Assert(condition, message) do { assert((condition) && (message)); } while(0)
|
||||||
|
|
||||||
// ::Util::Size::Defines::
|
|
||||||
|
|
||||||
#define KB(n) n * 1024LL
|
#define KB(n) n * 1024LL
|
||||||
#define MB(n) KB(n) * 1024LL
|
#define MB(n) KB(n) * 1024LL
|
||||||
#define GB(n) MB(n) * 1024LL
|
#define GB(n) MB(n) * 1024LL
|
||||||
#define TB(n) GB(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 BitEq(var, bits) (((var) & (bits)) == (bits))
|
||||||
#define AlignPow2(x, b) (((x) + (b) - 1) & (~((b) - 1)))
|
#define AlignPow2(x, b) (((x) + (b) - 1) & (~((b) - 1)))
|
||||||
#define IsPow2(x) ((x) != 0 && ((x) &((x) - 1)) == 0)
|
#define IsPow2(x) ((x) != 0 && ((x) &((x) - 1)) == 0)
|
||||||
#define PtrAdd(ptr, add) (((char *)ptr) + add)
|
#define PtrAdd(ptr, add) (((char *)ptr) + add)
|
||||||
|
|
||||||
// ::Util::Array::Defines::
|
|
||||||
|
|
||||||
#define MakeArray(arena, type, count) ArenaAlloc(arena, (isize)(sizeof(type)) * (isize)(count))
|
#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])))))
|
#define Len(x) ((sizeof(x)/sizeof(0[x])) / ((size_t)(!(sizeof(x) % sizeof(0[x])))))
|
||||||
|
|
||||||
// ::Util::Compression::Defines::
|
#define Str8L(x) (Str8){ .len = StrLen(x), .value = (u8 *)x }
|
||||||
|
|
||||||
#define HM_MAX_SYMBOLS 256
|
|
||||||
|
|
||||||
// ::Util::Strings::Defines::
|
|
||||||
#define Str8L(x) (Str8){ .len = Len(x), .value = (u8 *)x }
|
|
||||||
#define MakeString(x) #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
|
#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::
|
// ::Util::Strings::Functions::Header::
|
||||||
|
|
||||||
u32 StrLen(const char *str);
|
u32 StrLen(const char *str);
|
||||||
@ -90,20 +53,17 @@ i32 i32Max(i32 l, i32 r);
|
|||||||
i32 i32Clamp(i32 v, i32 min, i32 max);
|
i32 i32Clamp(i32 v, i32 min, i32 max);
|
||||||
u32 u32Clamp(u32 v, u32 min, u32 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::
|
// ::Util::Hashing::Functions::Header::
|
||||||
|
|
||||||
u64 static inline HashFromString(Str8 string);
|
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