Skip to content

Vulkan for XR tutorial using Simple Engine#335

Merged
gpx1000 merged 26 commits into
KhronosGroup:mainfrom
gpx1000:Vulkan-OpenXR
Jul 1, 2026
Merged

Vulkan for XR tutorial using Simple Engine#335
gpx1000 merged 26 commits into
KhronosGroup:mainfrom
gpx1000:Vulkan-OpenXR

Conversation

@gpx1000

@gpx1000 gpx1000 commented Mar 17, 2026

Copy link
Copy Markdown
Contributor

Add engine integration sections for spatial computing chapters 10-20
Add "Incorporating into the Engine" sections demonstrating practical implementation of Variable Rate Shading, Canted Displays, CAVE Architecture, Warp and Blend, LightField Theory, Plenoptic Synthesis, Scene Understanding, ML Inference, Semantic Occlusion, Platform Divergence, and Spatial Diagnostics CI/CD. Include C++ code examples for renderer_core.cpp, renderer_rendering.cpp, and engine.cpp showing feature enablement, pipeline setup, and compute passes using Vulkan 1.4 and Slang shaders.

This is a WIP currently, doing this to help test the CI scripts.

gpx1000 added 7 commits March 16, 2026 22:37
Add "Incorporating into the Engine" sections demonstrating practical implementation of Variable Rate Shading, Canted Displays, CAVE Architecture, Warp and Blend, LightField Theory, Plenoptic Synthesis, Scene Understanding, ML Inference, Semantic Occlusion, Platform Divergence, and Spatial Diagnostics CI/CD. Include C++ code examples for renderer_core.cpp, renderer_rendering.cpp, and engine.cpp showing feature enablement, pipeline setup, and compute passes using Vulkan 1.4 and Slang shaders.
…igation

Add navigation structure for new OpenXR-Vulkan spatial computing guide covering 20 chapters: OpenXR-Vulkan handshake, runtime-owned swapchains, dynamic rendering, predictive frame loop, late latching, action spaces, Slang shaders, quad-views with foveated rendering, variable rate shading, canted displays, CAVE architecture, warp and blend, lightfield theory, plenoptic synthesis, scene understanding, ML inference, semantic occlusion, platform divergence, and spatial diagnostics. Each chapter includes introduction, technical deep-dives, and engine integration sections.
…ration

Replace openxr.hpp C++ wrapper with native openxr.h C API throughout xr_context. Add OpenXR::OpenXR alias for openxr_loader target compatibility. Fix memory_pool.cpp source path and Assets copy destination. Load Vulkan extension function pointers explicitly via xrGetInstanceProcAddr. Implement proper LUID extraction from OpenXR-selected physical device using VkPhysicalDeviceIDProperties. Replace XrGuidMSFT with XrUuidMSFT for spatial mesh structure. Update all OpenXR handle types from C++ wrappers to native C types (XrInstance, XrSession, XrSpace, XrAction, XrSwapchain). Convert all OpenXR API calls from method-style to function-style. Initialize views vector with proper XR_TYPE_VIEW structure type.
…llation

Add vcpkg PATH resolution using VCPKG_INSTALLATION_ROOT. Add error checking after simple_engine and openxr-loader installation steps. Implement vcpkg caching in GitHub Actions workflow to speed up CI builds. Consolidate vcpkg environment setup into separate step with binary cache configuration.
…Properties2/getFeatures2

Replace manual pNext chaining with type-safe templated Vulkan-Hpp methods for querying PhysicalDeviceIDProperties and PhysicalDevicePresentBarrierFeaturesNV. Update code examples in hardware alignment, CAVE architecture, and renderer_core.cpp to use getProperties2<>/getFeatures2<> with compile-time type specification and .get<>() accessor pattern.
@SaschaWillems

Copy link
Copy Markdown
Collaborator

That's a pretty comprehensive PR 👍🏻

Will prob. take some time to review this, but at first glance: Can we lower the baseline from Vulkan 1.4 to 1.3? 1.4 didn't add that much, but it has very limited support on mobile.

@SaschaWillems SaschaWillems left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Did a first quick review. I don't have much experience with OpenXR, but this looks good to me and was easy to follow.

Aside from the comments, I'd like to see links to existing documentation like the tutorial, the spec and/or the guide, making it easier for people to discover relevant adjacent information.

Comment thread en/OpenXR_Vulkan_Spatial_Computing/10_Variable_Rate_Shading/01_introduction.adoc Outdated
Comment thread en/OpenXR_Vulkan_Spatial_Computing/19_Platform_Divergence/03_mobile_mastery.adoc Outdated
@SaschaWillems

SaschaWillems commented Mar 30, 2026

Copy link
Copy Markdown
Collaborator

CMake setup for the source fails for me, but maybe I'm doing something wrong (I didn't find build instructions for the OpenXR engine variation). When running CMake from the attachments/openxr_engine folder, I get the following errors:

CMake Error at V:/Vulkan-Docs-Site/Vulkan-Tutorial-review/attachments/simple_engine/CMake/Findtinygltf.cmake:80 (file):
  file failed to create symbolic link
  'V:/Vulkan-Docs-Site/Vulkan-Tutorial-review/attachments/openxr_engine/build/_deps/tinygltf-src/nlohmann/json.hpp':
  Dem Client fehlt ein erforderliches Recht.

Call Stack (most recent call first):
  CMakeLists.txt:22 (find_package)


CMake Error at C:/Program Files/CMake/share/cmake-4.1/Modules/FindPackageHandleStandardArgs.cmake:227 (message):
  Could NOT find KTX (missing: KTX_INCLUDE_DIR KTX_LIBRARY)
Call Stack (most recent call first):
  C:/Program Files/CMake/share/cmake-4.1/Modules/FindPackageHandleStandardArgs.cmake:591 (_FPHSA_FAILURE_MESSAGE)
  V:/Vulkan-Docs-Site/Vulkan-Tutorial-review/attachments/simple_engine/CMake/FindKTX.cmake:55 (find_package_handle_standard_args)
  CMakeLists.txt:23 (find_package)

gpx1000 and others added 8 commits May 30, 2026 21:51
…ration

Replace openxr.hpp C++ wrapper with native openxr.h C API throughout xr_context. Add OpenXR::OpenXR alias for openxr_loader target compatibility. Fix memory_pool.cpp source path and Assets copy destination. Load Vulkan extension function pointers explicitly via xrGetInstanceProcAddr. Implement proper LUID extraction from OpenXR-selected physical device using VkPhysicalDeviceIDProperties. Replace XrGuidMSFT with XrUuidMSFT for spatial mesh structure. Update all OpenXR handle types from C++ wrappers to native C types (XrInstance, XrSession, XrSpace, XrAction, XrSwapchain). Convert all OpenXR API calls from method-style to function-style. Initialize views vector with proper XR_TYPE_VIEW structure type.
@SaschaWillems

Copy link
Copy Markdown
Collaborator

Documentation looks good and the code builds, but it crashes for me inside QueueFamilyIndices Renderer::findQueueFamilies at device.getSurfaceSupportKHR (Line 150).

I get the following validation layer error before the crash:

Validation layer: vkGetPhysicalDeviceSurfaceSupportKHR(): surface Invalid VkSurfaceKHR Object 0x1fff5c6dc10.
The Vulkan spec states: surface must be a valid VkSurfaceKHR handle (https://docs.vulkan.org/spec/latest/chapters/VK_KHR_surface/wsi.html#VUID-vkGetPhysicalDeviceSurfaceSupportKHR-surface-parameter)
Validation layer: vkGetPhysicalDeviceSurfaceSupportKHR(): Couldn't find VkSurfaceKHR Object 0x1fff5c6dc10. This should not happen and may indicate a bug in the application.

This is on Windows with an RTX 4070 using Meta's OpenXR simulator.

@gpx1000

gpx1000 commented Jun 28, 2026

Copy link
Copy Markdown
Contributor Author

Give that another try. I haven't tried it in Meta's OpenXR simulator,. But it does seem to work in monada runtime and our runtime. I did test it in Windows so hopefully Meta's runtime will be good to go.

gpx1000 added 4 commits June 29, 2026 00:14
…latform header

XR_USE_PLATFORM_WIN32 causes openxr_platform.h to pull in Win32 extension
structs that use LARGE_INTEGER and IUnknown.  The former is in <windows.h>;
the latter is in <unknwn.h> which WIN32_LEAN_AND_MEAN excludes from the
windows.h umbrella.  Previously xr_context.h hardcoded XR_USE_PLATFORM_XLIB
(even on Windows), so the Win32 sections were never compiled.  Now that the
platform define is correct, add the explicit prerequisite includes.
- Implemented OpenXR session state handling to support session start/stop events.
- Integrated an ImGui system for rendering custom UI components.
- Enhanced XR frame rendering logic to respect session state.
- Added logic to dynamically select XR reference spaces based on platform compatibility.
- Updated Vulkan rendering logic to handle ImGui frame closures and pipeline binding conditions.
- Prevented GTK modules from loading to avoid crashes on Wayland.
- Made several fixes, including fallback rendering when the session isn't running and bindings for XR actions and poses.
@SaschaWillems

Copy link
Copy Markdown
Collaborator

Thanks. It's now starting up. But I do get some validation errors:

 vkCreateDevice(): If the pNext chain includes a VkPhysicalDeviceVulkan11Features structure, then it must not include a VkPhysicalDeviceMultiviewFeatures structure. The features in VkPhysicalDeviceMultiviewFeatures were promoted in Vulkan 1.1 and is also found in VkPhysicalDeviceVulkan11Features. To prevent one feature setting something to VK_TRUE and the other to VK_FALSE, only one struct containing the feature is allowed.
pNext chain: VkDeviceCreateInfo::pNext -> [VK_STRUCTURE_TYPE_LOADER_DEVICE_CREATE_INFO] -> [VK_STRUCTURE_TYPE_LOADER_DEVICE_CREATE_INFO] -> [VkPhysicalDeviceFeatures2] -> [VkPhysicalDeviceMultiviewFeatures] -> [VkPhysicalDeviceTimelineSemaphoreFeatures] -> [VkPhysicalDeviceVulkanMemoryModelFeatures] -> [VkPhysicalDeviceBufferDeviceAddressFeatures] -> [VkPhysicalDevice8BitStorageFeatures] -> [VkPhysicalDeviceVulkan11Features] -> [VkPhysicalDeviceVulkan13Features] -> [VkPhysicalDeviceDescriptorIndexingFeatures] -> [VkPhysicalDeviceRobustness2FeaturesKHR] -> [VkPhysicalDeviceDynamicRenderingLocalReadFeatures] -> [VkPhysicalDeviceAccelerationStructureFeaturesKHR] -> [VkPhysicalDeviceRayQueryFeaturesKHR].
The Vulkan spec states: If the pNext chain includes a VkPhysicalDeviceVulkan11Features structure, then it must not include a VkPhysicalDevice16BitStorageFeatures, VkPhysicalDeviceMultiviewFeatures, VkPhysicalDeviceVariablePointersFeatures, VkPhysicalDeviceProtectedMemoryFeatures, VkPhysicalDeviceSamplerYcbcrConversionFeatures, or VkPhysicalDeviceShaderDrawParametersFeatures structure (https://docs.vulkan.org/spec/latest/chapters/devsandqueues.html#VUID-VkDeviceCreateInfo-pNext-02829)

and

Validation layer: vkCreatePipelineCache(): pCreateInfo->flags includes VK_PIPELINE_CACHE_CREATE_EXTERNALLY_SYNCHRONIZED_BIT, but pipelineCreationCacheControl feature was not enabled.
The Vulkan spec states: If the pipelineCreationCacheControl feature is not enabled, flags must not include VK_PIPELINE_CACHE_CREATE_EXTERNALLY_SYNCHRONIZED_BIT (https://docs.vulkan.org/spec/latest/chapters/pipelines.html#VUID-VkPipelineCacheCreateInfo-pipelineCreationCacheControl-02892)

And afterwards I do see the Meta XR simulator spinning up, but all I get is a white screen.

Last line in std::out is:

Requesting acceleration structure build for loaded scene...

Then pressing any key results in an assertion;

Assertion failed: ImGui::IsNamedKeyOrMod(key), file V:\Vulkan-Docs-Site\Vulkan-Tutorial-review\attachments\simple_engine\imgui\imgui.cpp, line 1850

Not sure if any of this is related to the Meta XR Simulator.

gpx1000 added 2 commits June 30, 2026 12:56
…ove OpenXR session handling.

- Removed XR multiview pipeline configurations and updated layer and swapchain logic for simpler rendering.
- Integrated pipelineCreationCacheControl and multiview into Vulkan 1.1+ feature structs, aligning with XR runtime requirements.
- Improved frame loop reliability by introducing `isSessionFraming` to handle READY state in Monado.
- Added reference space sync to align scene and XR environments post-loading.
- Updated memory pool to optimize allocation scanning with `nextFreeHint` and freed-space reuse.
- Disabled ImGui integration while addressing heap corruption issues.
- Refactored session lifecycle handling to reduce busy-spinning, improve stability, and add debug logging.
- Improved the Vulkan platform abstraction to include standalone XR headset support.
# Conflicts:
#	en/Building_a_Simple_Engine/Tooling/index.adoc
@gpx1000
gpx1000 merged commit 45852ce into KhronosGroup:main Jul 1, 2026
9 checks passed
@gpx1000
gpx1000 deleted the Vulkan-OpenXR branch July 1, 2026 03:33
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants