c++graphicsvulkanvalidation-layers

Vulkan queue waiting on semaphore that has no way to be signaled


Validation error:

VUID-vkQueuePresentKHR-pWaitSemaphores-03268(ERROR / SPEC): msgNum: 622825338 - Validation Error: [ VUID-vkQueuePresentKHR-pWaitSemaphores-03268 ] Object 0: handle = 0x2ad2f2d8a38, type = VK_OBJECT_TYPE_QUEUE; Object 1: handle = 0xdd3a8a0000000015, type = VK_OBJECT_TYPE_SEMAPHORE; | MessageID = 0x251f8f7a | vkQueuePresentKHR: Queue VkQueue 0x2ad2f2d8a38[] is waiting on pWaitSemaphores[0] (VkSemaphore 0xdd3a8a0000000015[]) that has no way to be signaled. The Vulkan spec states: All elements of the pWaitSemaphores member of pPresentInfo must reference a semaphore signal operation that has been submitted for execution and any semaphore signal operations on which it depends (if any) must have also been submitted for execution (https://vulkan.lunarg.com/doc/view/1.2.182.0/windows/1.2-extensions/vkspec.html#VUID-vkQueuePresentKHR-pWaitSemaphores-03268)
    Objects: 2
        [0] 0x2ad2f2d8a38, type: 4, name: NULL
        [1] 0xdd3a8a0000000015, type: 5, name: NULL

This error happens in GraphicsQueue submit function. And this is the last error that I have to fix. I do not know what to do next.

What have I done wrong here?

void SwapChain::SubmitCommandBuffer(const vk::CommandBuffer& buffer, const size_t imageIndex)
    {
        vk::Result result{};

        if (_imagesInFlight[imageIndex])
        {
            result = _device.GetDevice().waitForFences(1, &_imagesInFlight[imageIndex], true, std::numeric_limits<uint64_t>::max());
            if (result != vk::Result::eSuccess)
                ENGINE_DEBUGBREAK();
        }

        _imagesInFlight[imageIndex] = _inFlightFences[_currentFrame];

        result = _device.GetDevice().resetFences(1, &_inFlightFences[_currentFrame]);
        if (result != vk::Result::eSuccess)
            ENGINE_DEBUGBREAK();

        const std::array<vk::PipelineStageFlags, 1> waitStages{ vk::PipelineStageFlagBits::eColorAttachmentOutput };
        const std::array<vk::Semaphore, 1> whaitSemaphores{ _imageAvailableSemaphores[_currentFrame] };
        const std::array<vk::Semaphore, 1> signalSemaphores{ _renderFinishedSemaphores[_currentFrame] };

        const vk::SubmitInfo submitInfo
        {
            .waitSemaphoreCount = static_cast<uint32_t>(whaitSemaphores.size()),
            .pWaitSemaphores = whaitSemaphores.data(),
            .pWaitDstStageMask = waitStages.data(),

            .commandBufferCount = 1,
            .pCommandBuffers = &buffer,

            .signalSemaphoreCount = static_cast<uint32_t>(signalSemaphores.size()),
            .pSignalSemaphores = signalSemaphores.data(),
        };

        _device.GetGraphicsQueue().submit(submitInfo, _inFlightFences[_currentFrame]);

        const std::array<vk::SwapchainKHR, 1> swapChains{ _swapChain.get() };
        const uint32_t imgeIndexUint{ static_cast<uint32_t>(imageIndex) };

        vk::PresentInfoKHR presentInfo
        {
            .pImageIndices = &imgeIndexUint,
        };

        presentInfo.setWaitSemaphores(whaitSemaphores);
        presentInfo.setSwapchains(swapChains);

        result = _device.GetPresentQueue().presentKHR(presentInfo);
        if (result != vk::Result::eSuccess)
            ENGINE_DEBUGBREAK();

        _currentFrame = (_currentFrame + 1) % MAX_FRAMES_IN_FLIGHT;
    }

Or maybe the essence of the error is not in this function?


Solution

  • You signal the _renderFinishedSemaphores[_currentFrame] semaphore, but then on present you wait on a different semaphore: _imageAvailableSemaphores[_currentFrame].