首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >vulkan-教程-如何同步渲染和演示

vulkan-教程-如何同步渲染和演示
EN

Stack Overflow用户
提问于 2022-08-02 09:50:41
回答 1查看 101关注 0票数 2

https://vulkan-tutorial.com/Drawing_a_triangle/Drawing/Rendering_and_presentation

在阅读上面的教程时,我发现了一个场景,其中多个项目堆积在表示队列中。

本教程有一个循环,反复运行下面的代码。

代码语言:javascript
运行
复制
   void drawFrame() {
        vkWaitForFences(device, 1, &inFlightFence, VK_TRUE, UINT64_MAX);
        vkResetFences(device, 1, &inFlightFence);

        uint32_t imageIndex;
        vkAcquireNextImageKHR(device, swapChain, UINT64_MAX, imageAvailableSemaphore, VK_NULL_HANDLE, &imageIndex);

        vkResetCommandBuffer(commandBuffer, /*VkCommandBufferResetFlagBits*/ 0);
        recordCommandBuffer(commandBuffer, imageIndex);

        VkSubmitInfo submitInfo{};
        submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;

        VkSemaphore waitSemaphores[] = {imageAvailableSemaphore};
        VkPipelineStageFlags waitStages[] = {VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT};
        submitInfo.waitSemaphoreCount = 1;
        submitInfo.pWaitSemaphores = waitSemaphores;
        submitInfo.pWaitDstStageMask = waitStages;

        submitInfo.commandBufferCount = 1;
        submitInfo.pCommandBuffers = &commandBuffer;

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

        if (vkQueueSubmit(graphicsQueue, 1, &submitInfo, inFlightFence) != VK_SUCCESS) {
            throw std::runtime_error("failed to submit draw command buffer!");
        }

        VkPresentInfoKHR presentInfo{};
        presentInfo.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR;

        presentInfo.waitSemaphoreCount = 1;
        presentInfo.pWaitSemaphores = signalSemaphores;

        VkSwapchainKHR swapChains[] = {swapChain};
        presentInfo.swapchainCount = 1;
        presentInfo.pSwapchains = swapChains;

        presentInfo.pImageIndices = &imageIndex;

        vkQueuePresentKHR(presentQueue, &presentInfo);

有两个信号量;一个用于呈现,另一个用于表示。

类似地,有两个队列用于呈现和表示。

下面是我发现的一种可能发生的情况。

  1. 在第一次迭代之后,每个队列都有一个项要处理。
  2. 在第二次迭代时,队列中的任何项都还没有处理。因此,它在vkWaitForFences.
  3. The上被阻塞,图形队列中的第一项被处理。semaphore.
  4. The
  5. --它向阻塞栅栏发出信号,而呈现第二次迭代则继续从vkWaitForFences.
    • Graphics队列接收第二项。它总共有一个item.
    • Present队列,也接收第二个条目。当前队列尚未处理第一个项,因此它总共有两个item.

  1. 图形队列处理第二项。
    • 它再次发出信号呈现信号量。渲染信号量已经接收到两个信号而不需要打开off.

现在,当前队列将只处理一个项,直到下一次迭代才会执行任何操作。即使在下一次迭代中,如果这个问题继续发生,未处理的项也会堆积在当前队列中。

因此,如果图形队列的处理速度恰好比当前队列快,就会出现饥饿问题。

本教程没有解释如何解决这个问题。Vulkan中是否有防止此问题发生的东西,或者我是否在教程代码中发现了一个缺陷?

EN

回答 1

Stack Overflow用户

发布于 2022-08-02 11:28:05

vkAcquireNextImageKHR使图像信号量在交换图像时获得信号,当它返回的索引可显示时。当带有索引的项在当前队列中处理时,vkAcquireNextImageKHR返回的索引的图像再次呈现。

因此,如果当前队列中的项未被处理,vkAcquireNextImageKHR将不会向图像信号量或块发送信号,从而停止下一个呈现。

可以同时驻留在当前队列中的项的数量不会无限增长,但是如果项的数量等于交换映像的数量,则停止增长。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/73205451

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档