微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

正在等待,但验证警告“commandBuffer 尚未完成”

如何解决正在等待,但验证警告“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 举报,一经查实,本站将立刻删除。