为什么 vkAcquireNextImageKHR() 从不阻塞我的线程?

Bra*_*ram 4 graphics semaphore vsync vulkan

我正在使用Vulkan 图形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
);
Run Code Online (Sandbox Code Playgroud)

目标硬件是手持控制台。

Nic*_*las 7

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

因此,所有vkAcquireNextImageKHR功能都是让您知道接下来将提供哪个图像。这是为了让您能够使用该图像(例如,通过构建以某种方式引用该图像的命令缓冲区)而需要发生的最低限度。然而,这种形象是不是还没有提供给您。

这就是为什么此功能需要您提供信号量和/或栅栏的原因:以便使用图像的进程可以等待图像可用。

如果使用图像的过程只是命令缓冲区中的一堆命令(即:您提交的内容vkQueueSubmit),您可以简单地让这批工作等待提供给获取操作的信号量。这意味着所有的等待都发生在 GPU 中。它属于哪里。

如果您(出于某种原因)希望CPU 能够等到获取完成,那么栅栏就在那里。但是 Vulkan 作为一个显式的低级 API,迫使您明确说明这是您想要的(而且它几乎永远不是您想要的)。

  • @Bram:队列提交操作不等待信号量;*GPU* 等待信号量。这就是为什么它们是 GPU 构造而不是 POSIX 互斥体或类似的东西。GPU 等待操作不应强制 CPU 等待。另外,你基本上不应该调用“vkQueueWaitIdle”。 (3认同)
  • @Bram:“*我尝试取消这些等待,但这会导致GPU崩溃。*”如果他们也依赖它来同步其他东西(比如内存/描述符访问),那么仅仅将它们拉出来是行不通的。我的观点是,在一个结构良好的应用程序中,CPU 永远不应该等待队列空闲,因为这代表着 GPU 性能的损失。CPU 可能会等待特定提交完成,但这将是在“栅栏”上等待,而不是等待队列停止执行“任何操作”。 (2认同)
  • @tuket:它不会阻塞,直到下一个图像可用。但它确实必须阻塞,直到显示引擎能够弄清楚下一张图像实际上是什么。 (2认同)