From 438458a575d7863b4f3082fb9a5891f06fe0b8cc Mon Sep 17 00:00:00 2001 From: PancakeTAS Date: Mon, 1 Sep 2025 18:31:51 +0200 Subject: [PATCH] refactor: update submit method --- framegen/include/vk/core/commandbuffer.hpp | 24 ++++--- framegen/include/vk/core/device.hpp | 2 - framegen/src/vk/core/commandbuffer.cpp | 74 ++++++++++++---------- framegen/src/vk/core/instance.cpp | 2 +- 4 files changed, 53 insertions(+), 49 deletions(-) diff --git a/framegen/include/vk/core/commandbuffer.hpp b/framegen/include/vk/core/commandbuffer.hpp index 2d87438..00eb20a 100644 --- a/framegen/include/vk/core/commandbuffer.hpp +++ b/framegen/include/vk/core/commandbuffer.hpp @@ -136,26 +136,24 @@ namespace VK::Core { /// void end(); - // FIXME: Submit logic is kind of janky. - /// /// Submit the command buffer to a queue. /// - /// @param queue Vulkan queue to submit to - /// @param fence Optional fence to signal when the command buffer has finished executing - /// @param waitSemaphores Semaphores to wait on before executing the command buffer - /// @param waitSemaphoreValues Values for the semaphores to wait on - /// @param signalSemaphores Semaphores to signal after executing the command buffer - /// @param signalSemaphoreValues Values for the semaphores to signal + /// @param device Vulkan device + /// @param fence Optional fence to signal after execution + /// @param wait Semaphores to wait on + /// @param signal Semaphores to signal after execution + /// @param waitTimelines Timeline semaphores to wait on + /// @param signalTimelines Timeline semaphores to signal after execution /// /// @throws std::logic_error if the command buffer is not in Full state. /// @throws VK::vulkan_error if submission fails. /// - void submit(VkQueue queue, std::optional fence, - const std::vector& waitSemaphores = {}, - std::optional> waitSemaphoreValues = std::nullopt, - const std::vector& signalSemaphores = {}, - std::optional> signalSemaphoreValues = std::nullopt); + void submit(const Device& device, std::optional fence, + const std::vector& wait = {}, + const std::vector& signal = {}, + const std::vector>& waitTimelines = {}, + const std::vector>& signalTimelines = {}); /// Get the state of the command buffer. [[nodiscard]] auto getState() const { return *this->state; } diff --git a/framegen/include/vk/core/device.hpp b/framegen/include/vk/core/device.hpp index a58cee1..97c3c41 100644 --- a/framegen/include/vk/core/device.hpp +++ b/framegen/include/vk/core/device.hpp @@ -11,8 +11,6 @@ namespace VK::Core { - // FIXME: More intelligent device choosing method. See #200. - /// /// C++ wrapper class for a Vulkan device. /// diff --git a/framegen/src/vk/core/commandbuffer.cpp b/framegen/src/vk/core/commandbuffer.cpp index e859972..50c151e 100644 --- a/framegen/src/vk/core/commandbuffer.cpp +++ b/framegen/src/vk/core/commandbuffer.cpp @@ -16,6 +16,7 @@ #include #include #include +#include #include #include @@ -203,52 +204,59 @@ void CommandBuffer::end() { *this->state = CommandBufferState::Full; } -void CommandBuffer::submit(VkQueue queue, std::optional fence, - const std::vector& waitSemaphores, - std::optional> waitSemaphoreValues, - const std::vector& signalSemaphores, - std::optional> signalSemaphoreValues) { +void CommandBuffer::submit(const Device& device, std::optional fence, + const std::vector& wait, + const std::vector& signal, + const std::vector>& waitTimelines, + const std::vector>& signalTimelines) { if (*this->state != CommandBufferState::Full) throw std::logic_error("Command buffer is not in Full state"); + // create wait semaphores and values + std::vector waitSemaphores(waitTimelines.size() + wait.size()); + std::vector waitSemaphoreValues(waitTimelines.size() + wait.size()); + for (const auto& entry : waitTimelines) { + waitSemaphores.push_back(entry.first.handle()); + waitSemaphoreValues.push_back(entry.second); + } + for (const auto& semaphore : wait) + waitSemaphores.push_back(semaphore.handle()); + + // create signal semaphores and values + std::vector signalSemaphores(signalTimelines.size() + signal.size()); + std::vector signalSemaphoreValues(signalTimelines.size() + signal.size()); + for (const auto& entry : signalTimelines) { + signalSemaphores.push_back(entry.first.handle()); + signalSemaphoreValues.push_back(entry.second); + } + for (const auto& semaphore : signal) + signalSemaphores.push_back(semaphore.handle()); + + // submit command buffer + const VkTimelineSemaphoreSubmitInfo timelineInfo{ + .sType = VK_STRUCTURE_TYPE_TIMELINE_SEMAPHORE_SUBMIT_INFO, + .waitSemaphoreValueCount = static_cast(waitSemaphoreValues.size()), + .pWaitSemaphoreValues = waitSemaphoreValues.data(), + .signalSemaphoreValueCount = static_cast(signalSemaphoreValues.size()), + .pSignalSemaphoreValues = signalSemaphoreValues.data() + }; const std::vector waitStages(waitSemaphores.size(), VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT); - VkTimelineSemaphoreSubmitInfo timelineInfo{ - .sType = VK_STRUCTURE_TYPE_TIMELINE_SEMAPHORE_SUBMIT_INFO, - }; - if (waitSemaphoreValues.has_value()) { - timelineInfo.waitSemaphoreValueCount = - static_cast(waitSemaphoreValues->size()); - timelineInfo.pWaitSemaphoreValues = waitSemaphoreValues->data(); - } - if (signalSemaphoreValues.has_value()) { - timelineInfo.signalSemaphoreValueCount = - static_cast(signalSemaphoreValues->size()); - timelineInfo.pSignalSemaphoreValues = signalSemaphoreValues->data(); - } - - std::vector waitSemaphoresHandles; - waitSemaphoresHandles.reserve(waitSemaphores.size()); - for (const auto& semaphore : waitSemaphores) - waitSemaphoresHandles.push_back(semaphore.handle()); - std::vector signalSemaphoresHandles; - signalSemaphoresHandles.reserve(signalSemaphores.size()); - for (const auto& semaphore : signalSemaphores) - signalSemaphoresHandles.push_back(semaphore.handle()); - const VkSubmitInfo submitInfo{ .sType = VK_STRUCTURE_TYPE_SUBMIT_INFO, - .pNext = (waitSemaphoreValues.has_value() || signalSemaphoreValues.has_value()) - ? &timelineInfo : nullptr, + .pNext = waitSemaphores.empty() && signalSemaphores.empty() + ? nullptr : &timelineInfo, .waitSemaphoreCount = static_cast(waitSemaphores.size()), - .pWaitSemaphores = waitSemaphoresHandles.data(), + .pWaitSemaphores = waitSemaphores.data(), .pWaitDstStageMask = waitStages.data(), .commandBufferCount = 1, .pCommandBuffers = &(*this->commandBuffer), .signalSemaphoreCount = static_cast(signalSemaphores.size()), - .pSignalSemaphores = signalSemaphoresHandles.data() + .pSignalSemaphores = signalSemaphores.data() }; - auto res = vkQueueSubmit(queue, 1, &submitInfo, fence ? fence->handle() : VK_NULL_HANDLE); + auto res = vkQueueSubmit(device.getComputeQueue(), + 1, &submitInfo, + fence ? fence->handle() : VK_NULL_HANDLE); if (res != VK_SUCCESS) throw VK::vulkan_error(res, "Unable to submit command buffer"); diff --git a/framegen/src/vk/core/instance.cpp b/framegen/src/vk/core/instance.cpp index 039b413..be5e4b9 100644 --- a/framegen/src/vk/core/instance.cpp +++ b/framegen/src/vk/core/instance.cpp @@ -15,7 +15,7 @@ const std::vector requiredExtensions = { }; Instance::Instance() { - volkInitialize(); // FIXME: get rid of volk dependency fully + volkInitialize(); // create Vulkan instance const VkApplicationInfo appInfo{