vkWaitForFences 和 vkDeviceWaitIdle 不等待

vkWaitForFences and vkDeviceWaitIdle not waiting

我刚买了一台使用 nvidia 显卡 (gtx 1060) 的新电脑,当我尝试 运行 我的程序(以前可以运行)时,我遇到了一堆错误,但大部分都已修复。我剩下的一个问题是 vkWaitForFences() 和 vkDeviceWaitIdle returns VK_ERROR_DEVICE_LOST。我的旧电脑使用的是 amd 显卡,但确实很旧,我使用的是旧版本的 vulkan sdk,但我认为这不是问题所在。

当然,我用谷歌搜索了这个错误,这对我帮助不大,因为没有多少人遇到过这个问题。我发现这可能是驱动程序的问题,所以按照建议,我更新了 windows 和 nvidia 驱动程序。那并没有多大帮助。我还追踪了问题发生的位置,它总是在我第二次提交命令缓冲区时发生。设备丢失也是第二次。

我的提交命令功能,有人想知道为什么结果是大声笑,因为那是我总是写一些快速调试的第一件事,并不是什么严重的事情。

    if (m_OldAllocCount == 0 || m_RecordCmdBuffers){
            recordPrimaryCmdBuffer();
        }

        VkResult lol = vkWaitForFences(m_ContextPtr->device, 1, &inFlightFences[current_frame], VK_TRUE, std::numeric_limits<uint64_t>::max());
        if (lol == VK_ERROR_DEVICE_LOST)
            std::cout << "device lost" << std::endl;

        uint32_t imageIndex = 0;
        VkResult result = vkAcquireNextImageKHR(m_ContextPtr->device, m_CurrentWindow->m_SwapChain.swapChain, std::numeric_limits<uint64_t>::max(),
            imageAvailableSemaphore[current_frame], VK_NULL_HANDLE, &imageIndex);

        m_RecordCmdBuffers = false;

        // If swapchain needs recreation
        if (result == VK_ERROR_OUT_OF_DATE_KHR)
        {
            recreateSwapChain(m_CurrentWindow->getWindowSize());
            viewport(Vector2i(0), m_CurrentWindow->getWindowSize());
        }
        else if(result != VK_SUCCESS && result != VK_SUBOPTIMAL_KHR)
            throw std::runtime_error("failed to acquire swap chain image!");

        // Set the correct index to image, for the uniform buffers to send data to correct block
        for (auto& shader : m_CurrentShaders)
        {
            shader->m_UniformBuffers[(int)ShaderStage::VertexBit].m_CurrentImage   = imageIndex;
            shader->m_UniformBuffers[(int)ShaderStage::FragmentBit].m_CurrentImage = imageIndex;
            shader->m_UniformBuffers[(int)ShaderStage::GeometryBit].m_CurrentImage = imageIndex;
        }

        VkSubmitInfo submitInfo = {};
        submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;

        VkSemaphore waitSemaphores[] = { imageAvailableSemaphore[current_frame] };
        VkPipelineStageFlags waitStages[] = { VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT };
        submitInfo.waitSemaphoreCount = 1;
        submitInfo.pWaitSemaphores = waitSemaphores;
        submitInfo.pWaitDstStageMask = waitStages;
        submitInfo.commandBufferCount = m_PrimaryCommandBuffer.size();
        submitInfo.pCommandBuffers = m_PrimaryCommandBuffer.data();

        VkSemaphore signalSemaphores[] = { renderFinishedSemaphore[current_frame] };
        submitInfo.signalSemaphoreCount = 1;
        submitInfo.pSignalSemaphores = signalSemaphores;

        // Reset the fences
        vkResetFences(m_ContextPtr->device, 1, &inFlightFences[current_frame]);

        // Submit the graphics queue
        if (vkQueueSubmit(m_ContextPtr->graphicsQueue, 1, &submitInfo, inFlightFences[current_frame]) != VK_SUCCESS)
            std::cout << "failed to submit command buffer" << std::endl;

        VkPresentInfoKHR presentInfo = {};
        presentInfo.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR;
        presentInfo.waitSemaphoreCount = 1;
        presentInfo.pWaitSemaphores = signalSemaphores;

        VkSwapchainKHR swapChains[] = { m_CurrentWindow->m_SwapChain.swapChain };
        presentInfo.swapchainCount = 1;
        presentInfo.pSwapchains = swapChains;
        presentInfo.pImageIndices = &imageIndex;
        presentInfo.pResults = nullptr;

        result = vkQueuePresentKHR(m_ContextPtr->presentQueue, &presentInfo);

        // If swapchain needs recreation
        if (result == VK_ERROR_OUT_OF_DATE_KHR || result == VK_SUBOPTIMAL_KHR || m_CurrentWindow->windowResized()) {
            vkWaitForFences(m_ContextPtr->device, 1, &inFlightFences[current_frame], VK_TRUE, std::numeric_limits<uint64_t>::max());

            recreateSwapChain(m_CurrentWindow->getWindowSize());
            viewport(Vector2i(0), m_CurrentWindow->getWindowSize());
        }
        else if (result != VK_SUCCESS)
            throw std::runtime_error("failed to present swap chain image!");

        current_frame = (current_frame + 1) % MAX_FRAMES_IN_FLIGHT;

        if (m_AllocCount > 0)
        {
            m_CurrentCmdBuf = 0;
            m_OldAllocCount = m_AllocCount;
        }

这是我的输出

[Run time : 0.00032s][Application]Info:    application version: 4194304
[Run time : 0.00495s][Application]Info:    engine version: 4194304
[Run time : 0.00641s][Application]Info:    api version: 4194304
[Run time : 0.02141s][Validation Layers]Debug:    Validation layers available
[Run time : 1.69485s][Extensions]Info:        VK_KHR_surface
[Run time : 1.69698s][Extensions]Info:        VK_KHR_win32_surface
[Run time : 1.69893s][Extensions]Info:        VK_EXT_debug_utils
[Run time : 3.35121s][Vulkan Instance]Trace:    Succesfully created instance
[Run time : 3.35314s][Vk Validation]Debug:    Added messenger
[Run time : 0.00004s][Application]Info:    application version: 4194304
[Run time : 0.00079s][Application]Info:    engine version: 4194304
[Run time : 0.00144s][Application]Info:    api version: 4194304
[Run time : 0.01320s][Validation Layers]Debug:    Validation layers available
[Run time : 0.01410s][Extensions]Info:        VK_KHR_surface
[Run time : 0.01502s][Extensions]Info:        VK_KHR_win32_surface
[Run time : 0.01580s][Extensions]Info:        VK_EXT_debug_utils
[Run time : 0.06975s][Vulkan Instance]Trace:    Succesfully created instance
[Run time : 0.07116s][Window]Trace:    Succesfully created window surface
[Run time : 0.07216s][GPU]Info:    Found atleast one GPU with vulkan support
[Run time : 0.07302s][GPU]Debug:    [GeForce GTX 1060]
[Run time : 0.07366s][GPU]Debug:        score: 82920
[Run time : 0.07434s][GPU]Debug:        device type: discrete
[Run time : 0.07496s][GPU]Debug:        driver version: 1749598208
[Run time : 0.07558s][GPU]Debug:        vulkan version: 4198484
[Run time : 0.07620s][GPU]Debug:        max viewports: 16
[Run time : 0.07680s][GPU]Debug:        max tesselation level: 64
[Run time : 0.07743s][GPU]Debug:        memory heap count: 2
[Run time : 0.07808s][GPU]Debug:        vendor id: 4318
[Run time : 0.08448s][GPU]Debug:    [Intel(R) UHD Graphics 630]
[Run time : 0.08767s][GPU]Debug:        score: 34816
[Run time : 0.08877s][GPU]Debug:        device type: integrated
[Run time : 0.09002s][GPU]Debug:        driver version: 1644692
[Run time : 0.09115s][GPU]Debug:        vulkan version: 4198482
[Run time : 0.09233s][GPU]Debug:        max viewports: 16
[Run time : 0.09377s][GPU]Debug:        max tesselation level: 64
[Run time : 0.09493s][GPU]Debug:        memory heap count: 1
[Run time : 0.09597s][GPU]Debug:        vendor id: 32902
[Run time : 0.09977s][GPU]Info:    Using discrete graphics [GeForce GTX 1060]
[Run time : 0.67138s][Logical Device]Trace:    Succesfully created logical device
[Run time : 0.95405s][Swap Chain]Trace:    Succesfully created swap chain
[Run time : 0.95670s][Swap Chain]Trace:    Succesfully created image views for swap chain
found obj file(resources/3d-models/common/cube.obj)
size of obj file resources/3d-models/common/cube.obj: 829
found obj file(resources/3d-models/sponza/sponza.obj)
size of obj file resources/3d-models/sponza/sponza.obj: 21109956
found obj file(resources/3d-models/common/example.obj)
size of obj file resources/3d-models/common/example.obj: 51671
[Run time : 28.05996s][Rendering]Trace:    Succesfully created renderpass for swap chain
[Run time : 28.06264s][Rendering]Trace:    Allocated command buffers
[Run time : 28.06549s][Rendering]Trace:    Allocated command buffers
[Run time : 28.06832s][Rendering]Trace:    Allocated command buffers
[Run time : 28.13745s][Uniform Buffer]Debug:    success!, created descriptor set layout for uniform buffer
[Run time : 28.14002s][Uniform Buffer]Debug:    success!, created descriptor pool
[Run time : 28.14322s][Uniform Buffer]Debug:    allocated descriptor sets
[Run time : 28.15548s][Vk Validation]Error:    Shader uses descriptor slot 0.1 but descriptor not accessible from stage VK_SHADER_STAGE_FRAGMENT_BIT
[Run time : 28.16189s][Rendering]Trace:    Succesfully created graphics pipeline
[Run time : 28.16439s][Rendering]Trace:    Allocated command buffers
[Run time : 28.16829s][Uniform Buffer]Debug:    success!, created descriptor set layout for uniform buffer
[Run time : 28.17082s][Uniform Buffer]Debug:    success!, created descriptor pool
[Run time : 28.17548s][Uniform Buffer]Debug:    allocated descriptor sets
[Run time : 28.18030s][Rendering]Trace:    Succesfully created graphics pipeline
[Run time : 28.18263s][Rendering]Trace:    Allocated command buffers
[Run time : 28.18724s][Uniform Buffer]Debug:    success!, created descriptor set layout for uniform buffer
[Run time : 28.18990s][Uniform Buffer]Debug:    success!, created descriptor pool
[Run time : 28.19598s][Uniform Buffer]Debug:    allocated descriptor sets
[Run time : 28.20237s][Rendering]Trace:    Succesfully created graphics pipeline
[Run time : 28.20461s][Rendering]Trace:    Allocated command buffers
submited command buffer
submited command buffer
device lost
[Run time : 28.50525s][Vk Validation]Error:    Cannot call vkDestroyFramebuffer on VkFramebuffer 0x34[] that is currently in use by a command buffer. The Vulkan spec states: All submitted commands that refer to framebuffer must have completed execution (https://www.khronos.org/registry/vulkan/specs/1.1-extensions/html/vkspec.html#VUID-vkDestroyFramebuffer-framebuffer-00892)
[Run time : 28.50789s][Vk Validation]Error:    Cannot call vkDestroyFramebuffer on VkFramebuffer 0x35[] that is currently in use by a command buffer. The Vulkan spec states: All submitted commands that refer to framebuffer must have completed execution (https://www.khronos.org/registry/vulkan/specs/1.1-extensions/html/vkspec.html#VUID-vkDestroyFramebuffer-framebuffer-00892)
[Run time : 28.51032s][Vk Validation]Error:    Cannot call vkDestroyFramebuffer on VkFramebuffer 0x36[] that is currently in use by a command buffer. The Vulkan spec states: All submitted commands that refer to framebuffer must have completed execution (https://www.khronos.org/registry/vulkan/specs/1.1-extensions/html/vkspec.html#VUID-vkDestroyFramebuffer-framebuffer-00892)
[Run time : 28.51312s][Vk Validation]Error:    Cannot call vkDestroyImageView on VkImageView 0x9[] that is currently in use by a command buffer. The Vulkan spec states: All submitted commands that refer to imageView must have completed execution (https://www.khronos.org/registry/vulkan/specs/1.1-extensions/html/vkspec.html#VUID-vkDestroyImageView-imageView-01026)
[Run time : 28.51778s][Vk Validation]Error:    Cannot call vkDestroyImageView on VkImageView 0xa[] that is currently in use by a command buffer. The Vulkan spec states: All submitted commands that refer to imageView must have completed execution (https://www.khronos.org/registry/vulkan/specs/1.1-extensions/html/vkspec.html#VUID-vkDestroyImageView-imageView-01026)
[Run time : 28.52056s][Vk Validation]Error:    Cannot call vkDestroyImageView on VkImageView 0xb[] that is currently in use by a command buffer. The Vulkan spec states: All submitted commands that refer to imageView must have completed execution (https://www.khronos.org/registry/vulkan/specs/1.1-extensions/html/vkspec.html#VUID-vkDestroyImageView-imageView-01026)
[Run time : 28.55500s][Vk Validation]Error:    Attempt to reset VkCommandBuffer 0x2048fbb6340[] which is in use. The Vulkan spec states: commandBuffer must not be in the pending state (https://www.khronos.org/registry/vulkan/specs/1.1-extensions/html/vkspec.html#VUID-vkResetCommandBuffer-commandBuffer-00045)
[Run time : 28.55764s][Vk Validation]Error:    Attempt to reset VkCommandBuffer 0x2048fb963b0[] which is in use. The Vulkan spec states: commandBuffer must not be in the pending state (https://www.khronos.org/registry/vulkan/specs/1.1-extensions/html/vkspec.html#VUID-vkResetCommandBuffer-commandBuffer-00045)
[Run time : 28.56087s][Vk Validation]Error:    Attempt to reset VkCommandBuffer 0x2048fb97b10[] which is in use. The Vulkan spec states: commandBuffer must not be in the pending state (https://www.khronos.org/registry/vulkan/specs/1.1-extensions/html/vkspec.html#VUID-vkResetCommandBuffer-commandBuffer-00045)
[Run time : 28.56487s][Vk Validation]Error:    Attempt to reset VkCommandBuffer 0x2048fb96fd0[] which is in use. The Vulkan spec states: commandBuffer must not be in the pending state (https://www.khronos.org/registry/vulkan/specs/1.1-extensions/html/vkspec.html#VUID-vkResetCommandBuffer-commandBuffer-00045)
[Run time : 28.57102s][Vk Validation]Error:    Attempt to reset VkCommandBuffer 0x2048fbae220[] which is in use. The Vulkan spec states: commandBuffer must not be in the pending state (https://www.khronos.org/registry/vulkan/specs/1.1-extensions/html/vkspec.html#VUID-vkResetCommandBuffer-commandBuffer-00045)
[Run time : 28.57564s][Vk Validation]Error:    Attempt to reset VkCommandBuffer 0x2048fbbf4a0[] which is in use. The Vulkan spec states: commandBuffer must not be in the pending state (https://www.khronos.org/registry/vulkan/specs/1.1-extensions/html/vkspec.html#VUID-vkResetCommandBuffer-commandBuffer-00045)
[Run time : 28.58219s][Vk Validation]Error:    Cannot call vkDestroyRenderPass on VkRenderPass 0x33[] that is currently in use by a command buffer. The Vulkan spec states: All submitted commands that refer to renderPass must have completed execution (https://www.khronos.org/registry/vulkan/specs/1.1-extensions/html/vkspec.html#VUID-vkDestroyRenderPass-renderPass-00873)
[Run time : 28.58625s][Vk Validation]Error:    Cannot call vkDestroyImageView on VkImageView 0x32[] that is currently in use by a command buffer. The Vulkan spec states: All submitted commands that refer to imageView must have completed execution (https://www.khronos.org/registry/vulkan/specs/1.1-extensions/html/vkspec.html#VUID-vkDestroyImageView-imageView-01026)
[Run time : 28.59076s][Vk Validation]Error:    Cannot call vkDestroyImage on VkImage 0x30[] that is currently in use by a command buffer. The Vulkan spec states: All submitted commands that refer to image, either directly or via a VkImageView, must have completed execution (https://www.khronos.org/registry/vulkan/specs/1.1-extensions/html/vkspec.html#VUID-vkDestroyImage-image-01000)
[Run time : 28.59819s][Vk Validation]Error:    Cannot call vkDestroyDescriptorPool on VkDescriptorPool 0x44[] that is currently in use by a command buffer. The Vulkan spec states: All submitted commands that refer to descriptorPool (via any allocated descriptor sets) must have completed execution (https://www.khronos.org/registry/vulkan/specs/1.1-extensions/html/vkspec.html#VUID-vkDestroyDescriptorPool-descriptorPool-00303)
[Run time : 28.60357s][Vk Validation]Error:    Cannot call vkDestroyDescriptorPool on VkDescriptorPool 0x5d[] that is currently in use by a command buffer. The Vulkan spec states: All submitted commands that refer to descriptorPool (via any allocated descriptor sets) must have completed execution (https://www.khronos.org/registry/vulkan/specs/1.1-extensions/html/vkspec.html#VUID-vkDestroyDescriptorPool-descriptorPool-00303)
[Run time : 28.61071s][Vk Validation]Error:    Cannot call vkDestroyDescriptorPool on VkDescriptorPool 0x76[] that is currently in use by a command buffer. The Vulkan spec states: All submitted commands that refer to descriptorPool (via any allocated descriptor sets) must have completed execution (https://www.khronos.org/registry/vulkan/specs/1.1-extensions/html/vkspec.html#VUID-vkDestroyDescriptorPool-descriptorPool-00303)
[Run time : 28.61863s][Vk Validation]Error:    Attempt to free VkCommandBuffer 0x2048fb6d740[] which is in use. The Vulkan spec states: All elements of pCommandBuffers must not be in the pending state (https://www.khronos.org/registry/vulkan/specs/1.1-extensions/html/vkspec.html#VUID-vkFreeCommandBuffers-pCommandBuffers-00047)
[Run time : 28.62422s][Rendering]Trace:    Succesfully created renderpass for swap chain
[Run time : 28.64659s][Swap Chain]Trace:    Succesfully created swap chain
[Run time : 28.64906s][Swap Chain]Trace:    Succesfully created image views for swap chain
[Run time : 28.65212s][Uniform Buffer]Debug:    success!, created descriptor pool
[Run time : 28.65492s][Uniform Buffer]Debug:    allocated descriptor sets
[Run time : 28.65860s][Uniform Buffer]Debug:    success!, created descriptor pool
[Run time : 28.66277s][Uniform Buffer]Debug:    allocated descriptor sets
[Run time : 28.66672s][Uniform Buffer]Debug:    success!, created descriptor pool
[Run time : 28.66859s][Uniform Buffer]Debug:    allocated descriptor sets
[Run time : 28.67708s][Vk Validation]Error:    VkFence 0x2c[] is in use. The Vulkan spec states: Each element of pFences must not be currently associated with any queue command that has not yet completed execution on that queue (https://www.khronos.org/registry/vulkan/specs/1.1-extensions/html/vkspec.html#VUID-vkResetFences-pFences-01123)
failed to submit command buffer

所以我解决了它,显然设备丢失是由于我输出中的描述符插槽 0.1 的东西,我认为这不是问题的原因是因为它在我的旧计算机上工作,即使那个错误弹出向上。我想这对于不同的 GPU 是不同的。它现在按预期工作,感谢任何试图提供帮助的人。