Vulkan 渲染在没有 vkQueuePresentKHR() 的情况下完成同步
Vulkan render finished synchronisation without vkQueuePresentKHR()
在 Oculus 移动版 VrApi 中,我们无法访问 vkQueuePresentKHR(),我们为每只眼睛提供了一层 vrapi_SubmitFrame2()。
vulkan 示例使用栅栏与 vkQueueSubmit() 和 vkWaitForFence() 同步。
它适用于简单的渲染,但是如果我使用更长的渲染,它在屏幕上显示时还没有完成。
据我了解,这是正常的,因为栅栏允许在 CPU 级别同步,但与 GPU 的同步是通过信号量完成的。
我可以用 vkQueueSubmit() 中的信号量表示渲染已完成,但我等不及发出信号量了,因为 vrapi_SubmitFrame2() 不使用“.pWaitSemaphores”字段.
如何等待渲染完成?
求助,Vulkan版本是1.0,不过我觉得可以用v1.1.
vrapi_SubmitFrame2
接受一个 CompletionFence
,它是一个 EGLsync
对象,因为 VrApi 被设计为使用 OpenGL ES,而不是 Vulkan。所以没有单步实现无气泡同步的方法。
最简单的解决方案是在调用 vrapi_SubmitFrame2 之前确保渲染已完成。通过栅栏进入 vkQueueSubmit
,等待它发出信号,然后调用 vrapi_SubmitFrame2
。但是,这会增加延迟并降低性能(通过减少 CPU 和 GPU 工作之间的并发性),这对于 VR 来说尤其难以接受。
更复杂的解决方案是使用 VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT
句柄类型创建 Vulkan 外部信号量。将其作为信号量传递给 vkQueueSubmit
。然后,您可以使用 vkGetSemaphoreFdKHR
提取底层同步 fd。使用 EGL_ANDROID_native_fence_sync 扩展从中创建一个 EGLsyncKHR
,并将其作为您的 CompletionFence
传递到 vrapi_SubmitFrame2
。这是很多步骤,但底层同步(渲染完成 -> timewarp 开始)应该与使用 GLES 渲染或 VrApi 原生支持 Vulkan 时获得的同步一样高效。
在 Oculus 移动版 VrApi 中,我们无法访问 vkQueuePresentKHR(),我们为每只眼睛提供了一层 vrapi_SubmitFrame2()。
vulkan 示例使用栅栏与 vkQueueSubmit() 和 vkWaitForFence() 同步。 它适用于简单的渲染,但是如果我使用更长的渲染,它在屏幕上显示时还没有完成。
据我了解,这是正常的,因为栅栏允许在 CPU 级别同步,但与 GPU 的同步是通过信号量完成的。
我可以用 vkQueueSubmit() 中的信号量表示渲染已完成,但我等不及发出信号量了,因为 vrapi_SubmitFrame2() 不使用“.pWaitSemaphores”字段.
如何等待渲染完成?
求助,Vulkan版本是1.0,不过我觉得可以用v1.1.
vrapi_SubmitFrame2
接受一个 CompletionFence
,它是一个 EGLsync
对象,因为 VrApi 被设计为使用 OpenGL ES,而不是 Vulkan。所以没有单步实现无气泡同步的方法。
最简单的解决方案是在调用 vrapi_SubmitFrame2 之前确保渲染已完成。通过栅栏进入 vkQueueSubmit
,等待它发出信号,然后调用 vrapi_SubmitFrame2
。但是,这会增加延迟并降低性能(通过减少 CPU 和 GPU 工作之间的并发性),这对于 VR 来说尤其难以接受。
更复杂的解决方案是使用 VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT
句柄类型创建 Vulkan 外部信号量。将其作为信号量传递给 vkQueueSubmit
。然后,您可以使用 vkGetSemaphoreFdKHR
提取底层同步 fd。使用 EGL_ANDROID_native_fence_sync 扩展从中创建一个 EGLsyncKHR
,并将其作为您的 CompletionFence
传递到 vrapi_SubmitFrame2
。这是很多步骤,但底层同步(渲染完成 -> timewarp 开始)应该与使用 GLES 渲染或 VrApi 原生支持 Vulkan 时获得的同步一样高效。