added unloading textures
This commit is contained in:
parent
6dd98807ca
commit
c4ce5328ef
@ -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,
|
||||
|
||||
27
src/ds.c
27
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::
|
||||
|
||||
|
||||
|
||||
@ -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 },
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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;
|
||||
|
||||
|
||||
@ -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::
|
||||
|
||||
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user