#include "mini/commandbuffer.hpp" #include "layer.hpp" #include using namespace Mini; CommandBuffer::CommandBuffer(VkDevice device, const CommandPool& pool) { // create command buffer const VkCommandBufferAllocateInfo desc{ .sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, .commandPool = pool.handle(), .level = VK_COMMAND_BUFFER_LEVEL_PRIMARY, .commandBufferCount = 1 }; VkCommandBuffer commandBufferHandle{}; auto res = Layer::ovkAllocateCommandBuffers(device, &desc, &commandBufferHandle); if (res != VK_SUCCESS || commandBufferHandle == VK_NULL_HANDLE) throw LSFG::vulkan_error(res, "Unable to allocate command buffer"); res = Layer::ovkSetDeviceLoaderData(device, commandBufferHandle); // store command buffer in shared ptr this->state = std::make_shared(CommandBufferState::Empty); this->commandBuffer = std::shared_ptr( new VkCommandBuffer(commandBufferHandle), [dev = device, pool = pool.handle()](VkCommandBuffer* cmdBuffer) { Layer::ovkFreeCommandBuffers(dev, pool, 1, cmdBuffer); } ); } void CommandBuffer::begin() { if (*this->state != CommandBufferState::Empty) throw std::logic_error("Command buffer is not in Empty state"); const VkCommandBufferBeginInfo beginInfo = { .sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, .flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT }; auto res = Layer::ovkBeginCommandBuffer(*this->commandBuffer, &beginInfo); if (res != VK_SUCCESS) throw LSFG::vulkan_error(res, "Unable to begin command buffer"); *this->state = CommandBufferState::Recording; } void CommandBuffer::end() { if (*this->state != CommandBufferState::Recording) throw std::logic_error("Command buffer is not in Recording state"); auto res = Layer::ovkEndCommandBuffer(*this->commandBuffer); if (res != VK_SUCCESS) throw LSFG::vulkan_error(res, "Unable to end command buffer"); *this->state = CommandBufferState::Full; } void CommandBuffer::submit(VkQueue queue, const std::vector& waitSemaphores, const std::vector& signalSemaphores) { if (*this->state != CommandBufferState::Full) throw std::logic_error("Command buffer is not in Full state"); const std::vector waitStages(waitSemaphores.size(), VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT); const VkSubmitInfo submitInfo{ .sType = VK_STRUCTURE_TYPE_SUBMIT_INFO, .waitSemaphoreCount = static_cast(waitSemaphores.size()), .pWaitSemaphores = waitSemaphores.data(), .pWaitDstStageMask = waitStages.data(), .commandBufferCount = 1, .pCommandBuffers = &(*this->commandBuffer), .signalSemaphoreCount = static_cast(signalSemaphores.size()), .pSignalSemaphores = signalSemaphores.data() }; auto res = Layer::ovkQueueSubmit(queue, 1, &submitInfo, VK_NULL_HANDLE); if (res != VK_SUCCESS) throw LSFG::vulkan_error(res, "Unable to submit command buffer"); *this->state = CommandBufferState::Submitted; }