added unloading textures

This commit is contained in:
Matthew 2025-05-11 21:23:06 +10:00
parent 6dd98807ca
commit c4ce5328ef
7 changed files with 96 additions and 172 deletions

View File

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

View File

@ -579,6 +579,33 @@ static void HashTableDeleteU64(HashTable *table, u64 key)
}
}
static rawptr HashTableDeleteU64Rawptr(HashTable *table, u64 key)
{
rawptr value = NULL;
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 = node->v.value_rawptr;
node->v.key_u64 = 0;
node->v.value_rawptr = NULL;
HTQueuePush(table->free_lists.first, table->free_lists.last, node);
break;
}
}
return value;
}
// ::DataStructures::HashTable::Functions::End::

View File

@ -28,7 +28,7 @@ const FileMapping g_Shader_File_Map[] = {
const FileMapping g_Texture_File_Map[] = {
{ .file_name = "pattermon.png", .ix = PATTERMON_OBESE },
{ .file_name = "patamon.png", .ix = PATTERMON_ORIENTAL },
{ .file_name = "patamon.png", .ix = PATTERMON_YUKATA },
{ .file_name = "purplemon.png", .ix = PATTERMON_PURPLOID },
{ .file_name = "hamster.png", .ix = HAMSTER },
{ .file_name = "ham_smoke.png", .ix = HAMSMOKER },

View File

@ -101,11 +101,8 @@ void rDestroy();
// ::Renderer::Buffers::Header::
static rBuffer rBufferCreate(rRenderBufferType type, u64 size);
static b32 rBufferMap();
static void rBufferFree(rRenderBuffer *buffers, u32 buffer_count);
static b32 rBufferUpload(rRenderBuffer **buffer, rawptr *ptr, u32 count, u32 thr_ix);
static void rBufferCreateAndUpload(ModelAsset asset_id);
static rDescHandle rTextureLoad(TextureAsset asset_id);
static void rTextureUnload(rDescHandle handle);
static void rBufferBindVertex(rRenderBuffer *buffer);

View File

@ -56,6 +56,11 @@ static inline u32 vFrameIndex()
return v_Renderer.state.renderer.frame_count % FRAME_OVERLAP;
}
static inline u32 vFrameNextIndex()
{
return (v_Renderer.state.renderer.frame_count + 1) % FRAME_OVERLAP;
}
static inline VkCommandBuffer vFrameCmdBuf()
{
return v_Renderer.frame_handles[vFrameIndex()].buffer;
@ -91,6 +96,16 @@ static inline vBufferAllocPtrArray *vFrameBuffers()
return v_Renderer.buffers.frame_buffers + vFrameIndex();
}
static inline b8 *vFrameTexDestroyQueue()
{
return v_Renderer.buffers.tex_destroy_queue[vFrameIndex()];
}
static inline b8 *vFrameNextTexDestroyQueue()
{
return v_Renderer.buffers.tex_destroy_queue[vFrameNextIndex()];
}
static inline void vImageCopyToImage(VkCommandBuffer cmd, VkImage src, VkImage dst, VkExtent2D src_ext, VkExtent2D dst_ext)
{
VkImageBlit2 blit = {
@ -402,7 +417,42 @@ static b32 vImageViewCreate(vImageView *view, u32 width, u32 height, u32 channel
return success;
}
static vImageView *vImageLookupExisting(TextureAsset asset_id)
static void vTextureCleanUp(vImageView *view)
{
VkDevice device = v_Renderer.handles.device;
VmaAllocator vma_alloc = v_Renderer.handles.vma_alloc;
HashTable *table = &v_Renderer.buffers.images;
b8 *queue = vFrameTexDestroyQueue();
for (u64 i = 0; i < TEXTURE_ASSET_MAX; i++)
{
if (queue[i])
{
vImageView *view = HashTableDeleteU64Rawptr(table, i);
Assert(view != NULL, "rTextureUnload failure: value not in hash table");
vkDestroyImageView(device, view->view, NULL);
vmaDestroyImage(vma_alloc, view->image.image, view->image.alloc);
FLMemFree(view);
queue[i] = false;
}
}
}
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);
}
static void vImagePop(TextureAsset asset_id)
{
}
static vImageView *vImageSearch(TextureAsset asset_id)
{
vImageView *view = NULL;
@ -1747,8 +1797,11 @@ static b32 vBuffersInit()
{
InitArrayType(buf->frame_buffers[i], arena, vBufferAlloc *, 128);
InitArrayType(buf->frame_images[i], arena, vImageView *, 128);
buf->tex_destroy_queue[i] = MakeArray(arena, b8, TEXTURE_ASSET_MAX);
}
b32 success = true;
VkResult result;

View File

@ -363,8 +363,11 @@ typedef struct vRBuffers
{
HashTable buffers;
vBufferAllocPtrArray frame_buffers[FRAME_OVERLAP];
HashTable images;
vImageViewPtrArray frame_images[FRAME_OVERLAP];
b8 *tex_destroy_queue[FRAME_OVERLAP];
vMappedBuffer transfer;
vMappedBuffer gui_vert;
vMappedBuffer gui_idx;
@ -513,6 +516,8 @@ 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 vBufferAllocPtrArray *vFrameBuffers();
static inline void vImageTransition(VkCommandBuffer cmd, vImage *img, VkImageLayout new);
static inline void vImageTransitionLayout(VkCommandBuffer cmd, VkImage img, VkImageLayout curr, VkImageLayout new);
@ -547,9 +552,11 @@ static void vSwapchainResize();
// ::Vulkan::Images::Functions::Header::
static b32 vImageViewCreate(vImageView *view, u32 width, u32 height, u32 channels);
static void vTextureCleanUp(vImageView *view);
static b32 vSamplerCreate(rTextureBuffer *buffer);
static void vImageUpload(rTextureBuffer *buffer, u8 *data, u32 thread_idx);
static vImageView *vImageLookupExisting(TextureAsset asset_id);
static void vImagePush(TextureAsset asset_id, vImageView *view);
static vImageView *vImageSearch(TextureAsset asset_id);
// ::Vulkan::Descriptors::Functions::Header::

View File

@ -125,171 +125,6 @@ void rDestroy()
// ::Vulkan::Renderer::Buffers::Functions::Start::
static rBuffer rBufferCreate(rRenderBufferType type, u64 size)
{
rBuffer buffer = NULL;
return buffer;
}
static b32 rBufferCreateOLD(rRenderBufferType type, u64 size)
{
Assert(type != rRBT_NONE, "rBufferCreate: rRenderBuffer type must not be rRBT_NONE");
b32 success = true;
VkResult result;
u32 gfx_queue = v_Renderer.state.vk.gfx_queue_idx;
u32 tfer_queue = v_Renderer.state.vk.tfer_queue_idx;
VmaAllocator alloc = v_Renderer.handles.vma_alloc;
VkBufferCreateInfo buffer_info = {
.sType = STYPE(BUFFER_CREATE_INFO),
//.size = (VkDeviceSize)buffer->size,
};
VmaAllocationCreateInfo alloc_info = {
.usage = VMA_MEMORY_USAGE_UNKNOWN,
.flags = VMA_ALLOCATION_CREATE_MAPPED_BIT,
};
switch (type)
{
case rRBT_VERTEX:
{
buffer_info.usage = VK_BUFFER_USAGE_VERTEX_BUFFER_BIT;
} break;
case rRBT_INDEX:
{
buffer_info.usage = VK_BUFFER_USAGE_INDEX_BUFFER_BIT;
} break;
case rRBT_UNIFORM:
{
buffer_info.usage = VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT;
} break;
case rRBT_STAGING:
{
buffer_info.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT;
} break;
case rRBT_STORAGE:
{
buffer_info.usage = VK_BUFFER_USAGE_STORAGE_BUFFER_BIT;
} break;
default:
break;
}
if ((type & rRBT_HOST) == rRBT_HOST || type == rRBT_STAGING)
{
alloc_info.requiredFlags = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT;
alloc_info.preferredFlags = VK_MEMORY_PROPERTY_HOST_CACHED_BIT;
}
else
{
buffer_info.usage |= VK_BUFFER_USAGE_TRANSFER_DST_BIT;
alloc_info.requiredFlags = VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT;
}
if (tfer_queue != gfx_queue)
{
buffer_info.sharingMode = VK_SHARING_MODE_CONCURRENT;
buffer_info.queueFamilyIndexCount = 2;
buffer_info.pQueueFamilyIndices = (u32[]){gfx_queue, tfer_queue};
}
//result = vmaCreateBuffer(alloc, &buffer_info, &alloc_info, &buffer->buffer, &buffer->alloc, &buffer->info);
//if (result != VK_SUCCESS)
//{
//Printfln("vmaCreateBuffer failure: %s", vVkResultStr(result));
//}
return success;
}
static b32 rBufferUpload(rRenderBuffer **buffers, rawptr *ptrs, u32 count, u32 thr_ix)
{
// TODO: replace
/*
Assert(buffers, "rBufferUpload: buffer must not be null");
Assert(ptrs, "rBufferUpload: ptr must not be null");
b32 success = true;
VkCommandBuffer cmd = renderer.vk.imm.cmds[thr_ix];
VkFence fence = renderer.vk.imm.fences[thr_ix];
VkDevice device = v_Renderer.handles.device;
VkQueue queue = renderer.vk.queues.transfer_queue;
VmaAllocator alloc = v_Renderer.handles.vma_alloc;
rawptr mapped_buffers[16] = {0};
rRenderBuffer staging_buffers[16] = {0};
u32 copy_count = 0;
b32 imm_started = success = vImmSubmitBegin(device, fence, cmd);
for (u32 i = 0; i < count && success; i++)
{
b32 host_visible = buffers[i]->type & HOST_VISIBLE_BUFFERS;
if (host_visible)
{
vmaMapMemory(alloc, buffers[i]->alloc, &mapped_buffers[i]);
MemCpy(mapped_buffers[i], ptrs[i], buffers[i]->size);
}
else
{
staging_buffers[copy_count].type = rRBT_STAGING;
staging_buffers[copy_count].size = buffers[i]->size;
//success = rBufferCreate(&staging_buffers[i]);
if (success)
{
vmaMapMemory(alloc, staging_buffers[i].alloc, &mapped_buffers[i]);
MemCpy(mapped_buffers[i], ptrs[i], staging_buffers[i].size);
VkBufferCopy buffer_copy = { .size = (VkDeviceSize)buffers[i]->size };
vkCmdCopyBuffer(cmd, staging_buffers[i].buffer, buffers[i]->buffer, 1, &buffer_copy);
copy_count += 1;
}
}
}
vImmSubmitFinish(device, fence, cmd, queue);
vkWaitForFences(device, 1, &fence, VK_TRUE, 999999999);
for (u32 i = 0; i < copy_count; i++)
{
vmaUnmapMemory(alloc, staging_buffers[i].alloc);
vmaDestroyBuffer(alloc, staging_buffers[i].buffer, staging_buffers[i].alloc);
}
*/
return false;
}
static void rBufferCreateAndUpload(ModelAsset asset_id)
{
/* TODO: figure out how buffers should be loaded to get index count, etc
TicketMutLock(&renderer.upload_queues[vDT_MATERIAL].ticket_mut);
rDescHandle handle = vDescHandleSearch(MODEL_ASSET, asset_id);
if (handle.asset_id != UINT32_MAX)
{
vBufferAlloc *buffer = FLMemAlloc(sizeof(vBufferAlloc));
buffer->
}
u32 job_idx = JobQueueAdd(&renderer.upload_queues[vDT_MATERIAL].job_queue, 1);
renderer.upload_queues[vDT_MATERIAL].queued_buffers[job_idx] = buffer;
renderer.upload_queues[vDT_MATERIAL].data[job_idx] = ptr;
TicketMutUnlock(&renderer.upload_queues[vDT_MATERIAL].ticket_mut);
vLoaderWake();
*/
}
static rDescHandle rTextureLoad(TextureAsset asset_id)
{
rDescHandle handle = vDescHandleSearch(vDT_SAMPLED_IMAGE, asset_id);
@ -326,6 +161,7 @@ static rDescHandle rTextureLoad(TextureAsset asset_id)
v_Renderer.upload.transfers[job_idx] = transfer;
vDescHandleInsert(vDT_SAMPLED_IMAGE, handle);
vImagePush(asset_id, view);
TicketMutUnlock(&v_Renderer.upload.mut);
@ -341,7 +177,9 @@ static void rTextureUnload(rDescHandle current_handle)
if (handle.asset_id != UINT32_MAX)
{
b8 *queue = vFrameNextTexDestroyQueue();
queue[handle.asset_id] = true;
}
}