Focus Engine OpenXR: 2 questions (bad latency + vulkan2?)

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.

My WaitFrame is here: FocusEngine/OpenXRHmd.cs at master · phr00t/FocusEngine · GitHub

My EndFrame starts here: FocusEngine/OpenXRHmd.cs at master · phr00t/FocusEngine · GitHub

… 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…

Any help is greatly appreciated!

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

I fixed it! Your comment actually helped, too!

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.