diff --git a/src/assets.h b/src/assets.h index 0456335..0aea7ca 100644 --- a/src/assets.h +++ b/src/assets.h @@ -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, diff --git a/src/ds.c b/src/ds.c index a204906..016907b 100644 --- a/src/ds.c +++ b/src/ds.c @@ -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:: diff --git a/src/packer.c b/src/packer.c index 2e17da7..ace35ef 100644 --- a/src/packer.c +++ b/src/packer.c @@ -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 }, diff --git a/src/renderer.h b/src/renderer.h index 7b5d6c6..dec19c3 100644 --- a/src/renderer.h +++ b/src/renderer.h @@ -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); diff --git a/src/renderer_vulkan.c b/src/renderer_vulkan.c index 9af2717..74d3535 100644 --- a/src/renderer_vulkan.c +++ b/src/renderer_vulkan.c @@ -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; diff --git a/src/renderer_vulkan.h b/src/renderer_vulkan.h index b570047..65c3c12 100644 --- a/src/renderer_vulkan.h +++ b/src/renderer_vulkan.h @@ -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:: diff --git a/src/renderer_vulkan_public.c b/src/renderer_vulkan_public.c index 5a71adf..141425c 100644 --- a/src/renderer_vulkan_public.c +++ b/src/renderer_vulkan_public.c @@ -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; } }