I’m working on implementing OpenXR for my 3D Focus Engine, and its overall going pretty good. I’ve got the expected display on my headset and headtracking is working. However, there is terrible latency. When I turn my head, it seems like it takes ~250ms before the scene rotates, causing sickness.
I pass PredictedDisplayTime from the Frame State to EndFrame, gathered via WaitFrame, as I see on examples… the big difference is, I don’t draw to the swapchain image until my frame is done (I just copy from a finished Vulkan texture to the swapchain image). However, I don’t know why this would break prediction or cause latency.
… and all of my other OpenXR code is here. If I use OpenVR (calling the abstract methods at the same place), there is no latency problem. I’m using SteamVR as a runtime.
Also – what is the difference between vulkan and vulkan2? Why are there 2 APIs? I am using vulkan…
Don’t know C# or the engine but I don’t notice an obvious problem. Maybe time the UpdatePositions and Commit functions to verify they run as often/as long as you expect? (Maybe randomly sticking a vkDeviceWaitIdle after the texture copy reveals something, stuff like that)
With the older vulkan_enable extension
the application queries required instance and device extensions
the application creates a VkInstance
the application asks the runtime for a VkPhysicalDevice
the application uses the VkPhysicalDevice to create a VkDevice
The problem was that more recent Vulkan versions have useful features that runtimes want to have enabled, but that are enabled with flags and extension structs and it would be a burden to ask application developers to create their VkInstance and VkDevice a certain way.
With the newer vulkan_enable2 extension
the application asks the runtime to create a VkInstance
the application asks the runtime for a VkPhysicalDevice
the application asks runtime to create a VkDevice with that VkPhysicalDevice
When I call commandList.Copy(sourceTexture, swapTexture); – it was just queuing that “command”, not actually doing the copy right then. So, when I called OpenXR’s EndFrame, that swapchain image didn’t actually get the latest frame yet.
I had to move EndFrame after the command list gets “flushed” and all queued commands actually get done. This is when the Vulkan texture copy happens, and when OpenXR can actually consider the swapchain image ready for EndFrame.
OpenVR, on the other hand, takes care of the copy for me, and does it right in its Submit at that exact time – which is why it worked fine for OpenVR.