/* ************************************************************************** */ /* */ /* ::: :::::::: */ /* vk_cmd_buffer.cpp :+: :+: :+: */ /* +:+ +:+ +:+ */ /* By: maldavid +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2022/10/06 18:26:06 by maldavid #+# #+# */ /* Updated: 2023/12/15 21:54:11 by maldavid ### ########.fr */ /* */ /* ************************************************************************** */ #include "vk_cmd_buffer.h" #include #include #include namespace mlx { void CmdBuffer::init(CmdManager* manager) { init(&manager->getCmdPool()); } void CmdBuffer::init(CmdPool* pool) { _pool = pool; VkCommandBufferAllocateInfo allocInfo{}; allocInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO; allocInfo.commandPool = pool->get(); allocInfo.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY; allocInfo.commandBufferCount = 1; if(vkAllocateCommandBuffers(Render_Core::get().getDevice().get(), &allocInfo, &_cmd_buffer) != VK_SUCCESS) core::error::report(e_kind::fatal_error, "Vulkan : failed to allocate command buffer"); #ifdef DEBUG core::error::report(e_kind::message, "Vulkan : created new command buffer"); #endif _fence.init(); } void CmdBuffer::beginRecord(VkCommandBufferUsageFlags usage) { if(_is_recording) return; VkCommandBufferBeginInfo beginInfo{}; beginInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO; beginInfo.flags = usage; if(vkBeginCommandBuffer(_cmd_buffer, &beginInfo) != VK_SUCCESS) core::error::report(e_kind::fatal_error, "Vulkan : failed to begin recording command buffer"); _is_recording = true; } void CmdBuffer::endRecord() { if(!_is_recording) return; if(vkEndCommandBuffer(_cmd_buffer) != VK_SUCCESS) core::error::report(e_kind::fatal_error, "Vulkan : failed to end recording command buffer"); _is_recording = false; } void CmdBuffer::submitIdle() noexcept { VkSubmitInfo submitInfo = {}; submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; submitInfo.commandBufferCount = 1; submitInfo.pCommandBuffers = &_cmd_buffer; VkFenceCreateInfo fenceCreateInfo = {}; fenceCreateInfo.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO; vkQueueSubmit(Render_Core::get().getQueue().getGraphic(), 1, &submitInfo, _fence.get()); waitForExecution(); } void CmdBuffer::submit(Semaphore& semaphores) noexcept { VkSemaphore signalSemaphores[] = { semaphores.getRenderImageSemaphore() }; VkSemaphore waitSemaphores[] = { semaphores.getImageSemaphore() }; VkPipelineStageFlags waitStages[] = { VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT }; VkSubmitInfo submitInfo{}; submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; submitInfo.waitSemaphoreCount = 1; submitInfo.pWaitSemaphores = waitSemaphores; submitInfo.pWaitDstStageMask = waitStages; submitInfo.commandBufferCount = 1; submitInfo.pCommandBuffers = &_cmd_buffer; submitInfo.signalSemaphoreCount = 1; submitInfo.pSignalSemaphores = signalSemaphores; if(vkQueueSubmit(Render_Core::get().getQueue().getGraphic(), 1, &submitInfo, _fence.get()) != VK_SUCCESS) core::error::report(e_kind::fatal_error, "Vulkan error : failed to submit draw command buffer"); } void CmdBuffer::destroy() noexcept { _fence.destroy(); _cmd_buffer = VK_NULL_HANDLE; } }