From e875198b37a2927a5f62ceeca4d114021d8381ec Mon Sep 17 00:00:00 2001 From: Magnus Norddahl Date: Tue, 26 Feb 2019 11:44:29 +0100 Subject: [PATCH] - create raii objects for semaphore and fence --- src/rendering/vulkan/system/vk_device.cpp | 43 ++++--------- src/rendering/vulkan/system/vk_device.h | 8 ++- .../vulkan/system/vk_framebuffer.cpp | 6 +- src/rendering/vulkan/system/vk_objects.h | 60 +++++++++++++++++++ 4 files changed, 79 insertions(+), 38 deletions(-) diff --git a/src/rendering/vulkan/system/vk_device.cpp b/src/rendering/vulkan/system/vk_device.cpp index 29d4c15de1..0364c1b8cf 100644 --- a/src/rendering/vulkan/system/vk_device.cpp +++ b/src/rendering/vulkan/system/vk_device.cpp @@ -40,6 +40,7 @@ extern HWND Window; #include "vk_device.h" #include "vk_swapchain.h" +#include "vk_objects.h" #include "c_cvars.h" #include "i_system.h" #include "version.h" @@ -100,20 +101,20 @@ void VulkanDevice::windowResized() void VulkanDevice::waitPresent() { - vkWaitForFences(device, 1, &renderFinishedFence, VK_TRUE, std::numeric_limits::max()); - vkResetFences(device, 1, &renderFinishedFence); + vkWaitForFences(device, 1, &renderFinishedFence->fence, VK_TRUE, std::numeric_limits::max()); + vkResetFences(device, 1, &renderFinishedFence->fence); } void VulkanDevice::beginFrame() { - VkResult result = vkAcquireNextImageKHR(device, swapChain->swapChain, std::numeric_limits::max(), imageAvailableSemaphore, VK_NULL_HANDLE, &presentImageIndex); + VkResult result = vkAcquireNextImageKHR(device, swapChain->swapChain, std::numeric_limits::max(), imageAvailableSemaphore->semaphore, VK_NULL_HANDLE, &presentImageIndex); if (result != VK_SUCCESS) throw std::runtime_error("Failed to acquire next image!"); } void VulkanDevice::presentFrame() { - VkSemaphore waitSemaphores[] = { renderFinishedSemaphore }; + VkSemaphore waitSemaphores[] = { renderFinishedSemaphore->semaphore }; VkSwapchainKHR swapChains[] = { swapChain->swapChain }; VkPresentInfoKHR presentInfo = {}; @@ -374,22 +375,9 @@ void VulkanDevice::createAllocator() void VulkanDevice::createSemaphores() { - VkSemaphoreCreateInfo semaphoreInfo = {}; - semaphoreInfo.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO; - - VkResult result = vkCreateSemaphore(device, &semaphoreInfo, nullptr, &imageAvailableSemaphore); - if (result != VK_SUCCESS) - throw std::runtime_error("Failed to create semaphore!"); - - result = vkCreateSemaphore(device, &semaphoreInfo, nullptr, &renderFinishedSemaphore); - if (result != VK_SUCCESS) - throw std::runtime_error("Failed to create semaphore!"); - - VkFenceCreateInfo fenceInfo = {}; - fenceInfo.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO; - result = vkCreateFence(device, &fenceInfo, nullptr, &renderFinishedFence); - if (result != VK_SUCCESS) - throw std::runtime_error("Failed to create fence!"); + imageAvailableSemaphore.reset(new VulkanSemaphore(this)); + renderFinishedSemaphore.reset(new VulkanSemaphore(this)); + renderFinishedFence.reset(new VulkanFence(this)); } void VulkanDevice::releaseResources() @@ -397,18 +385,9 @@ void VulkanDevice::releaseResources() if (device) vkDeviceWaitIdle(device); - if (imageAvailableSemaphore) - vkDestroySemaphore(device, imageAvailableSemaphore, nullptr); - imageAvailableSemaphore = 0; - - if (renderFinishedSemaphore) - vkDestroySemaphore(device, renderFinishedSemaphore, nullptr); - renderFinishedSemaphore = 0; - - if (renderFinishedFence) - vkDestroyFence(device, renderFinishedFence, nullptr); - renderFinishedFence = 0; - + imageAvailableSemaphore.reset(); + renderFinishedSemaphore.reset(); + renderFinishedFence.reset(); swapChain.reset(); if (device) diff --git a/src/rendering/vulkan/system/vk_device.h b/src/rendering/vulkan/system/vk_device.h index d820ac0c83..6beeb6554a 100644 --- a/src/rendering/vulkan/system/vk_device.h +++ b/src/rendering/vulkan/system/vk_device.h @@ -7,6 +7,8 @@ #include class VulkanSwapChain; +class VulkanSemaphore; +class VulkanFence; class VulkanDevice { @@ -33,9 +35,9 @@ public: VkQueue graphicsQueue = nullptr; - VkSemaphore imageAvailableSemaphore = VK_NULL_HANDLE; - VkSemaphore renderFinishedSemaphore = VK_NULL_HANDLE; - VkFence renderFinishedFence = VK_NULL_HANDLE; + std::unique_ptr imageAvailableSemaphore; + std::unique_ptr renderFinishedSemaphore; + std::unique_ptr renderFinishedFence; VmaAllocator allocator = VK_NULL_HANDLE; diff --git a/src/rendering/vulkan/system/vk_framebuffer.cpp b/src/rendering/vulkan/system/vk_framebuffer.cpp index de71fbfdbb..ae1e8b110b 100644 --- a/src/rendering/vulkan/system/vk_framebuffer.cpp +++ b/src/rendering/vulkan/system/vk_framebuffer.cpp @@ -109,7 +109,7 @@ void VulkanFrameBuffer::Update() mPresentCommands->end(); - VkSemaphore waitSemaphores[] = { device->imageAvailableSemaphore }; + VkSemaphore waitSemaphores[] = { device->imageAvailableSemaphore->semaphore }; VkPipelineStageFlags waitStages[] = { VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT }; VkSubmitInfo submitInfo = {}; @@ -120,8 +120,8 @@ void VulkanFrameBuffer::Update() submitInfo.commandBufferCount = 1; submitInfo.pCommandBuffers = &mPresentCommands->buffer; submitInfo.signalSemaphoreCount = 1; - submitInfo.pSignalSemaphores = &device->renderFinishedSemaphore; - VkResult result = vkQueueSubmit(device->graphicsQueue, 1, &submitInfo, device->renderFinishedFence); + submitInfo.pSignalSemaphores = &device->renderFinishedSemaphore->semaphore; + VkResult result = vkQueueSubmit(device->graphicsQueue, 1, &submitInfo, device->renderFinishedFence->fence); if (result != VK_SUCCESS) I_FatalError("Failed to submit command buffer!\n"); diff --git a/src/rendering/vulkan/system/vk_objects.h b/src/rendering/vulkan/system/vk_objects.h index 9492fe1edd..959a356905 100644 --- a/src/rendering/vulkan/system/vk_objects.h +++ b/src/rendering/vulkan/system/vk_objects.h @@ -5,6 +5,34 @@ class VulkanCommandPool; class VulkanDescriptorPool; +class VulkanSemaphore +{ +public: + VulkanSemaphore(VulkanDevice *device); + ~VulkanSemaphore(); + + VulkanDevice *device = nullptr; + VkSemaphore semaphore = VK_NULL_HANDLE; + +private: + VulkanSemaphore(const VulkanSemaphore &) = delete; + VulkanSemaphore &operator=(const VulkanSemaphore &) = delete; +}; + +class VulkanFence +{ +public: + VulkanFence(VulkanDevice *device); + ~VulkanFence(); + + VulkanDevice *device = nullptr; + VkFence fence = VK_NULL_HANDLE; + +private: + VulkanFence(const VulkanFence &) = delete; + VulkanFence &operator=(const VulkanFence &) = delete; +}; + class VulkanBuffer { public: @@ -300,6 +328,38 @@ private: ///////////////////////////////////////////////////////////////////////////// +inline VulkanSemaphore::VulkanSemaphore(VulkanDevice *device) : device(device) +{ + VkSemaphoreCreateInfo semaphoreInfo = {}; + semaphoreInfo.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO; + VkResult result = vkCreateSemaphore(device->device, &semaphoreInfo, nullptr, &semaphore); + if (result != VK_SUCCESS) + throw std::runtime_error("Failed to create semaphore!"); +} + +inline VulkanSemaphore::~VulkanSemaphore() +{ + vkDestroySemaphore(device->device, semaphore, nullptr); +} + +///////////////////////////////////////////////////////////////////////////// + +inline VulkanFence::VulkanFence(VulkanDevice *device) : device(device) +{ + VkFenceCreateInfo fenceInfo = {}; + fenceInfo.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO; + VkResult result = vkCreateFence(device->device, &fenceInfo, nullptr, &fence); + if (result != VK_SUCCESS) + throw std::runtime_error("Failed to create fence!"); +} + +inline VulkanFence::~VulkanFence() +{ + vkDestroyFence(device->device, fence, nullptr); +} + +///////////////////////////////////////////////////////////////////////////// + inline VulkanBuffer::VulkanBuffer(VulkanDevice *device, VkBuffer buffer, VmaAllocation allocation, size_t size) : device(device), buffer(buffer), allocation(allocation), size(size) { }