fixed allocator and asset system bug, still experiencing an awful asset cleanup bug though

This commit is contained in:
Matthew 2025-05-14 07:05:47 +10:00
parent f0e44b5c37
commit 0640032505
11 changed files with 112 additions and 33 deletions

View File

@ -480,7 +480,10 @@ static void FreeListInsert(FLNode **head, FLNode *prev_node, FLNode *new_node)
if (prev_node == &FL_NIL_NODE) if (prev_node == &FL_NIL_NODE)
{ {
if (*head != &FL_NIL_NODE) if (*head != &FL_NIL_NODE)
{
new_node->next = *head; new_node->next = *head;
*head = new_node;
}
else else
*head = new_node; *head = new_node;
} }

View File

@ -19,7 +19,6 @@ typedef enum AssetType_e : u32
typedef enum ShaderAsset_e : u32 typedef enum ShaderAsset_e : u32
{ {
SHADER_ASSET_NONE,
QUAD_FRAG_SPIRV_SHADER, QUAD_FRAG_SPIRV_SHADER,
QUAD_VERT_SPIRV_SHADER, QUAD_VERT_SPIRV_SHADER,
GUI_FRAG_SPIRV_SHADER, GUI_FRAG_SPIRV_SHADER,
@ -30,7 +29,6 @@ typedef enum ShaderAsset_e : u32
typedef enum TextureAsset_e : u32 typedef enum TextureAsset_e : u32
{ {
TEXTURE_ASSET_NONE,
PATTERMON_OBESE, PATTERMON_OBESE,
PATTERMON_PURPLOID, PATTERMON_PURPLOID,
PATTERMON_YUKATA, PATTERMON_YUKATA,

View File

@ -511,7 +511,7 @@ static HashNode *HashTablePushU64Rawptr(HashTable *table, u64 key, rawptr value)
static HashNode *HashTablePushU64U64Split(HashTable *table, u64 key, u32 upper, u32 lower) static HashNode *HashTablePushU64U64Split(HashTable *table, u64 key, u32 upper, u32 lower)
{ {
u64 hash = HashFromString(String8Struct(&key)); u64 hash = HashFromString(String8Struct(&key));
return HashTablePush(table, hash, (KeyValuePair){ .key_u64 = key, .value_u64_upper = upper, .value_u64_lower = lower }); return HashTablePush(table, hash, (KeyValuePair){ .key_u64 = key, .value_u64_split = { .upper = upper, .lower = lower }});
} }
static HashNode *HashTablePushRawptrU64(HashTable *table, rawptr key, u64 value) static HashNode *HashTablePushRawptrU64(HashTable *table, rawptr key, u64 value)
@ -606,6 +606,35 @@ static rawptr HashTableDeleteU64Rawptr(HashTable *table, u64 key)
return value; return value;
} }
static U64Split HashTableDeleteU64U64Split(HashTable *table, u64 key)
{
U64Split value = { .upper = UINT32_MAX };
u64 hash = HashFromString(String8Struct(&key));
u64 index = hash % table->cap;
HashList *list = table->lists + index;
HashNode *prev = P_HT_NIL;
for (HashNode *node = list->first; node != P_HT_NIL; node = node->next)
{
if (node->v.key_u64 == key)
{
if (prev != P_HT_NIL)
prev->next = node->next;
value.upper = node->v.value_u64_split.upper;
value.lower = node->v.value_u64_split.lower;
node->v.key_u64 = 0;
node->v.value_u64_split.upper = 0;
node->v.value_u64_split.lower = 0;
HTQueuePush(table->free_lists.first, table->free_lists.last, node);
break;
}
}
return value;
}
// ::DataStructures::HashTable::Functions::End:: // ::DataStructures::HashTable::Functions::End::

View File

@ -86,11 +86,7 @@ typedef struct KeyValuePair
rawptr value_rawptr; rawptr value_rawptr;
u32 value_u32; u32 value_u32;
u64 value_u64; u64 value_u64;
union U64Split value_u64_split;
{
u32 value_u64_upper;
u32 value_u64_lower;
};
}; };
} KeyValuePair; } KeyValuePair;
@ -127,5 +123,6 @@ static HashNode *HashTablePushU64U64(HashTable *table, u64 key, u64 value);
static HashNode *HashTablePushU64String8(HashTable *table, u64 key, String8 value); static HashNode *HashTablePushU64String8(HashTable *table, u64 key, String8 value);
static HashNode *HashTablePushU64Rawptr(HashTable *table, u64 key, rawptr value); static HashNode *HashTablePushU64Rawptr(HashTable *table, u64 key, rawptr value);
static HashNode *HashTablePushU64U64Split(HashTable *table, u64 key, u32 upper, u32 lower); static HashNode *HashTablePushU64U64Split(HashTable *table, u64 key, u32 upper, u32 lower);
static rawptr HashTableDeleteU64Rawptr(HashTable *table, u64 key);
static void HashTableDeleteU64(HashTable *table, u64 key); static void HashTableDeleteU64(HashTable *table, u64 key);

View File

@ -59,6 +59,14 @@ static void gRunCycle(gGameCtx *ctx, pGameInput *inputs, u32 i_count)
gHandleInputs(inputs, i_count); gHandleInputs(inputs, i_count);
rFrameBegin();
// This is fucked up, it's triggering before even being set
vTextureCleanUp();
Printfln("post clean up");
/* /*
if (gButton(ctx, "Show 2", 150.0f, 150.0f, 200.0f, 200.0f)) if (gButton(ctx, "Show 2", 150.0f, 150.0f, 200.0f, 200.0f))
{ {
@ -76,19 +84,19 @@ static void gRunCycle(gGameCtx *ctx, pGameInput *inputs, u32 i_count)
} }
*/ */
u64 index = vFrameIndex();
rDescHandle texture;
if (index == 0)
texture = rTextureLoad(HAMSMOKER);
else
texture = rTextureLoad(HOG);
rTextureUnload(texture);
rViewportSize(&ctx->pc.res); rViewportSize(&ctx->pc.res);
ctx->pc.time = (f32)pCPUTimerRead(); ctx->pc.time = (f32)pCPUTimerRead();
rDescHandle pattermon = rTextureLoad(CHEESOID); gWindow(ctx, "texture", 100.0f, 100.0f, 300.0f, 300.0f, texture);
rDescHandle pattermon2 = rTextureLoad(HAMSTER);
rDescHandle purplemon = rTextureLoad(HAMSMOKER);
rDescHandle hog = rTextureLoad(HOG);
gWindow(ctx, "Pattermon", 100.0f, 100.0f, 300.0f, 300.0f, pattermon);
gWindow(ctx, "Pattermon2", 350.0f, 350.0f, 550.0f, 550.0f, purplemon);
gWindow(ctx, "Pattermon3", 600.0f, 100.0f, 800.0f, 300.0f, pattermon2);
gWindow(ctx, "ham", 100.0f, 600.0f, 300.0f, 800.0f, pattermon2);
gWindow(ctx, "hog", 150.0f, 820.0f, 450.0f, 1020.0f, hog);
rawptr vert_buffer = rBufferGUIVertMapping(); rawptr vert_buffer = rBufferGUIVertMapping();
rawptr idx_buffer = rBufferGUIIdxMapping(); rawptr idx_buffer = rBufferGUIIdxMapping();
@ -98,8 +106,6 @@ static void gRunCycle(gGameCtx *ctx, pGameInput *inputs, u32 i_count)
vBufferQueueWait(); vBufferQueueWait();
rFrameBegin();
rPipelineBind(R_PIPELINE_GUI, rPT_GRAPHICS); rPipelineBind(R_PIPELINE_GUI, rPT_GRAPHICS);
rPushConstantsSet(&ctx->pc); rPushConstantsSet(&ctx->pc);

View File

@ -132,6 +132,8 @@ static inline u64 pCPUTimerRead();
// ::Platform::Atomics::Header:: // ::Platform::Atomics::Header::
static inline void AtomicSignalFenceSeqCst();
#define DefSigAtomicFetchIncr(T) static inline T p##T##AtomicFetchIncr(T volatile *ptr) #define DefSigAtomicFetchIncr(T) static inline T p##T##AtomicFetchIncr(T volatile *ptr)
#define DefSigAtomicFetchSub(T) static inline T p##T##AtomicFetchSub(T volatile *ptr, T count) #define DefSigAtomicFetchSub(T) static inline T p##T##AtomicFetchSub(T volatile *ptr, T count)
#define DefSigAtomicIncr(T) static inline void p##T##AtomicIncr(T volatile *ptr) #define DefSigAtomicIncr(T) static inline void p##T##AtomicIncr(T volatile *ptr)

View File

@ -334,6 +334,11 @@ static inline u64 pCPUTimerRead()
// ::Platform::Atomics::Functions::Start:: // ::Platform::Atomics::Functions::Start::
static inline void AtomicSignalFenceSeqCst()
{
__atomic_signal_fence(__ATOMIC_SEQ_CST);
}
DefScalarImpl(AtomicFetchIncr); DefScalarImpl(AtomicFetchIncr);
DefScalarImpl(AtomicIncr); DefScalarImpl(AtomicIncr);
DefScalarImpl(AtomicStore); DefScalarImpl(AtomicStore);

View File

@ -401,18 +401,27 @@ static b32 vImageViewCreate(vImageView *view, u32 width, u32 height, u32 channel
return success; return success;
} }
static void vTextureCleanUp(vImageView *view) static void vTextureCleanUp()
{ {
VkDevice device = v_Renderer.handles.device; VkDevice device = v_Renderer.handles.device;
VmaAllocator vma_alloc = v_Renderer.handles.vma_alloc; VmaAllocator vma_alloc = v_Renderer.handles.vma_alloc;
HashTable *table = &v_Renderer.buffers.images; HashTable *table = &v_Renderer.buffers.images;
b8 *queue = vFrameTexDestroyQueue(); b8 *queue = vFrameTexDestroyQueue();
Printfln("frame: %llu", v_Renderer.state.renderer.frame_count);
// NOTE: might need a mutex here at some point, check if crashes related to image access
for (u64 i = 0; i < TEXTURE_ASSET_MAX; i++) for (u64 i = 0; i < TEXTURE_ASSET_MAX; i++)
{ {
if (queue[i]) if (queue[i])
{ {
vImageView *view = HashTableDeleteU64Rawptr(table, i); Printfln("fetching handle for id: %llu", i);
rDescHandle handle = vDescHandlePop(vDT_SAMPLED_IMAGE, (u32)i);
vDescIndexPush(vDT_SAMPLED_IMAGE, handle.desc_index);
Printfln("queue %llu %d", i, queue[i]);
vImageView *view = vImagePop(i);
Assert(view != NULL, "rTextureUnload failure: value not in hash table"); Assert(view != NULL, "rTextureUnload failure: value not in hash table");
vkDestroyImageView(device, view->view, NULL); vkDestroyImageView(device, view->view, NULL);
@ -423,17 +432,19 @@ static void vTextureCleanUp(vImageView *view)
queue[i] = false; queue[i] = false;
} }
} }
AtomicSignalFenceSeqCst();
} }
static void vImagePush(TextureAsset asset_id, vImageView *view) static void vImagePush(TextureAsset asset_id, vImageView *view)
{ {
Assert(asset_id != 0, "asset_id is TEXTURE_ASSET_NONE");
HashTablePushU64Rawptr(&v_Renderer.buffers.images, asset_id, view); HashTablePushU64Rawptr(&v_Renderer.buffers.images, asset_id, view);
} }
static void vImagePop(TextureAsset asset_id) static vImageView *vImagePop(TextureAsset asset_id)
{ {
Printfln("popping id: %llu", asset_id);
return (vImageView *)HashTableDeleteU64Rawptr(&v_Renderer.buffers.images, asset_id);
} }
static vImageView *vImageSearch(TextureAsset asset_id) static vImageView *vImageSearch(TextureAsset asset_id)
@ -507,24 +518,41 @@ static rDescHandle vDescHandleSearch(vDescType type, u32 asset_id)
.asset_id = UINT32_MAX, .asset_id = UINT32_MAX,
}; };
Printfln("search asset_id: %llu", asset_id);
HashTable *table = &v_Renderer.desc_bindings[type].lookup_table; HashTable *table = &v_Renderer.desc_bindings[type].lookup_table;
KeyValuePair *kv_pair = HashTableSearchU64(table, asset_id); KeyValuePair *kv_pair = HashTableSearchU64(table, asset_id);
if (kv_pair != NULL) if (kv_pair != NULL)
{ {
asset_info.asset_id = kv_pair->value_u64_upper; asset_info.asset_id = kv_pair->value_u64_split.upper;
asset_info.desc_index = kv_pair->value_u64_lower; asset_info.desc_index = kv_pair->value_u64_split.lower;
} }
return asset_info; return asset_info;
} }
static void vDescHandleInsert(vDescType type, rDescHandle handle) static void vDescHandlePush(vDescType type, rDescHandle handle)
{ {
HashTable *table = &v_Renderer.desc_bindings[type].lookup_table; HashTable *table = &v_Renderer.desc_bindings[type].lookup_table;
HashTablePushU64U64Split(table, handle.asset_id, handle.asset_id, handle.desc_index); HashTablePushU64U64Split(table, handle.asset_id, handle.asset_id, handle.desc_index);
} }
static rDescHandle vDescHandlePop(vDescType type, u32 asset_id)
{
HashTable *table = &v_Renderer.desc_bindings[type].lookup_table;
U64Split split = HashTableDeleteU64U64Split(table, (u64)asset_id);
Assert(split.upper != UINT32_MAX, "vDescHandlePop failure: unable to find asset handle");
rDescHandle handle = {
.asset_id = split.upper,
.desc_index = split.lower,
};
return handle;
}
static void vDescHandleDelete(vDescType type, u32 asset_id) static void vDescHandleDelete(vDescType type, u32 asset_id)
{ {
HashTable *table = &v_Renderer.desc_bindings[type].lookup_table; HashTable *table = &v_Renderer.desc_bindings[type].lookup_table;
@ -1433,6 +1461,7 @@ static b32 vDescriptorsInit()
{ {
for (u32 i = 0; i < vDT_MAX; i++) for (u32 i = 0; i < vDT_MAX; i++)
{ {
// FREE MIGHT BE NULL
bindings[i].free = ArenaAlloc(v_Renderer.mem.perm_arena, sizeof(u32) * DESC_MAX_BINDINGS); bindings[i].free = ArenaAlloc(v_Renderer.mem.perm_arena, sizeof(u32) * DESC_MAX_BINDINGS);
HashTableInit(&bindings[i].lookup_table, 6); HashTableInit(&bindings[i].lookup_table, 6);
@ -1626,6 +1655,7 @@ static b32 vBuffersInit()
InitArrayType(buf->frame_images[i], arena, vImageView *, 128); InitArrayType(buf->frame_images[i], arena, vImageView *, 128);
buf->tex_destroy_queue[i] = MakeArray(arena, b8, TEXTURE_ASSET_MAX); buf->tex_destroy_queue[i] = MakeArray(arena, b8, TEXTURE_ASSET_MAX);
MemZero(buf->tex_destroy_queue, sizeof(b8) * TEXTURE_ASSET_MAX);
} }

View File

@ -550,8 +550,9 @@ static void vSwapchainResize();
// ::Vulkan::Images::Functions::Header:: // ::Vulkan::Images::Functions::Header::
static b32 vImageViewCreate(vImageView *view, u32 width, u32 height, u32 channels); static b32 vImageViewCreate(vImageView *view, u32 width, u32 height, u32 channels);
static void vTextureCleanUp(vImageView *view); static void vTextureCleanUp();
static void vImagePush(TextureAsset asset_id, vImageView *view); static void vImagePush(TextureAsset asset_id, vImageView *view);
static vImageView *vImagePop(TextureAsset asset_id);
static vImageView *vImageSearch(TextureAsset asset_id); static vImageView *vImageSearch(TextureAsset asset_id);
// ::Vulkan::Descriptors::Functions::Header:: // ::Vulkan::Descriptors::Functions::Header::
@ -559,7 +560,8 @@ static vImageView *vImageSearch(TextureAsset asset_id);
static void vDescIndexPush(vDescType type, u32 index); static void vDescIndexPush(vDescType type, u32 index);
static u32 vDescIndexPop(vDescType type); static u32 vDescIndexPop(vDescType type);
static rDescHandle vDescHandleSearch(vDescType type, u32 asset_id); static rDescHandle vDescHandleSearch(vDescType type, u32 asset_id);
static void vDescHandleInsert(vDescType type, rDescHandle handle); static void vDescHandlePush(vDescType type, rDescHandle handle);
static rDescHandle vDescHandlePop(vDescType type, u32 asset_id);
static void vDescHandleDelete(vDescType type, u32 asset_id); static void vDescHandleDelete(vDescType type, u32 asset_id);
static u32 vDescPushImage(vImageView *view); static u32 vDescPushImage(vImageView *view);

View File

@ -139,6 +139,7 @@ static rDescHandle rTextureLoad(TextureAsset asset_id)
// TODO: handle errors instead of failing // TODO: handle errors instead of failing
Assert(vImageViewCreate(view, meta.w, meta.h, meta.ch), "rTextureLoad failure: vImageViewCreate failed"); Assert(vImageViewCreate(view, meta.w, meta.h, meta.ch), "rTextureLoad failure: vImageViewCreate failed");
Printfln("Loading asset: %llu", asset_id);
handle.asset_id = asset_id; handle.asset_id = asset_id;
handle.desc_index = vDescPushImage(view); handle.desc_index = vDescPushImage(view);
@ -160,7 +161,7 @@ static rDescHandle rTextureLoad(TextureAsset asset_id)
v_Renderer.upload.transfers[job_idx] = transfer; v_Renderer.upload.transfers[job_idx] = transfer;
vDescHandleInsert(vDT_SAMPLED_IMAGE, handle); vDescHandlePush(vDT_SAMPLED_IMAGE, handle);
vImagePush(asset_id, view); vImagePush(asset_id, view);
TicketMutUnlock(&v_Renderer.upload.mut); TicketMutUnlock(&v_Renderer.upload.mut);
@ -177,9 +178,9 @@ static void rTextureUnload(rDescHandle current_handle)
if (handle.asset_id != UINT32_MAX) if (handle.asset_id != UINT32_MAX)
{ {
b8 *queue = vFrameNextTexDestroyQueue(); b8 *queue = vFrameTexDestroyQueue();
queue[handle.asset_id] = true; queue[current_handle.asset_id] = true;
} }
} }

View File

@ -77,6 +77,12 @@ typedef uint32_t usize;
#endif #endif
typedef union
{
struct { u32 upper, lower; };
u64 full;
} U64Split;
typedef union typedef union
{ {
struct { f32 r, g; }; struct { f32 r, g; };