refactor: update submit method

This commit is contained in:
PancakeTAS 2025-09-01 18:31:51 +02:00
parent eef8d4a245
commit 438458a575
No known key found for this signature in database
4 changed files with 53 additions and 49 deletions

View file

@ -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> fence,
const std::vector<Semaphore>& waitSemaphores = {},
std::optional<std::vector<uint64_t>> waitSemaphoreValues = std::nullopt,
const std::vector<Semaphore>& signalSemaphores = {},
std::optional<std::vector<uint64_t>> signalSemaphoreValues = std::nullopt);
void submit(const Device& device, std::optional<Fence> fence,
const std::vector<Semaphore>& wait = {},
const std::vector<Semaphore>& signal = {},
const std::vector<std::pair<Semaphore, uint64_t>>& waitTimelines = {},
const std::vector<std::pair<Semaphore, uint64_t>>& signalTimelines = {});
/// Get the state of the command buffer.
[[nodiscard]] auto getState() const { return *this->state; }

View file

@ -11,8 +11,6 @@
namespace VK::Core {
// FIXME: More intelligent device choosing method. See #200.
///
/// C++ wrapper class for a Vulkan device.
///

View file

@ -16,6 +16,7 @@
#include <optional>
#include <cstddef>
#include <cstdint>
#include <utility>
#include <memory>
#include <vector>
@ -203,52 +204,59 @@ void CommandBuffer::end() {
*this->state = CommandBufferState::Full;
}
void CommandBuffer::submit(VkQueue queue, std::optional<Fence> fence,
const std::vector<Semaphore>& waitSemaphores,
std::optional<std::vector<uint64_t>> waitSemaphoreValues,
const std::vector<Semaphore>& signalSemaphores,
std::optional<std::vector<uint64_t>> signalSemaphoreValues) {
void CommandBuffer::submit(const Device& device, std::optional<Fence> fence,
const std::vector<Semaphore>& wait,
const std::vector<Semaphore>& signal,
const std::vector<std::pair<Semaphore, uint64_t>>& waitTimelines,
const std::vector<std::pair<Semaphore, uint64_t>>& signalTimelines) {
if (*this->state != CommandBufferState::Full)
throw std::logic_error("Command buffer is not in Full state");
// create wait semaphores and values
std::vector<VkSemaphore> waitSemaphores(waitTimelines.size() + wait.size());
std::vector<uint64_t> 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<VkSemaphore> signalSemaphores(signalTimelines.size() + signal.size());
std::vector<uint64_t> 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<uint32_t>(waitSemaphoreValues.size()),
.pWaitSemaphoreValues = waitSemaphoreValues.data(),
.signalSemaphoreValueCount = static_cast<uint32_t>(signalSemaphoreValues.size()),
.pSignalSemaphoreValues = signalSemaphoreValues.data()
};
const std::vector<VkPipelineStageFlags> 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<uint32_t>(waitSemaphoreValues->size());
timelineInfo.pWaitSemaphoreValues = waitSemaphoreValues->data();
}
if (signalSemaphoreValues.has_value()) {
timelineInfo.signalSemaphoreValueCount =
static_cast<uint32_t>(signalSemaphoreValues->size());
timelineInfo.pSignalSemaphoreValues = signalSemaphoreValues->data();
}
std::vector<VkSemaphore> waitSemaphoresHandles;
waitSemaphoresHandles.reserve(waitSemaphores.size());
for (const auto& semaphore : waitSemaphores)
waitSemaphoresHandles.push_back(semaphore.handle());
std::vector<VkSemaphore> 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<uint32_t>(waitSemaphores.size()),
.pWaitSemaphores = waitSemaphoresHandles.data(),
.pWaitSemaphores = waitSemaphores.data(),
.pWaitDstStageMask = waitStages.data(),
.commandBufferCount = 1,
.pCommandBuffers = &(*this->commandBuffer),
.signalSemaphoreCount = static_cast<uint32_t>(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");

View file

@ -15,7 +15,7 @@ const std::vector<const char*> requiredExtensions = {
};
Instance::Instance() {
volkInitialize(); // FIXME: get rid of volk dependency fully
volkInitialize();
// create Vulkan instance
const VkApplicationInfo appInfo{