rework of asset loading

This commit is contained in:
Matthew 2025-06-02 06:21:44 +10:00
parent 0b9f802451
commit e628f2b323
14 changed files with 477 additions and 271 deletions

0
assets/textures/cheesoid.png Executable file → Normal file
View File

Before

Width:  |  Height:  |  Size: 42 KiB

After

Width:  |  Height:  |  Size: 42 KiB

View File

@ -121,15 +121,17 @@ fi
# Packer Codegen # Packer Codegen
$compile $codegen_source_files $compile_link $link_os_gfx $codegen_flags $packer_include_flags $out $codegen_out_name $compile $codegen_source_files $compile_link $link_os_gfx $codegen_flags $packer_include_flags $out $codegen_out_name
./Codegen
# Packer # Packer
if [ -v packer ] || ! [ -f Packer ]; then if [ -v packer ] || ! [ -f Packer ]; then
$compile $packer_source_files $compile_link $link_os_gfx $packer_flags $packer_include_flags $out $packer_out_name $compile $packer_source_files $compile_link $link_os_gfx $packer_flags $packer_include_flags $out $packer_out_name
fi fi
#if [ -v pack ] || ! [ -f assets.sgp ]; then if [ -v pack ] || ! [ -f assets.sgp ]; then
# ./Packer ./Packer
#fi fi
#if ! [ -v packer ]; then if ! [ -v packer ]; then
# $compile $source_files $compile_link $link_os_gfx $out $out_name $compile $source_files $compile_link $link_os_gfx $out $out_name
#fi fi

View File

@ -36,19 +36,8 @@ const u32 M3D_LABEL = CreateMagicValue('L', 'B', 'L', 'S');
static FileHeader File_Header = {0}; static FileHeader File_Header = {0};
static AssetFile Texture_Assets[TEXTURE_ASSET_MAX]; static AssetFile Asset_Info[ASSET_MAX];
static Asset Texture_Asset_Lookup[TEXTURE_ASSET_MAX]; static Asset Asset_Data[ASSET_MAX];
static AssetFile Shader_Assets[SHADER_ASSET_MAX];
static Asset Shader_Asset_Lookup[SHADER_ASSET_MAX];
static AssetFile Model_Assets[MODEL_ASSET_MAX];
static Asset Model_Asset_Lookup[MODEL_ASSET_MAX];
// TODO(MA): Implement async asset handling
static u32 Shader_Asset_Ref_Count[SHADER_ASSET_MAX];
static u32 Texture_Asset_Ref_Count[TEXTURE_ASSET_MAX];
static u32 Model_Asset_Ref_Count[MODEL_ASSET_MAX];
static b32 ASSET_HEADER_LOADED = false; static b32 ASSET_HEADER_LOADED = false;
@ -64,8 +53,9 @@ static void apInit()
MemCpy(&File_Header, ASSET_PACK, sizeof(FileHeader)); MemCpy(&File_Header, ASSET_PACK, sizeof(FileHeader));
Assert(File_Header.magic_num == CreateMagicValue('s', 't', 'e', 'g'), "Magic value is incorrect"); Assert(File_Header.magic_num == CreateMagicValue('s', 't', 'e', 'g'), "Magic value is incorrect");
Assert(File_Header.version == FILE_VERSION, "Asset file version mismatch");
MemCpy(Texture_Assets, &ASSET_PACK[File_Header.asset_offset], sizeof(AssetFile) * File_Header.asset_counts); MemCpy(Asset_Info, &ASSET_PACK[File_Header.asset_offset], sizeof(AssetFile) * File_Header.asset_counts);
ASSET_HEADER_LOADED = true; ASSET_HEADER_LOADED = true;
} }
@ -76,12 +66,81 @@ static void apInit()
// ::Assets::Loading::Functions::Start:: // ::Assets::Loading::Functions::Start::
static Asset *
apAssetSearch(u64 hash)
{
Asset *asset = NULL;
for (u64 i = 0; i < ASSET_MAX; i++)
{
if (asset == NULL && Asset_Data[i].hash == 0)
{
asset = Asset_Data + i;
}
if (hash == Asset_Data[i].hash)
{
asset = Asset_Data + i;
break;
}
}
return asset;
}
static Asset
apLoadWithHash(u64 hash)
{
if (!ASSET_HEADER_LOADED)
{
apInit();
}
Asset *asset = apAssetSearch(hash);
AssetFile file_info = {0};
if (asset->bytes == NULL)
{
for (u64 i = 0; i < ASSET_MAX; i++)
{
if (hash == Asset_Info[i].hash)
{
file_info = Asset_Info[i];
break;
}
}
if (file_info.hash != 0)
{
asset->hash = hash;
asset->type = file_info.type;
u8 *bytes = FLMemAlloc(file_info.len);
MemCpy(bytes, &ASSET_PACK[file_info.data_offset], file_info.len);
if (file_info.type == AT_MODEL)
{
asset->model = apParseModel(bytes);
asset->model_meta = file_info.model_meta;
FLMemFree(bytes);
}
else
{
asset->len = file_info.len;
asset->bytes = bytes;
asset->texture_meta = file_info.texture_meta;
}
}
}
return *asset;
}
static Asset static Asset
apLoad(c8 *str) apLoad(c8 *str)
{ {
Asset asset = {0}; u64 hash = HashFromString(String8CStr(str));
return apLoadWithHash(hash);
return asset;
} }
static Asset static Asset
@ -90,10 +149,34 @@ apLoadS8(String8 str)
return apLoad(str.value); return apLoad(str.value);
} }
static void
apUnloadWithHash(u64 hash)
{
Asset *asset = apAssetSearch(hash);
if (asset->bytes != NULL)
{
if (asset->type == AT_MODEL)
{
apFreeModel(asset->model);
}
else
{
FLMemFree(asset->bytes);
}
asset->bytes = NULL;
asset->type = AT_NONE;
asset->len = 0;
asset->hash = 0;
}
}
static void static void
apUnload(c8 *str) apUnload(c8 *str)
{ {
u64 hash = HashFromString(String8CStr(str));
apUnloadWithHash(hash);
} }
static void static void
@ -288,5 +371,12 @@ static m3dModel *apParseModel(rawptr data)
return model; return model;
} }
static void apFreeModel(m3dModel *model)
{
FLMemFree(model->vertices);
FLMemFree(model->indices);
FLMemFree(model);
}
// ::Assets::Models::Functions::End:: // ::Assets::Models::Functions::End::

View File

@ -2,7 +2,7 @@
// ::Assets::Macros::Header:: // ::Assets::Macros::Header::
#define FILE_VERSION 1 #define FILE_VERSION 3U
#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))
@ -37,25 +37,6 @@ typedef struct ModelMeta
u64 i_count; u64 i_count;
} ModelMeta; } ModelMeta;
typedef struct AssetMeta
{
union
{
TexMeta texture;
ModelMeta model;
};
} AssetMeta;
typedef struct Asset
{
union
{
u8 *bytes;
m3dModel *model;
};
u64 len;
} Asset;
typedef struct AssetTag typedef struct AssetTag
{ {
u32 tag_id; u32 tag_id;
@ -70,6 +51,23 @@ typedef enum AssetType_e
AT_MODEL, AT_MODEL,
} AssetType; } AssetType;
typedef struct Asset
{
union
{
u8 *bytes;
m3dModel *model;
};
union
{
TexMeta texture_meta;
ModelMeta model_meta;
};
u64 hash;
u64 len;
AssetType type;
} Asset;
typedef struct AssetFile typedef struct AssetFile
{ {
union union
@ -99,9 +97,12 @@ static void apInit();
static Asset apLoad(c8 *str); static Asset apLoad(c8 *str);
static Asset apLoadS8(String8 str); static Asset apLoadS8(String8 str);
static Asset apLoadWithHash(u64 hash);
static void apUnload(c8 *str); static void apUnload(c8 *str);
static void apUnloadS8(String8 str); static void apUnloadS8(String8 str);
static void apUnloadWithHash(u64 hash);
static u64 apAssetIndex(c8 *str); static u64 apAssetIndex(c8 *str);
static Asset *apAssetSearch(u64 hash);
// ::Assets::Util::Functions::Header:: // ::Assets::Util::Functions::Header::
@ -112,3 +113,4 @@ static inline void apMarkLoaded(c8 *str);
// ::Assets::Models::Functions::Header:: // ::Assets::Models::Functions::Header::
static m3dModel *apParseModel(rawptr data); static m3dModel *apParseModel(rawptr data);
static void apFreeModel(m3dModel *model);

View File

@ -1,5 +1,7 @@
#include "codegen.h" #include "codegen.h"
#include "xxhash/xxhash.c"
u64 u64
WriteArrayToFile(Arena *arena, pFile file, String8 array_name, rawptr elements, u32 count, String8 type, u64 offset) WriteArrayToFile(Arena *arena, pFile file, String8 array_name, rawptr elements, u32 count, String8 type, u64 offset)
{ {
@ -89,6 +91,7 @@ CodeGenAssetLookups(Arena *arena)
}, },
}; };
u64 total_assets = 0;
u64 offset = 0; u64 offset = 0;
u32 dir_count = sizeof(dirs) / sizeof(struct AssetDirInfo); u32 dir_count = sizeof(dirs) / sizeof(struct AssetDirInfo);
for (u32 i = 0; i < dir_count; i += 1) for (u32 i = 0; i < dir_count; i += 1)
@ -104,7 +107,7 @@ CodeGenAssetLookups(Arena *arena)
{ {
strs[j] = String8Concat(arena, String8CStr(dirs[i].prefix), strs[j]); strs[j] = String8Concat(arena, String8CStr(dirs[i].prefix), strs[j]);
i64 offset = String8FindLast(strs[j], '.'); i64 offset = String8FindLast(strs[j], '.');
hashes[j] = XXH3_64bits_withSeed(strs[j].value, strs[j].len - offset, HASH_SEED); hashes[j] = XXH3_64bits_withSeed(strs[j].value, offset, HASH_SEED);
} }
offset += WriteArrayToFile( offset += WriteArrayToFile(
@ -128,10 +131,18 @@ CodeGenAssetLookups(Arena *arena)
); );
c8 buf[256]; c8 buf[256];
i32 decl_len = SPrintf(buf, 256, "#define %s_MAX %llu\n\n#define %s %d\n\n", dirs[i].define, count, dirs[i].define, i); i32 decl_len = SPrintf(buf, 256, "#define %s_MAX %lluU\n\n#define %s %dU\n\n", dirs[i].define, count, dirs[i].define, i);
offset += pFileWrite(file, offset, buf, decl_len); offset += pFileWrite(file, offset, buf, decl_len);
total_assets += count;
if (i == dir_count-1)
{
decl_len = SPrintf(buf, 256, "#define ASSET_MAX %lluU\n\n#define RENDERER_ASSET_MAX (ASSET_MAX - SHADER_ASSET_MAX)\n\n#define ASSET_TYPE_MAX %dU\n\n", total_assets, i+1);
pFileWrite(file, offset, buf, decl_len);
}
Assert(pDirNavigate("..") == 0, "CodeGenAssetLookups failure: unable to move back to build directory"); Assert(pDirNavigate("..") == 0, "CodeGenAssetLookups failure: unable to move back to build directory");
} }

View File

@ -12,17 +12,17 @@ g_Shader_Asset_Names[] =
static u64 static u64
g_Shader_Asset_Hashes[] = g_Shader_Asset_Hashes[] =
{ {
12100337026595633089U, 15780387719315455808U,
12100337026595633089U, 2230071466542309169U,
12100337026595633089U, 14797956403837654625U,
12100337026595633089U, 8430018914716708078U,
12100337026595633089U, 14432191255225961360U,
12100337026595633089U, 8518761701216801634U,
}; };
#define SHADER_ASSET_MAX 6 #define SHADER_ASSET_MAX 6U
#define SHADER_ASSET 0 #define SHADER_ASSET 0U
static c8 * static c8 *
g_Model_Asset_Names[] = g_Model_Asset_Names[] =
@ -34,13 +34,13 @@ g_Model_Asset_Names[] =
static u64 static u64
g_Model_Asset_Hashes[] = g_Model_Asset_Hashes[] =
{ {
2356409063604999112U, 13826959199295087925U,
2356409063604999112U, 4559395153940738542U,
}; };
#define MODEL_ASSET_MAX 2 #define MODEL_ASSET_MAX 2U
#define MODEL_ASSET 1 #define MODEL_ASSET 1U
static c8 * static c8 *
g_Texture_Asset_Names[] = g_Texture_Asset_Names[] =
@ -57,16 +57,22 @@ g_Texture_Asset_Names[] =
static u64 static u64
g_Texture_Asset_Hashes[] = g_Texture_Asset_Hashes[] =
{ {
5461253849680765905U, 15457434128510259736U,
5461253849680765905U, 12443444479937967236U,
5461253849680765905U, 5538438794723924882U,
5461253849680765905U, 16650761267170532297U,
5461253849680765905U, 11718504567089932798U,
5461253849680765905U, 7627422980398294448U,
5461253849680765905U, 14316598952102237724U,
}; };
#define TEXTURE_ASSET_MAX 7 #define TEXTURE_ASSET_MAX 7U
#define TEXTURE_ASSET 2 #define TEXTURE_ASSET 2U
#define ASSET_MAX 15U
#define RENDERER_ASSET_MAX (ASSET_MAX - SHADER_ASSET_MAX)
#define ASSET_TYPE_MAX 3U

View File

@ -72,14 +72,9 @@ gRunCycle(gGameCtx *ctx, pGameInput *inputs, u32 i_count)
rFrameBegin(); rFrameBegin();
vTextureCleanUp();
u64 index = vFrameIndex(); u64 index = vFrameIndex();
/* rDescHandle yoder = rGetAsset("models/yoda");
rDescHandle yoder = rMeshLoad(MODEL_YODA);
ctx->pc.mesh_index = yoder.desc_index;
*/
rViewportSize(&ctx->pc.res); rViewportSize(&ctx->pc.res);
ctx->pc.time = (f32)pCPUTimerRead(); ctx->pc.time = (f32)pCPUTimerRead();
@ -90,19 +85,16 @@ gRunCycle(gGameCtx *ctx, pGameInput *inputs, u32 i_count)
MemCpy(vert_buffer, ctx->gui.vertices, sizeof(rUIVertex) * ctx->gui.vertices_len); MemCpy(vert_buffer, ctx->gui.vertices, sizeof(rUIVertex) * ctx->gui.vertices_len);
MemCpy(idx_buffer, ctx->gui.indices, sizeof(u32) * ctx->gui.indices_len); MemCpy(idx_buffer, ctx->gui.indices, sizeof(u32) * ctx->gui.indices_len);
vBufferQueueWait();
rPipelineBind(rPIPELINE_PBR, rPT_GRAPHICS); rPipelineBind(rPIPELINE_PBR, rPT_GRAPHICS);
rPushConstantsSet(&ctx->pc); rPushConstantsSet(&ctx->pc);
//rBufferBindGUIVertex(); //rBufferBindGUIVertex();
//rBufferBindGUIIndex(); //rBufferBindGUIIndex();
//rBufferBindMesh(&ctx->pc, yoder); rBufferBindMesh(&ctx->pc, yoder);
//rDrawIndexed(model_meta.i_count, 1); rDrawMesh(yoder);
rFrameFinish(); rFrameFinish();

View File

@ -56,24 +56,24 @@ InitHeader(FileHeader *header)
void void
PackFiles(Arena *arena, FileHeader *header) PackFiles(Arena *arena, FileHeader *header)
{ {
pFile file = pFileOpen("assets.sgp", pFS_WRITE | pFS_TRUNC); pFile file = pFileOpen("assets.sgp", pFS_WRITE | pFS_TRUNC | pFS_CREATE);
u64 file_pos = pFileWrite(file, 0, header, sizeof(FileHeader)); u64 file_pos = pFileWrite(file, 0, header, sizeof(FileHeader));
c8 *return_dir = ".";
Assert(pDirNavigate("../assets") == 0, "Unable to move to assets directory"); Assert(pDirNavigate("../assets") == 0, "Unable to move to assets directory");
u64 total_assets = SHADER_ASSET_MAX + TEXTURE_ASSET_MAX + MODEL_ASSET_MAX; u64 total_assets = SHADER_ASSET_MAX + TEXTURE_ASSET_MAX + MODEL_ASSET_MAX;
u64 asset_count = 0; u64 asset_count = 0;
AssetFile *assets = MakeArray(arena, AssetFile, total_assets); AssetFile *assets = MakeArray(arena, AssetFile, total_assets);
u64 data_offset = header->asset_offset + (sizeof(AssetFile) + total_assets); u64 data_offset = header->asset_offset + (sizeof(AssetFile) * total_assets);
Printfln("%llu %d", data_offset, sizeof(FileHeader));
for (u32 i = 0; i < SHADER_ASSET_MAX; i++, asset_count++) for (u32 i = 0; i < SHADER_ASSET_MAX; i++, asset_count++)
{ {
c8 *asset_name = g_Shader_Asset_Names[i]; c8 *asset_name = g_Shader_Asset_Names[i];
Printfln("Packing file: %s...", asset_name); Printfln("Packing file: %s at offset %llu...", asset_name, data_offset);
pFile asset_file = pFileOpen(asset_name, pFS_READ); pFile asset_file = pFileOpen(asset_name, pFS_READ);
u64 file_size = pFileLength(asset_file); u64 file_size = pFileLength(asset_file);
@ -82,13 +82,14 @@ PackFiles(Arena *arena, FileHeader *header)
pFileRead(asset_file, 0, file_data, file_size); pFileRead(asset_file, 0, file_data, file_size);
u64 prev_offset = data_offset; u64 prev_offset = data_offset;
data_offset += pFileWrite(file, data_offset, file_data, file_size); data_offset += pFileWrite(file, prev_offset, file_data, file_size);
Assert((data_offset - prev_offset) == file_size, "File write size invalid"); Assert((data_offset - prev_offset) == file_size, "File write size invalid");
assets[asset_count].data_offset = prev_offset; assets[asset_count].data_offset = prev_offset;
assets[asset_count].len = file_size; assets[asset_count].len = file_size;
assets[asset_count].type = AT_SHADER; assets[asset_count].type = AT_SHADER;
assets[asset_count].hash = g_Shader_Asset_Hashes[i];
pFileClose(asset_file); pFileClose(asset_file);
} }
@ -97,7 +98,7 @@ PackFiles(Arena *arena, FileHeader *header)
{ {
c8 *asset_name = g_Texture_Asset_Names[i]; c8 *asset_name = g_Texture_Asset_Names[i];
Printfln("Packing file: %s...", asset_name); Printfln("Packing file: %s at offset %llu...", asset_name, data_offset);
pFile asset_file = pFileOpen(asset_name, pFS_READ); pFile asset_file = pFileOpen(asset_name, pFS_READ);
u64 file_size = pFileLength(asset_file); u64 file_size = pFileLength(asset_file);
@ -124,6 +125,7 @@ PackFiles(Arena *arena, FileHeader *header)
assets[asset_count].data_offset = prev_offset; assets[asset_count].data_offset = prev_offset;
assets[asset_count].len = loaded_length; assets[asset_count].len = loaded_length;
assets[asset_count].type = AT_TEXTURE; assets[asset_count].type = AT_TEXTURE;
assets[asset_count].hash = g_Texture_Asset_Hashes[i];
assets[asset_count].texture_meta.w = u32(w); assets[asset_count].texture_meta.w = u32(w);
assets[asset_count].texture_meta.h = u32(h); assets[asset_count].texture_meta.h = u32(h);
assets[asset_count].texture_meta.ch = u32(ch); assets[asset_count].texture_meta.ch = u32(ch);
@ -131,13 +133,14 @@ PackFiles(Arena *arena, FileHeader *header)
stbi_image_free(image_bytes); stbi_image_free(image_bytes);
pFileClose(asset_file); pFileClose(asset_file);
} }
for (u32 i = 0; i < MODEL_ASSET_MAX; i++, asset_count++) for (u32 i = 0; i < MODEL_ASSET_MAX; i++, asset_count++)
{ {
c8 *asset_name = g_Model_Asset_Names[i]; c8 *asset_name = g_Model_Asset_Names[i];
Printfln("Packing file: %s...", asset_name); Printfln("Packing file: %s at offset %llu...", asset_name, data_offset);
pFile asset_file = pFileOpen(asset_name, pFS_READ); pFile asset_file = pFileOpen(asset_name, pFS_READ);
u64 file_size = pFileLength(asset_file); u64 file_size = pFileLength(asset_file);
@ -155,12 +158,19 @@ PackFiles(Arena *arena, FileHeader *header)
assets[asset_count].data_offset = prev_offset; assets[asset_count].data_offset = prev_offset;
assets[asset_count].type = AT_MODEL; assets[asset_count].type = AT_MODEL;
assets[asset_count].len = file_size; assets[asset_count].len = file_size;
assets[asset_count].hash = g_Model_Asset_Hashes[i];
assets[asset_count].model_meta.i_count = u64(model->numface * 3); assets[asset_count].model_meta.i_count = u64(model->numface * 3);
m3d_free(model);
pFileClose(asset_file); pFileClose(asset_file);
} }
pFileWrite(file, header->asset_offset, assets, sizeof(AssetFile)*asset_count); pFileWrite(file, header->asset_offset, assets, sizeof(AssetFile)*asset_count);
pFileClose(file);
Assert(pDirNavigate("../build") == 0, "Unable to navigate back to build directory");
} }
// ::Packer::Packing::Functions::End:: // ::Packer::Packing::Functions::End::
@ -218,6 +228,8 @@ TestAssetPack(Arena *arena)
{ {
pFile file = pFileOpen("assets.sgp", pFS_READ); pFile file = pFileOpen("assets.sgp", pFS_READ);
Assert(pDirNavigate("../assets") == 0, "Unable to navigate back to assets directory");
FileHeader header; FileHeader header;
i64 offset = pFileRead(file, 0, &header, sizeof(FileHeader)); i64 offset = pFileRead(file, 0, &header, sizeof(FileHeader));
@ -235,16 +247,19 @@ TestAssetPack(Arena *arena)
for (u32 i = 0; i < SHADER_ASSET_MAX; i++, current_asset++) for (u32 i = 0; i < SHADER_ASSET_MAX; i++, current_asset++)
{ {
TestAssetIsCorrect(arena, g_Shader_Asset_Names[i], files + current_asset, file); TestAssetIsCorrect(arena, g_Shader_Asset_Names[i], files + current_asset, file);
Assert(files[current_asset].hash == g_Shader_Asset_Hashes[i], "Shader asset hash mismatch");
} }
for (u32 i = 0; i < TEXTURE_ASSET_MAX; i++, current_asset++) for (u32 i = 0; i < TEXTURE_ASSET_MAX; i++, current_asset++)
{ {
TestAssetIsCorrect(arena, g_Texture_Asset_Names[i], files + current_asset, file); TestAssetIsCorrect(arena, g_Texture_Asset_Names[i], files + current_asset, file);
Assert(files[current_asset].hash == g_Texture_Asset_Hashes[i], "Texture asset hash mismatch");
} }
for (u32 i = 0; i < MODEL_ASSET_MAX; i++, current_asset++) for (u32 i = 0; i < MODEL_ASSET_MAX; i++, current_asset++)
{ {
TestAssetIsCorrect(arena, g_Model_Asset_Names[i], files + current_asset, file); TestAssetIsCorrect(arena, g_Model_Asset_Names[i], files + current_asset, file);
Assert(files[current_asset].hash == g_Model_Asset_Hashes[i], "Model asset hash mismatch");
} }
} }
@ -271,16 +286,11 @@ main(int argc, c8 **argv)
void *mem = pMemAllocZeroed(GB(1)); void *mem = pMemAllocZeroed(GB(1));
Arena *arena = ArenaInitDebug(mem, GB(1), __LINE__); Arena *arena = ArenaInitDebug(mem, GB(1), __LINE__);
pFile file = pFileOpen("assets.sgp", pFS_WRITE | pFS_TRUNC | pFS_CREATE);
Assert(file > 0, "File is null");
FileHeader header = {0}; FileHeader header = {0};
InitHeader(&header); InitHeader(&header);
PackFiles(arena, &header); PackFiles(arena, &header);
pFileClose(file);
TestAssetPack(arena); TestAssetPack(arena);
} }

View File

@ -110,12 +110,6 @@ void rDestroy();
// ::Renderer::Buffers::Header:: // ::Renderer::Buffers::Header::
static b32 rBufferMap(); static b32 rBufferMap();
static rDescHandle rAssetLoad(c8 *name);
static void rAssetUnload(rDescHandle handle);
static rDescHandle rTextureLoad(TextureAsset asset_id);
static rDescHandle rMeshLoad(ModelAsset asset_id);
static void rTextureUnload(rDescHandle handle);
static void rMeshUnload(rDescHandle handle);
static void rBufferBindVertex(rRenderBuffer *buffer); static void rBufferBindVertex(rRenderBuffer *buffer);
static void rBufferBindIndex(rRenderBuffer *buffer); static void rBufferBindIndex(rRenderBuffer *buffer);
static rawptr rBufferGUIVertMapping(); static rawptr rBufferGUIVertMapping();
@ -141,6 +135,11 @@ static b32 rFrameBegin();
static b32 rFrameFinish(); static b32 rFrameFinish();
static void rDrawIndexed(u32 index_count, u32 instance_count); static void rDrawIndexed(u32 index_count, u32 instance_count);
static void rPipelineBind(rPipelineHandle handle, rPipelineType type); static void rPipelineBind(rPipelineHandle handle, rPipelineType type);
static void rDrawMesh(rDescHandle handle);
// ::Renderer::Assets::Header::
static rDescHandle rGetAsset(c8 *asset_name);
// ::Renderer::Includes::Header:: // ::Renderer::Includes::Header::

View File

@ -80,25 +80,7 @@ vFrameRenderSem()
static inline VkSemaphore static inline VkSemaphore
vFrameSwapSem() vFrameSwapSem()
{ {
return v_Renderer.frame_handles[vFrameIndex()].sc_sem; return v_Renderer.handles.sc_sems[v_Renderer.state.vk.image_idx];
}
static inline vBufferPtrArray *
vFrameBuffers()
{
return v_Renderer.buffers.frame_buffers + vFrameIndex();
}
static inline b8 *
vFrameTexDestroyQueue()
{
return v_Renderer.buffers.tex_destroy_queue.data[vFrameIndex()];
}
static inline b8 *
vFrameNextTexDestroyQueue()
{
return v_Renderer.buffers.tex_destroy_queue.data[vFrameNextIndex()];
} }
static inline void static inline void
@ -316,6 +298,7 @@ vImmSubmitFinish(VkDevice device, VkFence fence, VkCommandBuffer cmd, VkQueue qu
if (success) if (success)
{ {
result = vkWaitForFences(device, 1, &f, true, 9999999999); result = vkWaitForFences(device, 1, &f, true, 9999999999);
Printfln("fence waited");
if (result != VK_SUCCESS) if (result != VK_SUCCESS)
{ {
Printfln("vkWaitForFences imm failure: %s", vVkResultStr(result)); Printfln("vkWaitForFences imm failure: %s", vVkResultStr(result));
@ -512,6 +495,41 @@ vDescIndexPop(vDescType type)
// ::Vulkan::Assets::Functions::Start::
static vAsset *
vAssetSearch(c8 *asset_name)
{
vAsset *asset = NULL;
u64 hash = HashFromString(String8CStr(asset_name));
Printfln("hash %llu", hash);
vAssetArray assets = v_Renderer.buffers.assets;
for (u64 i = 0; i < assets.length; i += 1)
{
Printfln("asset_hash %llu", assets.data[i].hash);
if (hash == assets.data[i].hash)
{
asset = assets.data + i;
break;
}
}
return asset;
}
static vAsset *
vAssetLookupIndex(u32 asset_idx)
{
Printfln("asset_idx %llu", asset_idx);
Assert(asset_idx < ASSET_MAX, "asset index is out of range");
return v_Renderer.buffers.assets.data + asset_idx;
}
// ::Vulkan::Assets::Functions::End::
// ::Vulkan::Buffers::Functions::Start:: // ::Vulkan::Buffers::Functions::Start::
static VkResult static VkResult
@ -1152,15 +1170,9 @@ vFrameStructuresInit()
if (result != VK_SUCCESS) if (result != VK_SUCCESS)
success = false; success = false;
result = vkCreateSemaphore(device, &g_Semaphore_Create_info, NULL, &handles->r_sem); result = vkCreateSemaphore(device, &g_Semaphore_Create_Info, NULL, &handles->r_sem);
if (result != VK_SUCCESS) if (result != VK_SUCCESS)
success = false; success = false;
result = vkCreateSemaphore(device, &g_Semaphore_Create_info, NULL, &handles->sc_sem);
if (result != VK_SUCCESS)
success = false;
//renderer.vk.frame.buffer_destroy_queues[i] = ArenaAlloc(v_Renderer.mem.perm_arena, sizeof(rRenderBuffer) * 64);
} }
return success; return success;
@ -1291,6 +1303,17 @@ vSwapchainInit()
v_Renderer.state.swapchain.extent.height = extent.height; v_Renderer.state.swapchain.extent.height = extent.height;
v_Renderer.state.swapchain.extent.depth = 1; v_Renderer.state.swapchain.extent.depth = 1;
v_Renderer.handles.sc_sems = MakeArray(arena, VkSemaphore, image_count);
for (u32 i = 0; i < image_count; i++)
{
result = vkCreateSemaphore(device, &g_Semaphore_Create_Info, NULL, v_Renderer.handles.sc_sems + i);
if (result != VK_SUCCESS)
{
Printfln("vkCreateSemaphore failure: failed to create swapchain semaphore %s", vVkResultStr(result));
success = false;
}
}
return success; return success;
} }
@ -1664,37 +1687,146 @@ vShaderModuleInit(u8 *bytes, u32 len, VkShaderModule *module)
return success; return success;
} }
static b32
vAssetsInit()
{
vRBuffers *buf = &v_Renderer.buffers;
Arena *arena = v_Renderer.mem.perm_arena;
VkDevice device = v_Renderer.handles.device;
VkFence fence = v_Renderer.imm.fence;
VkQueue queue = v_Renderer.handles.tfer_queue;
VkCommandBuffer cmd = v_Renderer.imm.buffer;
vMappedBuffer *transfer = &v_Renderer.buffers.transfer;
InitArrayType(buf->assets, arena, vAsset, RENDERER_ASSET_MAX);
Assert(vImmSubmitBegin(device, fence, cmd), "Unable to begin immediate submit");
u64 asset_index = 0;
for (u64 i = 0; i < TEXTURE_ASSET_MAX; i++, asset_index++)
{
u64 hash = g_Texture_Asset_Hashes[i];
Asset asset = apLoadWithHash(hash);
vImageView *view = vImageViewCreate(asset.texture_meta);
Assert(view != NULL, "Unable to create vImageView");
VkBufferImageCopy copy = {
.bufferRowLength = asset.texture_meta.w,
.bufferImageHeight = asset.texture_meta.h,
.imageSubresource = {
.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
.layerCount = 1,
},
.imageExtent = {
.width = asset.texture_meta.w,
.height = asset.texture_meta.h,
.depth = 1,
},
.bufferOffset = 0,
};
MemCpy(transfer->ptr, asset.bytes, asset.len);
vImageTransitionLayout(cmd, view->image.image, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
vkCmdCopyBufferToImage(cmd, transfer->alloc.buffer, view->image.image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &copy);
vImageTransitionLayout(cmd, view->image.image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
vAsset *asset_data = buf->assets.data + asset_index;
asset_data->hash = hash;
asset_data->handle.asset_index = asset_index;
asset_data->handle.desc_index = vDescPushImageDesc(view);
asset_data->texture_meta = asset.texture_meta;
asset_data->texture = view;
apUnloadWithHash(hash);
}
for (u64 i = 0; i < MODEL_ASSET_MAX; i++, asset_index++)
{
u64 hash = g_Model_Asset_Hashes[i];
Asset asset = apLoadWithHash(hash);
vMeshAsset *buffer = FLMemAlloc(sizeof(vMeshAsset));
Assert(vBufferCreate(&buffer->mesh.mesh, rRBT_ADDR | rRBT_STORAGE, sizeof(Vertex) * asset.model->v_count) == VK_SUCCESS, "Unable to create mesh buffer");
Assert(vBufferCreate(&buffer->mesh.uniform, rRBT_UNIFORM, sizeof(vMesh)) == VK_SUCCESS, "Unable to create uniform buffer");
Assert(vBufferCreate(&buffer->index, rRBT_INDEX, sizeof(u32) * asset.model->i_count) == VK_SUCCESS, "Unable to create index buffer");
VkBufferDeviceAddressInfo addr_info = {
.sType = STYPE(BUFFER_DEVICE_ADDRESS_INFO),
.buffer = buffer->mesh.mesh.buffer,
};
vMesh mesh = {
.vertices = vkGetBufferDeviceAddress(device, &addr_info),
};
VkBufferCopy uniform_copy = {
.srcOffset = 0,
.dstOffset = 0,
.size = sizeof(vMesh),
};
rawptr ptr = transfer->ptr;
MemCpy(ptr, &mesh, sizeof(vMesh));
ptr = PtrAdd(ptr, sizeof(vMesh));
u64 offset = sizeof(vMesh);
u64 vertex_size = sizeof(Vertex) * asset.model->v_count;
VkBufferCopy mesh_copy = {
.srcOffset = offset,
.dstOffset = 0,
.size = vertex_size,
};
MemCpy(ptr, asset.model->vertices, vertex_size);
ptr = PtrAdd(ptr, vertex_size);
offset += vertex_size;
u64 index_size = sizeof(u32) * asset.model->i_count;
VkBufferCopy index_copy = {
.srcOffset = offset,
.dstOffset = 0,
.size = index_size,
};
offset += sizeof(Vertex) * asset.model->v_count;
MemCpy(ptr, asset.model->indices, index_size);
vkCmdCopyBuffer(cmd, transfer->alloc.buffer, buffer->mesh.uniform.buffer, 1, &uniform_copy);
vkCmdCopyBuffer(cmd, transfer->alloc.buffer, buffer->mesh.mesh.buffer, 1, &mesh_copy);
vkCmdCopyBuffer(cmd, transfer->alloc.buffer, buffer->index.buffer, 1, &index_copy);
vAsset *asset_data = buf->assets.data + asset_index;
asset_data->hash = hash;
asset_data->handle.asset_index = asset_index;
asset_data->handle.desc_index = vDescPushMeshDesc(&buffer->mesh);
asset_data->model_meta = asset.model_meta;
asset_data->mesh = buffer;
apUnloadWithHash(hash);
}
Assert(vImmSubmitFinish(device, fence, cmd, queue), "Unable to finish immediate submit");
return true;
}
static b32 static b32
vBuffersInit() vBuffersInit()
{ {
vRBuffers *buf = &v_Renderer.buffers; vRBuffers *buf = &v_Renderer.buffers;
Arena *arena = v_Renderer.mem.perm_arena; Arena *arena = v_Renderer.mem.perm_arena;
HashTableInit(&buf->buffers, 8);
HashTableInit(&buf->images, 8);
buf->tex_destroy_queue.data = MakeArray(arena, b8 *, FRAME_OVERLAP);
buf->tex_destroy_queue.length = FRAME_OVERLAP;
for (u32 i = 0; i < FRAME_OVERLAP; i++)
{
InitArrayType(buf->frame_buffers[i], arena, vBuffer *, 128);
InitArrayType(buf->frame_images[i], arena, vImageView *, 128);
buf->tex_destroy_queue.data[i] = MakeArray(arena, b8, TEXTURE_ASSET_MAX);
MemZero(buf->tex_destroy_queue.data[i], sizeof(b8) * TEXTURE_ASSET_MAX);
}
b32 success = true; b32 success = true;
VkResult result; VkResult result;
if (success)
{
result = vBufferCreate(&buf->gui_vert.alloc, rRBT_VERTEX | rRBT_HOST, VERTEX_BUFFER_CAP); result = vBufferCreate(&buf->gui_vert.alloc, rRBT_VERTEX | rRBT_HOST, VERTEX_BUFFER_CAP);
if (result != VK_SUCCESS) if (result != VK_SUCCESS)
success = false; success = false;
}
if (success) if (success)
{ {
@ -1872,7 +2004,7 @@ vTransferUpload(vTransfer **transfers, u32 count)
} }
else if (transfers[i]->type == vTT_BUFFER || transfers[i]->type == vTT_MESH) else if (transfers[i]->type == vTT_BUFFER || transfers[i]->type == vTT_MESH)
{ {
VkBuffer target_buf; VkBuffer target_buf = 0;
if (transfers[i]->type == vTT_BUFFER) if (transfers[i]->type == vTT_BUFFER)
target_buf = transfers[i]->buffer; target_buf = transfers[i]->buffer;
else if (transfers[i]->type == vTT_MESH) else if (transfers[i]->type == vTT_MESH)

View File

@ -185,7 +185,7 @@ typedef enum DescType_e
typedef struct rDescHandle typedef struct rDescHandle
{ {
u32 asset_id; u32 asset_index;
u32 desc_index; u32 desc_index;
} rDescHandle; } rDescHandle;
@ -193,11 +193,7 @@ typedef struct vAssetInfo
{ {
rDescHandle handle; rDescHandle handle;
vDescType type; vDescType type;
union
{
u64 asset_id; u64 asset_id;
TextureAsset texture_id;
};
} vAssetInfo; } vAssetInfo;
typedef struct vDeviceQueues typedef struct vDeviceQueues
@ -263,8 +259,8 @@ typedef struct vMeshBuffer
typedef struct vMeshAsset typedef struct vMeshAsset
{ {
vMeshBuffer *mesh; vMeshBuffer mesh;
vBuffer *index; vBuffer index;
} vMeshAsset; } vMeshAsset;
typedef enum vAssetType_e typedef enum vAssetType_e
@ -276,14 +272,18 @@ typedef enum vAssetType_e
typedef struct vAsset typedef struct vAsset
{ {
u64 hash; union
rDescHandle handle; {
TexMeta texture_meta;
ModelMeta model_meta;
};
union union
{ {
vMeshAsset *mesh; vMeshAsset *mesh;
vImageView *texture; vImageView *texture;
}; };
AssetMeta meta; u64 hash;
rDescHandle handle;
} vAsset; } vAsset;
ArrayType(vAsset); ArrayType(vAsset);
@ -310,6 +310,8 @@ typedef struct vRendererState
rPipelineHandle pipeline; rPipelineHandle pipeline;
u32 width; u32 width;
u32 height; u32 height;
u32 curr_vert_buf;
u32 curr_index_buf;
} vRendererState; } vRendererState;
typedef struct vState typedef struct vState
@ -332,7 +334,6 @@ typedef struct vFrameHandles
{ {
VkCommandPool pool; VkCommandPool pool;
VkCommandBuffer buffer; VkCommandBuffer buffer;
VkSemaphore sc_sem;
VkSemaphore r_sem; VkSemaphore r_sem;
VkFence r_fence; VkFence r_fence;
} vFrameHandles; } vFrameHandles;
@ -361,6 +362,7 @@ typedef struct vRHandles
VkQueue gfx_queue; VkQueue gfx_queue;
VkQueue tfer_queue; VkQueue tfer_queue;
VkSampler nearest_sampler; VkSampler nearest_sampler;
VkSemaphore *sc_sems;
#ifdef BUILD_DEBUG #ifdef BUILD_DEBUG
VkDebugUtilsMessengerEXT debug; VkDebugUtilsMessengerEXT debug;
#endif #endif
@ -529,6 +531,7 @@ static b32 vShaderModuleInit(u8 *bytes, u32 len, VkShaderModule *module);
static void vUploadQueuesInit(); static void vUploadQueuesInit();
static void vLoaderStartThreads(); static void vLoaderStartThreads();
static b32 vBuffersInit(); static b32 vBuffersInit();
static b32 vAssetsInit();
static b32 vRenderDocInit(); static b32 vRenderDocInit();
// ::Vulkan::Util::Functions::Header:: // ::Vulkan::Util::Functions::Header::
@ -541,9 +544,6 @@ static inline VkSemaphore vFrameRenderSem();
static inline VkSemaphore vFrameSwapSem(); static inline VkSemaphore vFrameSwapSem();
static inline u32 vFrameIndex(); static inline u32 vFrameIndex();
static inline VkImage vFrameSwapImage(); static inline VkImage vFrameSwapImage();
static inline b8 *vFrameTexDestroyQueue();
static inline b8 *vFrameNextTexDestroyQueue();
static inline vBufferPtrArray *vFrameBuffers();
static inline void vImageTransition(VkCommandBuffer cmd, vImage *img, VkImageLayout new); static inline void vImageTransition(VkCommandBuffer cmd, vImage *img, VkImageLayout new);
static inline void vImageTransitionLayout(VkCommandBuffer cmd, VkImage img, VkImageLayout curr, VkImageLayout new); static inline void vImageTransitionLayout(VkCommandBuffer cmd, VkImage img, VkImageLayout curr, VkImageLayout new);
static inline void vImageCopyToImage(VkCommandBuffer cmd, VkImage src, VkImage dst, VkExtent2D src_ext, VkExtent2D dst_ext); static inline void vImageCopyToImage(VkCommandBuffer cmd, VkImage src, VkImage dst, VkExtent2D src_ext, VkExtent2D dst_ext);
@ -578,7 +578,6 @@ static void vSwapchainResize();
static vTransfer *vTextureTransferInit(Arena *arena, u32 asset_id, VkImage image, rawptr bytes, TexMeta *meta); static vTransfer *vTextureTransferInit(Arena *arena, u32 asset_id, VkImage image, rawptr bytes, TexMeta *meta);
static vImageView *vImageViewCreate(TexMeta meta); static vImageView *vImageViewCreate(TexMeta meta);
static b32 vImageViewInit(vImageView *view, u32 width, u32 height, u32 channels); static b32 vImageViewInit(vImageView *view, u32 width, u32 height, u32 channels);
static void vTextureCleanUp();
// ::Vulkan::Descriptors::Functions::Header:: // ::Vulkan::Descriptors::Functions::Header::
@ -592,10 +591,13 @@ static rDescHandle vDescHandlePop(vDescType type, u32 asset_id);
static u32 vDescPushImageDesc(vImageView *view); static u32 vDescPushImageDesc(vImageView *view);
static u32 vDescPushMeshDesc(vMeshBuffer *buffer); static u32 vDescPushMeshDesc(vMeshBuffer *buffer);
// ::Vulkan::Assets::Functions::Header::
static vAsset *vAssetSearch(c8 *asset_name);
static vAsset *vAssetLookupIndex(u32 asset_idx);
// ::Vulkan::Buffers::Functions::Header:: // ::Vulkan::Buffers::Functions::Header::
static vTransfer *vMeshTransferInit(Arena *arena, u32 asset_id, vMeshBuffer *mesh, rawptr bytes, u64 size);
static vTransfer *vBufferTransferInit(Arena *arena, u32 asset_id, vBuffer *index, rawptr bytes, u64 size);
static VkResult vBufferCreate(vBuffer* buf, rRenderBufferType type, u64 size); static VkResult vBufferCreate(vBuffer* buf, rRenderBufferType type, u64 size);
static rawptr vMapBuffer(VmaAllocation alloc); static rawptr vMapBuffer(VmaAllocation alloc);

View File

@ -26,6 +26,7 @@ rInit()
Assert(vDescriptorsInit(), "Unable to initialize descriptors."); Assert(vDescriptorsInit(), "Unable to initialize descriptors.");
Assert(vPipelinesInit(), "Unable to initialize pipelines."); Assert(vPipelinesInit(), "Unable to initialize pipelines.");
Assert(vBuffersInit(), "Unable to initialize buffers."); Assert(vBuffersInit(), "Unable to initialize buffers.");
Assert(vAssetsInit(), "Unable to initialize assets.");
vUploadQueuesInit(); vUploadQueuesInit();
vLoaderStartThreads(); vLoaderStartThreads();
@ -40,7 +41,6 @@ rDestroy()
{ {
VkDevice device = v_Renderer.handles.device; VkDevice device = v_Renderer.handles.device;
VkInstance instance = v_Renderer.handles.inst; VkInstance instance = v_Renderer.handles.inst;
vBufferPtrArray *frame_buffers = v_Renderer.buffers.frame_buffers;
vImmHandles imm = v_Renderer.imm; vImmHandles imm = v_Renderer.imm;
VmaAllocator vma_alloc = v_Renderer.handles.vma_alloc; VmaAllocator vma_alloc = v_Renderer.handles.vma_alloc;
VkSwapchainKHR swapchain = v_Renderer.handles.swapchain; VkSwapchainKHR swapchain = v_Renderer.handles.swapchain;
@ -78,13 +78,9 @@ rDestroy()
vFrameHandles fh = v_Renderer.frame_handles[i]; vFrameHandles fh = v_Renderer.frame_handles[i];
vkDestroySemaphore(device, fh.r_sem, NULL); vkDestroySemaphore(device, fh.r_sem, NULL);
vkDestroySemaphore(device, fh.sc_sem, NULL);
vkDestroyFence(device, fh.r_fence, NULL); vkDestroyFence(device, fh.r_fence, NULL);
vkFreeCommandBuffers(device, fh.pool, 1, &fh.buffer); vkFreeCommandBuffers(device, fh.pool, 1, &fh.buffer);
vkDestroyCommandPool(device, fh.pool, NULL); vkDestroyCommandPool(device, fh.pool, NULL);
for (u32 j = 0; j < frame_buffers[i].length; j++)
vmaDestroyBuffer(vma_alloc, frame_buffers[i].data[j]->buffer, frame_buffers[i].data[j]->alloc);
} }
vmaUnmapMemory(vma_alloc, v_Renderer.buffers.transfer.alloc.alloc); vmaUnmapMemory(vma_alloc, v_Renderer.buffers.transfer.alloc.alloc);
@ -121,95 +117,6 @@ rDestroy()
// ::Vulkan::Renderer::Buffers::Functions::Start:: // ::Vulkan::Renderer::Buffers::Functions::Start::
static rDescHandle
rTextureLoad(TextureAsset asset_id)
{
rDescHandle handle = vDescHandleSearch(vDT_SAMPLED_IMAGE, asset_id);
if (handle.asset_id == UINT32_MAX)
{
vImageView *view = FLMemAlloc(sizeof(vImageView));
Asset asset = apLoadTexture(asset_id);
TexMeta meta = apGetTextureMeta(asset_id);
// TODO: handle errors instead of failing
Assert(vImageViewInit(view, meta.w, meta.h, meta.ch), "rTextureLoad failure: vImageViewInit failed");
handle.asset_id = asset_id;
handle.desc_index = vDescPushImageDesc(view);
vTransfer *transfer = vTextureTransferInit(vFrameArena(), asset_id, view->image.image, asset.bytes, &meta);
TicketMutLock(&v_Renderer.upload.mut);
u32 job_idx = JobQueueAdd(&v_Renderer.upload.job_queue, 1);
v_Renderer.upload.transfers[job_idx] = transfer;
vDescPushImageAndHandle(handle, view);
TicketMutUnlock(&v_Renderer.upload.mut);
vLoaderWake();
}
return handle;
}
static rDescHandle
rMeshLoad(ModelAsset asset_id)
{
rDescHandle handle = vDescHandleSearch(vDT_MESH, asset_id);
if (handle.asset_id == UINT32_MAX)
{
vMeshBuffer *buffer = FLMemAlloc(sizeof(vMeshBuffer));
vBuffer *index_buffer = FLMemAlloc(sizeof(vBuffer));
vModelBuffers *model_buffer = FLMemAlloc(sizeof(vModelBuffers));
model_buffer->mesh = buffer;
model_buffer->index = index_buffer;
Asset asset = apLoadModel(asset_id);
// TODO: handle errors
Assert(vBufferCreate(&buffer->mesh, rRBT_STORAGE | rRBT_ADDR, sizeof(rPBRVertex) * asset.model->v_count) == VK_SUCCESS, "rMeshLoad failure: vBufferCreate didn't return VK_SUCCESS");
Assert(vBufferCreate(&buffer->uniform, rRBT_UNIFORM, sizeof(vMesh)) == VK_SUCCESS, "rMeshLoad failure: vBufferCreate didn't return VK_SUCCESS");
Assert(vBufferCreate(index_buffer, rRBT_INDEX, sizeof(u32) * asset.model->i_count) == VK_SUCCESS, "rMeshLoad failure: vBufferCreate didn't return VK_SUCCESS");
handle.asset_id = asset_id;
handle.desc_index = vDescPushMeshDesc(buffer);
vTransfer *transfer = vMeshTransferInit(vFrameArena(), asset_id, buffer, asset.model->vertices, asset.model->v_count * sizeof(rPBRVertex));
vTransfer *index_transfer = vBufferTransferInit(vFrameArena(), asset_id, index_buffer, asset.model->indices, asset.model->i_count * sizeof(u32));
TicketMutLock(&v_Renderer.upload.mut);
u32 job_idx = JobQueueAdd(&v_Renderer.upload.job_queue, 2);
v_Renderer.upload.transfers[job_idx] = transfer;
v_Renderer.upload.transfers[job_idx + 1] = index_transfer;
vDescPushModelAndHandle(handle, model_buffer);
TicketMutUnlock(&v_Renderer.upload.mut);
vLoaderWake();
}
return handle;
}
static void
rTextureUnload(rDescHandle current_handle)
{
rDescHandle handle = vDescHandleSearch(vDT_SAMPLED_IMAGE, current_handle.asset_id);
if (handle.asset_id != UINT32_MAX)
{
b8 *queue = vFrameTexDestroyQueue();
queue[current_handle.asset_id] = true;
}
}
static void static void
rBufferBindVertex(rRenderBuffer *buffer) rBufferBindVertex(rRenderBuffer *buffer)
{ {
@ -275,10 +182,15 @@ rBufferBindGUIIndex()
static void static void
rBufferBindMesh(rPushConst *pc, rDescHandle handle) rBufferBindMesh(rPushConst *pc, rDescHandle handle)
{ {
vModelBuffers *buffers = vModelSearch(handle.asset_id); if (v_Renderer.state.renderer.curr_vert_buf != handle.asset_index)
if (buffers != NULL)
{ {
vkCmdBindIndexBuffer(vFrameCmdBuf(), buffers->index->buffer, 0, VK_INDEX_TYPE_UINT32); vAsset *asset = vAssetLookupIndex(handle.asset_index);
if (asset != NULL)
{
vkCmdBindIndexBuffer(vFrameCmdBuf(), asset->mesh->index.buffer, 0, VK_INDEX_TYPE_UINT32);
pc->mesh_index = asset->handle.desc_index;
v_Renderer.state.renderer.curr_vert_buf = handle.asset_index;
}
} }
} }
@ -358,7 +270,7 @@ rFrameBegin()
result = vkWaitForFences(device, 1, &fence, VK_TRUE, 1000000000); result = vkWaitForFences(device, 1, &fence, VK_TRUE, 1000000000);
if (result != VK_SUCCESS) if (result != VK_SUCCESS)
{ {
Printf("vkWaitForFences failure: %s", vVkResultStr(result)); Printfln("vkWaitForFences failure: %s", vVkResultStr(result));
success = false; success = false;
} }
@ -528,6 +440,22 @@ rDrawIndexed(u32 index_count, u32 instance_count)
vkCmdDrawIndexed(cmd, index_count, instance_count, 0, 0, 0); vkCmdDrawIndexed(cmd, index_count, instance_count, 0, 0, 0);
} }
static void
rDrawMesh(rDescHandle handle)
{
VkCommandBuffer cmd = vFrameCmdBuf();
if (v_Renderer.state.renderer.curr_index_buf != handle.asset_index)
{
vAsset *asset = vAssetLookupIndex(handle.asset_index);
if (asset != NULL)
{
vkCmdDrawIndexed(cmd, asset->model_meta.i_count, 1, 0, 0, 0);
v_Renderer.state.renderer.curr_index_buf = handle.asset_index;
}
}
}
static void static void
rPipelineBind(rPipelineHandle handle, rPipelineType type) rPipelineBind(rPipelineHandle handle, rPipelineType type)
{ {
@ -554,3 +482,24 @@ rPipelineBind(rPipelineHandle handle, rPipelineType type)
} }
// ::Vulkan::Renderer::Rendering::Functions::End:: // ::Vulkan::Renderer::Rendering::Functions::End::
// ::Vulkan::Renderer::Assets::Start::
static rDescHandle
rGetAsset(c8 *asset_name)
{
rDescHandle handle = {UINT32_MAX};
vAsset *asset = vAssetSearch(asset_name);
if (asset != NULL)
{
handle = asset->handle;
}
Assert(handle.asset_index != UINT32_MAX, "invalid descriptor handle");
return handle;
}
// ::Vulkan::Renderer::Assets::End::

View File

@ -381,6 +381,7 @@ typedef enum KeyboardInput_e
# include <x86intrin.h> # include <x86intrin.h>
# include <sys/time.h> # include <sys/time.h>
# include <fcntl.h> # include <fcntl.h>
# include <errno.h>
// ::Platform::Linux::Defines::Header:: // ::Platform::Linux::Defines::Header::
@ -741,7 +742,6 @@ typedef struct T##Array \
{ \ { \
T *data; \ T *data; \
u64 length; \ u64 length; \
u64 cap; \
} T##Array } T##Array
#define PtrArrayType(T) \ #define PtrArrayType(T) \
@ -749,13 +749,11 @@ typedef struct T##PtrArray \
{ \ { \
T **data; \ T **data; \
u64 length; \ u64 length; \
u64 cap; \
} T##PtrArray } T##PtrArray
#define InitArrayType(arr, arena, T, len) \ #define InitArrayType(arr, arena, T, len) \
arr.data = MakeArray(arena, T, len); \ arr.data = MakeArray(arena, T, len); \
arr.length = 0; \ arr.length = len
arr.cap = len
// ::Util::LinkedList::Macros:: // ::Util::LinkedList::Macros::
@ -1298,27 +1296,39 @@ static void HashTableDeleteU64(HashTable *table, u64 key);
if (BitEq(acc, pFS_CREATE)) if (BitEq(acc, pFS_CREATE))
flags |= O_CREAT; flags |= O_CREAT;
return open(file_name, flags, S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP); i64 file = open(file_name, flags, S_IRUSR|S_IWUSR|S_IRGRP);
if (file < 0)
{
Printfln("errno: %d", errno);
Assert(false, "failed to open file");
}
return file;
} }
static void static void
pFileClose(pFile file) pFileClose(pFile file)
{ {
fsync(file);
close(file); close(file);
} }
// TODO: make these more resilient
static u64 static u64
pFileRead(pFile file, u64 offset, void * buf, u64 len) pFileRead(pFile file, u64 offset, void * buf, u64 len)
{ {
lseek(file, (ssize_t)offset, SEEK_SET); i64 new_offset = lseek(file, offset, SEEK_SET);
if (new_offset < 0)
{
Printfln("errno: %d", errno);
Assert(false, "failed to read file");
}
return read(file, buf, (size_t)len); return read(file, buf, (size_t)len);
} }
static u64 static u64
pFileWrite(pFile file, u64 offset, void * buf, u64 len) pFileWrite(pFile file, u64 offset, void * buf, u64 len)
{ {
lseek(file, (ssize_t)offset, SEEK_SET); lseek(file, offset, SEEK_SET);
return write(file, buf, (size_t)len); return write(file, buf, (size_t)len);
} }

View File

@ -154,7 +154,7 @@ g_Fence_Create_Info =
}; };
static VkSemaphoreCreateInfo static VkSemaphoreCreateInfo
g_Semaphore_Create_info = g_Semaphore_Create_Info =
{ {
.sType = STYPE(SEMAPHORE_CREATE_INFO), .sType = STYPE(SEMAPHORE_CREATE_INFO),
}; };
@ -259,10 +259,11 @@ g_Depth_View_Info =
static VkDescriptorPoolSize static VkDescriptorPoolSize
g_Desc_Pool_Sizes[] = g_Desc_Pool_Sizes[] =
{ {
{ .type = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, .descriptorCount = 4096 }, { .type = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, .descriptorCount = 4096 },
{ .type = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, .descriptorCount = 4096}, { .type = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, .descriptorCount = 4096},
{ .type = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, .descriptorCount = 4096}, { .type = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, .descriptorCount = 4096},
{ .type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, .descriptorCount = 4096}, { .type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, .descriptorCount = 4096},
{ .type = VK_DESCRIPTOR_TYPE_SAMPLER, .descriptorCount = 4096 },
}; };
static VkDescriptorPoolCreateInfo static VkDescriptorPoolCreateInfo