- create raii objects for semaphore and fence

This commit is contained in:
Magnus Norddahl 2019-02-26 11:44:29 +01:00
parent 27e78e7d8d
commit e875198b37
4 changed files with 79 additions and 38 deletions

View file

@ -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<uint64_t>::max());
vkResetFences(device, 1, &renderFinishedFence);
vkWaitForFences(device, 1, &renderFinishedFence->fence, VK_TRUE, std::numeric_limits<uint64_t>::max());
vkResetFences(device, 1, &renderFinishedFence->fence);
}
void VulkanDevice::beginFrame()
{
VkResult result = vkAcquireNextImageKHR(device, swapChain->swapChain, std::numeric_limits<uint64_t>::max(), imageAvailableSemaphore, VK_NULL_HANDLE, &presentImageIndex);
VkResult result = vkAcquireNextImageKHR(device, swapChain->swapChain, std::numeric_limits<uint64_t>::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)

View file

@ -7,6 +7,8 @@
#include <algorithm>
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<VulkanSemaphore> imageAvailableSemaphore;
std::unique_ptr<VulkanSemaphore> renderFinishedSemaphore;
std::unique_ptr<VulkanFence> renderFinishedFence;
VmaAllocator allocator = VK_NULL_HANDLE;

View file

@ -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");

View file

@ -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)
{
}