Add Vulkan sync primitives
This commit is contained in:
parent
7def557f92
commit
e5c0552585
1 changed files with 97 additions and 0 deletions
|
@ -5,6 +5,7 @@
|
|||
#include <cstring>
|
||||
#include <cstdio>
|
||||
#include <array>
|
||||
#include <limits>
|
||||
|
||||
#include "gfx_rendering_api.h"
|
||||
#include "gfx_pc.h"
|
||||
|
@ -22,6 +23,15 @@ static std::vector<VkImage> swapchain_images;
|
|||
static std::vector<VkImageView> swapchain_views;
|
||||
static VkRenderPass render_pass = VK_NULL_HANDLE;
|
||||
|
||||
// TODO: removed hardcoded 3 frame queue, should be variable
|
||||
static std::array<VkCommandBuffer, 3> command_buffers;
|
||||
static std::array<VkSemaphore, 3> image_available;
|
||||
static std::array<VkSemaphore, 3> render_finished;
|
||||
static std::array<VkFence, 3> in_flight;
|
||||
static uint32_t current_frame = 0;
|
||||
static uint32_t image_index = 0;
|
||||
static VkCommandBuffer current_cmd = VK_NULL_HANDLE;
|
||||
|
||||
VKAPI_ATTR VkBool32 VKAPI_CALL
|
||||
gfx_vulkan_debug_callback(VkDebugUtilsMessageSeverityFlagBitsEXT messageSeverity,
|
||||
VkDebugUtilsMessageTypeFlagsEXT messageType,
|
||||
|
@ -415,11 +425,37 @@ static void gfx_vulkan_create_render_pass() {
|
|||
vkCreateRenderPass(device, &render_pass_create_info, nullptr, &render_pass);
|
||||
}
|
||||
|
||||
static void gfx_vulkan_create_sync() {
|
||||
for(int i = 0; i < 3; i++) {
|
||||
VkCommandBufferAllocateInfo allocate_info = {};
|
||||
allocate_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
|
||||
allocate_info.commandPool = command_pool;
|
||||
allocate_info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
|
||||
allocate_info.commandBufferCount = 1;
|
||||
|
||||
vkAllocateCommandBuffers(device, &allocate_info, &command_buffers[i]);
|
||||
}
|
||||
|
||||
VkSemaphoreCreateInfo semaphore_create_info = {};
|
||||
semaphore_create_info.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO;
|
||||
|
||||
VkFenceCreateInfo fence_create_info = {};
|
||||
fence_create_info.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
|
||||
fence_create_info.flags = VK_FENCE_CREATE_SIGNALED_BIT;
|
||||
|
||||
for (size_t i = 0; i < 3; i++) {
|
||||
vkCreateSemaphore(device, &semaphore_create_info, nullptr, &image_available[i]);
|
||||
vkCreateSemaphore(device, &semaphore_create_info, nullptr, &render_finished[i]);
|
||||
vkCreateFence(device, &fence_create_info, nullptr, &in_flight[i]);
|
||||
}
|
||||
}
|
||||
|
||||
static void gfx_vulkan_renderer_init(void) {
|
||||
gfx_vulkan_create_instance();
|
||||
gfx_vulkan_create_device();
|
||||
gfx_vulkan_create_swapchain();
|
||||
gfx_vulkan_create_render_pass();
|
||||
gfx_vulkan_create_sync();
|
||||
}
|
||||
|
||||
static void gfx_vulkan_renderer_on_resize(void) {
|
||||
|
@ -427,12 +463,73 @@ static void gfx_vulkan_renderer_on_resize(void) {
|
|||
}
|
||||
|
||||
static void gfx_vulkan_renderer_start_frame(void) {
|
||||
vkWaitForFences(
|
||||
device, 1,
|
||||
&in_flight[current_frame],
|
||||
VK_TRUE, std::numeric_limits<uint64_t>::max());
|
||||
|
||||
image_index = 0;
|
||||
VkResult result = vkAcquireNextImageKHR(
|
||||
device, swapchain,
|
||||
std::numeric_limits<uint64_t>::max(),
|
||||
image_available[current_frame],
|
||||
VK_NULL_HANDLE, &image_index);
|
||||
|
||||
if (result == VK_ERROR_OUT_OF_DATE_KHR) {
|
||||
printf("Swapchain is out of date!\n");
|
||||
return;
|
||||
}
|
||||
|
||||
current_cmd = command_buffers[current_frame];
|
||||
|
||||
VkCommandBufferBeginInfo beginInfo = {};
|
||||
beginInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
|
||||
beginInfo.flags = VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT;
|
||||
|
||||
vkBeginCommandBuffer(current_cmd, &beginInfo);
|
||||
}
|
||||
|
||||
static void gfx_vulkan_renderer_end_frame(void) {
|
||||
vkEndCommandBuffer(current_cmd);
|
||||
}
|
||||
|
||||
static void gfx_vulkan_renderer_finish_render(void) {
|
||||
VkSubmitInfo submit_info = {};
|
||||
submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
|
||||
|
||||
VkSemaphore wait_semaphores[] = {image_available[current_frame]};
|
||||
VkPipelineStageFlags wait_stages[] = {
|
||||
VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT};
|
||||
submit_info.waitSemaphoreCount = 1;
|
||||
submit_info.pWaitSemaphores = wait_semaphores;
|
||||
submit_info.pWaitDstStageMask = wait_stages;
|
||||
submit_info.commandBufferCount = 1;
|
||||
submit_info.pCommandBuffers = ¤t_cmd;
|
||||
|
||||
VkSemaphore signal_semaphores[] = {render_finished[current_frame]};
|
||||
submit_info.signalSemaphoreCount = 1;
|
||||
submit_info.pSignalSemaphores = signal_semaphores;
|
||||
|
||||
vkResetFences(device, 1, &in_flight[current_frame]);
|
||||
|
||||
if (vkQueueSubmit(graphics_queue, 1, &submit_info, in_flight[current_frame]) != VK_SUCCESS) {
|
||||
return;
|
||||
}
|
||||
|
||||
// present
|
||||
VkPresentInfoKHR present_info = {};
|
||||
present_info.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR;
|
||||
|
||||
present_info.waitSemaphoreCount = 1;
|
||||
present_info.pWaitSemaphores = signal_semaphores;
|
||||
VkSwapchainKHR swapChains[] = {swapchain};
|
||||
present_info.swapchainCount = 1;
|
||||
present_info.pSwapchains = swapChains;
|
||||
present_info.pImageIndices = &image_index;
|
||||
|
||||
vkQueuePresentKHR(present_queue, &present_info);
|
||||
|
||||
current_frame = (current_frame + 1) % 3;
|
||||
}
|
||||
|
||||
static const char* gfx_vulkan_get_name() {
|
||||
|
|
Loading…
Add table
Reference in a new issue