diff --git a/src/entry_linux.c b/src/entry_linux.c index 6785d9b..4964372 100644 --- a/src/entry_linux.c +++ b/src/entry_linux.c @@ -51,7 +51,6 @@ int main(int argc, char **argv) #endif Arena *arena = ArenaCreateDebug(MB(32), __LINE__); - Arena *renderer_arena = ArenaCreateDebug(MB(16), __LINE__); Arena *game_arena = ArenaCreateDebug(MB(16), __LINE__); Assert(pWindowInit(WINDOW_NAME), "Failed to initialize the window"); @@ -63,7 +62,7 @@ int main(int argc, char **argv) gGameCtx ctx = {0}; - gInit(renderer_arena, &ctx, game_arena); + gInit(&ctx); while (!global_quit) { diff --git a/src/game.c b/src/game.c index cc72437..52a215a 100644 --- a/src/game.c +++ b/src/game.c @@ -16,23 +16,23 @@ i16 mouse_pos_y = 0; // ::Game::Init::Functions::Start:: -static void gInit(Arena *arena, gGameCtx *ctx, Arena *ctx_arena) +static void gInit(gGameCtx *ctx) { - Assert(rInit(arena), "Failed to initialize the renderer"); + Assert(rInit(), "Failed to initialize the renderer"); - ctx->gui.vertices = MakeArray(ctx_arena, rUIVertex, 128); + ctx->arena = ArenaCreateDebug(MB(16), __LINE__); + + ctx->gui.vertices = MakeArray(ctx->arena, rUIVertex, 128); ctx->gui.vertices_len = 0; - ctx->gui.indices = MakeArray(ctx_arena, u32, 768); + ctx->gui.indices = MakeArray(ctx->arena, u32, 768); ctx->gui.indices_len = 0; ctx->gui.instance_count = 0; - ctx->windows = MakeArray(ctx_arena, gWindowWidget, 32); + ctx->windows = MakeArray(ctx->arena, gWindowWidget, 32); ctx->window_len = 0; - ctx->buttons = MakeArray(ctx_arena, gButtonWidget, 64); + ctx->buttons = MakeArray(ctx->arena, gButtonWidget, 64); ctx->btn_len = 0; - - ctx->arena = arena; } static void gDestroy() @@ -46,6 +46,11 @@ static void gDestroy() // ::Game::GameLoop::Functions::Start:: +static void gFrameStartNew() +{ + +} + static void gRunCycle(gGameCtx *ctx, pGameInput *inputs, u32 i_count) { rBufferQueueReset(); @@ -75,11 +80,11 @@ static void gRunCycle(gGameCtx *ctx, pGameInput *inputs, u32 i_count) //rDescHandle pattermon = rTextureCreateAndUpload(PATTERMON_OBESE); rRenderBuffer *vertex_buffer = MakeArray(ctx->arena, rRenderBuffer, 1); - vertex_buffer->type = RENDER_BUFFER_TYPE_VERTEX; + vertex_buffer->type = rRBT_VERTEX; vertex_buffer->size = sizeof(rUIVertex) * ctx->gui.vertices_len; rRenderBuffer *index_buffer = MakeArray(ctx->arena, rRenderBuffer, 1); - index_buffer->type = RENDER_BUFFER_TYPE_INDEX, + index_buffer->type = rRBT_INDEX, index_buffer->size = sizeof(u32) * ctx->gui.indices_len, rBufferCreateAndUpload(vertex_buffer, ctx->gui.vertices); @@ -89,7 +94,7 @@ static void gRunCycle(gGameCtx *ctx, pGameInput *inputs, u32 i_count) rFrameBegin(); - rPipelineBind(PIPELINE_GUI, PIPELINE_TYPE_GRAPHICS); + rPipelineBind(R_PIPELINE_GUI, rPT_GRAPHICS); rPushConstantsSet(&ctx->pc); @@ -98,7 +103,7 @@ static void gRunCycle(gGameCtx *ctx, pGameInput *inputs, u32 i_count) rDrawIndexed(6, ctx->gui.instance_count); - FinishFrame(); + rFrameFinish(); rBufferFree(vertex_buffer, 1); rBufferFree(index_buffer, 1); diff --git a/src/game.h b/src/game.h index a0a1b54..c096451 100644 --- a/src/game.h +++ b/src/game.h @@ -43,7 +43,7 @@ typedef struct gGameCtx // ::Game::Init::Functions::Header:: -static void gInit(Arena *arena, gGameCtx *ctx, Arena *ctx_arena); +static void gInit(gGameCtx *ctx); static void gDestroy(); // ::Game::GameLoop::Functions::Header:: diff --git a/src/renderer.h b/src/renderer.h index d52471a..0f02fe6 100644 --- a/src/renderer.h +++ b/src/renderer.h @@ -22,39 +22,44 @@ typedef struct rShaderGlobals rShaderGlobals; typedef enum Pipeline_e { - PIPELINE_CUBE, - PIPELINE_GUI, + R_PIPELINE_CUBE, + R_PIPELINE_GUI, - PIPELINE_MAX, + R_PIPELINE_MAX, } rPipelineHandle; typedef enum PipelineType_e { - PIPELINE_TYPE_GRAPHICS = 0, - PIPELINE_TYPE_COMPUTE = 1, + rPT_GRAPHICS = 0, + rPT_COMPUTE = 1, } rPipelineType; typedef enum RenderBufferType_e { - RENDER_BUFFER_TYPE_NONE = 0x0000, - RENDER_BUFFER_TYPE_VERTEX = 0x0001, - RENDER_BUFFER_TYPE_INDEX = 0x0002, - RENDER_BUFFER_TYPE_UNIFORM = 0x0004, - RENDER_BUFFER_TYPE_STAGING = 0x0008, - RENDER_BUFFER_TYPE_STORAGE = 0x0010, + rRBT_NONE = 0x0000, + rRBT_VERTEX = 0x0001, + rRBT_INDEX = 0x0002, + rRBT_UNIFORM = 0x0004, + rRBT_STORAGE = 0x0008, + rRBT_HOST = 0x0010, + rRBT_STAGING = 0x0020, + rRBT_HOST_VERTEX = rRBT_HOST | rRBT_VERTEX, + rRBT_HOST_INDEX = rRBT_HOST | rRBT_INDEX, + rRBT_HOST_UNIFORM = rRBT_HOST | rRBT_UNIFORM, + rRBT_HOST_STORAGE = rRBT_HOST | rRBT_STORAGE, } rRenderBufferType; typedef enum TextureBufferType_e { - TEXTURE_BUFFER_TYPE_NONE = 0x0000, - TEXTURE_BUFFER_TYPE_IMAGE = 0x0001, - TEXTURE_BUFFER_TYPE_SAMPLER = 0x0002, + rTBT_NONE = 0x0000, + rTBT_IMAGE = 0x0001, + rTBT_SAMPLER = 0x0002, } rTextureBufferType; typedef enum VertexAttrType_e { - VERTEX_ATTRIBUTE_TYPE_VERTEX = 0, - VERTEX_ATTRIBUTE_TYPE_COLOR = 1, + rVAT_VERTEX = 0, + rVAT_COLOR = 1, } rVertexAttrType; // ::Renderer::Types::Header:: @@ -75,7 +80,7 @@ typedef struct rUploadQueue rTextureBuffer **queued_textures; rawptr *queued_ptrs; }; - rawptr *data; + rawptr *data; TicketMut ticket_mut; Mut mut; JobQueue job_queue; @@ -83,14 +88,17 @@ typedef struct rUploadQueue typedef u32 rAssetHandle; +typedef rawptr rBuffer; + // ::Renderer::Initialization::Header:: -b32 rInit(Arena *arena); +b32 rInit(); void rDestroy(); // ::Renderer::Buffers::Header:: -static b32 rBufferCreate(rRenderBuffer *buffer); +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(rRenderBuffer *buffer, rawptr ptr); @@ -115,7 +123,7 @@ static void rThreadCountSet(u32 n); // ::Renderer::Rendering::Header:: static b32 rFrameBegin(); -static b32 FinishFrame(); +static b32 rFrameFinish(); static void rDrawIndexed(u32 index_count, u32 instance_count); static void rPipelineBind(rPipelineHandle handle, rPipelineType type); diff --git a/src/renderer_vulkan.c b/src/renderer_vulkan.c index 6466792..057e0f8 100644 --- a/src/renderer_vulkan.c +++ b/src/renderer_vulkan.c @@ -1,5 +1,20 @@ // ::Vulkan::Globals::Start:: +static vRenderer2 v_Renderer = { + .state = { + .vk = { + .gfx_queue_idx = UINT32_MAX, + .tfer_queue_idx = UINT32_MAX, + }, + .swapchain = { + .format = INT_MAX, + .color_space = INT_MAX, + .present_mode = INT_MAX, + }, + }, +}; + +/* static vRenderer renderer = { .vk = { .queues = { @@ -13,14 +28,7 @@ static vRenderer renderer = { }, } }; - -static u32 vk_thread_indices[10] = {0}; - -#if __linux__ -pthread_cond_t cond; -#elif _WIN32 -# error threading not yet implemented -#endif +*/ // ::Vulkan::Globals::End:: @@ -38,37 +46,42 @@ pthread_cond_t cond; static inline u32 vFrameIndex() { - return renderer.frame_state.frame_cnt % FRAME_OVERLAP; + return v_Renderer.state.renderer.frame_count % FRAME_OVERLAP; } static inline VkCommandBuffer vFrameCmdBuf() { - return renderer.vk.frame.buffers[vFrameIndex()]; + return v_Renderer.frame_handles[vFrameIndex()].buffer; } -static inline VkFence *vFrameRenderFence() +static inline VkFence vFrameRenderFence() { - return &renderer.vk.frame.render_fences[vFrameIndex()]; + return v_Renderer.frame_handles[vFrameIndex()].r_fence; +} + +static inline VkImage vFrameImage() +{ + return v_Renderer.images.sc.data[v_Renderer.state.vk.image_idx].image.image; +} + +static inline Arena *vFrameArena() +{ + return v_Renderer.mem.frame_arenas[vFrameIndex()]; } static inline VkSemaphore vFrameRenderSem() { - return renderer.vk.frame.render_sems[vFrameIndex()]; + return v_Renderer.frame_handles[vFrameIndex()].r_sem; } static inline VkSemaphore vFrameSwapSem() { - return renderer.vk.frame.swapchain_sems[vFrameIndex()]; + return v_Renderer.frame_handles[vFrameIndex()].sc_sem; } -static inline u32 *vFrameBufferCount() +static inline vBufferAlloc *vFrameBuffers() { - return &renderer.vk.frame.buffer_counts[vFrameIndex()]; -} - -static inline rRenderBuffer *vFrameRenderBuffers() -{ - return renderer.vk.frame.buffer_destroy_queues[vFrameIndex()]; + return v_Renderer.frame_buffers + vFrameIndex(); } static inline void vImageCopyToImage(VkCommandBuffer cmd, VkImage src, VkImage dst, VkExtent2D src_ext, VkExtent2D dst_ext) @@ -142,8 +155,8 @@ static inline void vImageTransitionLayout(VkCommandBuffer cmd, VkImage img, VkIm static inline void vImageTransition(VkCommandBuffer cmd, vImage *img, VkImageLayout new) { - vImageTransitionLayout(cmd, img->img, img->curr_layout, new); - img->curr_layout = new; + vImageTransitionLayout(cmd, img->image, img->layout, new); + img->layout = new; } // ::Vulkan::Util::Functions::End:: @@ -155,16 +168,16 @@ static inline void vImageTransition(VkCommandBuffer cmd, vImage *img, VkImageLay static void vRenderingBegin() { VkCommandBuffer cmd = vFrameCmdBuf(); - VkImage curr_img = renderer.vk.sc.imgs[renderer.frame_state.img_ix]; + VkImage curr_img = v_Renderer.images.sc.data[v_Renderer.state.vk.image_idx].image.image; - vImageTransition(cmd, &renderer.vk.sc.draw_img, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL); - vImageTransition(cmd, &renderer.vk.sc.depth_img, VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL); + vImageTransition(cmd, &v_Renderer.images.draw.image, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL); + vImageTransition(cmd, &v_Renderer.images.depth.image, VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL); vImageTransitionLayout(cmd, curr_img, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL); VkRenderingAttachmentInfo col_attach_info = { .sType = STYPE(RENDERING_ATTACHMENT_INFO), - .imageView = renderer.vk.sc.draw_img.view, + .imageView = v_Renderer.images.draw.view, .imageLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, .loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR, .storeOp = VK_ATTACHMENT_STORE_OP_STORE, @@ -173,7 +186,7 @@ static void vRenderingBegin() VkRenderingAttachmentInfo depth_attach_info = { .sType = STYPE(RENDERING_ATTACHMENT_INFO), - .imageView = renderer.vk.sc.depth_img.view, + .imageView = v_Renderer.images.depth.view, .imageLayout = VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL, .loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR, .storeOp = VK_ATTACHMENT_STORE_OP_STORE, @@ -187,15 +200,15 @@ static void vRenderingBegin() .pDepthAttachment = &depth_attach_info, .renderArea = { .extent = { - .width = renderer.vk.sc.extent.width, - .height = renderer.vk.sc.extent.height, + .width = v_Renderer.state.swapchain.extent.width, + .height = v_Renderer.state.swapchain.extent.height, }, }, }; vkCmdBeginRendering(cmd, &render_info); - vkCmdBindDescriptorSets(cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, renderer.vk.pipe.pipeline_layout, 0, DESC_TYPE_MAX, renderer.vk.pipe.sets, 0, NULL); + vkCmdBindDescriptorSets(cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, v_Renderer.handles.pipeline_layout, 0, V_DESC_TYPE_MAX, v_Renderer.handles.desc_sets, 0, NULL); } // ::Vulkan::Rendering::Functions::End:: @@ -298,19 +311,18 @@ static b32 vImmSubmitFinish(VkDevice device, VkFence fence, VkCommandBuffer cmd, static void vSwapchainResize() { - vkDeviceWaitIdle(renderer.vk.device); + vkDeviceWaitIdle(v_Renderer.handles.device); vSwapchainDestroy(); vDrawImagesDestroy(); - renderer.vk.sc.extent.width = renderer.pending.render_width; - renderer.vk.sc.extent.height = renderer.pending.render_height; + // TODO: fix + //v_Renderer.state.swapchain.extent.width = v_Renderer.state.renderer.width; + //v_Renderer.state.swapchain.extent.height = v_Renderer.state.renderer.height; Assert(vSwapchainInit(), "Unable to recreate swapchain"); Assert(vDrawImagesInit(), "Unable to recreate draw images"); - - renderer.pending.resized = false; } // ::Vulkan::Swapchain::Functions::End:: @@ -321,11 +333,12 @@ static void vSwapchainResize() static b32 vSamplerCreate(rTextureBuffer *buffer) { + /* b32 success = true; vImage *image = &buffer->image; rRenderBuffer staging_buffer = { - .type = RENDER_BUFFER_TYPE_STAGING, + .type = rRBT_STAGING, .size = buffer->width * buffer->height, }; @@ -352,14 +365,14 @@ static b32 vSamplerCreate(rTextureBuffer *buffer) }, }; - if (renderer.vk.queues.graphics != renderer.vk.queues.transfer) + if (v_Renderer.state.vk.gfx_queue_idx != v_Renderer.state.vk.tfer_queue_idx) { image_info.sharingMode = VK_SHARING_MODE_CONCURRENT; image_info.queueFamilyIndexCount = 2; - image_info.pQueueFamilyIndices = (u32[]){renderer.vk.queues.graphics, renderer.vk.queues.transfer}; + image_info.pQueueFamilyIndices = (u32[]){v_Renderer.state.vk.gfx_queue_idx, v_Renderer.state.vk.tfer_queue_idx}; } - VkResult result = vmaCreateImage(renderer.vk.alloc, &image_info, + VkResult result = vmaCreateImage(v_Renderer.handles.vma_alloc, &image_info, &alloc_create_info, &image->img, &image->alloc, NULL); if (result != VK_SUCCESS) { @@ -383,7 +396,7 @@ static b32 vSamplerCreate(rTextureBuffer *buffer) } }; - result = vkCreateImageView(renderer.vk.device, &view_info, NULL, &image->view); + result = vkCreateImageView(v_Renderer.handles.device, &view_info, NULL, &image->view); if (result != VK_SUCCESS) success = false; } @@ -391,7 +404,7 @@ static b32 vSamplerCreate(rTextureBuffer *buffer) if (success) { VkPhysicalDeviceProperties properties; - vkGetPhysicalDeviceProperties(renderer.vk.phys_device, &properties); + vkGetPhysicalDeviceProperties(v_Renderer.handles.phys_device, &properties); // TODO: handle no anisotropy VkSamplerCreateInfo sampler_info = { @@ -408,19 +421,23 @@ static b32 vSamplerCreate(rTextureBuffer *buffer) .mipmapMode = VK_SAMPLER_MIPMAP_MODE_LINEAR, }; - result = vkCreateSampler(renderer.vk.device, &sampler_info, NULL, &image->sampler); + result = vkCreateSampler(v_Renderer.handles.device, &sampler_info, NULL, &image->sampler); if (result != VK_SUCCESS) success = false; } return success; + */ + + return false; } static void vImageUpload(rTextureBuffer *buffer, u8 *data, u32 thread_idx) { + /* b32 success = true; - VkDevice device = renderer.vk.device; + VkDevice device = v_Renderer.handles.device; VkCommandBuffer cmd = renderer.vk.imm.cmds[thread_idx]; VkFence fence = renderer.vk.imm.fences[thread_idx]; VkQueue queue = renderer.vk.queues.transfer_queue; @@ -429,7 +446,7 @@ static void vImageUpload(rTextureBuffer *buffer, u8 *data, u32 thread_idx) u32 height = buffer->height; u32 channels = buffer->channels; rRenderBuffer staging_buffer = { - .type = RENDER_BUFFER_TYPE_STAGING, + .type = rRBT_STAGING, .size = width * height * channels, }; @@ -437,13 +454,14 @@ static void vImageUpload(rTextureBuffer *buffer, u8 *data, u32 thread_idx) success = vImmSubmitBegin(device, fence, cmd); - if (success) - Assert(rBufferCreate(&staging_buffer), "vImageUpload failure: error creating buffer"); + // TODO: FIX + //if (success) + //Assert(rBufferCreate(&staging_buffer), "vImageUpload failure: error creating buffer"); if (success) { rawptr mapped_buf = NULL; - vmaMapMemory(renderer.vk.alloc, staging_buffer.alloc, &mapped_buf); + vmaMapMemory(v_Renderer.handles.vma_alloc, staging_buffer.alloc, &mapped_buf); MemCpy(mapped_buf, data, width * height * channels); VkBufferImageCopy buffer_copy = { @@ -462,11 +480,12 @@ static void vImageUpload(rTextureBuffer *buffer, u8 *data, u32 thread_idx) vkCmdCopyBufferToImage(cmd, staging_buffer.buffer, image->img, image->curr_layout, 1, &buffer_copy); - vmaUnmapMemory(renderer.vk.alloc, staging_buffer.alloc); - vmaDestroyBuffer(renderer.vk.alloc, staging_buffer.buffer, staging_buffer.alloc); + vmaUnmapMemory(v_Renderer.handles.vma_alloc, staging_buffer.alloc); + vmaDestroyBuffer(v_Renderer.handles.vma_alloc, staging_buffer.buffer, staging_buffer.alloc); success = vImmSubmitFinish(device, fence, cmd, queue); } + */ } // ::Vulkan::Images::Functions::End:: @@ -477,7 +496,7 @@ static void vImageUpload(rTextureBuffer *buffer, u8 *data, u32 thread_idx) static void vDescHandlePush(vDescType type, rDescHandle handle) { - vDescBindings *bindings = renderer.vk.pipe.bindings + type; + vDescBindings *bindings = v_Renderer.desc_bindings + type; Assert(bindings->free_count < DESC_MAX_BINDINGS-1, "vDescHandlePush failure: free_count equal to DESC_MAX_BINDINGS-1"); @@ -487,7 +506,7 @@ static void vDescHandlePush(vDescType type, rDescHandle handle) static rDescHandle vDescHandlePop(vDescType type) { - vDescBindings *bindings = renderer.vk.pipe.bindings + type; + vDescBindings *bindings = v_Renderer.desc_bindings + type; Assert(bindings->free_count > 0, "vDescHandlePop failure: free_count is 0"); @@ -499,7 +518,7 @@ static vAssetInfo *vDescHandleSearch(vDescType type, u64 asset_id) { vAssetInfo *asset_info = NULL; - HashTable *table = &renderer.vk.pipe.bindings[type].lookup_table; + HashTable *table = &v_Renderer.desc_bindings[type].lookup_table; KeyValuePair *kv_pair = HashTableSearchU64(table, asset_id); if (kv_pair != NULL) @@ -518,13 +537,13 @@ static void DescriptorTableInsert(vDescType type, u64 asset_id, rDescHandle hand asset_info->type = type; asset_info->asset_id = asset_id; - HashTable *table = &renderer.vk.pipe.bindings[type].lookup_table; + HashTable *table = &v_Renderer.desc_bindings[type].lookup_table; HashTablePushU64Rawptr(table, asset_id, asset_info); } static void vDescHandleDelete(vDescType type, u64 asset_id) { - HashTable *table = &renderer.vk.pipe.bindings[type].lookup_table; + HashTable *table = &v_Renderer.desc_bindings[type].lookup_table; HashTableDeleteU64(table, asset_id); } @@ -534,6 +553,45 @@ static void vDescHandleDelete(vDescType type, u64 asset_id) // ::Vulkan::Init::Functions::Start:: +static b32 vInitInstance() +{ + b32 success = true; + + Assert(vGlobalFunctionsInit(), "Unable to load vulkan functions"); + + VkResult result = vkCreateInstance(&inst_info, NULL, &v_Renderer.handles.inst); + if (result != VK_SUCCESS) + { + success = false; + Printfln("vkCreateInstance failure: %s", vVkResultStr(result)); + } + + return success; +} + +static void vEnableDebug() +{ + if (vValidationSupported()) + { + Assert(vkCreateDebugUtilsMessengerEXT(v_Renderer.handles.inst, &debug_msg_info, NULL, &v_Renderer.handles.debug) == VK_SUCCESS, + "Unable to initialize debug messenger"); + } + else + { + Printfln("Validation layers not supported, continuing without."); + } +} + +static void vInitArenas() +{ + v_Renderer.mem.perm_arena = ArenaCreateDebug(MB(16), __LINE__); + + for (u32 i = 0; i < FRAME_OVERLAP; i++) + { + v_Renderer.mem.frame_arenas[i] = ArenaCreateDebug(MB(8), i); + } +} + static b32 vVmaAllocatorInit() { VmaVulkanFunctions vk_functions = { @@ -541,11 +599,11 @@ static b32 vVmaAllocatorInit() .vkGetDeviceProcAddr = vkGetDeviceProcAddr, }; vma_create_info.pVulkanFunctions = &vk_functions; - vma_create_info.physicalDevice = renderer.vk.phys_device; - vma_create_info.device = renderer.vk.device; - vma_create_info.instance = renderer.vk.inst; + vma_create_info.physicalDevice = v_Renderer.handles.phys_device; + vma_create_info.device = v_Renderer.handles.device; + vma_create_info.instance = v_Renderer.handles.inst; - VkResult result = vmaCreateAllocator(&vma_create_info, &renderer.vk.alloc); + VkResult result = vmaCreateAllocator(&vma_create_info, &v_Renderer.handles.vma_alloc); if (result != VK_SUCCESS) { Printf("vmaCreateAllocator failure: %d", result); @@ -564,10 +622,11 @@ static b32 vQueueCheckSurfaceSupport(i32 index, VkPhysicalDevice device, VkSurfa static vDeviceQueues vQueueCheckSupport(VkPhysicalDevice device, VkSurfaceKHR surface) { vDeviceQueues queues = { .graphics = -1, .transfer = -1 }; + Arena *arena = vFrameArena(); u32 queue_count; vkGetPhysicalDeviceQueueFamilyProperties(device, &queue_count, NULL); - VkQueueFamilyProperties *families = MakeArray(renderer.arena, VkQueueFamilyProperties, queue_count); + VkQueueFamilyProperties *families = MakeArray(arena, VkQueueFamilyProperties, queue_count); vkGetPhysicalDeviceQueueFamilyProperties(device, &queue_count, families); if (queue_count == 1 && @@ -625,6 +684,8 @@ static vDeviceQueues vQueueCheckSupport(VkPhysicalDevice device, VkSurfaceKHR su static b32 vDeviceCheckPropertiesSupport(VkPhysicalDevice device, VkSurfaceKHR surface, b32 *discrete) { b32 success = false; + Arena *arena = vFrameArena(); + VkPhysicalDeviceProperties properties = {0}; vkGetPhysicalDeviceProperties(device, &properties); @@ -632,7 +693,7 @@ static b32 vDeviceCheckPropertiesSupport(VkPhysicalDevice device, VkSurfaceKHR s { u32 ext_count; vkEnumerateDeviceExtensionProperties(device, NULL, &ext_count, NULL); - VkExtensionProperties *ext_properties = ArenaAlloc(renderer.arena, sizeof(VkExtensionProperties) * ext_count); + VkExtensionProperties *ext_properties = ArenaAlloc(arena, sizeof(VkExtensionProperties) * ext_count); vkEnumerateDeviceExtensionProperties(device, NULL, &ext_count, ext_properties); i32 matched = 0; @@ -692,17 +753,18 @@ static b32 vDeviceCheckFeatureSupport(VkPhysicalDevice device) static b32 vDeviceInit() { - VkInstance inst = renderer.vk.inst; - VkSurfaceKHR surface = renderer.vk.surface; + VkInstance inst = v_Renderer.handles.inst; + VkSurfaceKHR surface = v_Renderer.handles.surface; + Arena *arena = vFrameArena(); u32 device_count; vkEnumeratePhysicalDevices(inst, &device_count, NULL); - VkPhysicalDevice *devices = ArenaAlloc(renderer.arena, sizeof(VkPhysicalDevice) * device_count); + VkPhysicalDevice *devices = ArenaAlloc(arena, sizeof(VkPhysicalDevice) * device_count); vkEnumeratePhysicalDevices(inst, &device_count, devices); b32 discrete_device = false; - vDeviceQueues *queues = &renderer.vk.queues; - VkPhysicalDevice *phys_device = &renderer.vk.phys_device; + vDeviceQueues queues = {0}; + VkPhysicalDevice phys_device = NULL; for (u32 i = 0; i < device_count; i++) { vDeviceQueues current_queues = vQueueCheckSupport(devices[i], surface); b32 discrete = false; @@ -717,10 +779,10 @@ static b32 vDeviceInit() continue; discrete_device = discrete; - *queues = current_queues; - *phys_device = devices[i]; + queues = current_queues; + phys_device = devices[i]; - if (discrete_device && queues->graphics != queues->transfer) + if (discrete_device && queues.graphics != queues.transfer) break; } @@ -733,19 +795,19 @@ static b32 vDeviceInit() u32 transfer_queue_index = 0; queue_info[0].sType = STYPE(DEVICE_QUEUE_CREATE_INFO); - queue_info[0].queueFamilyIndex = queues->graphics; + queue_info[0].queueFamilyIndex = queues.graphics; queue_info[0].queueCount = 1; queue_info[0].pQueuePriorities = &priority; queue_info[0].flags = 0; - if (!queues->single_queue) { + if (!queues.single_queue) { queue_info[1].sType = STYPE(DEVICE_QUEUE_CREATE_INFO); - queue_info[1].queueFamilyIndex = queues->transfer; + queue_info[1].queueFamilyIndex = queues.transfer; queue_info[1].queueCount = 1; queue_info[1].pQueuePriorities = &priority; queue_info[1].flags = 0; - if (queues->transfer == queues->graphics) + if (queues.transfer == queues.graphics) transfer_queue_index = 1; count++; @@ -754,7 +816,7 @@ static b32 vDeviceInit() device_info.queueCreateInfoCount = count; device_info.pQueueCreateInfos = &queue_info[0]; - VkResult result = vkCreateDevice(renderer.vk.phys_device, &device_info, NULL, &renderer.vk.device); + VkResult result = vkCreateDevice(v_Renderer.handles.phys_device, &device_info, NULL, &v_Renderer.handles.device); if (result != VK_SUCCESS) { Printf("vkCreateDevice failure: %d", result); } @@ -762,8 +824,26 @@ static b32 vDeviceInit() { Assert(vDeviceFunctionsInit(), "Failed to initialize device functions"); - vkGetDeviceQueue(renderer.vk.device, queues->graphics, 0, &queues->graphics_queue); - vkGetDeviceQueue(renderer.vk.device, queues->transfer, transfer_queue_index, &queues->transfer_queue); + vkGetDeviceQueue( + v_Renderer.handles.device, + queues.graphics, + 0, + &queues.graphics_queue); + + vkGetDeviceQueue( + v_Renderer.handles.device, + queues.transfer, + transfer_queue_index, + &queues.transfer_queue); + + v_Renderer.handles.phys_device = phys_device; + + v_Renderer.handles.gfx_queue = queues.graphics_queue; + v_Renderer.handles.tfer_queue = queues.transfer_queue; + + v_Renderer.state.vk.gfx_queue_idx = queues.graphics; + v_Renderer.state.vk.tfer_queue_idx = queues.transfer; + success = true; } } @@ -786,7 +866,7 @@ static b32 vGlobalFunctionsInit() static b32 vInstanceFunctionsInit() { - VkInstance instance = renderer.vk.inst; + VkInstance instance = v_Renderer.handles.inst; #ifdef __linux__ { @@ -828,7 +908,7 @@ static b32 vInstanceFunctionsInit() } static b32 vDeviceFunctionsInit() { - VkDevice device = renderer.vk.device; + VkDevice device = v_Renderer.handles.device; INIT_DEV_FN(vkCreateSwapchainKHR); INIT_DEV_FN(vkCreateImage); @@ -903,7 +983,7 @@ static b32 vSurfaceInit() .window = window->window }; - VkResult result = vkCreateXcbSurfaceKHR(renderer.vk.inst, &surface_info, NULL, &renderer.vk.surface); + VkResult result = vkCreateXcbSurfaceKHR(v_Renderer.handles.inst, &surface_info, NULL, &v_Renderer.handles.surface); if (result != VK_SUCCESS) { Printf("Unable to create surface: %d", result); } @@ -922,7 +1002,7 @@ static b32 vSurfaceInit() .hwnd = window->handle, }; - VkResult result = vkCreateWin32SurfaceKHR(renderer.vk.inst, &surface_info, NULL, &renderer.vk.surface); + VkResult result = vkCreateWin32SurfaceKHR(v_Renderer.handles.inst, &surface_info, NULL, &v_Renderer.handles.surface); if (result != VK_SUCCESS) { Printfln("Unable to create surface: %s", vVkResultStr(result)); @@ -935,7 +1015,7 @@ static b32 vSurfaceInit() static b32 vLibraryLoad() { - pLibrary *lib = &renderer.vk.lib; + pLibrary *lib = &v_Renderer.handles.lib; b32 lib_found; pFunction fn; for (i32 i = 0; i < Len(vulkan_libs); i++) { @@ -953,47 +1033,39 @@ static b32 vLibraryLoad() static b32 vFrameStructuresInit() { b32 success = true; - vFrameStructures *data = &renderer.vk.frame; - u32 img_count = renderer.vk.sc.img_count; + u32 img_count = v_Renderer.images.sc.length; - pool_create_info.queueFamilyIndex = renderer.vk.queues.graphics; - - renderer.vk.frame.pools = MakeArray(renderer.perm_arena, VkCommandPool, img_count); - renderer.vk.frame.buffers = MakeArray(renderer.perm_arena, VkCommandBuffer, img_count); - renderer.vk.frame.swapchain_sems = MakeArray(renderer.perm_arena, VkSemaphore, img_count); - renderer.vk.frame.render_sems = MakeArray(renderer.perm_arena, VkSemaphore, img_count); - renderer.vk.frame.render_fences = MakeArray(renderer.perm_arena, VkFence, img_count); - renderer.vk.frame.buffer_destroy_queues = MakeArray(renderer.perm_arena, rRenderBuffer *, FRAME_OVERLAP); - renderer.vk.frame.buffer_counts = MakeArray(renderer.perm_arena, u32, FRAME_OVERLAP); + pool_create_info.queueFamilyIndex = v_Renderer.state.vk.gfx_queue_idx; for (u32 i = 0; i < FRAME_OVERLAP; i++) { VkResult result; - VkDevice device = renderer.vk.device; + VkDevice device = v_Renderer.handles.device; + vFrameHandles *handles = &v_Renderer.frame_handles[i]; - result = vkCreateCommandPool(device, &pool_create_info, NULL, &data->pools[i]); + result = vkCreateCommandPool(device, &pool_create_info, NULL, &handles->pool); if (result != VK_SUCCESS) success = false; - cmd_buf_info.commandPool = data->pools[i]; + cmd_buf_info.commandPool = handles->pool; - result = vkAllocateCommandBuffers(device, &cmd_buf_info, &data->buffers[i]); + result = vkAllocateCommandBuffers(device, &cmd_buf_info, &handles->buffer); if (result != VK_SUCCESS) success = false; - result = vkCreateFence(device, &fence_create_info, NULL, &data->render_fences[i]); + result = vkCreateFence(device, &fence_create_info, NULL, &handles->r_fence); if (result != VK_SUCCESS) success = false; - result = vkCreateSemaphore(device, &semaphore_create_info, NULL, &data->render_sems[i]); + result = vkCreateSemaphore(device, &semaphore_create_info, NULL, &handles->r_sem); if (result != VK_SUCCESS) success = false; - result = vkCreateSemaphore(device, &semaphore_create_info, NULL, &data->swapchain_sems[i]); + result = vkCreateSemaphore(device, &semaphore_create_info, NULL, &handles->sc_sem); if (result != VK_SUCCESS) success = false; - renderer.vk.frame.buffer_destroy_queues[i] = ArenaAlloc(renderer.perm_arena, sizeof(rRenderBuffer) * 64); + //renderer.vk.frame.buffer_destroy_queues[i] = ArenaAlloc(v_Renderer.mem.perm_arena, sizeof(rRenderBuffer) * 64); } return success; @@ -1003,32 +1075,32 @@ static b32 vImmediateStructuresInit() { b32 success = true; VkResult result; - VkDevice device = renderer.vk.device; - vImmediateStructures *imm = &renderer.vk.imm; - pool_create_info.queueFamilyIndex = renderer.vk.queues.transfer; + VkDevice device = v_Renderer.handles.device; + vImmHandlesArray *imm = &v_Renderer.imm_handles; + pool_create_info.queueFamilyIndex = v_Renderer.state.vk.tfer_queue_idx; - if (renderer.vk_conf.avail_threads >= 4 && !renderer.vk.queues.single_queue) - renderer.vk_conf.avail_threads = 1; + if (v_Renderer.async.count >= 4 && !v_Renderer.state.vk.single_queue) + v_Renderer.async.count = 1; else - renderer.vk_conf.avail_threads = 0; + v_Renderer.async.count = 0; - imm->pools = MakeArray(renderer.perm_arena, VkCommandPool, renderer.vk_conf.avail_threads); - imm->cmds = MakeArray(renderer.perm_arena, VkCommandBuffer, renderer.vk_conf.avail_threads); - imm->fences = MakeArray(renderer.perm_arena, VkFence, renderer.vk_conf.avail_threads); + + imm->data = MakeArray(v_Renderer.mem.perm_arena, vImmHandles, v_Renderer.async.count); + imm->length = v_Renderer.async.count; - for (u32 i = 0; i < renderer.vk_conf.avail_threads && success; i++) + for (u32 i = 0; i < v_Renderer.async.count && success; i++) { - result = vkCreateCommandPool(device, &pool_create_info, NULL, &imm->pools[i]); + result = vkCreateCommandPool(device, &pool_create_info, NULL, &imm->data[i].pool); if (result != VK_SUCCESS) success = false; - cmd_buf_info.commandPool = imm->pools[i]; + cmd_buf_info.commandPool = imm->data[i].pool; - result = vkAllocateCommandBuffers(device, &cmd_buf_info, &imm->cmds[i]); + result = vkAllocateCommandBuffers(device, &cmd_buf_info, &imm->data[i].buffer); if (result != VK_SUCCESS) success = false; - result = vkCreateFence(device, &fence_create_info, NULL, &imm->fences[i]); + result = vkCreateFence(device, &fence_create_info, NULL, &imm->data[i].fence); if (result != VK_SUCCESS) success = false; } @@ -1038,22 +1110,25 @@ static b32 vImmediateStructuresInit() static void vUploadQueuesInit() { - for (u32 i = 0; i < DESC_TYPE_MAX; i++) + /* + for (u32 i = 0; i < V_DESC_TYPE_MAX; i++) { - renderer.upload_queues[i].queued_ptrs = MakeArray(renderer.perm_arena, rawptr, BUFFER_QUEUE_LEN); - renderer.upload_queues[i].data = MakeArray(renderer.perm_arena, rawptr, BUFFER_QUEUE_LEN); + renderer.upload_queues[i].queued_ptrs = MakeArray(v_Renderer.mem.perm_arena, rawptr, BUFFER_QUEUE_LEN); + renderer.upload_queues[i].data = MakeArray(v_Renderer.mem.perm_arena, rawptr, BUFFER_QUEUE_LEN); } + */ } static b32 vSwapchainInit() { b32 success = true; - VkPhysicalDevice phys_device = renderer.vk.phys_device; - VkDevice device = renderer.vk.device; - VkSurfaceKHR surface = renderer.vk.surface; - VkPresentModeKHR present_mode = renderer.vk.sc.present_mode; - VkFormat format = renderer.vk.sc.format; - VkColorSpaceKHR color_space = renderer.vk.sc.color_space; + VkPhysicalDevice phys_device = v_Renderer.handles.phys_device; + VkDevice device = v_Renderer.handles.device; + VkSurfaceKHR surface = v_Renderer.handles.surface; + VkPresentModeKHR present_mode = v_Renderer.state.swapchain.present_mode; + VkFormat format = v_Renderer.state.swapchain.format; + VkColorSpaceKHR color_space = v_Renderer.state.swapchain.color_space; + Arena *arena = vFrameArena(); VkSurfaceCapabilitiesKHR capabilities; vkGetPhysicalDeviceSurfaceCapabilitiesKHR(phys_device, surface, &capabilities); @@ -1061,8 +1136,8 @@ static b32 vSwapchainInit() // Maybe reconsider handling window sizing within here and only handle it from events themselves // causes issues when the window size is out of sync with the current swapchain VkExtent2D extent; - u32 width = renderer.vk.sc.extent.width; - u32 height = renderer.vk.sc.extent.height; + u32 width = v_Renderer.state.swapchain.extent.width; + u32 height = v_Renderer.state.swapchain.extent.height; extent.width = Clampu32((u32)width, capabilities.minImageExtent.width, capabilities.maxImageExtent.width); extent.height = Clampu32((u32)height, capabilities.minImageExtent.height, capabilities.maxImageExtent.height); @@ -1071,7 +1146,7 @@ static b32 vSwapchainInit() { u32 format_count; vkGetPhysicalDeviceSurfaceFormatsKHR(phys_device, surface, &format_count, NULL); - VkSurfaceFormatKHR *formats = ArenaAlloc(renderer.arena, sizeof(VkSurfaceFormatKHR) * format_count); + VkSurfaceFormatKHR *formats = ArenaAlloc(arena, sizeof(VkSurfaceFormatKHR) * format_count); vkGetPhysicalDeviceSurfaceFormatsKHR(phys_device, surface, &format_count, formats); format = formats[0].format; @@ -1079,7 +1154,7 @@ static b32 vSwapchainInit() u32 present_count; vkGetPhysicalDeviceSurfacePresentModesKHR(phys_device, surface, &present_count, NULL); - VkPresentModeKHR *present_modes = ArenaAlloc(renderer.arena, sizeof(VkSurfaceFormatKHR) * present_count); + VkPresentModeKHR *present_modes = ArenaAlloc(arena, sizeof(VkSurfaceFormatKHR) * present_count); vkGetPhysicalDeviceSurfacePresentModesKHR(phys_device, surface, &present_count, present_modes); for (u32 i = 0; i < present_count; i++) @@ -1104,35 +1179,35 @@ static b32 vSwapchainInit() swapchain_create_info.presentMode = present_mode; VkResult result; - result = vkCreateSwapchainKHR(device, &swapchain_create_info, NULL, &renderer.vk.swapchain); + result = vkCreateSwapchainKHR(device, &swapchain_create_info, NULL, &v_Renderer.handles.swapchain); if (result != VK_SUCCESS) success = false; u32 image_count; - vkGetSwapchainImagesKHR(device, renderer.vk.swapchain, &image_count, NULL); - VkImage *sc_images = ArenaAlloc(renderer.perm_arena, sizeof(VkImage) * image_count); - VkImageView *sc_views = ArenaAlloc(renderer.perm_arena, sizeof(VkImageView) * image_count); - vkGetSwapchainImagesKHR(device, renderer.vk.swapchain, &image_count, sc_images); + vkGetSwapchainImagesKHR(device, v_Renderer.handles.swapchain, &image_count, NULL); + VkImage *sc_images = ArenaAlloc(v_Renderer.mem.perm_arena, sizeof(VkImage) * image_count); + VkImageView *sc_views = ArenaAlloc(v_Renderer.mem.perm_arena, sizeof(VkImageView) * image_count); + vkGetSwapchainImagesKHR(device, v_Renderer.handles.swapchain, &image_count, sc_images); for (u32 i = 0; i < image_count; i++) { + v_Renderer.images.sc.data[i].image.image = sc_images[i]; sc_image_view_create_info.image = sc_images[i]; sc_image_view_create_info.format = format; - result = vkCreateImageView(device, &sc_image_view_create_info, NULL, &sc_views[i]); + result = vkCreateImageView(device, &sc_image_view_create_info, NULL, &v_Renderer.images.sc.data[i].view); if (result != VK_SUCCESS) success = false; } - renderer.vk.sc.format = format; - renderer.vk.sc.color_space = color_space; - renderer.vk.sc.present_mode = present_mode; - renderer.vk.sc.imgs = sc_images; - renderer.vk.sc.views = sc_views; - renderer.vk.sc.img_count = image_count; - renderer.vk.sc.extent.width = extent.width; - renderer.vk.sc.extent.height = extent.height; - renderer.vk.sc.extent.depth = 1; + v_Renderer.images.sc.length = image_count; + + v_Renderer.state.swapchain.format = format; + v_Renderer.state.swapchain.color_space = color_space; + v_Renderer.state.swapchain.present_mode = present_mode; + v_Renderer.state.swapchain.extent.width = extent.width; + v_Renderer.state.swapchain.extent.height = extent.height; + v_Renderer.state.swapchain.extent.depth = 1; return success; } @@ -1143,8 +1218,8 @@ static b32 vDrawImagesInit() VkResult result; VkFormat image_format = vImageFormatGet(); - VkExtent3D extent = renderer.vk.sc.extent; - VkDevice device = renderer.vk.device; + VkExtent3D extent = v_Renderer.state.swapchain.extent; + VkDevice device = v_Renderer.handles.device; VmaAllocationCreateInfo alloc_create_info = { .usage = VMA_MEMORY_USAGE_GPU_ONLY, @@ -1155,46 +1230,46 @@ static b32 vDrawImagesInit() draw_image_create_info.format = image_format; draw_image_create_info.extent = extent; - result = vmaCreateImage(renderer.vk.alloc, &draw_image_create_info, - &alloc_create_info, &renderer.vk.sc.draw_img.img, &renderer.vk.sc.draw_img.alloc, NULL); + result = vmaCreateImage(v_Renderer.handles.vma_alloc, &draw_image_create_info, + &alloc_create_info, &v_Renderer.images.draw.image.image, &v_Renderer.images.draw.image.alloc, NULL); if (result != VK_SUCCESS) success = false; // Draw vImage View - draw_image_view_create_info.image = renderer.vk.sc.draw_img.img; + draw_image_view_create_info.image = v_Renderer.images.draw.image.image; draw_image_view_create_info.format = image_format; - result = vkCreateImageView(device, &draw_image_view_create_info, NULL, &renderer.vk.sc.draw_img.view); + result = vkCreateImageView(device, &draw_image_view_create_info, NULL, &v_Renderer.images.draw.view); if (result != VK_SUCCESS) success = false; // Depth vImage depth_image_create_info.extent = extent; - result = vmaCreateImage(renderer.vk.alloc, &depth_image_create_info, - &alloc_create_info, &renderer.vk.sc.depth_img.img, &renderer.vk.sc.depth_img.alloc, NULL); + result = vmaCreateImage(v_Renderer.handles.vma_alloc, &depth_image_create_info, + &alloc_create_info, &v_Renderer.images.depth.image.image, &v_Renderer.images.depth.image.alloc, NULL); if (result != VK_SUCCESS) success = false; // Depth vImage View - depth_image_view_create_info.image = renderer.vk.sc.depth_img.img; - result = vkCreateImageView(device, &depth_image_view_create_info, NULL, &renderer.vk.sc.depth_img.view); + depth_image_view_create_info.image = v_Renderer.images.depth.image.image; + result = vkCreateImageView(device, &depth_image_view_create_info, NULL, &v_Renderer.images.depth.view); if (result != VK_SUCCESS) success = false; // Setting values - renderer.vk.sc.extent = extent; - renderer.vk.sc.depth_img.fmt = depth_image_create_info.format; - renderer.vk.sc.depth_img.curr_layout = VK_IMAGE_LAYOUT_UNDEFINED; - renderer.vk.sc.draw_img.fmt = draw_image_create_info.format; - renderer.vk.sc.draw_img.curr_layout = VK_IMAGE_LAYOUT_UNDEFINED; + v_Renderer.state.swapchain.extent = extent; + v_Renderer.images.depth.image.format = depth_image_create_info.format; + v_Renderer.images.depth.image.layout = VK_IMAGE_LAYOUT_UNDEFINED; + v_Renderer.images.draw.image.format = draw_image_create_info.format; + v_Renderer.images.draw.image.layout = VK_IMAGE_LAYOUT_UNDEFINED; return success; } static VkFormat vImageFormatGet() { - VkPhysicalDevice phys_device = renderer.vk.phys_device; + VkPhysicalDevice phys_device = v_Renderer.handles.phys_device; VkImageType image_type = VK_IMAGE_TYPE_2D; VkImageTiling tiling = VK_IMAGE_TILING_OPTIMAL; VkImageUsageFlags usage_flags = VK_IMAGE_USAGE_TRANSFER_SRC_BIT | @@ -1228,45 +1303,43 @@ static b32 vDescriptorsInit() { b32 success = true; - renderer.vk.pipe.bindings = ArenaAlloc(renderer.perm_arena, sizeof(vDescBindings) * DESC_TYPE_MAX); - - VkDevice device = renderer.vk.device; + VkDevice device = v_Renderer.handles.device; VkResult result; - vDescBindings *bindings = renderer.vk.pipe.bindings; + vDescBindings *bindings = v_Renderer.desc_bindings; - result = vkCreateDescriptorPool(device, &desc_pool_info, NULL, &renderer.vk.pipe.pool); + result = vkCreateDescriptorPool(device, &desc_pool_info, NULL, &v_Renderer.handles.desc_pool); if (result != VK_SUCCESS) success = false; - result = vkCreateDescriptorSetLayout(device, &shared_layout_create_info, NULL, &renderer.vk.pipe.layouts[DESC_TYPE_SHARED]); + result = vkCreateDescriptorSetLayout(device, &shared_layout_create_info, NULL, &v_Renderer.handles.desc_layouts[V_DESC_TYPE_SHARED]); if (result != VK_SUCCESS) success = false; - for (u32 i = DESC_TYPE_SAMPLER; i < DESC_TYPE_MAX; i++) + for (u32 i = V_DESC_TYPE_SAMPLER; i < V_DESC_TYPE_MAX; i++) { bindless_layout_binding.descriptorType = desc_type_map[i]; - result = vkCreateDescriptorSetLayout(device, &bindless_layout_create_info, NULL, &renderer.vk.pipe.layouts[i]); + result = vkCreateDescriptorSetLayout(device, &bindless_layout_create_info, NULL, &v_Renderer.handles.desc_layouts[i]); if (result != VK_SUCCESS) success = false; } - set_allocate_info.descriptorPool = renderer.vk.pipe.pool; - set_allocate_info.pSetLayouts = renderer.vk.pipe.layouts; + set_allocate_info.descriptorPool = v_Renderer.handles.desc_pool; + set_allocate_info.pSetLayouts = v_Renderer.handles.desc_layouts; - result = vkAllocateDescriptorSets(device, &set_allocate_info, renderer.vk.pipe.sets); + result = vkAllocateDescriptorSets(device, &set_allocate_info, v_Renderer.handles.desc_sets); if (result != VK_SUCCESS) success = false; - pipeline_layout_create_info.setLayoutCount = DESC_TYPE_MAX; - pipeline_layout_create_info.pSetLayouts = renderer.vk.pipe.layouts; + pipeline_layout_create_info.setLayoutCount = V_DESC_TYPE_MAX; + pipeline_layout_create_info.pSetLayouts = v_Renderer.handles.desc_layouts; - result = vkCreatePipelineLayout(device, &pipeline_layout_create_info, NULL, &renderer.vk.pipe.pipeline_layout); + result = vkCreatePipelineLayout(device, &pipeline_layout_create_info, NULL, &v_Renderer.handles.pipeline_layout); if (result != VK_SUCCESS) success = false; - for (u32 i = 0; i < DESC_TYPE_MAX; i++) + for (u32 i = 0; i < V_DESC_TYPE_MAX; i++) { - bindings[i].free = ArenaAlloc(renderer.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); @@ -1287,7 +1360,7 @@ static b32 vPipelinesInit() { b32 success = true; VkResult result; - VkDevice device = renderer.vk.device; + VkDevice device = v_Renderer.handles.device; Asset quad_vert_shader = apLoadShader(QUAD_VERT_SPIRV_SHADER); Asset quad_frag_shader = apLoadShader(QUAD_FRAG_SPIRV_SHADER); @@ -1299,8 +1372,8 @@ static b32 vPipelinesInit() VkPipelineRenderingCreateInfo pipeline_render_info = { .sType = STYPE(PIPELINE_RENDERING_CREATE_INFO), .colorAttachmentCount = 1, - .pColorAttachmentFormats = &renderer.vk.sc.draw_img.fmt, - .depthAttachmentFormat = renderer.vk.sc.depth_img.fmt, + .pColorAttachmentFormats = &v_Renderer.images.draw.image.format, + .depthAttachmentFormat = v_Renderer.images.depth.image.format, }; VkPipelineShaderStageCreateInfo cube_shader_stages[] = { @@ -1320,10 +1393,10 @@ static b32 vPipelinesInit() cube_create_info.pStages = cube_shader_stages; cube_create_info.stageCount = Len(cube_shader_stages); - cube_create_info.layout = renderer.vk.pipe.pipeline_layout; + cube_create_info.layout = v_Renderer.handles.pipeline_layout; cube_create_info.pNext = &pipeline_render_info; - result = vkCreateGraphicsPipelines(device, 0, 1, &cube_create_info, NULL, &renderer.vk.pipe.pipelines[PIPELINE_CUBE]); + result = vkCreateGraphicsPipelines(device, 0, 1, &cube_create_info, NULL, &v_Renderer.handles.pipelines[R_PIPELINE_CUBE]); if (result != VK_SUCCESS) { Printf("vkCreateGraphicsPipelines failure: %s", vVkResultStr(result)); @@ -1360,10 +1433,10 @@ static b32 vPipelinesInit() gui_create_info.pStages = gui_shader_stages; gui_create_info.stageCount = Len(gui_shader_stages); - gui_create_info.layout = renderer.vk.pipe.pipeline_layout; + gui_create_info.layout = v_Renderer.handles.pipeline_layout; gui_create_info.pNext = &pipeline_render_info; - result = vkCreateGraphicsPipelines(device, 0, 1, &gui_create_info, NULL, &renderer.vk.pipe.pipelines[PIPELINE_GUI]); + result = vkCreateGraphicsPipelines(device, 0, 1, &gui_create_info, NULL, &v_Renderer.handles.pipelines[R_PIPELINE_GUI]); if (result != VK_SUCCESS) { Printfln("vkCreateGraphicsPipelines failure: %s", vVkResultStr(result)); @@ -1390,7 +1463,7 @@ static b32 vShaderModuleInit(u8 *bytes, u32 len, VkShaderModule *module) .pCode = (u32 *)bytes, }; - result = vkCreateShaderModule(renderer.vk.device, &module_info, NULL, module); + result = vkCreateShaderModule(v_Renderer.handles.device, &module_info, NULL, module); if (result != VK_SUCCESS) { Printf("vkCreateShaderModule failure: %s", vVkResultStr(result)); @@ -1404,16 +1477,16 @@ static b32 vShaderModuleInit(u8 *bytes, u32 len, VkShaderModule *module) static void vLoaderStartThreads() { - if (renderer.vk_conf.avail_threads == 0) + if (v_Renderer.async.count == 0) return; - u32 count = renderer.vk_conf.avail_threads; - pthread_t *threads = ArenaAlloc(renderer.perm_arena, sizeof(pthread_t) * count); + u32 count = v_Renderer.async.count; + pthread_t *threads = ArenaAlloc(v_Renderer.mem.perm_arena, sizeof(pthread_t) * count); for (u32 i = 0; i < count; i++) { - vk_thread_indices[i] = i; - pthread_create(&threads[i], NULL, vLoaderStart, &vk_thread_indices[i]); + v_Renderer.async.thread_idx[i] = i; + pthread_create(&threads[i], NULL, vLoaderStart, &v_Renderer.async.thread_idx[i]); } } @@ -1431,10 +1504,11 @@ static void vLoaderStartThreads() static u32 vLoaderProcessBuffers(u32 thread_index) { - JobQueue *job_queue = &renderer.upload_queues[DESC_TYPE_BUFFER].job_queue; - TicketMut *ticket_mut = &renderer.upload_queues[DESC_TYPE_BUFFER].ticket_mut; - rRenderBuffer **render_buffers = renderer.upload_queues[DESC_TYPE_BUFFER].queued_buffers; - rawptr *buffer_data = renderer.upload_queues[DESC_TYPE_BUFFER].data; + /* + JobQueue *job_queue = &renderer.upload_queues[V_DESC_TYPE_BUFFER].job_queue; + TicketMut *ticket_mut = &renderer.upload_queues[V_DESC_TYPE_BUFFER].ticket_mut; + rRenderBuffer **render_buffers = renderer.upload_queues[V_DESC_TYPE_BUFFER].queued_buffers; + rawptr *buffer_data = renderer.upload_queues[V_DESC_TYPE_BUFFER].data; u32 buffer_count = JobQueueGetCount(job_queue); u32 count = 0; @@ -1455,8 +1529,9 @@ static u32 vLoaderProcessBuffers(u32 thread_index) TicketMutUnlock(ticket_mut); - for (u32 i = 0; i < count; i++) - Assert(rBufferCreate(buffers[i]), "vLoaderProcessBuffers failure: rBufferCreate failed"); + // TODO: FIX + //for (u32 i = 0; i < count; i++) + //Assert(rBufferCreate(buffers[i]), "vLoaderProcessBuffers failure: rBufferCreate failed"); Assert(rBufferUpload(buffers, data, count, thread_index), "vLoaderProcessBuffers failure: rBufferUpload failed"); @@ -1464,14 +1539,19 @@ static u32 vLoaderProcessBuffers(u32 thread_index) } return count; + + */ + + return 0; } static u32 vLoaderProcessSamplers(u32 thread_index) { - JobQueue *job_queue = &renderer.upload_queues[DESC_TYPE_SAMPLER].job_queue; - TicketMut *ticket_mut = &renderer.upload_queues[DESC_TYPE_SAMPLER].ticket_mut; - rTextureBuffer **texture_buffers = renderer.upload_queues[DESC_TYPE_SAMPLER].queued_textures; - rawptr *texture_data = renderer.upload_queues[DESC_TYPE_SAMPLER].data; + /* + JobQueue *job_queue = &renderer.upload_queues[V_DESC_TYPE_SAMPLER].job_queue; + TicketMut *ticket_mut = &renderer.upload_queues[V_DESC_TYPE_SAMPLER].ticket_mut; + rTextureBuffer **texture_buffers = renderer.upload_queues[V_DESC_TYPE_SAMPLER].queued_textures; + rawptr *texture_data = renderer.upload_queues[V_DESC_TYPE_SAMPLER].data; u32 buffer_count = JobQueueGetCount(job_queue); u32 count = 0; @@ -1507,6 +1587,10 @@ static u32 vLoaderProcessSamplers(u32 thread_index) } return count; + + */ + + return 0; } @@ -1521,20 +1605,21 @@ void *vLoaderStart(void *i) u32 processed_count = 0; u32 iter_count = 0; + /* for (;;) { - for (u32 i = 0; i < DESC_TYPE_MAX; i++) + for (u32 i = 0; i < V_DESC_TYPE_MAX; i++) { Mut *mut = &renderer.upload_queues[i].mut; if (MutTryLock(mut)) { switch (i) { - case DESC_TYPE_BUFFER: + case V_DESC_TYPE_BUFFER: { processed_count += vLoaderProcessBuffers(index); } break; - case DESC_TYPE_SAMPLER: + case V_DESC_TYPE_SAMPLER: { processed_count += vLoaderProcessSamplers(index); } break; @@ -1553,19 +1638,22 @@ void *vLoaderStart(void *i) else if (processed_count == 0 && iter_count >= 3) { iter_count = 0; - AtomicIncru8(&renderer.vk_conf.sleeping_threads); + pu8AtomicIncr(&v_Renderer.async.sleeping); pthread_mutex_lock(&mut); - pthread_cond_wait(&cond, &mut); + pthread_cond_wait(&v_Renderer.async.cond, &mut); pthread_mutex_unlock(&mut); - pu8AtomicFetchSub(&renderer.vk_conf.sleeping_threads, 1); + pu8AtomicFetchSub(&v_Renderer.async.sleeping, 1); } } + */ + + pthread_exit(NULL); } void vLoaderWake() { - for (u32 i = 0; i < renderer.vk_conf.avail_threads; i++) - pthread_cond_signal(&cond); + for (u32 i = 0; i < v_Renderer.async.count; i++) + pthread_cond_signal(&v_Renderer.async.cond); } #elif _WIN32 @@ -1582,25 +1670,29 @@ void vLoaderWake() static void vSwapchainDestroy() { - for (u32 i = 0; i < renderer.vk.sc.img_count; i++) + vImageViewArray images = v_Renderer.images.sc; + VkDevice device = v_Renderer.handles.device; + VkSwapchainKHR swapchain = v_Renderer.handles.swapchain; + + for (u32 i = 0; i < images.length; i++) { - vkDestroyImageView(renderer.vk.device, renderer.vk.sc.views[i], NULL); + vkDestroyImageView(device, images.data[i].view, NULL); } - vkDestroySwapchainKHR(renderer.vk.device, renderer.vk.swapchain, NULL); + vkDestroySwapchainKHR(device, swapchain, NULL); } static void vDrawImagesDestroy() { - vSwapchainStructures *sc = &renderer.vk.sc; - VkDevice device = renderer.vk.device; - VmaAllocator vma_alloc = renderer.vk.alloc; + vRImages *images = &v_Renderer.images; + VkDevice device = v_Renderer.handles.device; + VmaAllocator vma_alloc = v_Renderer.handles.vma_alloc; - vkDestroyImageView(device, sc->draw_img.view, NULL); - vmaDestroyImage(vma_alloc, sc->draw_img.img, sc->draw_img.alloc); + vkDestroyImageView(device, images->draw.view, NULL); + vmaDestroyImage(vma_alloc, images->draw.image.image, images->draw.image.alloc); - vkDestroyImageView(device, sc->depth_img.view, NULL); - vmaDestroyImage(vma_alloc, sc->depth_img.img, sc->depth_img.alloc); + vkDestroyImageView(device, images->depth.view, NULL); + vmaDestroyImage(vma_alloc, images->depth.image.image, images->depth.image.alloc); } // ::Vulkan::CleanUp::Functions::End:: @@ -1804,12 +1896,13 @@ static VKAPI_ATTR VkBool32 vDebugCallback( static b32 vValidationSupported() { b32 success = false; + Arena *arena = vFrameArena(); u32 count; vkEnumerateInstanceLayerProperties(&count, NULL); Assert(count, "vValidationSupported(): vkEnumerateInstanceLayerProperties returned a count of 0"); - VkLayerProperties *layers = ArenaAlloc(renderer.arena, sizeof(VkLayerProperties) * count); + VkLayerProperties *layers = ArenaAlloc(arena, sizeof(VkLayerProperties) * count); vkEnumerateInstanceLayerProperties(&count, layers); for (u32 i = 0; i < count; i++) { diff --git a/src/renderer_vulkan.h b/src/renderer_vulkan.h index 5ca477f..9c3a7a4 100644 --- a/src/renderer_vulkan.h +++ b/src/renderer_vulkan.h @@ -1,13 +1,9 @@ #pragma once #if __linux__ - -#define VK_USE_PLATFORM_XCB_KHR - +# define VK_USE_PLATFORM_XCB_KHR #elif _WIN32 - -#define VK_USE_PLATFORM_WIN32_KHR - +# define VK_USE_PLATFORM_WIN32_KHR #endif #define VK_NO_PROTOTYPES @@ -37,6 +33,8 @@ static char *vulkan_libs[] = { #error Not yet implemented #endif +#define V_THREAD_MAX 2 + // ::Vulkan::Macros::Header:: #define VK_DECLARE(fn) static PFN_##fn fn = NULL @@ -166,64 +164,38 @@ VK_DECLARE(vkCreateSampler); #define FRAME_OVERLAP 2 #define DESC_MAX_BINDINGS 256 #define BUFFER_QUEUE_LEN 32 -#define HOST_VISIBLE_BUFFERS (RENDER_BUFFER_TYPE_UNIFORM | RENDER_BUFFER_TYPE_STAGING) +#define HOST_VISIBLE_BUFFERS (rRBT_UNIFORM | rRBT_STAGING) // ::Vulkan::Types::Header:: typedef enum DescType_e { - DESC_TYPE_SHARED, - DESC_TYPE_SAMPLER, // DO NOT MOVE FROM POSITION 1 !! - DESC_TYPE_STORAGE_IMAGE, - DESC_TYPE_UNIFORM, - DESC_TYPE_BUFFER, + V_DESC_TYPE_SHARED, + V_DESC_TYPE_SAMPLER, // DO NOT MOVE FROM POSITION 1 !! + V_DESC_TYPE_STORAGE_IMAGE, + V_DESC_TYPE_UNIFORM, + V_DESC_TYPE_BUFFER, - DESC_TYPE_MAX, + V_DESC_TYPE_MAX, } vDescType; -typedef struct vImage -{ - VkImage img; - VkImageView view; - VkSampler sampler; - VmaAllocation alloc; - VkFormat fmt; - VkImageLayout curr_layout; -} vImage; - +/* typedef struct vMeshBuffer { - rRenderBuffer index_buf, vertex_buf; + //TODO: FIX + //rRenderBuffer index_buf, vertex_buf; u32 index_count; } vMeshBuffer; -typedef struct vAssetInfo -{ - rDescHandle handle; - vDescType type; - union - { - u64 asset_id; - TextureAsset texture_id; - }; -} vAssetInfo; - -typedef struct vDescBindings -{ - u32 *free; - u32 free_count; - HashTable lookup_table; -} vDescBindings; - typedef struct vPipelineStructures { VkPipelineLayout pipeline_layout; VkDescriptorPool pool; - VkDescriptorSetLayout layouts[DESC_TYPE_MAX]; - VkDescriptorSet sets[DESC_TYPE_MAX]; + VkDescriptorSetLayout layouts[V_DESC_TYPE_MAX]; + VkDescriptorSet sets[V_DESC_TYPE_MAX]; vDescBindings *bindings; u16 bindings_count; - VkPipeline pipelines[PIPELINE_MAX]; + VkPipeline pipelines[R_PIPELINE_MAX]; } vPipelineStructures; typedef struct vFrameStructures @@ -244,13 +216,6 @@ typedef struct vImmediateStructures VkFence *fences; } vImmediateStructures; -typedef struct vDeviceQueues -{ - i32 graphics, transfer; - VkQueue graphics_queue, transfer_queue; - b8 single_queue; -} vDeviceQueues; - typedef struct vSwapchainStructures { VkFormat format; @@ -312,17 +277,187 @@ typedef struct vVulkanConfig #endif } vVulkanConfig; + typedef struct vRenderer { - vVulkan vk; + vVulkan vk; vVulkanConfig vk_conf; vFrameState frame_state; vPendingUpdates pending; - Arena *arena; Arena *perm_arena; - rUploadQueue upload_queues[DESC_TYPE_MAX]; + Arena *frame_arena[FRAME_OVERLAP]; + rUploadQueue upload_queues[V_DESC_TYPE_MAX]; } vRenderer; +*/ + +// NEW + +typedef struct vAssetInfo +{ + rDescHandle handle; + vDescType type; + union + { + u64 asset_id; + TextureAsset texture_id; + }; +} vAssetInfo; + +typedef struct vDeviceQueues +{ + i32 graphics, transfer; + VkQueue graphics_queue, transfer_queue; + b8 single_queue; +} vDeviceQueues; + +typedef struct vDescBindings +{ + u32 *free; + u32 free_count; + HashTable lookup_table; +} vDescBindings; + +typedef struct vImage +{ + VkImage image; + VmaAllocation alloc; + VkFormat format; + VkImageLayout layout; +} vImage; + +typedef struct vImageView +{ + vImage image; + VkImageView view; +} vImageView; + +typedef struct vSampler +{ + vImage image; + VkImageView view; + VkSampler sampler; +} vSampler; + +typedef struct vBufferAlloc +{ + VkBuffer buffer; + VmaAllocation alloc; +} vBufferAlloc; + +ArrayType(vBufferAlloc); +ArrayType(vImageView); + +typedef struct vSwapchainState +{ + VkFormat format; + VkColorSpaceKHR color_space; + VkPresentModeKHR present_mode; + VkExtent3D extent; +} vSwapchainState; + +typedef struct vVkState +{ + u32 gfx_queue_idx; + u32 tfer_queue_idx; + u32 image_idx; + b8 single_queue; +} vVkState; + +typedef struct vRendererState +{ + u64 frame_count; + rPipelineHandle pipeline; + u32 width; + u32 height; +} vRendererState; + +typedef struct vState +{ + vSwapchainState swapchain; + vRendererState renderer; + vVkState vk; +} vState; + +typedef struct vImmHandles +{ + VkCommandPool pool; + VkCommandBuffer buffer; + VkFence fence; +} vImmHandles; + +ArrayType(vImmHandles); + +typedef struct vFrameHandles +{ + VkCommandPool pool; + VkCommandBuffer buffer; + VkSemaphore sc_sem; + VkSemaphore r_sem; + VkFence r_fence; +} vFrameHandles; + +typedef struct vAsync +{ + u32 thread_idx[V_THREAD_MAX]; +#ifdef __linux__ + pthread_t threads[V_THREAD_MAX]; + pthread_cond_t cond; +#elif _WIN32 +# error not yet implemented +#endif + u8 count; + u8 sleeping; +} vAsync; + +typedef struct vRHandles +{ + pLibrary lib; + VkInstance inst; + VkPhysicalDevice phys_device; + VkDevice device; + VkSurfaceKHR surface; + VkSwapchainKHR swapchain; + VmaAllocator vma_alloc; + VkDescriptorPool desc_pool; + VkPipeline pipelines[R_PIPELINE_MAX]; + VkPipelineLayout pipeline_layout; + VkDescriptorSetLayout desc_layouts[V_DESC_TYPE_MAX]; + VkDescriptorSet desc_sets[V_DESC_TYPE_MAX]; + VkQueue gfx_queue; + VkQueue tfer_queue; +#ifdef BUILD_DEBUG + VkDebugUtilsMessengerEXT debug; +#endif +} vRHandles; + +typedef struct vMemory +{ + Arena *perm_arena; + Arena *frame_arenas[FRAME_OVERLAP]; +} vMemory; + +typedef struct vRImages +{ + vImageView draw; + vImageView depth; + vImageViewArray sc; +} vRImages; + +typedef struct vRenderer2 +{ + vRHandles handles; + vFrameHandles frame_handles[FRAME_OVERLAP]; + vState state; + vBufferAllocArray buffers; + vBufferAlloc frame_buffers[FRAME_OVERLAP]; + vImmHandlesArray imm_handles; + vDescBindings desc_bindings[V_DESC_TYPE_MAX]; + vAsync async; + vMemory mem; + vRImages images; +} vRenderer2; + // ::Vulkan::FrontEndTypes::Header:: typedef struct rShaderGlobals @@ -342,7 +477,7 @@ typedef struct rTextureBuffer typedef struct rRenderBuffer { - rRenderBufferType type; + rRenderBufferType type; VkBuffer buffer; VmaAllocation alloc; VmaAllocationInfo info; @@ -374,6 +509,9 @@ const char *vVkResultStr(VkResult result); // ::Vulkan::Init::Functions::Header:: +static b32 vInitInstance(); +static void vEnableDebug(); +static void vInitArenas(); static b32 vLibraryLoad(); static b32 vInstanceFunctionsInit(); static b32 vGlobalFunctionsInit(); @@ -399,13 +537,14 @@ static void vLoaderStartThreads(); // ::Vulkan::Util::Functions::Header:: static inline VkCommandBuffer vFrameCmdBuf(); -static inline VkFence *vFrameRenderFence(); +static inline VkFence vFrameRenderFence(); +static inline VkImage vFrameImage(); +static inline Arena *vFrameArena(); static inline VkSemaphore vFrameRenderSem(); static inline VkSemaphore vFrameSwapSem(); static inline u32 vFrameIndex(); static inline VkImage vFrameSwapImage(); -static inline u32 *vFrameBufferCount(); -static inline rRenderBuffer *vFrameRenderBuffers(); +static inline vBufferAlloc *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); diff --git a/src/renderer_vulkan_public.c b/src/renderer_vulkan_public.c index e9c2d3d..2edcacf 100644 --- a/src/renderer_vulkan_public.c +++ b/src/renderer_vulkan_public.c @@ -1,38 +1,22 @@ // ::Vulkan::Renderer::Initialization::Functions::Start:: -b32 rInit(Arena *arena) +b32 rInit() { rThreadCountSet(pCPUCountGet()); + vInitArenas(); + vCustomizePipelines(); - CustomizePipelines(); - - Assert(arena != NULL, "Vulkan memory is null"); - renderer.perm_arena = arena; - void *mem = ArenaAlloc(arena, MB(8)); - renderer.arena = ArenaInit(mem, MB(8)); - - Assert(vGlobalFunctionsInit(), "Unable to load vulkan functions"); - { - VkResult result = vkCreateInstance(&inst_info, NULL, &renderer.vk.inst); - if (result != VK_SUCCESS) - { - Printfln("vkCreateInstance failure: %s", vVkResultStr(result)); - assert(false && "Failed to initialize instance"); - } - } + Assert(vInitInstance(), "Unable to initialize instance"); Assert(vInstanceFunctionsInit(), "Unable to initialize instance functions"); #ifdef BUILD_DEBUG { - Assert(vValidationSupported(), "DEBUG_BUILD ERROR: Validation layers are not supported"); - Assert(vkCreateDebugUtilsMessengerEXT(renderer.vk.inst, &debug_msg_info, NULL, &renderer.vk.debug) == VK_SUCCESS, - "Unable to initialize debug messenger"); + vEnableDebug(); } #endif Assert(vSurfaceInit(), "Unable to create surface"); Assert(vDeviceInit(), "Unable to create device"); - Assert(vVmaAllocatorInit(), "Unable to create VMA allocator"); Assert(vSwapchainInit(), "Unable to initialize swapchain and draw images"); Assert(vDrawImagesInit(), "Unable to create draw images"); @@ -40,78 +24,93 @@ b32 rInit(Arena *arena) Assert(vImmediateStructuresInit(), "Unable to create immediate structures"); Assert(vDescriptorsInit(), "Unable to initialize descriptors."); Assert(vPipelinesInit(), "Unable to initialize pipelines."); - vUploadQueuesInit(); + vUploadQueuesInit(); vLoaderStartThreads(); - ArenaFree(renderer.arena); + ArenaFree(vFrameArena()); return true; } void rDestroy() { - VkDevice device = renderer.vk.device; - VkInstance instance = renderer.vk.inst; - vFrameStructures data = renderer.vk.frame; - vImmediateStructures imm = renderer.vk.imm; - vSwapchainStructures sc = renderer.vk.sc; - VmaAllocator vma_alloc = renderer.vk.alloc; - VkSwapchainKHR swapchain = renderer.vk.swapchain; - vPipelineStructures pipe = renderer.vk.pipe; + VkDevice device = v_Renderer.handles.device; + VkInstance instance = v_Renderer.handles.inst; + vBufferAlloc *frame_buffers = v_Renderer.frame_buffers; + vBufferAllocArray buffers = v_Renderer.buffers; + vImmHandlesArray imm = v_Renderer.imm_handles; + VmaAllocator vma_alloc = v_Renderer.handles.vma_alloc; + VkSwapchainKHR swapchain = v_Renderer.handles.swapchain; + VkPipeline *pipelines = v_Renderer.handles.pipelines; + VkPipelineLayout pipeline_layout = v_Renderer.handles.pipeline_layout; + VkDescriptorSetLayout *desc_layouts = v_Renderer.handles.desc_layouts; + VkDescriptorPool desc_pool = v_Renderer.handles.desc_pool; + vAsync async = v_Renderer.async; vkDeviceWaitIdle(device); - for (u32 i = PIPELINE_CUBE; i < PIPELINE_MAX; i++) - vkDestroyPipeline(device, pipe.pipelines[i], NULL); + for (u32 i = R_PIPELINE_CUBE; i < R_PIPELINE_MAX; i++) + vkDestroyPipeline(device, pipelines[i], NULL); - vkDestroyPipelineLayout(device, pipe.pipeline_layout, NULL); + vkDestroyPipelineLayout(device, pipeline_layout, NULL); - for (u32 i = DESC_TYPE_SHARED; i < DESC_TYPE_MAX; i++) - vkDestroyDescriptorSetLayout(device, pipe.layouts[i], NULL); + for (u32 i = V_DESC_TYPE_SHARED; i < V_DESC_TYPE_MAX; i++) + vkDestroyDescriptorSetLayout(device, desc_layouts[i], NULL); - vkDestroyDescriptorPool(device, pipe.pool, NULL); + vkDestroyDescriptorPool(device, desc_pool, NULL); vDrawImagesDestroy(); vSwapchainDestroy(); - for (u32 i = 0; i < renderer.vk_conf.avail_threads; i++) + for (u32 i = 0; i < async.count; i++) { - vkDestroyFence(device, imm.fences[i], NULL); - vkFreeCommandBuffers(device, imm.pools[i], 1, &imm.cmds[i]); - vkDestroyCommandPool(device, imm.pools[i], NULL); + vImmHandles ih = imm.data[i]; + + vkDestroyFence(device, ih.fence, NULL); + vkFreeCommandBuffers(device, ih.pool, 1, &ih.buffer); + vkDestroyCommandPool(device, ih.pool, NULL); } for (u32 i = 0; i < FRAME_OVERLAP; i++) { - vkDestroySemaphore(device, data.render_sems[i], NULL); - vkDestroySemaphore(device, data.swapchain_sems[i], NULL); - vkDestroyFence(device, data.render_fences[i], NULL); - vkFreeCommandBuffers(device, data.pools[i], 1, &data.buffers[i]); - vkDestroyCommandPool(device, data.pools[i], NULL); + 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); + + // TODO: replace + /* if (data.buffer_counts[i] > 0) { - for (u32 j = 0; j < data.buffer_counts[i]; j++) - vmaDestroyBuffer(renderer.vk.alloc, data.buffer_destroy_queues[i][j].buffer, data.buffer_destroy_queues[i][j].alloc); + //for (u32 j = 0; j < data.buffer_counts[i]; j++) + //vmaDestroyBuffer(v_Renderer.handles.vma_alloc, data.buffer_destroy_queues[i][j].buffer, data.buffer_destroy_queues[i][j].alloc); } + */ } - vmaDestroyAllocator(renderer.vk.alloc); - vkDestroyDevice(renderer.vk.device, NULL); - vkDestroySurfaceKHR(renderer.vk.inst, renderer.vk.surface, NULL); + vmaDestroyAllocator(v_Renderer.handles.vma_alloc); + vkDestroyDevice(v_Renderer.handles.device, NULL); + vkDestroySurfaceKHR(v_Renderer.handles.inst, v_Renderer.handles.surface, NULL); #ifdef BUILD_DEBUG { - vkDestroyDebugUtilsMessengerEXT(renderer.vk.inst, renderer.vk.debug, NULL); + vkDestroyDebugUtilsMessengerEXT(v_Renderer.handles.inst, v_Renderer.handles.debug, NULL); } #endif - vkDestroyInstance(renderer.vk.inst, NULL); + vkDestroyInstance(v_Renderer.handles.inst, NULL); - ArenaFree(renderer.arena); - ArenaFree(renderer.perm_arena); + for (u32 i = 0; i < FRAME_OVERLAP; i++) + { + ArenaFree(v_Renderer.mem.frame_arenas[i]); + } + + ArenaFree(v_Renderer.mem.perm_arena); } // ::Vulkan::Renderer::Initialization::Functions::End:: @@ -120,20 +119,28 @@ void rDestroy() // ::Vulkan::Renderer::Buffers::Functions::Start:: -static b32 rBufferCreate(rRenderBuffer *buffer) +static rBuffer rBufferCreate(rRenderBufferType type, u64 size) { - Assert(buffer, "rBufferCreate: rRenderBuffer must not be null"); - Assert(buffer->type != RENDER_BUFFER_TYPE_NONE, "rBufferCreate: rRenderBuffer type must not be RENDER_BUFFER_TYPE_NONE"); + 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; - vDeviceQueues *queues = &renderer.vk.queues; - VmaAllocator alloc = renderer.vk.alloc; + 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, + //.size = (VkDeviceSize)buffer->size, }; VmaAllocationCreateInfo alloc_info = { @@ -141,65 +148,64 @@ static b32 rBufferCreate(rRenderBuffer *buffer) .flags = VMA_ALLOCATION_CREATE_MAPPED_BIT, }; - switch (buffer->type) + switch (type) { - case RENDER_BUFFER_TYPE_VERTEX: + case rRBT_VERTEX: { - buffer_info.usage = VK_BUFFER_USAGE_VERTEX_BUFFER_BIT | - VK_BUFFER_USAGE_TRANSFER_DST_BIT | - VK_BUFFER_USAGE_TRANSFER_SRC_BIT; - alloc_info.requiredFlags = VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT; + buffer_info.usage = VK_BUFFER_USAGE_VERTEX_BUFFER_BIT; } break; - case RENDER_BUFFER_TYPE_INDEX: + case rRBT_INDEX: { - buffer_info.usage = VK_BUFFER_USAGE_INDEX_BUFFER_BIT | - VK_BUFFER_USAGE_TRANSFER_DST_BIT | - VK_BUFFER_USAGE_TRANSFER_SRC_BIT; - alloc_info.requiredFlags = VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT; + buffer_info.usage = VK_BUFFER_USAGE_INDEX_BUFFER_BIT; } break; - case RENDER_BUFFER_TYPE_UNIFORM: + case rRBT_UNIFORM: { - buffer_info.usage = VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT | - VK_BUFFER_USAGE_TRANSFER_DST_BIT; - alloc_info.requiredFlags = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | - VK_MEMORY_PROPERTY_HOST_COHERENT_BIT; + buffer_info.usage = VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT; } break; - case RENDER_BUFFER_TYPE_STAGING: + case rRBT_STAGING: { buffer_info.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT; - alloc_info.requiredFlags = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | - VK_MEMORY_PROPERTY_HOST_COHERENT_BIT; } break; - case RENDER_BUFFER_TYPE_STORAGE: + case rRBT_STORAGE: { - buffer_info.usage = VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | - VK_BUFFER_USAGE_TRANSFER_DST_BIT; - alloc_info.requiredFlags = VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT; + buffer_info.usage = VK_BUFFER_USAGE_STORAGE_BUFFER_BIT; } break; - case RENDER_BUFFER_TYPE_NONE: + case rRBT_NONE: default: Assert(false, "rBufferCreate: Unknown buffer type provided"); } + + 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 (queues->graphics != queues->transfer) + if (tfer_queue != gfx_queue) { buffer_info.sharingMode = VK_SHARING_MODE_CONCURRENT; buffer_info.queueFamilyIndexCount = 2; - buffer_info.pQueueFamilyIndices = (u32[]){queues->graphics, queues->transfer}; + 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)); - success = false; - } + //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"); @@ -207,9 +213,9 @@ static b32 rBufferUpload(rRenderBuffer **buffers, rawptr *ptrs, u32 count, u32 t VkCommandBuffer cmd = renderer.vk.imm.cmds[thr_ix]; VkFence fence = renderer.vk.imm.fences[thr_ix]; - VkDevice device = renderer.vk.device; + VkDevice device = v_Renderer.handles.device; VkQueue queue = renderer.vk.queues.transfer_queue; - VmaAllocator alloc = renderer.vk.alloc; + VmaAllocator alloc = v_Renderer.handles.vma_alloc; rawptr mapped_buffers[16] = {0}; rRenderBuffer staging_buffers[16] = {0}; @@ -226,10 +232,10 @@ static b32 rBufferUpload(rRenderBuffer **buffers, rawptr *ptrs, u32 count, u32 t } else { - staging_buffers[copy_count].type = RENDER_BUFFER_TYPE_STAGING; + staging_buffers[copy_count].type = rRBT_STAGING; staging_buffers[copy_count].size = buffers[i]->size; - success = rBufferCreate(&staging_buffers[i]); + //success = rBufferCreate(&staging_buffers[i]); if (success) { @@ -252,19 +258,24 @@ static b32 rBufferUpload(rRenderBuffer **buffers, rawptr *ptrs, u32 count, u32 t vmaUnmapMemory(alloc, staging_buffers[i].alloc); vmaDestroyBuffer(alloc, staging_buffers[i].buffer, staging_buffers[i].alloc); } + */ - return success; + return false; } static void rBufferCreateAndUpload(rRenderBuffer *buffer, rawptr ptr) { - TicketMutLock(&renderer.upload_queues[DESC_TYPE_BUFFER].ticket_mut); - u32 job_idx = JobQueueAdd(&renderer.upload_queues[DESC_TYPE_BUFFER].job_queue, 1); - renderer.upload_queues[DESC_TYPE_BUFFER].queued_buffers[job_idx] = buffer; - renderer.upload_queues[DESC_TYPE_BUFFER].data[job_idx] = ptr; + // TODO: replace + /* + TicketMutLock(&renderer.upload_queues[V_DESC_TYPE_BUFFER].ticket_mut); - TicketMutUnlock(&renderer.upload_queues[DESC_TYPE_BUFFER].ticket_mut); + u32 job_idx = JobQueueAdd(&renderer.upload_queues[V_DESC_TYPE_BUFFER].job_queue, 1); + renderer.upload_queues[V_DESC_TYPE_BUFFER].queued_buffers[job_idx] = buffer; + renderer.upload_queues[V_DESC_TYPE_BUFFER].data[job_idx] = ptr; + + TicketMutUnlock(&renderer.upload_queues[V_DESC_TYPE_BUFFER].ticket_mut); + */ vLoaderWake(); } @@ -273,26 +284,28 @@ static rDescHandle rTextureCreateAndUpload(TextureAsset asset_id) { rDescHandle handle = 0; - vAssetInfo *info = vDescHandleSearch(DESC_TYPE_SAMPLER, asset_id); + // TODO: replace it + /* + vAssetInfo *info = vDescHandleSearch(V_DESC_TYPE_SAMPLER, asset_id); if (info == NULL) { Asset asset = apLoadTexture(asset_id); rTextureBuffer *buffer = FLMemAlloc(sizeof(rTextureBuffer)); - buffer->type = TEXTURE_BUFFER_TYPE_SAMPLER; + buffer->type = rTBT_SAMPLER; buffer->width = asset.texture_meta.w; buffer->height = asset.texture_meta.h; buffer->channels = asset.texture_meta.ch; - TicketMutLock(&renderer.upload_queues[DESC_TYPE_SAMPLER].ticket_mut); + TicketMutLock(&renderer.upload_queues[V_DESC_TYPE_SAMPLER].ticket_mut); - u32 job_idx = JobQueueAdd(&renderer.upload_queues[DESC_TYPE_SAMPLER].job_queue, 1); - renderer.upload_queues[DESC_TYPE_SAMPLER].queued_textures[job_idx] = buffer; - renderer.upload_queues[DESC_TYPE_SAMPLER].data[job_idx] = asset.bytes; + u32 job_idx = JobQueueAdd(&renderer.upload_queues[V_DESC_TYPE_SAMPLER].job_queue, 1); + renderer.upload_queues[V_DESC_TYPE_SAMPLER].queued_textures[job_idx] = buffer; + renderer.upload_queues[V_DESC_TYPE_SAMPLER].data[job_idx] = asset.bytes; - handle = vDescHandlePop(DESC_TYPE_SAMPLER); + handle = vDescHandlePop(V_DESC_TYPE_SAMPLER); - TicketMutUnlock(&renderer.upload_queues[DESC_TYPE_SAMPLER].ticket_mut); + TicketMutUnlock(&renderer.upload_queues[V_DESC_TYPE_SAMPLER].ticket_mut); vLoaderWake(); } @@ -300,30 +313,28 @@ static rDescHandle rTextureCreateAndUpload(TextureAsset asset_id) { handle = info->handle; } + */ return handle; } static void rBufferFree(rRenderBuffer *buffers, u32 buffer_count) { - VkDevice device = renderer.vk.device; - VmaAllocator alloc = renderer.vk.alloc; - u32 frame_index = renderer.frame_state.begin_rendering ? renderer.frame_state.frame_cnt : renderer.frame_state.prev_frame; - frame_index = frame_index % FRAME_OVERLAP; + VkDevice device = v_Renderer.handles.device; + VmaAllocator alloc = v_Renderer.handles.vma_alloc; + u32 frame_index = vFrameIndex(); - u32 *buf_count = &renderer.vk.frame.buffer_counts[frame_index]; - // TODO: make this better at some point - for (u32 i = 0; i < buffer_count; i++) - { - renderer.vk.frame.buffer_destroy_queues[frame_index][*buf_count] = buffers[i]; - *buf_count += 1; - } + // TODO: replace it + //for (u32 i = 0; i < buffer_count; i++) + //{ + // *buf_count += 1; + //} } static void rBufferBindVertex(rRenderBuffer *buffer) { - Assert(buffer && buffer->type == RENDER_BUFFER_TYPE_VERTEX, "rBufferBindVertex: invalid buffer provided"); + Assert(buffer && buffer->type == rRBT_VERTEX, "rBufferBindVertex: invalid buffer provided"); VkCommandBuffer cmd = vFrameCmdBuf(); VkDeviceSize offsets = 0; @@ -333,7 +344,7 @@ static void rBufferBindVertex(rRenderBuffer *buffer) static void rBufferBindIndex(rRenderBuffer *buffer) { - Assert(buffer && buffer->type == RENDER_BUFFER_TYPE_INDEX, "rBufferBindIndex: invalid buffer provided"); + Assert(buffer && buffer->type == rRBT_INDEX, "rBufferBindIndex: invalid buffer provided"); VkCommandBuffer cmd = vFrameCmdBuf(); @@ -349,21 +360,25 @@ static rAssetHandle rTextureLoad(TextureAsset asset_id) static void WaitForBufferQueue() { - for (u32 i = 0; i < DESC_TYPE_MAX; i++) + for (u32 i = 0; i < V_DESC_TYPE_MAX; i++) { - while (!JobQueueCompleted(&renderer.upload_queues[DESC_TYPE_BUFFER].job_queue)) + // TODO: replace + /* + while (!JobQueueCompleted(&renderer.upload_queues[V_DESC_TYPE_BUFFER].job_queue)) { - if (renderer.vk_conf.sleeping_threads > 0) + if (v_Renderer.state.renderer.height > 0) vLoaderWake(); } + */ } } static void rBufferQueueReset() { - for (u32 i = 0; i < DESC_TYPE_MAX; i++) + for (u32 i = 0; i < V_DESC_TYPE_MAX; i++) { - JobQueueReset(&renderer.upload_queues[i].job_queue); + // TODO: replace + //JobQueueReset(&renderer.upload_queues[i].job_queue); } } @@ -376,8 +391,8 @@ static void rBufferQueueReset() static void rViewportSize(Vec2 *size) { - size->x = (f32)renderer.vk.sc.extent.width; - size->y = (f32)renderer.vk.sc.extent.height; + size->x = (f32)v_Renderer.state.swapchain.extent.width; + size->y = (f32)v_Renderer.state.swapchain.extent.height; } static void rGlobalUniformSet(rShaderGlobals *globals) @@ -390,7 +405,7 @@ static void rPushConstantsSet(rPushConst *pc) VkCommandBuffer cmd = vFrameCmdBuf(); vkCmdPushConstants(cmd, - renderer.vk.pipe.pipeline_layout, + v_Renderer.handles.pipeline_layout, VK_SHADER_STAGE_VERTEX_BIT|VK_SHADER_STAGE_FRAGMENT_BIT|VK_SHADER_STAGE_COMPUTE_BIT, 0, sizeof(rPushConst), @@ -406,14 +421,13 @@ static void rPushConstantsSet(rPushConst *pc) static void rResolutionSet(u32 x, u32 y) { - renderer.pending.render_width = x; - renderer.pending.render_height = y; - renderer.pending.resized = true; + v_Renderer.state.renderer.width = x; + v_Renderer.state.renderer.height = y; } static void rThreadCountSet(u32 n) { - renderer.vk_conf.avail_threads = n; + v_Renderer.async.count = n; } // ::Vulkan::Renderer::Config::Functions::End:: @@ -427,18 +441,15 @@ b32 rFrameBegin() b32 success = true; VkResult result; - if (renderer.pending.resized) - vSwapchainResize(); - - VkDevice device = renderer.vk.device; - VkSwapchainKHR swapchain = renderer.vk.swapchain; + VkDevice device = v_Renderer.handles.device; + VkSwapchainKHR swapchain = v_Renderer.handles.swapchain; VkCommandBuffer cmd = vFrameCmdBuf(); - VkFence *fence = vFrameRenderFence(); + VkFence fence = vFrameRenderFence(); VkSemaphore sc_sem = vFrameSwapSem(); VkSemaphore rndr_sem = vFrameRenderSem(); // TODO(MA): make this work with VK_PRESENT_MODE_MAILBOX_KHR and remove assignment of present mode to FIFO - result = vkWaitForFences(device, 1, fence, VK_TRUE, 1000000000); + result = vkWaitForFences(device, 1, &fence, VK_TRUE, 1000000000); if (result != VK_SUCCESS) { Printf("vkWaitForFences failure: %s", vVkResultStr(result)); @@ -447,16 +458,19 @@ b32 rFrameBegin() if (success) { + // TODO: replace + /* u32 *buf_count = vFrameBufferCount(); if (*buf_count > 0) { rRenderBuffer *buffers = vFrameRenderBuffers(); for (u32 i = 0; i < *buf_count; i++) - vmaDestroyBuffer(renderer.vk.alloc, buffers[i].buffer, buffers[i].alloc); + vmaDestroyBuffer(v_Renderer.handles.vma_alloc, buffers[i].buffer, buffers[i].alloc); *buf_count = 0; } + */ - result = vkResetFences(device, 1, fence); + result = vkResetFences(device, 1, &fence); if (result != VK_SUCCESS) { Printf("vkResetFences failure: %s", vVkResultStr(result)); @@ -466,7 +480,7 @@ b32 rFrameBegin() if (success) { - result = vkAcquireNextImageKHR(device, swapchain, 1000000000, sc_sem, 0, &renderer.frame_state.img_ix); + result = vkAcquireNextImageKHR(device, swapchain, 1000000000, sc_sem, 0, &v_Renderer.state.vk.image_idx); if (result == VK_ERROR_OUT_OF_DATE_KHR) vSwapchainResize(); else if (result != VK_SUCCESS && result != VK_SUBOPTIMAL_KHR) @@ -500,37 +514,35 @@ b32 rFrameBegin() Printf("vkBeginCommandBuffer failure: %s", vVkResultStr(result)); success = false; } + + if (success) + vRenderingBegin(); } return success; } -b32 FinishFrame() +b32 rFrameFinish() { - if (!renderer.frame_state.begin_rendering) - Assert(false, "FinishFrame called without beginning rendering"); - - renderer.frame_state.begin_rendering = false; - b32 success = true; VkResult result; VkCommandBuffer cmd = vFrameCmdBuf(); VkSemaphore sc_sem = vFrameSwapSem(); VkSemaphore rndr_sem = vFrameRenderSem(); - VkFence *fence = vFrameRenderFence(); - VkImage curr_img = renderer.vk.sc.imgs[renderer.frame_state.img_ix]; + VkFence fence = vFrameRenderFence(); + VkImage curr_img = vFrameImage(); vkCmdEndRendering(cmd); - vImageTransition(cmd, &renderer.vk.sc.draw_img, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL); + vImageTransition(cmd, &v_Renderer.images.draw.image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL); VkExtent2D extent = { - .width = renderer.vk.sc.extent.width, - .height = renderer.vk.sc.extent.height, + .width = v_Renderer.state.swapchain.extent.width, + .height = v_Renderer.state.swapchain.extent.height, }; - vImageCopyToImage(cmd, renderer.vk.sc.draw_img.img, curr_img, extent, extent); + vImageCopyToImage(cmd, v_Renderer.images.draw.image.image, curr_img, extent, extent); vImageTransitionLayout(cmd, curr_img, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_PRESENT_SRC_KHR); @@ -572,7 +584,7 @@ b32 FinishFrame() .pCommandBufferInfos = &cmd_info, }; - result = vkQueueSubmit2(renderer.vk.queues.graphics_queue, 1, &submit_info, *fence); + result = vkQueueSubmit2(v_Renderer.handles.gfx_queue, 1, &submit_info, fence); if (result != VK_SUCCESS) { Printf("vkQueueSubmit2 failure: %s", vVkResultStr(result)); @@ -584,15 +596,15 @@ b32 FinishFrame() { VkPresentInfoKHR present_info = { .sType = STYPE(PRESENT_INFO_KHR), - .pSwapchains = &renderer.vk.swapchain, + .pSwapchains = &v_Renderer.handles.swapchain, .swapchainCount = 1, .pWaitSemaphores = &rndr_sem, .waitSemaphoreCount = 1, - .pImageIndices = &renderer.frame_state.img_ix, + .pImageIndices = &v_Renderer.state.vk.image_idx, }; - result = vkQueuePresentKHR(renderer.vk.queues.graphics_queue, &present_info); - if (result == VK_ERROR_OUT_OF_DATE_KHR || result == VK_SUBOPTIMAL_KHR || renderer.pending.resized) + result = vkQueuePresentKHR(v_Renderer.handles.gfx_queue, &present_info); + if (result == VK_ERROR_OUT_OF_DATE_KHR || result == VK_SUBOPTIMAL_KHR) vSwapchainResize(); else if (result != VK_SUCCESS) { @@ -601,8 +613,7 @@ b32 FinishFrame() } } - renderer.frame_state.prev_frame = renderer.frame_state.frame_cnt; - renderer.frame_state.frame_cnt++; + v_Renderer.state.renderer.frame_count += 1; return success; } @@ -616,19 +627,13 @@ static void rDrawIndexed(u32 index_count, u32 instance_count) static void rPipelineBind(rPipelineHandle handle, rPipelineType type) { - if (!renderer.frame_state.begin_rendering) - { - vRenderingBegin(); - renderer.frame_state.begin_rendering = true; - } - VkCommandBuffer cmd = vFrameCmdBuf(); - vkCmdBindPipeline(cmd, (VkPipelineBindPoint)type, renderer.vk.pipe.pipelines[handle]); + vkCmdBindPipeline(cmd, (VkPipelineBindPoint)type, v_Renderer.handles.pipelines[handle]); VkViewport viewport = { - .width = (f32)renderer.vk.sc.extent.width, - .height = (f32)renderer.vk.sc.extent.height, + .width = (f32)v_Renderer.state.swapchain.extent.width, + .height = (f32)v_Renderer.state.swapchain.extent.height, .maxDepth = 1.0, }; @@ -636,8 +641,8 @@ static void rPipelineBind(rPipelineHandle handle, rPipelineType type) VkRect2D scissor = { .extent = { - .width = renderer.vk.sc.extent.width, - .height = renderer.vk.sc.extent.height, + .width = v_Renderer.state.swapchain.extent.width, + .height = v_Renderer.state.swapchain.extent.height, }, }; diff --git a/src/util.h b/src/util.h index cc7db2a..9eb3d7f 100644 --- a/src/util.h +++ b/src/util.h @@ -72,6 +72,13 @@ typedef struct Arena Arena; Def##def(b8); \ Def##def(b32) +#define ArrayType(T) \ +typedef struct T##Array \ +{ \ + T *data; \ + u64 length; \ +} T##Array + // ::Util::LinkedList::Macros:: diff --git a/src/vulkan_config.c b/src/vulkan_config.c index 44db42a..8dc4d0c 100644 --- a/src/vulkan_config.c +++ b/src/vulkan_config.c @@ -251,10 +251,10 @@ static VkDescriptorSetLayoutCreateInfo shared_layout_create_info = { .flags = VK_DESCRIPTOR_SET_LAYOUT_CREATE_UPDATE_AFTER_BIND_POOL_BIT, }; -static VkDescriptorType desc_type_map[DESC_TYPE_MAX] = { - [DESC_TYPE_SAMPLER] = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, - [DESC_TYPE_STORAGE_IMAGE] = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, - [DESC_TYPE_UNIFORM] = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, +static VkDescriptorType desc_type_map[V_DESC_TYPE_MAX] = { + [V_DESC_TYPE_SAMPLER] = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, + [V_DESC_TYPE_STORAGE_IMAGE] = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, + [V_DESC_TYPE_UNIFORM] = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, }; static VkDescriptorBindingFlags bindless_desc_binding_flags = VK_DESCRIPTOR_BINDING_UPDATE_AFTER_BIND_BIT | VK_DESCRIPTOR_BINDING_PARTIALLY_BOUND_BIT; @@ -281,7 +281,7 @@ static VkDescriptorSetLayoutCreateInfo bindless_layout_create_info = { static VkDescriptorSetAllocateInfo set_allocate_info = { .sType = STYPE(DESCRIPTOR_SET_ALLOCATE_INFO), - .descriptorSetCount = DESC_TYPE_MAX, + .descriptorSetCount = V_DESC_TYPE_MAX, }; static VkPushConstantRange push_const_range = { @@ -292,7 +292,7 @@ static VkPushConstantRange push_const_range = { static VkPipelineLayoutCreateInfo pipeline_layout_create_info = { .sType = STYPE(PIPELINE_LAYOUT_CREATE_INFO), - .setLayoutCount = DESC_TYPE_MAX, + .setLayoutCount = V_DESC_TYPE_MAX, .pushConstantRangeCount = 1, .pPushConstantRanges = &push_const_range, }; @@ -448,7 +448,7 @@ VkPipelineInputAssemblyStateCreateInfo gui_assembly_info = { .primitiveRestartEnable = VK_FALSE, }; -static void CustomizePipelines() +static void vCustomizePipelines() { gui_create_info.pVertexInputState = &gui_vertex_input_info; gui_create_info.pInputAssemblyState = &gui_assembly_info;