diff --git a/include/Nazara/VulkanRenderer/VulkanRenderImage.hpp b/include/Nazara/VulkanRenderer/VulkanRenderImage.hpp index 07328bea9..00a3242a9 100644 --- a/include/Nazara/VulkanRenderer/VulkanRenderImage.hpp +++ b/include/Nazara/VulkanRenderer/VulkanRenderImage.hpp @@ -14,7 +14,6 @@ #include #include #include -#include namespace Nz { @@ -26,7 +25,7 @@ namespace Nz VulkanRenderImage(VulkanSwapchain& owner); VulkanRenderImage(const VulkanRenderImage&) = delete; VulkanRenderImage(VulkanRenderImage&&) = delete; - ~VulkanRenderImage(); + ~VulkanRenderImage() = default; void Execute(const FunctionRef& callback, QueueTypeFlags queueTypeFlags) override; @@ -47,9 +46,9 @@ namespace Nz VulkanRenderImage& operator=(VulkanRenderImage&&) = delete; private: - std::size_t m_currentCommandBuffer; - std::vector m_inFlightCommandBuffers; - std::vector m_graphicalCommandsBuffers; + std::size_t m_freeCommandBufferIndex; + std::vector m_allocatedCommandBuffers;; + std::vector m_graphicalCommandBuffers; VulkanSwapchain& m_owner; Vk::CommandPool m_commandPool; Vk::Fence m_inFlightFence; diff --git a/include/Nazara/VulkanRenderer/VulkanRenderImage.inl b/include/Nazara/VulkanRenderer/VulkanRenderImage.inl index fa3553403..d1aaa46d1 100644 --- a/include/Nazara/VulkanRenderer/VulkanRenderImage.inl +++ b/include/Nazara/VulkanRenderer/VulkanRenderImage.inl @@ -30,9 +30,10 @@ namespace Nz { FlushReleaseQueue(); - m_graphicalCommandsBuffers.clear(); - m_currentCommandBuffer = 0; + m_graphicalCommandBuffers.clear(); + m_freeCommandBufferIndex = 0; m_imageIndex = imageIndex; + m_commandPool.Reset(); m_uploadPool.Reset(); } } diff --git a/include/Nazara/VulkanRenderer/Wrapper/CommandBuffer.hpp b/include/Nazara/VulkanRenderer/Wrapper/CommandBuffer.hpp index f5c1dcf44..336ea2a40 100644 --- a/include/Nazara/VulkanRenderer/Wrapper/CommandBuffer.hpp +++ b/include/Nazara/VulkanRenderer/Wrapper/CommandBuffer.hpp @@ -22,6 +22,7 @@ namespace Nz::Vk public: inline CommandBuffer(); + inline CommandBuffer(CommandPool& pool, VkCommandBuffer handle); CommandBuffer(const CommandBuffer&) = delete; inline CommandBuffer(CommandBuffer&& commandBuffer) noexcept; ~CommandBuffer() = default; @@ -111,8 +112,6 @@ namespace Nz::Vk inline operator VkCommandBuffer() const; private: - inline CommandBuffer(CommandPool& pool, VkCommandBuffer handle); - CommandPool* m_pool; VkCommandBuffer m_handle; VkResult m_lastErrorCode; diff --git a/include/Nazara/VulkanRenderer/Wrapper/CommandPool.hpp b/include/Nazara/VulkanRenderer/Wrapper/CommandPool.hpp index dcb8d3bcf..7a0aac47a 100644 --- a/include/Nazara/VulkanRenderer/Wrapper/CommandPool.hpp +++ b/include/Nazara/VulkanRenderer/Wrapper/CommandPool.hpp @@ -32,7 +32,7 @@ namespace Nz using DeviceObject::Create; inline bool Create(Device& device, UInt32 queueFamilyIndex, VkCommandPoolCreateFlags flags = 0, const VkAllocationCallbacks* allocator = nullptr); - inline bool Reset(VkCommandPoolResetFlags flags); + inline bool Reset(VkCommandPoolResetFlags flags = 0); CommandPool& operator=(const CommandPool&) = delete; CommandPool& operator=(CommandPool&&) = delete; diff --git a/src/Nazara/VulkanRenderer/VulkanRenderImage.cpp b/src/Nazara/VulkanRenderer/VulkanRenderImage.cpp index 699875a7a..bc22220f7 100644 --- a/src/Nazara/VulkanRenderer/VulkanRenderImage.cpp +++ b/src/Nazara/VulkanRenderer/VulkanRenderImage.cpp @@ -6,56 +6,50 @@ #include #include #include +#include #include #include namespace Nz { VulkanRenderImage::VulkanRenderImage(VulkanSwapchain& owner) : + m_freeCommandBufferIndex(0), m_owner(owner), m_uploadPool(m_owner.GetDevice(), 2 * 1024 * 1024) { Vk::QueueHandle& graphicsQueue = m_owner.GetGraphicsQueue(); - if (!m_commandPool.Create(m_owner.GetDevice(), graphicsQueue.GetQueueFamilyIndex(), VK_COMMAND_POOL_CREATE_TRANSIENT_BIT | VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT)) + if (!m_commandPool.Create(m_owner.GetDevice(), graphicsQueue.GetQueueFamilyIndex(), VK_COMMAND_POOL_CREATE_TRANSIENT_BIT)) throw std::runtime_error("failed to create command pool: " + TranslateVulkanError(m_commandPool.GetLastErrorCode())); if (!m_imageAvailableSemaphore.Create(m_owner.GetDevice())) throw std::runtime_error("failed to create image available semaphore: " + TranslateVulkanError(m_imageAvailableSemaphore.GetLastErrorCode())); if (!m_renderFinishedSemaphore.Create(m_owner.GetDevice())) - throw std::runtime_error("failed to create image finished semaphore: " + TranslateVulkanError(m_imageAvailableSemaphore.GetLastErrorCode())); + throw std::runtime_error("failed to create image finished semaphore: " + TranslateVulkanError(m_renderFinishedSemaphore.GetLastErrorCode())); if (!m_inFlightFence.Create(m_owner.GetDevice(), VK_FENCE_CREATE_SIGNALED_BIT)) throw std::runtime_error("failed to create in-flight fence: " + TranslateVulkanError(m_inFlightFence.GetLastErrorCode())); } - VulkanRenderImage::~VulkanRenderImage() - { - m_inFlightCommandBuffers.clear(); - } - void VulkanRenderImage::Execute(const FunctionRef& callback, QueueTypeFlags queueTypeFlags) { - Vk::CommandBuffer* commandBuffer; - if (m_currentCommandBuffer >= m_inFlightCommandBuffers.size()) + if (m_freeCommandBufferIndex >= m_allocatedCommandBuffers.size()) { - Vk::AutoCommandBuffer& newlyAllocatedBuffer = m_inFlightCommandBuffers.emplace_back(m_commandPool.AllocateCommandBuffer(VK_COMMAND_BUFFER_LEVEL_PRIMARY)); - commandBuffer = &newlyAllocatedBuffer.Get(); - m_currentCommandBuffer++; + assert(m_freeCommandBufferIndex == m_allocatedCommandBuffers.size()); + m_allocatedCommandBuffers.push_back(m_commandPool.AllocateCommandBuffer(VK_COMMAND_BUFFER_LEVEL_PRIMARY)); } - else - commandBuffer = &m_inFlightCommandBuffers[m_currentCommandBuffer++].Get(); - if (!commandBuffer->Begin(VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT)) - throw std::runtime_error("failed to begin command buffer: " + TranslateVulkanError(commandBuffer->GetLastErrorCode())); + Vk::CommandBuffer commandBuffer(m_commandPool, m_allocatedCommandBuffers[m_freeCommandBufferIndex++]); + if (!commandBuffer.Begin(VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT)) + throw std::runtime_error("failed to begin command buffer: " + TranslateVulkanError(commandBuffer.GetLastErrorCode())); - VulkanCommandBufferBuilder builder(*commandBuffer); + VulkanCommandBufferBuilder builder(commandBuffer); callback(builder); - if (!commandBuffer->End()) - throw std::runtime_error("failed to build command buffer: " + TranslateVulkanError(commandBuffer->GetLastErrorCode())); + if (!commandBuffer.End()) + throw std::runtime_error("failed to build command buffer: " + TranslateVulkanError(commandBuffer.GetLastErrorCode())); - SubmitCommandBuffer(*commandBuffer, queueTypeFlags); + SubmitCommandBuffer(commandBuffer, queueTypeFlags); } VulkanUploadPool& VulkanRenderImage::GetUploadPool() @@ -66,7 +60,7 @@ namespace Nz void VulkanRenderImage::Present() { Vk::QueueHandle& graphicsQueue = m_owner.GetGraphicsQueue(); - if (!graphicsQueue.Submit(UInt32(m_graphicalCommandsBuffers.size()), m_graphicalCommandsBuffers.data(), m_imageAvailableSemaphore, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, m_renderFinishedSemaphore, m_inFlightFence)) + if (!graphicsQueue.Submit(UInt32(m_graphicalCommandBuffers.size()), m_graphicalCommandBuffers.data(), m_imageAvailableSemaphore, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, m_renderFinishedSemaphore, m_inFlightFence)) throw std::runtime_error("Failed to submit command buffers: " + TranslateVulkanError(graphicsQueue.GetLastErrorCode())); m_owner.Present(m_imageIndex, m_renderFinishedSemaphore); @@ -82,7 +76,7 @@ namespace Nz void VulkanRenderImage::SubmitCommandBuffer(VkCommandBuffer commandBuffer, QueueTypeFlags queueTypeFlags) { if (queueTypeFlags & QueueType::Graphics) - m_graphicalCommandsBuffers.push_back(commandBuffer); + m_graphicalCommandBuffers.push_back(commandBuffer); else { Vk::QueueHandle& graphicsQueue = m_owner.GetGraphicsQueue();