rework of asset loading
This commit is contained in:
parent
0b9f802451
commit
e628f2b323
0
assets/textures/cheesoid.png
Executable file → Normal file
0
assets/textures/cheesoid.png
Executable file → Normal file
|
Before Width: | Height: | Size: 42 KiB After Width: | Height: | Size: 42 KiB |
14
build.sh
14
build.sh
@ -121,15 +121,17 @@ fi
|
||||
# Packer Codegen
|
||||
$compile $codegen_source_files $compile_link $link_os_gfx $codegen_flags $packer_include_flags $out $codegen_out_name
|
||||
|
||||
./Codegen
|
||||
|
||||
# Packer
|
||||
if [ -v packer ] || ! [ -f Packer ]; then
|
||||
$compile $packer_source_files $compile_link $link_os_gfx $packer_flags $packer_include_flags $out $packer_out_name
|
||||
fi
|
||||
|
||||
#if [ -v pack ] || ! [ -f assets.sgp ]; then
|
||||
# ./Packer
|
||||
#fi
|
||||
if [ -v pack ] || ! [ -f assets.sgp ]; then
|
||||
./Packer
|
||||
fi
|
||||
|
||||
#if ! [ -v packer ]; then
|
||||
# $compile $source_files $compile_link $link_os_gfx $out $out_name
|
||||
#fi
|
||||
if ! [ -v packer ]; then
|
||||
$compile $source_files $compile_link $link_os_gfx $out $out_name
|
||||
fi
|
||||
|
||||
126
src/assets.c
126
src/assets.c
@ -36,19 +36,8 @@ const u32 M3D_LABEL = CreateMagicValue('L', 'B', 'L', 'S');
|
||||
|
||||
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];
|
||||
|
||||
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 AssetFile Asset_Info[ASSET_MAX];
|
||||
static Asset Asset_Data[ASSET_MAX];
|
||||
|
||||
static b32 ASSET_HEADER_LOADED = false;
|
||||
|
||||
@ -64,8 +53,9 @@ static void apInit()
|
||||
MemCpy(&File_Header, ASSET_PACK, sizeof(FileHeader));
|
||||
|
||||
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;
|
||||
}
|
||||
@ -76,12 +66,81 @@ static void apInit()
|
||||
|
||||
// ::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
|
||||
apLoad(c8 *str)
|
||||
{
|
||||
Asset asset = {0};
|
||||
|
||||
return asset;
|
||||
u64 hash = HashFromString(String8CStr(str));
|
||||
return apLoadWithHash(hash);
|
||||
}
|
||||
|
||||
static Asset
|
||||
@ -90,10 +149,34 @@ apLoadS8(String8 str)
|
||||
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
|
||||
apUnload(c8 *str)
|
||||
{
|
||||
|
||||
u64 hash = HashFromString(String8CStr(str));
|
||||
apUnloadWithHash(hash);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -288,5 +371,12 @@ static m3dModel *apParseModel(rawptr data)
|
||||
return model;
|
||||
}
|
||||
|
||||
static void apFreeModel(m3dModel *model)
|
||||
{
|
||||
FLMemFree(model->vertices);
|
||||
FLMemFree(model->indices);
|
||||
FLMemFree(model);
|
||||
}
|
||||
|
||||
// ::Assets::Models::Functions::End::
|
||||
|
||||
|
||||
42
src/assets.h
42
src/assets.h
@ -2,7 +2,7 @@
|
||||
|
||||
// ::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))
|
||||
|
||||
@ -37,25 +37,6 @@ typedef struct ModelMeta
|
||||
u64 i_count;
|
||||
} ModelMeta;
|
||||
|
||||
typedef struct AssetMeta
|
||||
{
|
||||
union
|
||||
{
|
||||
TexMeta texture;
|
||||
ModelMeta model;
|
||||
};
|
||||
} AssetMeta;
|
||||
|
||||
typedef struct Asset
|
||||
{
|
||||
union
|
||||
{
|
||||
u8 *bytes;
|
||||
m3dModel *model;
|
||||
};
|
||||
u64 len;
|
||||
} Asset;
|
||||
|
||||
typedef struct AssetTag
|
||||
{
|
||||
u32 tag_id;
|
||||
@ -70,6 +51,23 @@ typedef enum AssetType_e
|
||||
AT_MODEL,
|
||||
} 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
|
||||
{
|
||||
union
|
||||
@ -99,9 +97,12 @@ static void apInit();
|
||||
|
||||
static Asset apLoad(c8 *str);
|
||||
static Asset apLoadS8(String8 str);
|
||||
static Asset apLoadWithHash(u64 hash);
|
||||
static void apUnload(c8 *str);
|
||||
static void apUnloadS8(String8 str);
|
||||
static void apUnloadWithHash(u64 hash);
|
||||
static u64 apAssetIndex(c8 *str);
|
||||
static Asset *apAssetSearch(u64 hash);
|
||||
|
||||
// ::Assets::Util::Functions::Header::
|
||||
|
||||
@ -112,3 +113,4 @@ static inline void apMarkLoaded(c8 *str);
|
||||
// ::Assets::Models::Functions::Header::
|
||||
|
||||
static m3dModel *apParseModel(rawptr data);
|
||||
static void apFreeModel(m3dModel *model);
|
||||
|
||||
@ -1,5 +1,7 @@
|
||||
#include "codegen.h"
|
||||
|
||||
#include "xxhash/xxhash.c"
|
||||
|
||||
u64
|
||||
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;
|
||||
u32 dir_count = sizeof(dirs) / sizeof(struct AssetDirInfo);
|
||||
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]);
|
||||
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(
|
||||
@ -128,10 +131,18 @@ CodeGenAssetLookups(Arena *arena)
|
||||
);
|
||||
|
||||
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);
|
||||
|
||||
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");
|
||||
}
|
||||
|
||||
|
||||
@ -12,17 +12,17 @@ g_Shader_Asset_Names[] =
|
||||
static u64
|
||||
g_Shader_Asset_Hashes[] =
|
||||
{
|
||||
12100337026595633089U,
|
||||
12100337026595633089U,
|
||||
12100337026595633089U,
|
||||
12100337026595633089U,
|
||||
12100337026595633089U,
|
||||
12100337026595633089U,
|
||||
15780387719315455808U,
|
||||
2230071466542309169U,
|
||||
14797956403837654625U,
|
||||
8430018914716708078U,
|
||||
14432191255225961360U,
|
||||
8518761701216801634U,
|
||||
};
|
||||
|
||||
#define SHADER_ASSET_MAX 6
|
||||
#define SHADER_ASSET_MAX 6U
|
||||
|
||||
#define SHADER_ASSET 0
|
||||
#define SHADER_ASSET 0U
|
||||
|
||||
static c8 *
|
||||
g_Model_Asset_Names[] =
|
||||
@ -34,13 +34,13 @@ g_Model_Asset_Names[] =
|
||||
static u64
|
||||
g_Model_Asset_Hashes[] =
|
||||
{
|
||||
2356409063604999112U,
|
||||
2356409063604999112U,
|
||||
13826959199295087925U,
|
||||
4559395153940738542U,
|
||||
};
|
||||
|
||||
#define MODEL_ASSET_MAX 2
|
||||
#define MODEL_ASSET_MAX 2U
|
||||
|
||||
#define MODEL_ASSET 1
|
||||
#define MODEL_ASSET 1U
|
||||
|
||||
static c8 *
|
||||
g_Texture_Asset_Names[] =
|
||||
@ -57,16 +57,22 @@ g_Texture_Asset_Names[] =
|
||||
static u64
|
||||
g_Texture_Asset_Hashes[] =
|
||||
{
|
||||
5461253849680765905U,
|
||||
5461253849680765905U,
|
||||
5461253849680765905U,
|
||||
5461253849680765905U,
|
||||
5461253849680765905U,
|
||||
5461253849680765905U,
|
||||
5461253849680765905U,
|
||||
15457434128510259736U,
|
||||
12443444479937967236U,
|
||||
5538438794723924882U,
|
||||
16650761267170532297U,
|
||||
11718504567089932798U,
|
||||
7627422980398294448U,
|
||||
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
|
||||
|
||||
|
||||
14
src/game.c
14
src/game.c
@ -72,14 +72,9 @@ gRunCycle(gGameCtx *ctx, pGameInput *inputs, u32 i_count)
|
||||
|
||||
rFrameBegin();
|
||||
|
||||
vTextureCleanUp();
|
||||
|
||||
u64 index = vFrameIndex();
|
||||
|
||||
/*
|
||||
rDescHandle yoder = rMeshLoad(MODEL_YODA);
|
||||
ctx->pc.mesh_index = yoder.desc_index;
|
||||
*/
|
||||
rDescHandle yoder = rGetAsset("models/yoda");
|
||||
|
||||
rViewportSize(&ctx->pc.res);
|
||||
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(idx_buffer, ctx->gui.indices, sizeof(u32) * ctx->gui.indices_len);
|
||||
|
||||
vBufferQueueWait();
|
||||
|
||||
rPipelineBind(rPIPELINE_PBR, rPT_GRAPHICS);
|
||||
|
||||
|
||||
rPushConstantsSet(&ctx->pc);
|
||||
|
||||
//rBufferBindGUIVertex();
|
||||
//rBufferBindGUIIndex();
|
||||
|
||||
//rBufferBindMesh(&ctx->pc, yoder);
|
||||
rBufferBindMesh(&ctx->pc, yoder);
|
||||
|
||||
//rDrawIndexed(model_meta.i_count, 1);
|
||||
rDrawMesh(yoder);
|
||||
|
||||
rFrameFinish();
|
||||
|
||||
|
||||
34
src/packer.c
34
src/packer.c
@ -56,24 +56,24 @@ InitHeader(FileHeader *header)
|
||||
void
|
||||
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));
|
||||
|
||||
c8 *return_dir = ".";
|
||||
Assert(pDirNavigate("../assets") == 0, "Unable to move to assets directory");
|
||||
|
||||
u64 total_assets = SHADER_ASSET_MAX + TEXTURE_ASSET_MAX + MODEL_ASSET_MAX;
|
||||
u64 asset_count = 0;
|
||||
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++)
|
||||
{
|
||||
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);
|
||||
u64 file_size = pFileLength(asset_file);
|
||||
@ -82,13 +82,14 @@ PackFiles(Arena *arena, FileHeader *header)
|
||||
pFileRead(asset_file, 0, file_data, file_size);
|
||||
|
||||
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");
|
||||
|
||||
assets[asset_count].data_offset = prev_offset;
|
||||
assets[asset_count].len = file_size;
|
||||
assets[asset_count].type = AT_SHADER;
|
||||
assets[asset_count].hash = g_Shader_Asset_Hashes[i];
|
||||
|
||||
pFileClose(asset_file);
|
||||
}
|
||||
@ -97,7 +98,7 @@ PackFiles(Arena *arena, FileHeader *header)
|
||||
{
|
||||
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);
|
||||
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].len = loaded_length;
|
||||
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.h = u32(h);
|
||||
assets[asset_count].texture_meta.ch = u32(ch);
|
||||
@ -131,13 +133,14 @@ PackFiles(Arena *arena, FileHeader *header)
|
||||
stbi_image_free(image_bytes);
|
||||
|
||||
pFileClose(asset_file);
|
||||
|
||||
}
|
||||
|
||||
for (u32 i = 0; i < MODEL_ASSET_MAX; i++, asset_count++)
|
||||
{
|
||||
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);
|
||||
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].type = AT_MODEL;
|
||||
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);
|
||||
|
||||
m3d_free(model);
|
||||
|
||||
pFileClose(asset_file);
|
||||
}
|
||||
|
||||
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::
|
||||
@ -218,6 +228,8 @@ TestAssetPack(Arena *arena)
|
||||
{
|
||||
pFile file = pFileOpen("assets.sgp", pFS_READ);
|
||||
|
||||
Assert(pDirNavigate("../assets") == 0, "Unable to navigate back to assets directory");
|
||||
|
||||
FileHeader header;
|
||||
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++)
|
||||
{
|
||||
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++)
|
||||
{
|
||||
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++)
|
||||
{
|
||||
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,15 +286,10 @@ main(int argc, c8 **argv)
|
||||
void *mem = pMemAllocZeroed(GB(1));
|
||||
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};
|
||||
InitHeader(&header);
|
||||
|
||||
PackFiles(arena, &header);
|
||||
|
||||
pFileClose(file);
|
||||
|
||||
TestAssetPack(arena);
|
||||
}
|
||||
|
||||
@ -110,12 +110,6 @@ void rDestroy();
|
||||
// ::Renderer::Buffers::Header::
|
||||
|
||||
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 rBufferBindIndex(rRenderBuffer *buffer);
|
||||
static rawptr rBufferGUIVertMapping();
|
||||
@ -141,6 +135,11 @@ static b32 rFrameBegin();
|
||||
static b32 rFrameFinish();
|
||||
static void rDrawIndexed(u32 index_count, u32 instance_count);
|
||||
static void rPipelineBind(rPipelineHandle handle, rPipelineType type);
|
||||
static void rDrawMesh(rDescHandle handle);
|
||||
|
||||
// ::Renderer::Assets::Header::
|
||||
|
||||
static rDescHandle rGetAsset(c8 *asset_name);
|
||||
|
||||
// ::Renderer::Includes::Header::
|
||||
|
||||
|
||||
@ -80,25 +80,7 @@ vFrameRenderSem()
|
||||
static inline VkSemaphore
|
||||
vFrameSwapSem()
|
||||
{
|
||||
return v_Renderer.frame_handles[vFrameIndex()].sc_sem;
|
||||
}
|
||||
|
||||
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()];
|
||||
return v_Renderer.handles.sc_sems[v_Renderer.state.vk.image_idx];
|
||||
}
|
||||
|
||||
static inline void
|
||||
@ -316,6 +298,7 @@ vImmSubmitFinish(VkDevice device, VkFence fence, VkCommandBuffer cmd, VkQueue qu
|
||||
if (success)
|
||||
{
|
||||
result = vkWaitForFences(device, 1, &f, true, 9999999999);
|
||||
Printfln("fence waited");
|
||||
if (result != VK_SUCCESS)
|
||||
{
|
||||
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::
|
||||
|
||||
static VkResult
|
||||
@ -1152,15 +1170,9 @@ vFrameStructuresInit()
|
||||
if (result != VK_SUCCESS)
|
||||
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)
|
||||
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;
|
||||
@ -1291,6 +1303,17 @@ vSwapchainInit()
|
||||
v_Renderer.state.swapchain.extent.height = extent.height;
|
||||
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;
|
||||
}
|
||||
|
||||
@ -1664,37 +1687,146 @@ vShaderModuleInit(u8 *bytes, u32 len, VkShaderModule *module)
|
||||
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, ©);
|
||||
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
|
||||
vBuffersInit()
|
||||
{
|
||||
vRBuffers *buf = &v_Renderer.buffers;
|
||||
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;
|
||||
VkResult result;
|
||||
|
||||
if (success)
|
||||
{
|
||||
result = vBufferCreate(&buf->gui_vert.alloc, rRBT_VERTEX | rRBT_HOST, VERTEX_BUFFER_CAP);
|
||||
if (result != VK_SUCCESS)
|
||||
success = false;
|
||||
}
|
||||
result = vBufferCreate(&buf->gui_vert.alloc, rRBT_VERTEX | rRBT_HOST, VERTEX_BUFFER_CAP);
|
||||
if (result != VK_SUCCESS)
|
||||
success = false;
|
||||
|
||||
if (success)
|
||||
{
|
||||
@ -1872,7 +2004,7 @@ vTransferUpload(vTransfer **transfers, u32 count)
|
||||
}
|
||||
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)
|
||||
target_buf = transfers[i]->buffer;
|
||||
else if (transfers[i]->type == vTT_MESH)
|
||||
|
||||
@ -185,7 +185,7 @@ typedef enum DescType_e
|
||||
|
||||
typedef struct rDescHandle
|
||||
{
|
||||
u32 asset_id;
|
||||
u32 asset_index;
|
||||
u32 desc_index;
|
||||
} rDescHandle;
|
||||
|
||||
@ -193,11 +193,7 @@ typedef struct vAssetInfo
|
||||
{
|
||||
rDescHandle handle;
|
||||
vDescType type;
|
||||
union
|
||||
{
|
||||
u64 asset_id;
|
||||
TextureAsset texture_id;
|
||||
};
|
||||
u64 asset_id;
|
||||
} vAssetInfo;
|
||||
|
||||
typedef struct vDeviceQueues
|
||||
@ -263,8 +259,8 @@ typedef struct vMeshBuffer
|
||||
|
||||
typedef struct vMeshAsset
|
||||
{
|
||||
vMeshBuffer *mesh;
|
||||
vBuffer *index;
|
||||
vMeshBuffer mesh;
|
||||
vBuffer index;
|
||||
} vMeshAsset;
|
||||
|
||||
typedef enum vAssetType_e
|
||||
@ -276,14 +272,18 @@ typedef enum vAssetType_e
|
||||
|
||||
typedef struct vAsset
|
||||
{
|
||||
u64 hash;
|
||||
rDescHandle handle;
|
||||
union
|
||||
{
|
||||
TexMeta texture_meta;
|
||||
ModelMeta model_meta;
|
||||
};
|
||||
union
|
||||
{
|
||||
vMeshAsset *mesh;
|
||||
vImageView *texture;
|
||||
};
|
||||
AssetMeta meta;
|
||||
u64 hash;
|
||||
rDescHandle handle;
|
||||
} vAsset;
|
||||
|
||||
ArrayType(vAsset);
|
||||
@ -310,6 +310,8 @@ typedef struct vRendererState
|
||||
rPipelineHandle pipeline;
|
||||
u32 width;
|
||||
u32 height;
|
||||
u32 curr_vert_buf;
|
||||
u32 curr_index_buf;
|
||||
} vRendererState;
|
||||
|
||||
typedef struct vState
|
||||
@ -332,7 +334,6 @@ typedef struct vFrameHandles
|
||||
{
|
||||
VkCommandPool pool;
|
||||
VkCommandBuffer buffer;
|
||||
VkSemaphore sc_sem;
|
||||
VkSemaphore r_sem;
|
||||
VkFence r_fence;
|
||||
} vFrameHandles;
|
||||
@ -361,6 +362,7 @@ typedef struct vRHandles
|
||||
VkQueue gfx_queue;
|
||||
VkQueue tfer_queue;
|
||||
VkSampler nearest_sampler;
|
||||
VkSemaphore *sc_sems;
|
||||
#ifdef BUILD_DEBUG
|
||||
VkDebugUtilsMessengerEXT debug;
|
||||
#endif
|
||||
@ -529,6 +531,7 @@ static b32 vShaderModuleInit(u8 *bytes, u32 len, VkShaderModule *module);
|
||||
static void vUploadQueuesInit();
|
||||
static void vLoaderStartThreads();
|
||||
static b32 vBuffersInit();
|
||||
static b32 vAssetsInit();
|
||||
static b32 vRenderDocInit();
|
||||
|
||||
// ::Vulkan::Util::Functions::Header::
|
||||
@ -541,9 +544,6 @@ static inline VkSemaphore vFrameRenderSem();
|
||||
static inline VkSemaphore vFrameSwapSem();
|
||||
static inline u32 vFrameIndex();
|
||||
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 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);
|
||||
@ -578,7 +578,6 @@ static void vSwapchainResize();
|
||||
static vTransfer *vTextureTransferInit(Arena *arena, u32 asset_id, VkImage image, rawptr bytes, TexMeta *meta);
|
||||
static vImageView *vImageViewCreate(TexMeta meta);
|
||||
static b32 vImageViewInit(vImageView *view, u32 width, u32 height, u32 channels);
|
||||
static void vTextureCleanUp();
|
||||
|
||||
// ::Vulkan::Descriptors::Functions::Header::
|
||||
|
||||
@ -592,10 +591,13 @@ static rDescHandle vDescHandlePop(vDescType type, u32 asset_id);
|
||||
static u32 vDescPushImageDesc(vImageView *view);
|
||||
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::
|
||||
|
||||
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 rawptr vMapBuffer(VmaAllocation alloc);
|
||||
|
||||
|
||||
@ -26,6 +26,7 @@ rInit()
|
||||
Assert(vDescriptorsInit(), "Unable to initialize descriptors.");
|
||||
Assert(vPipelinesInit(), "Unable to initialize pipelines.");
|
||||
Assert(vBuffersInit(), "Unable to initialize buffers.");
|
||||
Assert(vAssetsInit(), "Unable to initialize assets.");
|
||||
|
||||
vUploadQueuesInit();
|
||||
vLoaderStartThreads();
|
||||
@ -40,7 +41,6 @@ rDestroy()
|
||||
{
|
||||
VkDevice device = v_Renderer.handles.device;
|
||||
VkInstance instance = v_Renderer.handles.inst;
|
||||
vBufferPtrArray *frame_buffers = v_Renderer.buffers.frame_buffers;
|
||||
vImmHandles imm = v_Renderer.imm;
|
||||
VmaAllocator vma_alloc = v_Renderer.handles.vma_alloc;
|
||||
VkSwapchainKHR swapchain = v_Renderer.handles.swapchain;
|
||||
@ -78,13 +78,9 @@ rDestroy()
|
||||
vFrameHandles fh = v_Renderer.frame_handles[i];
|
||||
|
||||
vkDestroySemaphore(device, fh.r_sem, NULL);
|
||||
vkDestroySemaphore(device, fh.sc_sem, NULL);
|
||||
vkDestroyFence(device, fh.r_fence, NULL);
|
||||
vkFreeCommandBuffers(device, fh.pool, 1, &fh.buffer);
|
||||
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);
|
||||
@ -121,95 +117,6 @@ rDestroy()
|
||||
|
||||
// ::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
|
||||
rBufferBindVertex(rRenderBuffer *buffer)
|
||||
{
|
||||
@ -275,10 +182,15 @@ rBufferBindGUIIndex()
|
||||
static void
|
||||
rBufferBindMesh(rPushConst *pc, rDescHandle handle)
|
||||
{
|
||||
vModelBuffers *buffers = vModelSearch(handle.asset_id);
|
||||
if (buffers != NULL)
|
||||
if (v_Renderer.state.renderer.curr_vert_buf != handle.asset_index)
|
||||
{
|
||||
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);
|
||||
if (result != VK_SUCCESS)
|
||||
{
|
||||
Printf("vkWaitForFences failure: %s", vVkResultStr(result));
|
||||
Printfln("vkWaitForFences failure: %s", vVkResultStr(result));
|
||||
success = false;
|
||||
}
|
||||
|
||||
@ -528,6 +440,22 @@ rDrawIndexed(u32 index_count, u32 instance_count)
|
||||
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
|
||||
rPipelineBind(rPipelineHandle handle, rPipelineType type)
|
||||
{
|
||||
@ -554,3 +482,24 @@ rPipelineBind(rPipelineHandle handle, rPipelineType type)
|
||||
}
|
||||
|
||||
// ::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::
|
||||
|
||||
26
src/stglib.h
26
src/stglib.h
@ -381,6 +381,7 @@ typedef enum KeyboardInput_e
|
||||
# include <x86intrin.h>
|
||||
# include <sys/time.h>
|
||||
# include <fcntl.h>
|
||||
# include <errno.h>
|
||||
|
||||
// ::Platform::Linux::Defines::Header::
|
||||
|
||||
@ -741,7 +742,6 @@ typedef struct T##Array \
|
||||
{ \
|
||||
T *data; \
|
||||
u64 length; \
|
||||
u64 cap; \
|
||||
} T##Array
|
||||
|
||||
#define PtrArrayType(T) \
|
||||
@ -749,13 +749,11 @@ typedef struct T##PtrArray \
|
||||
{ \
|
||||
T **data; \
|
||||
u64 length; \
|
||||
u64 cap; \
|
||||
} T##PtrArray
|
||||
|
||||
#define InitArrayType(arr, arena, T, len) \
|
||||
arr.data = MakeArray(arena, T, len); \
|
||||
arr.length = 0; \
|
||||
arr.cap = len
|
||||
arr.length = len
|
||||
|
||||
// ::Util::LinkedList::Macros::
|
||||
|
||||
@ -1298,27 +1296,39 @@ static void HashTableDeleteU64(HashTable *table, u64 key);
|
||||
if (BitEq(acc, pFS_CREATE))
|
||||
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
|
||||
pFileClose(pFile file)
|
||||
{
|
||||
fsync(file);
|
||||
close(file);
|
||||
}
|
||||
|
||||
// TODO: make these more resilient
|
||||
static u64
|
||||
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);
|
||||
}
|
||||
|
||||
static u64
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
@ -154,7 +154,7 @@ g_Fence_Create_Info =
|
||||
};
|
||||
|
||||
static VkSemaphoreCreateInfo
|
||||
g_Semaphore_Create_info =
|
||||
g_Semaphore_Create_Info =
|
||||
{
|
||||
.sType = STYPE(SEMAPHORE_CREATE_INFO),
|
||||
};
|
||||
@ -259,10 +259,11 @@ g_Depth_View_Info =
|
||||
static VkDescriptorPoolSize
|
||||
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_BUFFER, .descriptorCount = 4096},
|
||||
{ .type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, .descriptorCount = 4096},
|
||||
{ .type = VK_DESCRIPTOR_TYPE_SAMPLER, .descriptorCount = 4096 },
|
||||
};
|
||||
|
||||
static VkDescriptorPoolCreateInfo
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user