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 <cstring>
|
||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
#include <array>
|
#include <array>
|
||||||
|
#include <limits>
|
||||||
|
|
||||||
#include "gfx_rendering_api.h"
|
#include "gfx_rendering_api.h"
|
||||||
#include "gfx_pc.h"
|
#include "gfx_pc.h"
|
||||||
|
@ -22,6 +23,15 @@ static std::vector<VkImage> swapchain_images;
|
||||||
static std::vector<VkImageView> swapchain_views;
|
static std::vector<VkImageView> swapchain_views;
|
||||||
static VkRenderPass render_pass = VK_NULL_HANDLE;
|
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
|
VKAPI_ATTR VkBool32 VKAPI_CALL
|
||||||
gfx_vulkan_debug_callback(VkDebugUtilsMessageSeverityFlagBitsEXT messageSeverity,
|
gfx_vulkan_debug_callback(VkDebugUtilsMessageSeverityFlagBitsEXT messageSeverity,
|
||||||
VkDebugUtilsMessageTypeFlagsEXT messageType,
|
VkDebugUtilsMessageTypeFlagsEXT messageType,
|
||||||
|
@ -415,11 +425,37 @@ static void gfx_vulkan_create_render_pass() {
|
||||||
vkCreateRenderPass(device, &render_pass_create_info, nullptr, &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) {
|
static void gfx_vulkan_renderer_init(void) {
|
||||||
gfx_vulkan_create_instance();
|
gfx_vulkan_create_instance();
|
||||||
gfx_vulkan_create_device();
|
gfx_vulkan_create_device();
|
||||||
gfx_vulkan_create_swapchain();
|
gfx_vulkan_create_swapchain();
|
||||||
gfx_vulkan_create_render_pass();
|
gfx_vulkan_create_render_pass();
|
||||||
|
gfx_vulkan_create_sync();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void gfx_vulkan_renderer_on_resize(void) {
|
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) {
|
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) {
|
static void gfx_vulkan_renderer_end_frame(void) {
|
||||||
|
vkEndCommandBuffer(current_cmd);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void gfx_vulkan_renderer_finish_render(void) {
|
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() {
|
static const char* gfx_vulkan_get_name() {
|
||||||
|
|
Loading…
Add table
Reference in a new issue