为什么 vkAcquireNextImageKHR() 永远不会阻塞我的线程?

问题描述 投票:0回答:1

我正在使用 Vulkan Graphics API(通过 BGFX)进行渲染。我一直在测量我的通话花费了多少(挂钟)时间。

我不明白的是 vkAcquireNextImageKHR() 总是很快,并且从不阻塞。即使我禁用超时并使用信号量等待演示。

演示文稿被锁定为 60Hz 显示速率,我看到我的主循环确实以 16.6 或 33.3 毫秒运行。

我不应该看到此显示速率的等待时间显示在

vkAcquireNextImageKHR()
呼叫的长度中吗?

分析器将此调用测量为 0.2 毫秒左右,而不是帧的重要部分。

VkResult result = vkAcquireNextImageKHR(
    m_device
  , m_swapchain
  , UINT64_MAX
  , renderWait
  , VK_NULL_HANDLE
  , &m_backBufferColorIdx
);

目标硬件是手持控制台。

graphics semaphore vulkan vsync
1个回答
17
投票

Vulkan 的全部目的是缓解CPU 瓶颈。让 CPU 停止直到 GPU 准备好执行某些操作则与此相反。特别是如果 CPU 本身实际上并不打算使用此操作的结果。

因此,

vkAcquireNextImageKHR
函数所做的就是让您知道交换链中的哪个图像接下来可以使用。 Vulkan 术语是“可用”。这是您能够使用该图像所需的最低限度(例如,通过构建以某种方式引用该图像的命令缓冲区)。然而,图像“可用”并不意味着它可以使用。

这就是为什么此函数要求您提供信号量和/或栅栏的原因。当图像实际可以使用时,将发出这些信号,并且在发出这些信号之前,图像不能在提交给 GPU 的一批工作中使用(尽管“可用”)。您可以构建使用图像的命令缓冲区,但如果提交这些命令缓冲区,则必须确保使用它们的命令等待同步。

如果使用图像的进程只是命令缓冲区中的一堆命令(即:使用

vkQueueSubmit
提交的内容),则可以简单地让该批工作等待提供给获取操作的信号量。这意味着所有等待都发生在 GPU 中。它属于哪里。

如果您(出于某种原因)

希望 CPU 能够等到获取的图像可供使用,则栅栏就在那里。但是 Vulkan 作为一个显式的低级 API,迫使您明确地说这就是您想要的(而它几乎从来都不是您想要的)。

因为“可用”的定义比“准备使用”宽松得多,所以 GPU 不必实际处理图像。系统只需要通过next找出将要完成的图像。因此,任何需要发生的 CPU 等待都会被最小化。

© www.soinside.com 2019 - 2024. All rights reserved.