diff options
author | omnisci3nce <17525998+omnisci3nce@users.noreply.github.com> | 2024-03-24 21:46:48 +1100 |
---|---|---|
committer | omnisci3nce <17525998+omnisci3nce@users.noreply.github.com> | 2024-03-24 21:46:48 +1100 |
commit | ce14deef131d3f4e11af6a1817fa1b786201ea12 (patch) | |
tree | 11937efcda9fcb582008f34cbb67b10d4653d45d /src | |
parent | 8b9094ff517126ed102b79425e5fe4c67c589e47 (diff) |
command pool and allocate command buffers
Diffstat (limited to 'src')
-rw-r--r-- | src/renderer/backends/backend_vulkan.c | 102 |
1 files changed, 100 insertions, 2 deletions
diff --git a/src/renderer/backends/backend_vulkan.c b/src/renderer/backends/backend_vulkan.c index ba12696..f6fc505 100644 --- a/src/renderer/backends/backend_vulkan.c +++ b/src/renderer/backends/backend_vulkan.c @@ -28,6 +28,8 @@ #include <glfw3.h> +KITC_DECL_TYPED_ARRAY(VkLayerProperties) + typedef struct vulkan_device { VkPhysicalDevice physical_device; VkDevice logical_device; @@ -40,6 +42,7 @@ typedef struct vulkan_device { VkQueue present_queue; VkQueue compute_queue; VkQueue transfer_queue; + VkCommandPool gfx_command_pool; VkPhysicalDeviceProperties properties; VkPhysicalDeviceFeatures features; VkPhysicalDeviceMemoryProperties memory; @@ -86,6 +89,9 @@ typedef enum vulkan_command_buffer_state { COMMAND_BUFFER_STATE_READY, COMMAND_BUFFER_STATE_IN_RENDER_PASS, COMMAND_BUFFER_STATE_RECORDING, + COMMAND_BUFFER_STATE_RECORDING_ENDED, + COMMAND_BUFFER_STATE_SUBMITTED, + COMMAND_BUFFER_STATE_NOT_ALLOCATED, } vulkan_command_buffer_state; typedef struct vulkan_command_buffer { @@ -93,6 +99,8 @@ typedef struct vulkan_command_buffer { vulkan_command_buffer_state state; } vulkan_command_buffer; +KITC_DECL_TYPED_ARRAY(vulkan_command_buffer) + typedef struct vulkan_context { VkInstance instance; VkAllocationCallbacks* allocator; @@ -102,6 +110,8 @@ typedef struct vulkan_context { u32 framebuffer_height; vulkan_swapchain swapchain; vulkan_renderpass main_renderpass; + vulkan_command_buffer_darray* gfx_command_buffers; + u32 image_index; u32 current_frame; @@ -118,8 +128,6 @@ static vulkan_context context; typedef struct vulkan_state { } vulkan_state; -KITC_DECL_TYPED_ARRAY(VkLayerProperties) - bool select_physical_device(vulkan_context* ctx) { u32 physical_device_count = 0; VK_CHECK(vkEnumeratePhysicalDevices(ctx->instance, &physical_device_count, 0)); @@ -255,6 +263,14 @@ bool vulkan_device_create(vulkan_context* context) { vkGetDeviceQueue(context->device.logical_device, context->device.transfer_queue_index, 0, &context->device.transfer_queue); + // create command pool for graphics queue + VkCommandPoolCreateInfo pool_create_info = { VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO }; + pool_create_info.queueFamilyIndex = context->device.graphics_queue_index; + pool_create_info.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT; + vkCreateCommandPool(context->device.logical_device, &pool_create_info, context->allocator, + &context->device.gfx_command_pool); + INFO("Created Command Pool") + return true; } void vulkan_device_destroy(vulkan_context* context) { @@ -365,6 +381,74 @@ void vulkan_image_create(vulkan_context* context, VkImageType image_type, u32 wi // TODO: vulkan_image_destroy +void vulkan_command_buffer_allocate(vulkan_context* context, VkCommandPool pool, bool is_primary, + vulkan_command_buffer* out_command_buffer) { + VkCommandBufferAllocateInfo allocate_info = { VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO }; + allocate_info.commandPool = pool; + allocate_info.level = + is_primary ? VK_COMMAND_BUFFER_LEVEL_PRIMARY : VK_COMMAND_BUFFER_LEVEL_SECONDARY; + allocate_info.commandBufferCount = 1; + allocate_info.pNext = 0; + + out_command_buffer->state = COMMAND_BUFFER_STATE_NOT_ALLOCATED; + vkAllocateCommandBuffers(context->device.logical_device, &allocate_info, + &out_command_buffer->handle); + out_command_buffer->state = COMMAND_BUFFER_STATE_READY; +} + +void vulkan_command_buffer_free(vulkan_context* context, VkCommandPool pool, + vulkan_command_buffer* out_command_buffer) { + // TODO: implement freeing +} + +void vulkan_command_buffer_begin(vulkan_command_buffer* command_buffer, bool is_single_use, + bool is_renderpass_continue, bool is_simultaneous_use) { + VkCommandBufferBeginInfo begin_info = { VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO }; + begin_info.flags = 0; + if (is_single_use) { + begin_info.flags |= VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT; + } + // TODO: RENDER_PASS_CONTINUE_BIT & SIMULTANEOUS_USE_BIT + + begin_info.pNext = 0; + begin_info.pInheritanceInfo = 0; + vkBeginCommandBuffer(command_buffer->handle, &begin_info); + + command_buffer->state = COMMAND_BUFFER_STATE_RECORDING; +} + +void vulkan_command_buffer_end(vulkan_command_buffer* command_buffer) { + VK_CHECK(vkEndCommandBuffer(command_buffer->handle)); + command_buffer->state = COMMAND_BUFFER_STATE_RECORDING_ENDED; +} +void vulkan_command_buffer_update_submitted(vulkan_command_buffer* command_buffer) { + command_buffer->state = COMMAND_BUFFER_STATE_SUBMITTED; +} +void vulkan_command_buffer_reset(vulkan_command_buffer* command_buffer) { + command_buffer->state = COMMAND_BUFFER_STATE_READY; +} + +void vulkan_command_buffer_allocate_and_begin_oneshot(vulkan_context* context, VkCommandPool pool, + vulkan_command_buffer* out_command_buffer) { + vulkan_command_buffer_allocate(context, pool, true, out_command_buffer); + vulkan_command_buffer_begin(out_command_buffer, true, false, false); +} + +void vulkan_command_buffer_end_oneshot(vulkan_context* context, VkCommandPool pool, + vulkan_command_buffer* command_buffer, VkQueue queue) { + vulkan_command_buffer_end(command_buffer); + + // submit to queue + VkSubmitInfo submit_info = { VK_STRUCTURE_TYPE_SUBMIT_INFO }; + submit_info.commandBufferCount = 1; + submit_info.pCommandBuffers = &command_buffer->handle; + VK_CHECK(vkQueueSubmit(queue, 1, &submit_info, 0)); + // wait for it to finish + VK_CHECK(vkQueueWaitIdle(queue)); + + vulkan_command_buffer_free(context, pool, command_buffer); +} + void vulkan_swapchain_create(vulkan_context* context, u32 width, u32 height, vulkan_swapchain* out_swapchain) { VkExtent2D swapchain_extent = { width, height }; @@ -617,6 +701,17 @@ void vulkan_renderpass_end(vulkan_command_buffer* command_buffer, vulkan_renderp command_buffer->state = COMMAND_BUFFER_STATE_RECORDING; } +void create_command_buffers(renderer* ren) { + if (!context.gfx_command_buffers) { + context.gfx_command_buffers = vulkan_command_buffer_darray_new(context.swapchain.image_count); + } + + for (u32 i = 0; i < context.swapchain.image_count; i++) { + vulkan_command_buffer_allocate(&context, context.device.gfx_command_pool, true, + &context.gfx_command_buffers->data[i]); + } +} + bool gfx_backend_init(renderer* ren) { INFO("loading Vulkan backend"); @@ -739,6 +834,9 @@ bool gfx_backend_init(renderer* ren) { vec4(0, 0, context.framebuffer_width, context.framebuffer_height), vec4(0.0, 0.0, 0.2, 1.0), 1.0, 0); + // Command buffers creation + create_command_buffers(ren); + INFO("Vulkan renderer initialisation succeeded"); return true; } |