diff --git a/examples/VulkanTest/main.cpp b/examples/VulkanTest/main.cpp index 811c8a21f..b1991c6e1 100644 --- a/examples/VulkanTest/main.cpp +++ b/examples/VulkanTest/main.cpp @@ -274,6 +274,11 @@ int main() Nz::UInt32 imageCount = vulkanWindow.GetFramebufferCount(); std::vector renderCmds = cmdPool.AllocateCommandBuffers(imageCount, VK_COMMAND_BUFFER_LEVEL_PRIMARY); + + std::vector fences(imageCount); + for (auto& fence : fences) + fence.Create(vulkanDevice.shared_from_this()); + for (Nz::UInt32 i = 0; i < imageCount; ++i) { Nz::Vk::CommandBuffer& renderCmd = renderCmds[i]; @@ -317,7 +322,7 @@ int main() 1U }; - renderCmd.Begin(VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT); + renderCmd.Begin(); vulkanWindow.BuildPreRenderCommands(i, renderCmd); @@ -426,6 +431,9 @@ int main() return EXIT_FAILURE; } + fences[imageIndex].Wait(); + fences[imageIndex].Reset(); + VkCommandBuffer renderCmdBuffer = renderCmds[imageIndex]; VkSemaphore waitSemaphore = vulkanWindow.GetRenderSemaphore(); @@ -442,7 +450,7 @@ int main() nullptr // const VkSemaphore *pSignalSemaphores }; - if (!graphicsQueue.Submit(submit_info)) + if (!graphicsQueue.Submit(submit_info, fences[imageIndex])) return false; vulkanWindow.Present(imageIndex); diff --git a/include/Nazara/VulkanRenderer/Wrapper.hpp b/include/Nazara/VulkanRenderer/Wrapper.hpp index 651a8e04f..84f8cd991 100644 --- a/include/Nazara/VulkanRenderer/Wrapper.hpp +++ b/include/Nazara/VulkanRenderer/Wrapper.hpp @@ -14,6 +14,7 @@ #include #include #include +#include #include #include #include diff --git a/include/Nazara/VulkanRenderer/Wrapper/CommandBuffer.hpp b/include/Nazara/VulkanRenderer/Wrapper/CommandBuffer.hpp index aad18cee7..c5164ebf5 100644 --- a/include/Nazara/VulkanRenderer/Wrapper/CommandBuffer.hpp +++ b/include/Nazara/VulkanRenderer/Wrapper/CommandBuffer.hpp @@ -27,7 +27,7 @@ namespace Nz inline ~CommandBuffer(); inline bool Begin(const VkCommandBufferBeginInfo& info); - inline bool Begin(VkCommandBufferUsageFlags flags); + inline bool Begin(VkCommandBufferUsageFlags flags = 0); inline bool Begin(VkCommandBufferUsageFlags flags, const VkCommandBufferInheritanceInfo& inheritanceInfo); inline bool Begin(VkCommandBufferUsageFlags flags, VkRenderPass renderPass, UInt32 subpass, VkFramebuffer framebuffer, bool occlusionQueryEnable, VkQueryControlFlags queryFlags, VkQueryPipelineStatisticFlags pipelineStatistics); inline bool Begin(VkCommandBufferUsageFlags flags, bool occlusionQueryEnable, VkQueryControlFlags queryFlags, VkQueryPipelineStatisticFlags pipelineStatistics); diff --git a/include/Nazara/VulkanRenderer/Wrapper/Device.hpp b/include/Nazara/VulkanRenderer/Wrapper/Device.hpp index cbf50d052..f38885fb6 100644 --- a/include/Nazara/VulkanRenderer/Wrapper/Device.hpp +++ b/include/Nazara/VulkanRenderer/Wrapper/Device.hpp @@ -119,6 +119,7 @@ namespace Nz NAZARA_VULKANRENDERER_DEVICE_FUNCTION(vkCreateDescriptorPool); NAZARA_VULKANRENDERER_DEVICE_FUNCTION(vkCreateDescriptorSetLayout); NAZARA_VULKANRENDERER_DEVICE_FUNCTION(vkCreateEvent); + NAZARA_VULKANRENDERER_DEVICE_FUNCTION(vkCreateFence); NAZARA_VULKANRENDERER_DEVICE_FUNCTION(vkCreateFramebuffer); NAZARA_VULKANRENDERER_DEVICE_FUNCTION(vkCreateGraphicsPipelines); NAZARA_VULKANRENDERER_DEVICE_FUNCTION(vkCreateImage); @@ -136,6 +137,7 @@ namespace Nz NAZARA_VULKANRENDERER_DEVICE_FUNCTION(vkDestroyDescriptorSetLayout); NAZARA_VULKANRENDERER_DEVICE_FUNCTION(vkDestroyDevice); NAZARA_VULKANRENDERER_DEVICE_FUNCTION(vkDestroyEvent); + NAZARA_VULKANRENDERER_DEVICE_FUNCTION(vkDestroyFence); NAZARA_VULKANRENDERER_DEVICE_FUNCTION(vkDestroyFramebuffer); NAZARA_VULKANRENDERER_DEVICE_FUNCTION(vkDestroyImage); NAZARA_VULKANRENDERER_DEVICE_FUNCTION(vkDestroyImageView); diff --git a/include/Nazara/VulkanRenderer/Wrapper/Fence.hpp b/include/Nazara/VulkanRenderer/Wrapper/Fence.hpp new file mode 100644 index 000000000..480e5524e --- /dev/null +++ b/include/Nazara/VulkanRenderer/Wrapper/Fence.hpp @@ -0,0 +1,47 @@ +// Copyright (C) 2016 Jérôme Leclercq +// This file is part of the "Nazara Engine - Vulkan Renderer" +// For conditions of distribution and use, see copyright notice in Config.hpp + +#pragma once + +#ifndef NAZARA_VULKANRENDERER_VKFENCE_HPP +#define NAZARA_VULKANRENDERER_VKFENCE_HPP + +#include +#include + +namespace Nz +{ + namespace Vk + { + class Fence : public DeviceObject + { + friend DeviceObject; + + public: + Fence() = default; + Fence(const Fence&) = delete; + Fence(Fence&&) = default; + ~Fence() = default; + + using DeviceObject::Create; + inline bool Create(DeviceHandle device, VkFenceCreateFlags flags = 0, const VkAllocationCallbacks* allocator = nullptr); + + inline bool Reset(); + + inline bool Wait(); + inline bool Wait(UInt64 timeout, bool* didTimeout = nullptr); + + Fence& operator=(const Fence&) = delete; + Fence& operator=(Fence&&) = delete; + + private: + static inline VkResult CreateHelper(const DeviceHandle& device, const VkFenceCreateInfo* createInfo, const VkAllocationCallbacks* allocator, VkFence* handle); + static inline void DestroyHelper(const DeviceHandle& device, VkFence handle, const VkAllocationCallbacks* allocator); + }; + } +} + +#include + +#endif // NAZARA_VULKANRENDERER_VKFENCE_HPP diff --git a/include/Nazara/VulkanRenderer/Wrapper/Fence.inl b/include/Nazara/VulkanRenderer/Wrapper/Fence.inl new file mode 100644 index 000000000..c67bfc6e5 --- /dev/null +++ b/include/Nazara/VulkanRenderer/Wrapper/Fence.inl @@ -0,0 +1,68 @@ +// Copyright (C) 2016 Jérôme Leclercq +// This file is part of the "Nazara Engine - Vulkan Renderer" +// For conditions of distribution and use, see copyright notice in Config.hpp + +#include +#include + +namespace Nz +{ + namespace Vk + { + inline bool Fence::Create(DeviceHandle device, VkFenceCreateFlags flags, const VkAllocationCallbacks* allocator) + { + VkFenceCreateInfo createInfo = + { + VK_STRUCTURE_TYPE_FENCE_CREATE_INFO, + nullptr, + flags + }; + + return Create(std::move(device), createInfo, allocator); + } + + inline bool Fence::Reset() + { + m_lastErrorCode = m_device->vkResetFences(*m_device, 1U, &m_handle); + if (m_lastErrorCode != VK_SUCCESS) + { + NazaraError("Failed to reset fence: " + TranslateVulkanError(m_lastErrorCode)); + return false; + } + + return true; + } + + inline bool Fence::Wait() + { + return Wait(std::numeric_limits::max()); + } + + inline bool Fence::Wait(UInt64 timeout, bool* didTimeout) + { + m_lastErrorCode = m_device->vkWaitForFences(*m_device, 1U, &m_handle, VK_TRUE, timeout); + if (m_lastErrorCode != VK_SUCCESS && m_lastErrorCode != VK_TIMEOUT) + { + NazaraError("Failed to wait for fence: " + TranslateVulkanError(m_lastErrorCode)); + return false; + } + + if (didTimeout) + *didTimeout = (m_lastErrorCode == VK_TIMEOUT); + + return true; + } + + inline VkResult Fence::CreateHelper(const DeviceHandle& device, const VkFenceCreateInfo* createInfo, const VkAllocationCallbacks* allocator, VkFence* handle) + { + return device->vkCreateFence(*device, createInfo, allocator, handle); + } + + inline void Fence::DestroyHelper(const DeviceHandle& device, VkFence handle, const VkAllocationCallbacks* allocator) + { + return device->vkDestroyFence(*device, handle, allocator); + } + } +} + +#include diff --git a/src/Nazara/VulkanRenderer/Wrapper/Device.cpp b/src/Nazara/VulkanRenderer/Wrapper/Device.cpp index 26e6c949e..32a54641c 100644 --- a/src/Nazara/VulkanRenderer/Wrapper/Device.cpp +++ b/src/Nazara/VulkanRenderer/Wrapper/Device.cpp @@ -107,6 +107,7 @@ namespace Nz NAZARA_VULKANRENDERER_LOAD_DEVICE(vkCreateDescriptorPool); NAZARA_VULKANRENDERER_LOAD_DEVICE(vkCreateDescriptorSetLayout); NAZARA_VULKANRENDERER_LOAD_DEVICE(vkCreateEvent); + NAZARA_VULKANRENDERER_LOAD_DEVICE(vkCreateFence); NAZARA_VULKANRENDERER_LOAD_DEVICE(vkCreateFramebuffer); NAZARA_VULKANRENDERER_LOAD_DEVICE(vkCreateGraphicsPipelines); NAZARA_VULKANRENDERER_LOAD_DEVICE(vkCreateImage); @@ -124,6 +125,7 @@ namespace Nz NAZARA_VULKANRENDERER_LOAD_DEVICE(vkDestroyDescriptorSetLayout); NAZARA_VULKANRENDERER_LOAD_DEVICE(vkDestroyDevice); NAZARA_VULKANRENDERER_LOAD_DEVICE(vkDestroyEvent); + NAZARA_VULKANRENDERER_LOAD_DEVICE(vkDestroyFence); NAZARA_VULKANRENDERER_LOAD_DEVICE(vkDestroyFramebuffer); NAZARA_VULKANRENDERER_LOAD_DEVICE(vkDestroyImage); NAZARA_VULKANRENDERER_LOAD_DEVICE(vkDestroyImageView);