diff options
author | omnisci3nce <17525998+omnisci3nce@users.noreply.github.com> | 2024-03-25 20:43:37 +1100 |
---|---|---|
committer | omnisci3nce <17525998+omnisci3nce@users.noreply.github.com> | 2024-03-25 20:43:37 +1100 |
commit | 8752fe1132f0fb19a7ac90dd257417a088e32100 (patch) | |
tree | 02f7890830f2c45d659dcfd67329f00ec1ae3b35 | |
parent | d3e977d6461738ca19d427f99a428b9fa537a26c (diff) |
sync objects
-rw-r--r-- | src/renderer/backends/backend_vulkan.c | 103 |
1 files changed, 97 insertions, 6 deletions
diff --git a/src/renderer/backends/backend_vulkan.c b/src/renderer/backends/backend_vulkan.c index 407053a..81a08e2 100644 --- a/src/renderer/backends/backend_vulkan.c +++ b/src/renderer/backends/backend_vulkan.c @@ -111,6 +111,11 @@ typedef struct vulkan_command_buffer { KITC_DECL_TYPED_ARRAY(vulkan_command_buffer) +typedef struct vulkan_fence { + VkFence handle; + bool is_signaled; +} vulkan_fence; + typedef struct vulkan_context { VkInstance instance; VkAllocationCallbacks* allocator; @@ -122,6 +127,12 @@ typedef struct vulkan_context { vulkan_renderpass main_renderpass; vulkan_command_buffer_darray* gfx_command_buffers; + VkSemaphore* image_available_semaphores; + VkSemaphore* queue_complete_semaphores; + u32 in_flight_fence_count; + vulkan_fence* in_flight_fences; + vulkan_fence** images_in_flight; + u32 image_index; u32 current_frame; @@ -394,17 +405,23 @@ void vulkan_image_create(vulkan_context* context, VkImageType image_type, u32 wi void vulkan_framebuffer_create(vulkan_context* context, vulkan_renderpass* renderpass, u32 width, u32 height, u32 attachment_count, VkImageView* attachments, vulkan_framebuffer* out_framebuffer) { - out_framebuffer->attachments = malloc(sizeof(VKImageView) * attachment_count); + out_framebuffer->attachments = malloc(sizeof(VkImageView) * attachment_count); for (u32 i = 0; i < attachment_count; i++) { out_framebuffer->attachments[i] = attachments[i]; } out_framebuffer->attachment_count = attachment_count; out_framebuffer->renderpass = renderpass; - VkFramebufferCreateInfo framebuffer_create_info = {}; // TODO + VkFramebufferCreateInfo framebuffer_create_info = { + VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO + }; // TODO framebuffer_create_info.renderPass = renderpass->handle; - // TODO: fill out info - https://youtu.be/Is6CwlsaCFE?si=86ZGxU7S8licijCD&t=252 + framebuffer_create_info.attachmentCount = attachment_count; + framebuffer_create_info.pAttachments = out_framebuffer->attachments; + framebuffer_create_info.width = width; + framebuffer_create_info.height = height; + framebuffer_create_info.layers = 1; vkCreateFramebuffer(context->device.logical_device, &framebuffer_create_info, context->allocator, &out_framebuffer->handle); @@ -613,6 +630,9 @@ void vulkan_swapchain_present(vulkan_context* context, vulkan_swapchain* swapcha if (result != VK_SUCCESS) { FATAL("Failed to present swapchain iamge"); } + + // advance the current frame + context->current_frame = (context->current_frame + 1) % swapchain->max_frames_in_flight; } void vulkan_renderpass_create(vulkan_context* context, vulkan_renderpass* out_renderpass, @@ -748,11 +768,52 @@ void regenerate_framebuffers(renderer* ren, vulkan_swapchain* swapchain, for (u32 i = 0; i < swapchain->image_count; i++) { u32 attachment_count = 2; // one for depth, one for colour - VkImageView attachments[2] = { swapchain->views[i], swapchain->depth_attachment }; + VkImageView attachments[2] = { swapchain->views[i], swapchain->depth_attachment.view }; - vulkan_framebuffer_create(context, renderpass, context.framebuffer_width, + vulkan_framebuffer_create(&context, renderpass, context.framebuffer_width, context.framebuffer_height, 2, attachments, - swapchain->framebuffers->data[i]); + &swapchain->framebuffers->data[i]); + } +} + +void vulkan_fence_create(vulkan_context* context, bool create_signaled, vulkan_fence* out_fence) { + out_fence->is_signaled = create_signaled; + VkFenceCreateInfo fence_create_info = { VK_STRUCTURE_TYPE_FENCE_CREATE_INFO }; + if (out_fence->is_signaled) { + fence_create_info.flags = VK_FENCE_CREATE_SIGNALED_BIT; + } + + vkCreateFence(context->device.logical_device, &fence_create_info, context->allocator, + &out_fence->handle); +} + +// TODO: vulkan_fence_destroy + +bool vulkan_fence_wait(vulkan_context* context, vulkan_fence* fence, u64 timeout_ns) { + if (!fence->is_signaled) { + VkResult result = + vkWaitForFences(context->device.logical_device, 1, &fence->handle, true, timeout_ns); + switch (result) { + case VK_SUCCESS: + fence->is_signaled = true; + return true; + case VK_TIMEOUT: + WARN("vk_fence_wait - Timed out"); + break; + default: + ERROR("vk_fence_wait - Unhanlded error type"); + break; + } + } else { + return true; + } + + return false; +} +void vulkan_fence_reset(vulkan_context* context, vulkan_fence* fence) { + if (fence->is_signaled) { + vkResetFences(context->device.logical_device, 1, &fence->handle); + fence->is_signaled = false; } } @@ -764,6 +825,9 @@ bool gfx_backend_init(renderer* ren) { context.allocator = 0; // TODO: custom allocator + context.framebuffer_width = SCR_WIDTH; + context.framebuffer_height = SCR_HEIGHT; + // Setup Vulkan instance VkApplicationInfo app_info = { VK_STRUCTURE_TYPE_APPLICATION_INFO }; app_info.apiVersion = VK_API_VERSION_1_3; @@ -881,9 +945,36 @@ bool gfx_backend_init(renderer* ren) { // Framebiffers creation context.swapchain.framebuffers = vulkan_framebuffer_darray_new(context.swapchain.image_count); regenerate_framebuffers(ren, &context.swapchain, &context.main_renderpass); + INFO("Framebuffers created"); // Command buffers creation create_command_buffers(ren); + INFO("Command buffers created"); + + // Sync objects + context.image_available_semaphores = + malloc(sizeof(VkSemaphore) * context.swapchain.max_frames_in_flight); + context.queue_complete_semaphores = + malloc(sizeof(VkSemaphore) * context.swapchain.max_frames_in_flight); + context.in_flight_fences = malloc(sizeof(vulkan_fence) * context.swapchain.max_frames_in_flight); + + for (u8 i = 0; i < context.swapchain.max_frames_in_flight; i++) { + VkSemaphoreCreateInfo semaphore_create_info = { VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO }; + vkCreateSemaphore(context.device.logical_device, &semaphore_create_info, context.allocator, + &context.image_available_semaphores[i]); + vkCreateSemaphore(context.device.logical_device, &semaphore_create_info, context.allocator, + &context.queue_complete_semaphores[i]); + + // create the fence in a signaled state + vulkan_fence_create(&context, true, &context.in_flight_fences[i]); + } + + context.images_in_flight = malloc(sizeof(vulkan_fence*) * context.swapchain.max_frames_in_flight); + for (u8 i = 0; i < context.swapchain.max_frames_in_flight; i++) { + context.images_in_flight[i] = 0; + } + + INFO("Sync objects created"); INFO("Vulkan renderer initialisation succeeded"); return true; |