diff --git a/src/allocators.c b/src/allocators.c index dbbb771..3803b8b 100644 --- a/src/allocators.c +++ b/src/allocators.c @@ -448,6 +448,8 @@ static void FreeListFree(FLAlloc *alloc, rawptr ptr) break; } } + + __atomic_fetch_add(&alloc->next_ticket, 1, __ATOMIC_SEQ_CST); } static void FreeListCoalescence(FreeList *alloc, FLNode *prev_node, FLNode *free_node) diff --git a/src/assets.c b/src/assets.c index e69de29..46ad512 100644 --- a/src/assets.c +++ b/src/assets.c @@ -0,0 +1,107 @@ + +// ::Assets::Globals::Start:: + +u8 ASSET_PACK[] = +{ + #embed "../assets.sgp" +}; + +static FileHeader File_Header = {0}; + +static AssetFile Texture_Assets[TEXTURE_ASSET_MAX]; +static Asset Texture_Asset_Lookup[TEXTURE_ASSET_MAX]; + +static AssetFile Shader_Assets[SHADER_ASSET_MAX]; +static Asset Shader_Asset_Lookup[SHADER_ASSET_MAX]; + + +// ::Assets::Global::End:: + + + +// ::Assets::Init::Functions::Start:: + +static void LoadAssetPackHeader() +{ + MemCpy(&File_Header, ASSET_PACK, sizeof(FileHeader)); + + Assert(File_Header.magic_num == CreateMagicValue('s', 't', 'e', 'g'), "Magic value is incorrect"); + + MemCpy(Texture_Assets, &ASSET_PACK[File_Header.asset_offsets[TEXTURE_ASSET]], sizeof(AssetFile) * File_Header.asset_counts[TEXTURE_ASSET]); + + MemCpy(Shader_Assets, &ASSET_PACK[File_Header.asset_offsets[SHADER_ASSET]], sizeof(AssetFile) * File_Header.asset_counts[SHADER_ASSET]); +} + +// ::Assets::Init::Functions::End:: + + + +// ::Assets::Loading::Functions::Start:: + +static Asset LoadTextureAsset(TextureAsset asset_id) +{ + Assert(asset_id < i32(TEXTURE_ASSET_MAX), "LoadTextureAsset failure: asset_id is higher than TEXTURE_ASSET_MAX"); + + Asset asset = Texture_Asset_Lookup[asset_id]; + if (asset.bytes == NULL) + { + AssetFile *asset_info = Texture_Assets + asset_id; + asset.bytes = FLMemAlloc(asset_info->len); + MemCpy(asset.bytes, &ASSET_PACK[asset_info->data_offset], asset_info->len); + asset.len = asset_info->len; + Texture_Asset_Lookup[asset_id] = asset; + } + + return asset; +} + +static Asset LoadShaderAsset(ShaderAsset asset_id) +{ + Assert(asset_id < SHADER_ASSET_MAX, "LoadShaderAsset failure: asset_id is higher than SHADER_ASSET_MAX"); + + Asset asset = Shader_Asset_Lookup[asset_id]; + if (asset.bytes == NULL) + { + AssetFile *asset_info = Shader_Assets + asset_id; + asset.bytes = FLMemAlloc(asset_info->len); + MemCpy(asset.bytes, &ASSET_PACK[asset_info->data_offset], asset_info->len); + asset.len = asset_info->len; + Shader_Asset_Lookup[asset_id] = asset; + } + + return asset; +} + +static void UnloadTextureAsset(Asset asset) +{ + Assert(asset.bytes != NULL, "UnloadTextureAsset assert failure: ptr is NULL"); + + for (u32 i = 0; i < TEXTURE_ASSET_MAX; i++) + { + if (asset.bytes == Texture_Asset_Lookup[i].bytes) + { + Texture_Asset_Lookup[i].bytes = NULL; + Texture_Asset_Lookup[i].len = 0; + FLMemFree(asset.bytes); + break; + } + } +} + +static void UnloadShaderAsset(Asset asset) +{ + Assert(asset.bytes != NULL, "UnloadShaderAsset assert failure: ptr is NULL"); + + for (u32 i = 0; i < SHADER_ASSET_MAX; i++) + { + if (asset.bytes == Shader_Asset_Lookup[i].bytes) + { + Shader_Asset_Lookup[i].bytes = NULL; + Shader_Asset_Lookup[i].len = 0; + FLMemFree(asset.bytes); + break; + } + } +} + +// ::Assets::Loading::Functions::End:: diff --git a/src/assets.h b/src/assets.h index bbcd90b..4e3bdcf 100644 --- a/src/assets.h +++ b/src/assets.h @@ -1,5 +1,11 @@ #pragma once +// ::Assets::Macros::Header:: + +#define FILE_VERSION 0 + +#define CreateMagicValue(a, b, c, d) ((u32)(d << 24) | (u32)(c << 16) | (u32)(b << 8) | (u32)(a)) + // ::Assets::Types::Header:: typedef enum AssetType_e @@ -55,5 +61,40 @@ typedef enum ModelAssetTag_e MODEL_ASSET_TAG_MAX, } ModelAssetTag; -static rawptr LoadTextureAsset(TextureAsset asset_id); -static rawptr LoadShaderAsset(ShaderAsset asset_id); +typedef struct Asset +{ + u8 *bytes; + u64 len; +} Asset; + +typedef struct AssetTag +{ + u32 tag_id; + f32 value; +} AssetTag; + +typedef struct AssetFile +{ + u64 data_offset; + u64 len; +} AssetFile; + +typedef struct FileHeader +{ + u32 magic_num; + u32 version; + + u32 tag_counts[ASSET_TYPE_MAX]; + u32 asset_counts[ASSET_TYPE_MAX]; + + u64 tag_offsets[ASSET_TYPE_MAX]; + u64 asset_offsets[ASSET_TYPE_MAX]; +} FileHeader; + +// ::Assets::Loading::Functions::Header:: + +static void LoadAssetPackHeader(); +static Asset LoadTextureAsset(TextureAsset asset_id); +static Asset LoadShaderAsset(ShaderAsset asset_id); +static void UnloadTextureAsset(Asset asset); +static void UnloadShaderAsset(Asset asset); diff --git a/src/entry_linux.c b/src/entry_linux.c index c92b901..d2ccee5 100644 --- a/src/entry_linux.c +++ b/src/entry_linux.c @@ -10,6 +10,7 @@ #include "platform/platform.c" #include "util.c" +#include "assets.c" #include "ds.c" #include "allocators.c" #include "renderer.c" @@ -18,13 +19,6 @@ # include "tests.c" #endif -// ::Entry::Linux::Globals::Start:: - -constexpr u8 asset_pack[] = -{ - #embed "../assets.sgp" -}; - static_assert(__COUNTER__ < Len(GLOBAL_PROFILER.anchors)); void TraverseNode(RBTree *tree, RBNode *node, RBNodeDir *dir) diff --git a/src/entry_linux.h b/src/entry_linux.h index 113499e..4d7c823 100644 --- a/src/entry_linux.h +++ b/src/entry_linux.h @@ -15,6 +15,7 @@ #include "shared_types.h" #include "util.h" +#include "assets.h" #include "ds.h" #include "platform/platform.h" #include "allocators.h" diff --git a/src/entry_windows.c b/src/entry_windows.c index 94d23b6..d42580e 100644 --- a/src/entry_windows.c +++ b/src/entry_windows.c @@ -4,6 +4,7 @@ #include "platform/platform.c" #include "ds.c" +#include "assets.c" #include "util.c" #include "allocators.c" #include "renderer.c" diff --git a/src/entry_windows.h b/src/entry_windows.h index 2d1967f..1a62171 100644 --- a/src/entry_windows.h +++ b/src/entry_windows.h @@ -10,6 +10,7 @@ #include "shared_types.h" #include "ds.h" +#include "assets.h" #include "platform/platform.h" #include "util.h" #include "allocators.h" diff --git a/src/game.c b/src/game.c index b0943b0..98028b0 100644 --- a/src/game.c +++ b/src/game.c @@ -18,6 +18,8 @@ i16 mouse_pos_y = 0; static void InitializeGame(Arena *arena, GameContext *ctx, Arena *ctx_arena) { + LoadAssetPackHeader(); + Assert(InitRenderer(arena), "Failed to initialize the renderer"); ctx->gui.vertices = MakeArray(ctx_arena, GUIVertex, 128); diff --git a/src/packer.c b/src/packer.c index 7755f53..8101f9c 100644 --- a/src/packer.c +++ b/src/packer.c @@ -6,8 +6,9 @@ #include "fastlz/fastlz.c" #include "platform/platform.c" -#include "ds.c" +#include "assets.c" #include "util.c" +#include "ds.c" #include "allocators.c" #include "renderer.c" #include "game.c" diff --git a/src/packer.h b/src/packer.h index fa8cc67..5dc95de 100644 --- a/src/packer.h +++ b/src/packer.h @@ -16,11 +16,11 @@ #include "xxhash/xxhash.h" #include "fastlz/fastlz.h" -#include "assets.h" #include "shared_types.h" +#include "assets.h" +#include "util.h" #include "ds.h" #include "platform/platform.h" -#include "util.h" #include "allocators.h" #include "renderer.h" #include "game.h" @@ -29,48 +29,11 @@ // ::Packer::Macros::Header:: -#define CreateMagicValue(a, b, c, d) ((u32)(d << 24) | (u32)(c << 16) | (u32)(b << 8) | (u32)(a)) #define FWrite(buf, size, count, file) ((size) * (fwrite(buf, size, count, file))) #define FRead(buf, size, count, file) ((size) * (fread(buf, size, count, file))) -// ::Packer::Defines::Header:: - -#define FILE_VERSION 0 - // ::Packer::Types::Header:: -typedef struct AssetTag -{ - u32 tag_id; - f32 value; -} AssetTag; - -typedef struct AssetFile -{ - u64 data_offset; - u64 len; -} AssetFile; - -typedef struct AssetHeader -{ - AssetTag *tags; - AssetFile *assets; - u32 tag_count; - u32 asset_count; -} AssetHeader; - -typedef struct FileHeader -{ - u32 magic_num; - u32 version; - - u32 tag_counts[ASSET_TYPE_MAX]; - u32 asset_counts[ASSET_TYPE_MAX]; - - u64 tag_offsets[ASSET_TYPE_MAX]; - u64 asset_offsets[ASSET_TYPE_MAX]; -} FileHeader; - typedef struct FileMapping { c8 *file_name; diff --git a/src/renderer_vulkan.c b/src/renderer_vulkan.c index 7ed3aa8..4bc46cd 100644 --- a/src/renderer_vulkan.c +++ b/src/renderer_vulkan.c @@ -1065,9 +1065,12 @@ static b32 CreatePipelines() VkResult result; VkDevice device = renderer.vk.device; + Asset quad_vert_shader = LoadShaderAsset(QUAD_VERT_SPIRV_SHADER); + Asset quad_frag_shader = LoadShaderAsset(QUAD_FRAG_SPIRV_SHADER); + VkShaderModule cube_vert, cube_frag; - success &= CreateShaderModule(shader_quad_vert, shader_quad_vert_len, &cube_vert); - success &= CreateShaderModule(shader_quad_frag, shader_quad_frag_len, &cube_frag); + success &= CreateShaderModule(quad_vert_shader.bytes, quad_vert_shader.len, &cube_vert); + success &= CreateShaderModule(quad_frag_shader.bytes, quad_frag_shader.len, &cube_frag); VkPipelineRenderingCreateInfo pipeline_render_info = { .sType = STYPE(PIPELINE_RENDERING_CREATE_INFO), @@ -1106,9 +1109,15 @@ static b32 CreatePipelines() vkDestroyShaderModule(device, cube_vert, NULL); vkDestroyShaderModule(device, cube_frag, NULL); + UnloadShaderAsset(quad_vert_shader); + UnloadShaderAsset(quad_frag_shader); + + Asset gui_vert_shader = LoadShaderAsset(GUI_VERT_SPIRV_SHADER); + Asset gui_frag_shader = LoadShaderAsset(GUI_FRAG_SPIRV_SHADER); + VkShaderModule gui_vert, gui_frag; - success &= CreateShaderModule(shader_gui_vert, shader_gui_vert_len, &gui_vert); - success &= CreateShaderModule(shader_gui_frag, shader_gui_frag_len, &gui_frag); + success &= CreateShaderModule(gui_vert_shader.bytes, gui_vert_shader.len, &gui_vert); + success &= CreateShaderModule(gui_frag_shader.bytes, gui_frag_shader.len, &gui_frag); VkPipelineShaderStageCreateInfo gui_shader_stages[] = { { @@ -1140,6 +1149,9 @@ static b32 CreatePipelines() vkDestroyShaderModule(device, gui_vert, NULL); vkDestroyShaderModule(device, gui_frag, NULL); + UnloadShaderAsset(gui_vert_shader); + UnloadShaderAsset(gui_frag_shader); + return success; }