如何解决正在等待,但验证警告“commandBuffer 尚未完成”
我从 Vulkan 开始,试图创建一个最小的渲染器来玩。 一切似乎都正常,但在记录命令缓冲区或销毁它们时出现验证错误:
VUID-vkBeginCommandBuffer-commandBuffer-00049(ERROR / SPEC): ...Calling vkBeginCommandBuffer() on active VkCommandBuffer 0x1b5ad3f2020[] before it has completed. You must check command buffer fence before this call...
和
VUID-vkDestroyCommandPool-commandPool-00041(ERROR / SPEC): ...Attempt to destroy command pool with VkCommandBuffer 0x1b5ad3fb1e0[] which is in use...
命令缓冲池是用VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT
标志创建的,我的渲染函数如下:
void VulkanRenderer::Draw(std::vector<Mesh*>* meshes)
{
static const uint64_t wait_timeout = std::numeric_limits<uint64_t>::max();
// wait for GPU
vkWaitForFences(_logicalDevice,1,&_drawFences[_currentFrameIndex],VK_TRUE,wait_timeout);
vkResetFences(_logicalDevice,&_drawFences[_currentFrameIndex]);
uint32_t swapchainImageIndex;
const VkResult result = vkAcquireNextimageKHR(_logicalDevice,_swapchain,wait_timeout,_imageAvailableSemaphores[_currentFrameIndex],VK_NULL_HANDLE,&swapchainImageIndex);
if (result != VK_SUCCESS)
{
throw std::runtime_error("Failed to acquire next swapchain image");
}
RecordCommands(swapchainImageIndex,meshes);
SubmitToGraphicsQueue(swapchainImageIndex);
PresentGraphicsQueue(swapchainImageIndex);
// advance to next frame
_currentFrameIndex = (_currentFrameIndex + 1) % MAX_FRAME_DRAWS;
}
void VulkanRenderer::RecordCommands(const uint32_t swapchainImageIndex,std::vector<Mesh*>* meshes)
{
VkCommandBuffer currentBuffer = _graphicsCommandBuffers[swapchainImageIndex];
// define command buffer recording start
VkCommandBufferBeginInfo commandBufferBeginInfo = {};
commandBufferBeginInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
commandBufferBeginInfo.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT;
commandBufferBeginInfo.pNext = nullptr;
commandBufferBeginInfo.pInheritanceInfo = nullptr;
// start recording commands into command buffer
VkResult result = vkBeginCommandBuffer(currentBuffer,&commandBufferBeginInfo);
if (result != VK_SUCCESS)
{
throw std::runtime_error("Failed to begin command buffer recording");
}
// commands recorded here...
// stop recording commands into command buffer
result = vkEndCommandBuffer(currentBuffer);
if (result != VK_SUCCESS)
{
throw std::runtime_error("Failed to end command buffer recording");
}
}
void VulkanRenderer::SubmitToGraphicsQueue(const uint32_t swapchainImageIndex)
{
// define semaphore wait stages
std::vector<VkPipelinestageFlags> semaphoreWaits = { VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT };
// define graphics queue submission
VkSubmitInfo graphicsQueueSubmitInfo = {};
graphicsQueueSubmitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
graphicsQueueSubmitInfo.pNext = nullptr;
graphicsQueueSubmitInfo.waitSemaphoreCount = 1;
graphicsQueueSubmitInfo.pWaitSemaphores = &_imageAvailableSemaphores[_currentFrameIndex];
graphicsQueueSubmitInfo.pWaitDstStageMask = semaphoreWaits.data();
graphicsQueueSubmitInfo.commandBufferCount = 1;
graphicsQueueSubmitInfo.pCommandBuffers = &_graphicsCommandBuffers[swapchainImageIndex];
graphicsQueueSubmitInfo.signalSemaphoreCount = 1;
graphicsQueueSubmitInfo.pSignalSemaphores = &_renderFinishedSemaphores[_currentFrameIndex];
// submit graphics queue
const VkResult result = vkQueueSubmit(_graphicsQueue,&graphicsQueueSubmitInfo,_drawFences[_currentFrameIndex]);
if (result != VK_SUCCESS)
{
throw std::runtime_error("Failed to submit graphics queue");
}
}
void VulkanRenderer::PresentGraphicsQueue(uint32_t swapchainImageIndex)
{
// define graphics queue presentation
VkPresentInfoKHR graphicsQueuePresentInfo = {};
graphicsQueuePresentInfo.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR;
graphicsQueuePresentInfo.pNext = nullptr;
graphicsQueuePresentInfo.waitSemaphoreCount = 1;
graphicsQueuePresentInfo.pWaitSemaphores = &_renderFinishedSemaphores[_currentFrameIndex];
graphicsQueuePresentInfo.swapchainCount = 1;
graphicsQueuePresentInfo.pSwapchains = &_swapchain;
graphicsQueuePresentInfo.pImageIndices = &swapchainImageIndex;
graphicsQueuePresentInfo.pResults = nullptr;
// present graphics queue
const VkResult result = vkQueuePresentKHR(_presentationQueue,&graphicsQueuePresentInfo);
if (result != VK_SUCCESS)
{
throw std::runtime_error("Failed to present graphics queue");
}
}
我显然有错误或遗漏了什么,但我不知道是什么。 在围栏上等待还不够吗?我是否提交了错误的围栏?
解决方法
您的栅栏由 _currentFrameIndex
索引,而您的命令缓冲区由 swapchainImageIndex
索引。因此,您等待的栅栏可能并不意味着给定的 cmdbuff 已完成。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。