From d2c901f4e4ad8c744cb38051d49ab1fd1275934d Mon Sep 17 00:00:00 2001 From: Abdelrahman Date: Sun, 14 Jun 2026 15:45:48 +0100 Subject: [PATCH] Add sync objects --- main.cpp | 98 ++++++++++++++++++++++++++++++++++++++++---------------- 1 file changed, 70 insertions(+), 28 deletions(-) diff --git a/main.cpp b/main.cpp index a285391..40a0fae 100644 --- a/main.cpp +++ b/main.cpp @@ -37,6 +37,7 @@ enum ExitCode { EXIT_CODE_NO_SUITABLE_QUEUE_FAMILY, EXIT_CODE_NO_SUITABLE_DEPTH_FORMAT, EXIT_CODE_MESH_LOAD_FAILED, + EXIT_CODE_SYNC_OBJ_CREATE_FAILED, }; struct Vertex { @@ -67,42 +68,47 @@ typedef VkImageView *VkImageViewArray; typedef VkFormat *VkFormatArray; typedef Vertex *VertexArray; typedef ShaderDataBuffer *ShaderDataBufferArray; +typedef VkFence *VkFenceArray; +typedef VkSemaphore *VkSemaphoreArray; wapp_intern inline void check(VkResult result); wapp_intern inline void check_swapchain(VkResult result); wapp_intern inline void check(bool result, i32 code); -wapp_intern constexpr u32 max_frames_in_flight = 2; -wapp_intern bool running = true; -wapp_intern bool update_swapchain = false; -wapp_intern f32 display_scale = 1.0f; -wapp_intern SDL_Window *window = nullptr; -wapp_intern VkInstance instance = VK_NULL_HANDLE; -wapp_intern VkPhysicalDevice physical_device = VK_NULL_HANDLE; -wapp_intern VkSurfaceKHR surface = VK_NULL_HANDLE; -wapp_intern u32 queue_family_index = 0; -wapp_intern VkDevice device = VK_NULL_HANDLE; -wapp_intern VkQueue queue = VK_NULL_HANDLE; -wapp_intern VmaAllocator allocator = VK_NULL_HANDLE; -wapp_intern glm::ivec2 window_size = {}; +wapp_intern constexpr u32 max_frames_in_flight = 2; +wapp_intern bool running = true; +wapp_intern bool update_swapchain = false; +wapp_intern f32 display_scale = 1.0f; +wapp_intern SDL_Window *window = nullptr; +wapp_intern VkInstance instance = VK_NULL_HANDLE; +wapp_intern VkPhysicalDevice physical_device = VK_NULL_HANDLE; +wapp_intern VkSurfaceKHR surface = VK_NULL_HANDLE; +wapp_intern u32 queue_family_index = 0; +wapp_intern VkDevice device = VK_NULL_HANDLE; +wapp_intern VkQueue queue = VK_NULL_HANDLE; +wapp_intern VmaAllocator allocator = VK_NULL_HANDLE; +wapp_intern glm::ivec2 window_size = {}; // NOTE (Abdelrahman): The following three variables are better queried from the physical device // to find the different supported values. For the purposes of this tutorial, we're using defaults // that are guaranteed by the spec to be available on any valid implementation. -wapp_intern VkFormat image_format = VK_FORMAT_B8G8R8A8_SRGB; -wapp_intern VkColorSpaceKHR colorspace = VK_COLOR_SPACE_SRGB_NONLINEAR_KHR; -wapp_intern VkPresentModeKHR present_mode = VK_PRESENT_MODE_FIFO_KHR; -wapp_intern VkSwapchainKHR swapchain = VK_NULL_HANDLE; -wapp_intern u32 swapchain_image_count = 0; -wapp_intern VkImageArray swapchain_images = nullptr; -wapp_intern VkImageViewArray swapchain_views = nullptr; -wapp_intern VkFormat depth_format = VK_FORMAT_UNDEFINED; -wapp_intern VkImage depth_image = VK_NULL_HANDLE; -wapp_intern VkImageView depth_view = VK_NULL_HANDLE; -wapp_intern VmaAllocation depth_allocation = VK_NULL_HANDLE; -wapp_intern VkBuffer vert_index_buf = VK_NULL_HANDLE; -wapp_intern VmaAllocation vert_index_buf_alloc = VK_NULL_HANDLE; -wapp_intern ShaderData shader_data = {}; -wapp_intern ShaderDataBufferArray shader_data_bufs; +wapp_intern VkFormat image_format = VK_FORMAT_B8G8R8A8_SRGB; +wapp_intern VkColorSpaceKHR colorspace = VK_COLOR_SPACE_SRGB_NONLINEAR_KHR; +wapp_intern VkPresentModeKHR present_mode = VK_PRESENT_MODE_FIFO_KHR; +wapp_intern VkSwapchainKHR swapchain = VK_NULL_HANDLE; +wapp_intern u32 swapchain_image_count = 0; +wapp_intern VkImageArray swapchain_images = nullptr; +wapp_intern VkImageViewArray swapchain_views = nullptr; +wapp_intern VkFormat depth_format = VK_FORMAT_UNDEFINED; +wapp_intern VkImage depth_image = VK_NULL_HANDLE; +wapp_intern VkImageView depth_view = VK_NULL_HANDLE; +wapp_intern VmaAllocation depth_allocation = VK_NULL_HANDLE; +wapp_intern VkBuffer vert_index_buf = VK_NULL_HANDLE; +wapp_intern VmaAllocation vert_index_buf_alloc = VK_NULL_HANDLE; +wapp_intern ShaderData shader_data = {}; +wapp_intern ShaderDataBufferArray shader_data_bufs; +wapp_intern VkFenceArray fences = nullptr; +wapp_intern VkSemaphoreArray image_acquired_semaphores = nullptr; +wapp_intern VkSemaphoreArray render_completed_semaphores = nullptr; int main() { // {{{ Initialisation @@ -538,6 +544,34 @@ int main() { } // }}} + // Synchronization Objects {{{ + fences = wapp_array_alloc_capacity(VkFence, &arena, max_frames_in_flight, ARRAY_INIT_FILLED); + check(fences != nullptr, EXIT_CODE_SYNC_OBJ_CREATE_FAILED); + + image_acquired_semaphores = wapp_array_alloc_capacity(VkSemaphore, &arena, max_frames_in_flight, ARRAY_INIT_FILLED); + check(image_acquired_semaphores != nullptr, EXIT_CODE_SYNC_OBJ_CREATE_FAILED); + + // The number of semaphores used to signal rendering needs to match that of the swapchain's images + render_completed_semaphores = wapp_array_alloc_capacity(VkSemaphore, &arena, swapchain_image_count, ARRAY_INIT_FILLED); + check(render_completed_semaphores != nullptr, EXIT_CODE_SYNC_OBJ_CREATE_FAILED); + + VkFenceCreateInfo fence_create_info = {}; + fence_create_info.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO; + fence_create_info.flags = VK_FENCE_CREATE_SIGNALED_BIT; + + VkSemaphoreCreateInfo semaphore_create_info = {}; + semaphore_create_info.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO; + + for (u32 i = 0; i < max_frames_in_flight; ++i) { + check(vkCreateFence(device, &fence_create_info, NULL, &fences[i])); + check(vkCreateSemaphore(device, &semaphore_create_info, NULL, &image_acquired_semaphores[i])); + } + + for (u32 i = 0; i < swapchain_image_count; ++i) { + check(vkCreateSemaphore(device, &semaphore_create_info, NULL, &render_completed_semaphores[i])); + } + // }}} + // {{{ Render Loop SDL_Event event = {}; while (running) { @@ -557,6 +591,14 @@ int main() { // }}} // {{{ Cleanup + + for (u32 i = 0; i < swapchain_image_count; ++i) { + vkDestroySemaphore(device, render_completed_semaphores[i], NULL); + } + for (u32 i = 0; i < max_frames_in_flight; ++i) { + vkDestroySemaphore(device, image_acquired_semaphores[i], NULL); + vkDestroyFence(device, fences[i], NULL); + } for (u32 i = 0; i < max_frames_in_flight; ++i) { vmaDestroyBuffer(allocator, shader_data_bufs[i].buffer, shader_data_bufs[i].allocation); }