SIGSEGV when calling pfnCreateVulkanDeviceKHR

Hello,

For learning purposes, I am attempting to implement headtracking using an HMD into a fork of an existing project. I have made a bit of progress through the initialization steps, but I have hit a roadblock when trying to create a Vulkan device through the PFN_xrCreateVulkanDeviceKHR pointer function.

The segfault occurs on this line exactly.

The PFN_xrCreateVulkanInstanceKHR pointer function, which is called earlier, doesn’t have this segfault. I can’t figure out why this segfault is occurring.

To test it yourself, run boo/test/main.cpp with the argument --openxr and see it segfault.

Note:
The project that I am forking, Boo, is part of a larger project called MetaForce by AxioDL.

1 Like

Build info for that project would be helpful, logvisor is not a proper submodule, I had to clone it myself into the boo repo.

Finding openxr like that in cmake didn’t work for me. The official cmake files aren’t much documented, but I think it’s supposed to be like this

diff --git a/CMakeLists.txt b/CMakeLists.txt
index 6d5ebf7..1ea40af 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -529,13 +529,14 @@ if(WINDOWS_STORE)
 endif()


-find_path(OPENXR_INCLUDE_DIR
-  NAMES openxr/openxr.h
-)
-
 # OpenXR
-find_library(OPENXR_LIBRARY openxr_loader)
+find_package(OpenXR REQUIRED)
+if (NOT OpenXR_FOUND)
+    MESSAGE(FATAL_ERROR "OpenXR not found!")
+endif()
+
 include(SelectLibraryConfigurations)
 select_library_configurations(OPENXR)
-target_link_libraries(boo PUBLIC ${OPENXR_LIBRARIES})
-target_include_directories(boo PUBLIC ${OPENXR_INCLUDE_DIR}/include)
\ No newline at end of file
+
+target_include_directories(boo PRIVATE ${OpenXR_INCLUDE_DIR})
+target_link_libraries(boo PRIVATE OpenXR::openxr_loader)

As for the issue, you need to do all the steps, including letting the runtime choose the VkPhysicalDevice The OpenXR Specification

diff --git a/lib/graphicsdev/Vulkan.cpp b/lib/graphicsdev/Vulkan.cpp
index ad603b4..fea2588 100644
--- a/lib/graphicsdev/Vulkan.cpp
+++ b/lib/graphicsdev/Vulkan.cpp
@@ -576,11 +576,22 @@ void VulkanContext::initDevice(PFN_vkGetInstanceProcAddr getVkProc, PFN_xrGetIns
   deviceInfo.pEnabledFeatures = &features;

   if (getXrProc){
+    XrVulkanGraphicsDeviceGetInfoKHR getInfo {XR_TYPE_VULKAN_GRAPHICS_DEVICE_GET_INFO_KHR};
+    getInfo.systemId = xrSystemId;
+    getInfo.vulkanInstance = m_instance;
+
+    VkPhysicalDevice physical_device = VK_NULL_HANDLE;
+
+    PFN_xrGetVulkanGraphicsDevice2KHR pfnGetVulkanGraphicsDevice2KHR = nullptr;
+    CHECK_XRCMD(getXrProc(xrInstance, "xrGetVulkanGraphicsDevice2KHR",
+                          reinterpret_cast<PFN_xrVoidFunction*>(&pfnGetVulkanGraphicsDevice2KHR)));
+    CHECK_XRCMD(pfnGetVulkanGraphicsDevice2KHR(xrInstance, &getInfo, &physical_device));
+
     XrVulkanDeviceCreateInfoKHR deviceCreateInfo{XR_TYPE_VULKAN_DEVICE_CREATE_INFO_KHR};
     deviceCreateInfo.systemId = xrSystemId;
     deviceCreateInfo.pfnGetInstanceProcAddr = getVkProc;
     deviceCreateInfo.vulkanCreateInfo = &deviceInfo;
-    deviceCreateInfo.vulkanPhysicalDevice = m_gpus[0];
+    deviceCreateInfo.vulkanPhysicalDevice = physical_device;
     deviceCreateInfo.vulkanAllocator = nullptr;
     VkResult err;

The reason being that the runtimes really really like applications to run on the same GPU as their own compositor.

1 Like

IIRC recently there was talk about the OpenXR validation layer lacking checks for this sequence of function calls and our own Monado runtime currently only prints a somewhat opaque message

XR_ERROR_VALIDATION_FAILURE: xrGetVulkanGraphicsDeviceKHR(sys->suggested_vulkan_physical_device == NULL)

(meaning that because xrGetVulkanGraphicsDevice2KHR has not been called, internally sys->suggested_vulkan_physical_device has not been set).

If you run on SteamVR you may find some relevant log messages in steam/logs/xrclient_<applicationname>.txt

1 Like

Thanks this appears to have done the trick. I was basing my implementation of OpenXR from the hello_xr test project within OpenXR-SDK-Source. Looks like I missed the getVulkanGraphicsDevice2KHR part entirely.
Regarding logvisor you are supposed to close the repository recursively. That’s how it was set-up in the original project.

1 Like