From 10bfaebe53c892f99445c3588ef1f8abcf282635 Mon Sep 17 00:00:00 2001 From: Konstantin Uni <2002erdi@gmail.com> Date: Wed, 30 Sep 2026 16:30:27 +0200 Subject: [PATCH] Initial commit: OpenXR simulator runtime, compositor, configurator, docs --- .gitignore | 12 + CMakeLists.txt | 144 + CMakePresets.json | 38 + README.md | 138 + config/openxr_simulator_config.json | 18 + docs/DESIGN.md | 323 + manifest/openxr_simulator.json.in | 7 + src/Common.h | 36 + src/Compositor.cpp | 896 +++ src/Compositor.h | 44 + src/CompositorStub.cpp | 21 + src/Config.cpp | 193 + src/Config.h | 71 + src/HeadsetPresets.h | 68 + src/Negotiation.cpp | 219 + src/Runtime.cpp | 1737 +++++ src/Runtime.h | 392 ++ third_party/openxr/openxr.h | 6135 +++++++++++++++++ .../openxr/openxr_loader_negotiation.h | 114 + third_party/openxr/openxr_platform.h | 714 ++ third_party/openxr/openxr_platform_defines.h | 114 + tools/configurator/ConfiguratorMain.cpp | 254 + 22 files changed, 11688 insertions(+) create mode 100644 .gitignore create mode 100644 CMakeLists.txt create mode 100644 CMakePresets.json create mode 100644 README.md create mode 100644 config/openxr_simulator_config.json create mode 100644 docs/DESIGN.md create mode 100644 manifest/openxr_simulator.json.in create mode 100644 src/Common.h create mode 100644 src/Compositor.cpp create mode 100644 src/Compositor.h create mode 100644 src/CompositorStub.cpp create mode 100644 src/Config.cpp create mode 100644 src/Config.h create mode 100644 src/HeadsetPresets.h create mode 100644 src/Negotiation.cpp create mode 100644 src/Runtime.cpp create mode 100644 src/Runtime.h create mode 100644 third_party/openxr/openxr.h create mode 100644 third_party/openxr/openxr_loader_negotiation.h create mode 100644 third_party/openxr/openxr_platform.h create mode 100644 third_party/openxr/openxr_platform_defines.h create mode 100644 tools/configurator/ConfiguratorMain.cpp diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..db67b6e --- /dev/null +++ b/.gitignore @@ -0,0 +1,12 @@ +out/ +build/ +.vs/ +.vscode/ +.idea/ +openxr_simulator_imgui.ini +imgui.ini +*.dll +*.lib +*.exp +*.pdb +*.ilk diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..7b5bc6d --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,144 @@ +cmake_minimum_required(VERSION 3.24) + +project(openxr_simulator VERSION 0.1.0 LANGUAGES CXX) + +set(CMAKE_CXX_STANDARD 20) +set(CMAKE_CXX_STANDARD_REQUIRED ON) +set(CMAKE_CXX_EXTENSIONS OFF) + +if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES) + set(CMAKE_BUILD_TYPE Release CACHE STRING "Build type" FORCE) +endif() + +option(XRSIM_BUILD_COMPOSITOR "Build the GLFW + Dear ImGui display window" ON) + +find_package(Vulkan REQUIRED) + +include(FetchContent) + +# --------------------------------------------------------------------------- +# GLFW +# --------------------------------------------------------------------------- +set(GLFW_BUILD_DOCS OFF CACHE BOOL "" FORCE) +set(GLFW_BUILD_TESTS OFF CACHE BOOL "" FORCE) +set(GLFW_BUILD_EXAMPLES OFF CACHE BOOL "" FORCE) +set(GLFW_INSTALL OFF CACHE BOOL "" FORCE) +FetchContent_Declare( + glfw + GIT_REPOSITORY https://github.com/glfw/glfw.git + GIT_TAG 3.4 +) +FetchContent_MakeAvailable(glfw) + +# --------------------------------------------------------------------------- +# Dear ImGui (docking branch, matches the engine's 1.91.4-docking) +# --------------------------------------------------------------------------- +FetchContent_Declare( + imgui + GIT_REPOSITORY https://github.com/ocornut/imgui.git + GIT_TAG v1.91.4-docking +) +# imgui has no CMakeLists.txt, so this only downloads it. +FetchContent_MakeAvailable(imgui) + +add_library(imgui STATIC + ${imgui_SOURCE_DIR}/imgui.cpp + ${imgui_SOURCE_DIR}/imgui_draw.cpp + ${imgui_SOURCE_DIR}/imgui_tables.cpp + ${imgui_SOURCE_DIR}/imgui_widgets.cpp + ${imgui_SOURCE_DIR}/imgui_demo.cpp + ${imgui_SOURCE_DIR}/backends/imgui_impl_glfw.cpp + ${imgui_SOURCE_DIR}/backends/imgui_impl_vulkan.cpp + ${imgui_SOURCE_DIR}/backends/imgui_impl_opengl3.cpp +) +target_include_directories(imgui SYSTEM PUBLIC + ${imgui_SOURCE_DIR} + ${imgui_SOURCE_DIR}/backends +) +target_link_libraries(imgui PUBLIC glfw Vulkan::Vulkan) + +# --------------------------------------------------------------------------- +# JSON dependency + shared runtime config +# --------------------------------------------------------------------------- +FetchContent_Declare( + json + GIT_REPOSITORY https://github.com/nlohmann/json.git + GIT_TAG v3.11.3 +) +FetchContent_MakeAvailable(json) + +add_library(xrsim_config STATIC src/Config.cpp) +target_include_directories(xrsim_config PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/src) +target_link_libraries(xrsim_config PUBLIC nlohmann_json::nlohmann_json) + +# --------------------------------------------------------------------------- +# OpenXR simulator runtime +# --------------------------------------------------------------------------- +add_library(openxr_simulator SHARED + src/Negotiation.cpp + src/Runtime.cpp +) + +if(XRSIM_BUILD_COMPOSITOR) + target_sources(openxr_simulator PRIVATE src/Compositor.cpp) + target_link_libraries(openxr_simulator PRIVATE imgui) +else() + target_sources(openxr_simulator PRIVATE src/CompositorStub.cpp) +endif() + +target_include_directories(openxr_simulator + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR}/src + ${CMAKE_CURRENT_SOURCE_DIR}/third_party +) + +target_compile_definitions(openxr_simulator + PRIVATE + XR_USE_PLATFORM_WIN32 + XR_USE_GRAPHICS_API_VULKAN + XR_NO_PROTOTYPES +) + +target_link_libraries(openxr_simulator PRIVATE Vulkan::Vulkan xrsim_config) + +if(MINGW) + # Statically link the GCC runtime (libstdc++/libgcc/libwinpthread) into the DLL so the OpenXR + # loader can load it when the app is launched from Explorer (no MinGW bin on PATH). + target_link_options(openxr_simulator PRIVATE -static-libgcc -static-libstdc++ -static) +endif() + +if(MSVC) + target_compile_options(openxr_simulator PRIVATE /W4) +else() + # Vulkan structs are routinely zero-initialized with `{ VK_STRUCTURE_TYPE_... }`. + target_compile_options(openxr_simulator PRIVATE -Wall -Wextra -Wno-missing-field-initializers) +endif() + +set_target_properties(openxr_simulator PROPERTIES + PREFIX "" + OUTPUT_NAME "openxr_simulator" +) + +# Runtime manifest consumed by the OpenXR loader (via XR_RUNTIME_JSON or registry). +set(SIM_RUNTIME_NAME "OpenXR Simulator") +configure_file( + ${CMAKE_CURRENT_SOURCE_DIR}/manifest/openxr_simulator.json.in + ${CMAKE_CURRENT_BINARY_DIR}/openxr_simulator.json + @ONLY +) + +# --------------------------------------------------------------------------- +# Configurator application (edits openxr_simulator_config.json) +# --------------------------------------------------------------------------- +if(XRSIM_BUILD_COMPOSITOR) + find_package(OpenGL REQUIRED) + + add_executable(openxr_simulator_configurator WIN32 tools/configurator/ConfiguratorMain.cpp) + target_link_libraries(openxr_simulator_configurator PRIVATE xrsim_config imgui glfw OpenGL::GL) + + if(MINGW) + target_link_options( + openxr_simulator_configurator PRIVATE -static-libgcc -static-libstdc++ -static + ) + endif() +endif() diff --git a/CMakePresets.json b/CMakePresets.json new file mode 100644 index 0000000..ea694d7 --- /dev/null +++ b/CMakePresets.json @@ -0,0 +1,38 @@ +{ + "version": 3, + "cmakeMinimumRequired": { + "major": 3, + "minor": 24, + "patch": 0 + }, + "configurePresets": [ + { + "name": "windows-mingw-release", + "displayName": "Windows MinGW Release", + "generator": "Ninja", + "binaryDir": "${sourceDir}/out/build/windows-mingw-release", + "cacheVariables": { + "CMAKE_BUILD_TYPE": "Release" + } + }, + { + "name": "windows-msvc-release", + "displayName": "Windows MSVC Release", + "generator": "Ninja", + "binaryDir": "${sourceDir}/out/build/windows-msvc-release", + "cacheVariables": { + "CMAKE_BUILD_TYPE": "Release" + } + } + ], + "buildPresets": [ + { + "name": "windows-mingw-release", + "configurePreset": "windows-mingw-release" + }, + { + "name": "windows-msvc-release", + "configurePreset": "windows-msvc-release" + } + ] +} diff --git a/README.md b/README.md new file mode 100644 index 0000000..c2511f6 --- /dev/null +++ b/README.md @@ -0,0 +1,138 @@ +# OpenXR Simulator + +A Windows OpenXR **runtime** that pretends to be a headset. OpenXR applications +run unmodified and render into runtime-owned Vulkan swapchains; the runtime +displays those swapchain images in a desktop window (GLFW + Dear ImGui docking). +Primary target is the `gl3-vulkan` / "Get Beaned" engine. + +See [`docs/DESIGN.md`](docs/DESIGN.md) for the full architecture and roadmap. + +## Status + +Implemented: + +- Loader negotiation, dispatch table, instance/system/view-config metadata. +- Vulkan instance/device creation on behalf of the app (augmenting the required + surface/swapchain extensions). +- Session lifecycle + session-state events, multiview swapchains, frame loop + (`xrWaitFrame`/`xrBeginFrame`/`xrEndFrame`), `xrLocateViews` with mouse/WASD + tracking. +- Action API with **emulated controllers**: advertises an Oculus Touch profile + and maps keyboard/mouse to trigger, grip, thumbstick, buttons, menu, and + aim/grip poses. The mapping is shown in the ImGui `Controls` window. +- GLFW + Dear ImGui (docking) compositor showing each eye in a dockable window. + +Set `XRSIM_NO_WINDOW=1` to run headless (no window, no eye display). +Remaining: Phase 5 polish (session-state edges, haptics, settings UI). + +## Layout + +```text +CMakeLists.txt Build the runtime DLL + configurator. +CMakePresets.json Configure/build presets. +config/openxr_simulator_config.json Reference config. +docs/DESIGN.md Architecture and roadmap. +manifest/openxr_simulator.json.in Runtime manifest template. +src/Common.h Logging. +src/Config.h / Config.cpp Shared config (JSON), used by DLL + configurator. +src/Runtime.h / Runtime.cpp Runtime state + xr* entry points. +src/Negotiation.cpp Export + xrGetInstanceProcAddr dispatch. +src/Compositor.cpp GLFW + ImGui display window. +tools/configurator/ GLFW + ImGui config editor. +third_party/openxr/ Vendored OpenXR 1.0.28 headers + negotiation. +``` + +## Requirements + +- CMake 3.24+, Ninja +- MinGW-w64 GCC or MSVC +- [Vulkan SDK](https://vulkan.lunarg.com/sdk/home) (`VULKAN_SDK` on `PATH`) + +## Build + +```powershell +cmake --preset windows-mingw-release +cmake --build --preset windows-mingw-release +``` + +Outputs `out/build/windows-mingw-release/openxr_simulator.dll` and +`openxr_simulator.json` side by side. + +## Configuration + +The runtime reads a JSON config from `XRSIM_CONFIG`, or else +`openxr_simulator_config.json` next to `openxr_simulator.dll`. A reference file +lives in [`config/openxr_simulator_config.json`](config/openxr_simulator_config.json). + +Editable via the configurator (built alongside the runtime): + +```powershell +.\out\build\windows-msvc-release\openxr_simulator_configurator.exe +``` + +The configurator includes headset presets — Meta Quest 2 / 3 / 3S / Pro, Valve +Index, Valve Steam Frame, HTC Vive / Vive Pro 2 / Focus 3, HP Reverb G2, Pico 4 / +4 Ultra / Neo 3, Varjo Aero / XR-4, Pimax Crystal, Bigscreen Beyond 2, +PlayStation VR2, Samsung Galaxy XR, and a generic 1280 headset — or you can set +values manually. + +Settings: + +| Key | Meaning | +| --- | --- | +| `systemName`, `vendorId` | Reported by `xrGetSystemProperties`. | +| `eyeWidth`, `eyeHeight` | Per-eye recommended render resolution. | +| `refreshRateHz` | Virtual headset strobe rate used by `xrWaitFrame`. | +| `fovLeftDeg`/`Right`/`Up`/`Down` | Per-eye half-angle field of view. | +| `ipdMeters` | Default interpupillary distance. | +| `swapchainImageCount` | Number of images per XR swapchain. | +| `windowTitle`, `windowWidth`, `windowHeight` | Simulator window. | +| `presentMode` | `mailbox`/`immediate` (uncapped) or `fifo` (vsync). | +| `displayMode` | `sideBySide`, `singleEyeLeft`, `singleEyeRight`. | + +### Frame rate / 60 Hz cap + +`presentMode: "fifo"` presents with vsync, which caps the whole app to the +monitor refresh (e.g. 60 Hz) because presentation happens on the app's thread. +The default `"mailbox"` (or `"immediate"`) presents without vsync. `refreshRateHz` +controls the simulated headset strobe independently of presentation. + +## Testing against the engine + +The engine already honours `XR_RUNTIME_JSON`, so no registry changes are needed. +From the engine build directory (`gl3-vulkan/code/out/build/`): + +```powershell +$env:XR_RUNTIME_JSON = "C:\Users\\openxr-simulator\out\build\windows-mingw-release\openxr_simulator.json" +.\Game.exe +``` + +Expected in this phase: the loader loads the simulator, `xrCreateInstance` and +`xrGetSystem` succeed, and the engine creates its Vulkan instance/device through +the runtime. It will then fail on the first unimplemented call (swapchain), which +is the Phase 2 milestone. + +## Installing system-wide (optional, later) + +Point the active runtime at the manifest: + +```powershell +New-Item -Path "HKLM:\SOFTWARE\Khronos\OpenXR\1" -Force | Out-Null +Set-ItemProperty -Path "HKLM:\SOFTWARE\Khronos\OpenXR\1" -Name "ActiveRuntime" ` + -Value "C:\Users\\openxr-simulator\out\build\windows-mingw-release\openxr_simulator.json" +``` + +Remember to restore the previous value (`SteamVR`/`Oculus`) when done. + +## Troubleshooting + +- **Loader logs `Failed to open dynamic library ... error 126`** (`ERROR_MOD_NOT_FOUND`) + when launching from Explorer: the runtime DLL's dependencies are missing from + `PATH`. The MinGW build statically links the GCC runtime + (`-static-libgcc -static-libstdc++ -static`) so this should not happen; if you + build with another toolchain, either link the CRT statically or ship the + required runtime DLLs next to `openxr_simulator.dll`. Inspect dependencies with + `objdump -p openxr_simulator.dll | findstr "DLL Name"`. +- **`library_path` must contain a path separator.** A bare `openxr_simulator.dll` + is resolved from the global library search path, not the manifest directory; + the generated manifest uses `./openxr_simulator.dll` for this reason. diff --git a/config/openxr_simulator_config.json b/config/openxr_simulator_config.json new file mode 100644 index 0000000..777f2ec --- /dev/null +++ b/config/openxr_simulator_config.json @@ -0,0 +1,18 @@ +{ + "systemName": "OpenXR Simulator", + "vendorId": 0, + "eyeWidth": 1280, + "eyeHeight": 1280, + "refreshRateHz": 90, + "fovLeftDeg": 45.0, + "fovRightDeg": 45.0, + "fovUpDeg": 45.0, + "fovDownDeg": 45.0, + "ipdMeters": 0.064, + "swapchainImageCount": 3, + "windowTitle": "OpenXR Simulator", + "windowWidth": 1600, + "windowHeight": 900, + "presentMode": "mailbox", + "displayMode": "sideBySide" +} diff --git a/docs/DESIGN.md b/docs/DESIGN.md new file mode 100644 index 0000000..f894749 --- /dev/null +++ b/docs/DESIGN.md @@ -0,0 +1,323 @@ +# OpenXR Simulator Runtime — Design + +A Windows OpenXR **runtime** that pretends to be a headset. OpenXR applications +(especially the `gl3-vulkan` / "Get Beaned" engine) run unmodified and render +into runtime-owned swapchains; the runtime displays those swapchain images in a +desktop window built with GLFW + Dear ImGui (docking). + +This document is the architecture of record for the scaffold in this repository. + +--- + +## 1. What an OpenXR runtime is on Windows + +The application links `openxr_loader.dll` (from OpenXR-SDK). The loader is not +the runtime; it locates one of the installed runtimes and forwards every `xr*` +call to it. + +Resolution order for the active runtime: + +1. `XR_RUNTIME_JSON` environment variable → path to a runtime manifest JSON. +2. Per-user registry `HKCU\SOFTWARE\Khronos\OpenXR\1\ActiveRuntime`. +3. Machine registry `HKLM\SOFTWARE\Khronos\OpenXR\1\ActiveRuntime`. + +The manifest points at a DLL that exports `xrNegotiateLoaderRuntimeInterface`. +That function hands the loader an `XrNegotiateRuntimeRequest` containing a +`PFN_xrGetInstanceProcAddr`. The loader uses that GIPA to resolve every core and +extension entry point. + +```json +{ + "file_format_version": "1.0.0", + "runtime": { + "library_path": "openxr_simulator.dll", + "name": "OpenXR Simulator" + } +} +``` + +The negotiation structs are in `third_party/openxr/openxr_loader_negotiation.h` +(vendored from OpenXR-SDK-Source `src/common/loader_interfaces.h`). + +### Development shortcut + +The `gl3-vulkan` engine already supports overriding the runtime without touching +the registry: `ApplicationContext::createOpenXrInstance(customOpenXrRuntimePath)` +sets `XR_RUNTIME_JSON` (`code/Engine/src/Engine/Core/ApplicationContext.cpp:904`). +So the whole simulator can be tested by launching the game with that env var +pointing at `openxr_simulator.json`. No system-wide install required. + +--- + +## 2. How `gl3-vulkan` uses OpenXR (the contract we must satisfy) + +The engine is the primary target. Key facts, with source references: + +### 2.1 The runtime owns Vulkan + +The engine does **not** create its own `VkInstance`/`VkDevice`. It asks the +runtime to: + +| Call | Location | +| --- | --- | +| `xrCreateVulkanInstanceKHR` | `ApplicationContext.cpp:1442` | +| `xrGetVulkanGraphicsDevice2KHR` | `ApplicationContext.cpp:177` | +| `xrCreateVulkanDeviceKHR` | `ApplicationContext.cpp:478` | + +Consequence: the runtime creates the instance and device, so it can create a +Win32 `VkSurfaceKHR`/present queue on the same objects and display the app's +images with **zero cross-device copies**. This is the single most important +design lever. + +### 2.2 Graphics binding and swapchains + +- Session is created with `XrGraphicsBindingVulkan2KHR` (app's instance, physical + device, device, graphics queue family/index): `Headset.cpp:59`. +- One **multiview** swapchain, `arraySize = 2` (`Headset.cpp:657`). Two eye + layers in one image, submitted as two projection views with + `imageArrayIndex = 0/1` (`Headset.cpp:762`). +- Format negotiated via `xrEnumerateSwapchainFormats`; engine prefers + `VK_FORMAT_R8G8B8A8_SRGB` (`Headset.cpp:23`), fallback `R8G8B8A8_UNORM` + + `MUTABLE_FORMAT` (`Headset.cpp:24,667`). +- `recommendedSwapchainSampleCount`, `recommendedImageRectWidth/Height` come + from our view configuration. +- Reference space is `XR_REFERENCE_SPACE_TYPE_STAGE` (`Headset.cpp:20`). + +### 2.3 Frame loop + +Per frame: `xrWaitFrame` → `xrBeginFrame` → `xrLocateViews` → +`xrAcquireSwapchainImage` → `xrWaitSwapchainImage` → [app renders] → +`xrReleaseSwapchainImage` → `xrEndFrame` with one +`XrCompositionLayerProjection` (2 views). See `Headset.cpp:1070-1161`. + +### 2.4 Required extensions and runtime behaviour + +- `XR_KHR_vulkan_enable2` is hard-required (`ApplicationContext.cpp:963,979`). +- Debug builds also require `XR_EXT_debug_utils` and call + `xrCreateDebugUtilsMessengerEXT` (`ApplicationContext.cpp:965-967,1090`). +- `XR_ENVIRONMENT_BLEND_MODE_OPAQUE` must be advertised + (`ApplicationContext.cpp:66,1194`). +- Session state events drive startup: the engine waits for + `XR_SESSION_STATE_READY` to call `xrBeginSession` + (`Engine.cpp:284`, `Headset.cpp:925`), and only renders in + READY/SYNCHRONIZED/VISIBLE/FOCUSED (`Headset.cpp:990`). We must enqueue + `XR_TYPE_EVENT_DATA_SESSION_STATE_CHANGED`. +- Input: the engine builds actions for ~16 interaction profiles and attaches + them (`XrInputHandler.cpp`). We must implement the action API and at least one + profile (`khr/simple_controller` and/or `oculus/touch_controller`). + +### 2.5 Gotcha: Vulkan requirement version encoding + +`getVulkanGraphicsRequirements2KHR` must report `minApiVersionSupported` / +`maxApiVersionSupported` using **`XR_MAKE_VERSION`** (major in bits 48-63), not +`VK_MAKE_VERSION`. The engine decodes with `XR_VERSION_MAJOR/MINOR` +(`ApplicationContext.cpp:1289-1297`) and rejects the runtime otherwise. Report +`XR_MAKE_VERSION(1,0,0)` .. `XR_MAKE_VERSION(1,4,0)`. + +--- + +## 3. Architecture + +``` + app process (Game.exe) + ┌─────────────────────────────────────────────────────────────┐ + │ engine ── xr* calls ──► openxr_loader.dll │ + │ │ │ + │ ▼ │ + │ openxr_simulator.dll (this repo)│ + │ ┌───────────────────────────────────────────────────────┐ │ + │ │ xrNegotiateLoaderRuntimeInterface (DLL export) │ │ + │ │ xrGetInstanceProcAddr (dispatch table) │ │ + │ │ │ │ + │ │ Instance ─ System ─ Session ─ Swapchain │ │ + │ │ │ │ │ │ + │ │ ▼ ▼ │ │ + │ │ Vulkan backend (owns VkInstance/VkDevice) │ │ + │ │ │ │ │ + │ │ ▼ │ │ + │ │ Compositor (GLFW window + ImGui docking) │ │ + │ │ - eye textures drawn in dockable ImGui windows │ │ + │ └───────────────────────────────────────────────────────┘ │ + └─────────────────────────────────────────────────────────────┘ +``` + +### 3.1 Layers + +| Layer | Responsibility | +| --- | --- | +| Negotiation | Export the interface, build the GIPA table. | +| Instance | State per `XrInstance`; registry of handles. | +| System / View config | Advertise HMD system, stereo view config, resolution, formats, blend modes. | +| Vulkan backend | Create/hold `VkInstance`/`VkDevice`, allocate swapchain images, own the present queue. | +| Session / Frame loop | Session state events, `xrWaitFrame` pacing, `xrEndFrame` submission. | +| Tracking | Head pose + controller poses (MVP: mouse/WASD/keyboard). | +| Actions | Action sets, bindings, `xrSyncActions`, state queries. | +| Compositor | GLFW+ImGui window; blit submitted eye layers into ImGui-visible textures. | + +### 3.2 Object model and handles + +OpenXR handles are opaque pointers (`XR_DEFINE_HANDLE`). We allocate small +structs and reinterpret-cast to the handle type, keeping them in a global +registry guarded by a mutex: + +```cpp +struct RuntimeInstance; struct RuntimeSession; struct RuntimeSwapchain; ... +RuntimeInstance* GetInstance(XrInstance); +RuntimeSession* GetSession(XrSession); +``` + +### 3.3 Vulkan ownership + +Because the engine delegates instance/device creation to us: + +- `xrCreateVulkanInstanceKHR`: call the app-supplied `pfnGetInstanceProcAddr` to + get `vkCreateInstance`, create the instance (augmenting the create info with + our own required extensions such as `VK_KHR_surface`, + `VK_KHR_win32_surface`). +- `xrGetVulkanGraphicsDevice2KHR`: enumerate devices, pick one that supports + graphics + present to our window surface, return it. +- `xrCreateVulkanDeviceKHR`: `vkCreateDevice` with the app's create info plus any + queue families/extensions we need (`VK_KHR_swapchain`). +- Swapchain images are allocated on this device; the compositor blits them on + the same device/queue. No interop needed. + +### 3.4 Compositor (GLFW + ImGui docking) + +Decision (MVP): the simulator window is a normal GLFW window rendered with the +Dear ImGui Vulkan backend, using ImGui docking so the user can freely arrange +windows. Rather than presenting to a raw swapchain, each submitted eye is shown +in a dockable `ImGui::Image` window. + +**Thread affinity (important).** The `gl3-vulkan` engine calls `xrEndFrame` from +a **background thread** (`EngineKern::completeFrameAsync`) and `xrWaitFrame` from +a worker pool, but calls `xrBeginFrame` from its main thread. GLFW/ImGui are +thread-affine, so the compositor splits into two phases: + +- `Present()` — called from `xrEndFrame` on any thread. Only *records* the + resolved eye images (`ResolveSubImage`, using the swapchain's + `lastReleasedIndex` because release already cleared the acquired index). No + GLFW/ImGui/Vulkan work. +- `Pump()` — called from `xrBeginFrame` and `xrWaitFrame`; does the real work + only when the caller is the thread that created the window (guarded by + `windowThreadId_`), otherwise returns immediately. + +Pump steps: + +1. Wait for the app's rendering to finish on the shared queue (MVP: + `vkQueueWaitIdle` on the app graphics queue; later: timeline/fence sync). +2. Copy the two array layers of the submitted XR swapchain image into two + persistent runtime "display" images (`TRANSFER_DST | SAMPLED`, kept in + `GENERAL` layout). +3. `ImGui::NewFrame()`; draw a menu + two image windows (`Eye L`, `Eye R`) + sampling the display images, plus simulator controls (tracking sliders). +4. Render ImGui into the window swapchain and present. + +Registering two persistent display images as ImGui textures decouples the ImGui +texture set from the XR swapchain image count and lets us scale each eye to fit +its dock window. + +Window/queue notes: + +- The simulator window surface is created on the runtime-owned `VkInstance`. +- Use the app's graphics queue (from `XrGraphicsBindingVulkan2KHR`) as the ImGui + queue so ordering on the same queue provides implicit synchronization, and + ensure that family supports present to our surface. If it does not, do a queue + family ownership transfer (or fall back to a dedicated runtime present queue + + explicit waits). +- `gl3-vulkan` also creates its own GLFW mirror window on the same instance. + GLFW is statically linked into both; each copy keeps independent state, so + both can coexist. If this proves fragile, the ImGui **Win32** backend is the + fallback (no GLFW dependency). + +### 3.5 Frame pacing and events + +- `xrWaitFrame` throttles to a configurable virtual refresh rate (default 90 Hz) + and returns `predictedDisplayTime` + `shouldRender`. +- Session state event sequence we enqueue: + `IDLE → READY` at session creation, then after `xrBeginSession` + `SYNCHRONIZED → VISIBLE → FOCUSED`. This matches what the engine's event + handler expects. + +### 3.6 Tracking and input + +- Head: mouse look (yaw/pitch) + WASD translation, integrated into an + `XrPosef` returned from `xrLocateViews`. STAGE space; y- is up. +- Controllers: the runtime advertises an emulated `oculus/touch_controller` + profile from `xrGetCurrentInteractionProfile` for both hands, so the app + activates that profile and wires up its aim/grip pose spaces. +- Action state (`xrGetActionState*`) is classified from the action name suffix + (`trigger_value`, `grip_value`, `thumbstick`, `a_button`, …) and the + subaction path (hand), then read from a global `InputState` updated by the + compositor. `xrLocateSpace` on an action space returns the emulated hand pose. + +Keyboard mapping (shown in the ImGui `Controls` window): + +| Control | Left hand | Right hand | +| --- | --- | --- | +| Head look / move | right-drag, WASD, Q/E | | +| Trigger | `F` | `H` | +| Grip | `G` | `U` | +| Thumbstick | `I`/`K`/`J`/`L` | arrow keys | +| Stick click | `R` | `O` | +| Face buttons | `C` (X), `V` (Y) | `N` (A), `M` (B) | +| Menu | `Tab` | | + +The hand poses are placed relative to the head, so they follow look direction. +A `TrackingProvider` interface is planned so a real HMD / OpenTrack / gamepad +bridge can be plugged in later without touching the session code. + +### 3.7 Configuration + +The runtime reads a JSON config (`src/Config.{h,cpp}`) from `XRSIM_CONFIG`, or +else `openxr_simulator_config.json` next to the DLL. It drives the emulated +headset: system name/vendor, per-eye resolution, refresh rate, FOV, IPD, +swapchain image count, and the compositor window (title/size/present mode/display +mode). The `configurator` tool (GLFW + ImGui, `tools/configurator/`) edits this +file and ships presets for common headsets; it does not render — it only writes +the config the DLL reads. + +Presentation mode matters for throughput: `fifo` presents with vsync and, because +presentation runs on the app's thread inside `xrBeginFrame`, caps the app to the +monitor refresh. The default `mailbox` (or `immediate`) is uncapped. `refreshRateHz` +sets the simulated strobe used by `xrWaitFrame`, independent of presentation. + +--- + +## 4. Phasing + +| Phase | Deliverable | Exit criterion | +| --- | --- | --- | +| 0 | Negotiation + GIPA + metadata functions (this scaffold) | Loader loads the DLL; `xrCreateInstance`/`xrGetSystem` succeed. | +| 1 | Vulkan passthrough | Engine creates its `VkInstance`/`VkDevice` through us. | +| 2 | Session, swapchain, frame loop, GLFW+ImGui compositor | Eye images (test pattern, then real) appear in the ImGui window. | +| 3 | Tracking | Mouse/WASD head pose drives `xrLocateViews`. | +| 4 | Actions/controllers | Game hands/inputs work; a profile is bound. | +| 5 | Polish | Session state edges, visibility/focus, haptics no-op, settings UI. | + +Phases 0–4 are implemented. Remaining: phase 5 polish. + +## 5. Risks / open questions + +- **Loader strictness**: GIPA must return non-null for every function the app + loads. Extension functions the engine loads (`xrGetVulkanGraphicsDevice2KHR`, + `xrGetVulkanGraphicsRequirements2KHR`, `xrCreateVulkanInstanceKHR`, + `xrCreateVulkanDeviceKHR`) must be real, or `OpenXrHelper::LoadXrFunction` + throws. +- **GPU sync without app-provided semaphores**: core OpenXR gives no sync + primitive for swapchain images; MVP uses `vkQueueWaitIdle`. +- **Present family mismatch** between the app's graphics family and our window + surface. +- **Duplicate GLFW instances** in one process (engine + runtime); fallback to + ImGui Win32 backend. +- **Format negotiation**: only advertise formats we can actually create and + sample. +- **Version encoding** for Vulkan requirements (§2.5). + +## 6. References + +- OpenXR-SDK `hello_xr` — what a runtime must answer. +- Monado — reference open-source runtime (negotiation + compositor). +- `openxr_loader_negotiation.h` — exact negotiation structs. +- Engine source: `code/Engine/src/Engine/Core/ApplicationContext.cpp`, + `code/Engine/src/Engine/Renderer/Headset.cpp`, + `code/Engine/src/Engine/Input/XrInputHandler.cpp`. diff --git a/manifest/openxr_simulator.json.in b/manifest/openxr_simulator.json.in new file mode 100644 index 0000000..681786a --- /dev/null +++ b/manifest/openxr_simulator.json.in @@ -0,0 +1,7 @@ +{ + "file_format_version": "1.0.0", + "runtime": { + "library_path": "./openxr_simulator.dll", + "name": "@SIM_RUNTIME_NAME@" + } +} diff --git a/src/Common.h b/src/Common.h new file mode 100644 index 0000000..2250a0f --- /dev/null +++ b/src/Common.h @@ -0,0 +1,36 @@ +#pragma once + +#include +#include +#include + +#ifdef _WIN32 +# ifndef WIN32_LEAN_AND_MEAN +# define WIN32_LEAN_AND_MEAN +# endif +# ifndef NOMINMAX +# define NOMINMAX +# endif +# include +#endif + +namespace xrsim +{ + inline void Log( const char * format, ... ) + { + char buffer[1024]; + va_list args; + va_start( args, format ); + vsnprintf( buffer, sizeof( buffer ), format, args ); + va_end( args ); + +#ifdef _WIN32 + OutputDebugStringA( "[xrsim] " ); + OutputDebugStringA( buffer ); + OutputDebugStringA( "\n" ); +#endif + fputs( "[xrsim] ", stderr ); + fputs( buffer, stderr ); + fputc( '\n', stderr ); + } +} // namespace xrsim diff --git a/src/Compositor.cpp b/src/Compositor.cpp new file mode 100644 index 0000000..f30c2d8 --- /dev/null +++ b/src/Compositor.cpp @@ -0,0 +1,896 @@ +#include "Compositor.h" +#include "Common.h" +#include "Config.h" + +#include +#include +#include +#include +#include +#include + +#define GLFW_INCLUDE_VULKAN +#include + +#include "imgui.h" +#include "imgui_impl_glfw.h" +#include "imgui_impl_vulkan.h" + +namespace xrsim +{ + namespace + { + constexpr uint32_t kDisplayWidth = 1280; + constexpr uint32_t kDisplayHeight = 1280; + constexpr VkFormat kDisplayFormat = VK_FORMAT_R8G8B8A8_UNORM; + constexpr uint32_t kMinImageCount = 2; + constexpr float kLookSpeed = 2.5f; // metres/second + + void TransitionImage( + VkCommandBuffer cmd, VkImage image, VkImageLayout oldLayout, VkImageLayout newLayout, + VkPipelineStageFlags srcStage, VkPipelineStageFlags dstStage, VkAccessFlags srcAccess, + VkAccessFlags dstAccess, uint32_t layerCount + ) + { + VkImageMemoryBarrier barrier{ VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER }; + barrier.oldLayout = oldLayout; + barrier.newLayout = newLayout; + barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; + barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; + barrier.image = image; + barrier.subresourceRange = { VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, layerCount }; + barrier.srcAccessMask = srcAccess; + barrier.dstAccessMask = dstAccess; + vkCmdPipelineBarrier( cmd, srcStage, dstStage, 0, 0, nullptr, 0, nullptr, 1, &barrier ); + } + + void FrameRender( ImGui_ImplVulkanH_Window * wd, VkDevice device, VkQueue queue ) + { + VkSemaphore imageAcquired = wd->FrameSemaphores[wd->SemaphoreIndex].ImageAcquiredSemaphore; + VkSemaphore renderComplete = wd->FrameSemaphores[wd->SemaphoreIndex].RenderCompleteSemaphore; + + vkAcquireNextImageKHR( + device, wd->Swapchain, UINT64_MAX, imageAcquired, VK_NULL_HANDLE, &wd->FrameIndex + ); + ImGui_ImplVulkanH_Frame * fd = &wd->Frames[wd->FrameIndex]; + vkWaitForFences( device, 1, &fd->Fence, VK_TRUE, UINT64_MAX ); + vkResetFences( device, 1, &fd->Fence ); + vkResetCommandPool( device, fd->CommandPool, 0 ); + + VkCommandBufferBeginInfo beginInfo{ VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO }; + beginInfo.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT; + vkBeginCommandBuffer( fd->CommandBuffer, &beginInfo ); + + VkRenderPassBeginInfo renderPassInfo{ VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO }; + renderPassInfo.renderPass = wd->RenderPass; + renderPassInfo.framebuffer = fd->Framebuffer; + renderPassInfo.renderArea.extent.width = static_cast( wd->Width ); + renderPassInfo.renderArea.extent.height = static_cast( wd->Height ); + renderPassInfo.clearValueCount = 1; + renderPassInfo.pClearValues = &wd->ClearValue; + vkCmdBeginRenderPass( fd->CommandBuffer, &renderPassInfo, VK_SUBPASS_CONTENTS_INLINE ); + + ImGui_ImplVulkan_RenderDrawData( ImGui::GetDrawData(), fd->CommandBuffer ); + + vkCmdEndRenderPass( fd->CommandBuffer ); + + VkPipelineStageFlags waitStage = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT; + VkSubmitInfo submitInfo{ VK_STRUCTURE_TYPE_SUBMIT_INFO }; + submitInfo.waitSemaphoreCount = 1; + submitInfo.pWaitSemaphores = &imageAcquired; + submitInfo.pWaitDstStageMask = &waitStage; + submitInfo.commandBufferCount = 1; + submitInfo.pCommandBuffers = &fd->CommandBuffer; + submitInfo.signalSemaphoreCount = 1; + submitInfo.pSignalSemaphores = &renderComplete; + vkEndCommandBuffer( fd->CommandBuffer ); + vkQueueSubmit( queue, 1, &submitInfo, fd->Fence ); + } + + void FramePresent( ImGui_ImplVulkanH_Window * wd, VkQueue queue ) + { + VkSemaphore renderComplete = wd->FrameSemaphores[wd->SemaphoreIndex].RenderCompleteSemaphore; + VkPresentInfoKHR presentInfo{ VK_STRUCTURE_TYPE_PRESENT_INFO_KHR }; + presentInfo.waitSemaphoreCount = 1; + presentInfo.pWaitSemaphores = &renderComplete; + presentInfo.swapchainCount = 1; + presentInfo.pSwapchains = &wd->Swapchain; + presentInfo.pImageIndices = &wd->FrameIndex; + vkQueuePresentKHR( queue, &presentInfo ); + wd->SemaphoreIndex = ( wd->SemaphoreIndex + 1 ) % wd->SemaphoreCount; + } + + class GlfwImGuiCompositor : public Compositor + { + public: + bool Initialize( RuntimeInstance * instance, RuntimeSession * session ) override; + void Shutdown() override; + void Present( RuntimeSession * session, const XrCompositionLayerProjection * layer ) override; + void Pump( RuntimeSession * session ) override; + + private: + struct PendingEye + { + VkImage image = VK_NULL_HANDLE; + uint32_t arrayLayer = 0; + uint32_t width = 0; + uint32_t height = 0; + }; + + void UpdateTracking(); + void DrawUi(); + void EnsureDisplayImages( uint32_t width, uint32_t height ); + void DestroyDisplayImages(); + void CopyEyes( RuntimeSession * session, const PendingEye * eyes, uint32_t eyeCount ); + void PumpAndRender(); + + std::thread::id windowThreadId_; + + std::mutex pendingMutex_; + PendingEye pendingEyes_[2]; + uint32_t pendingEyeCount_ = 0; + bool pendingValid_ = false; + + RuntimeInstance * instance_ = nullptr; + RuntimeSession * session_ = nullptr; + + GLFWwindow * window_ = nullptr; + bool glfwOwned_ = false; + bool contextCreated_ = false; + bool glfwBackendCreated_ = false; + bool vulkanBackendCreated_ = false; + bool swapchainCreated_ = false; + + ImGui_ImplVulkanH_Window imguiWindow_{}; + VkDescriptorPool descriptorPool_ = VK_NULL_HANDLE; + VkSampler sampler_ = VK_NULL_HANDLE; + + // Per-eye display targets sampled by ImGui. + VkImage displayImages_[2] = { VK_NULL_HANDLE, VK_NULL_HANDLE }; + VkDeviceMemory displayMemory_[2] = { VK_NULL_HANDLE, VK_NULL_HANDLE }; + VkImageView displayViews_[2] = { VK_NULL_HANDLE, VK_NULL_HANDLE }; + VkDescriptorSet displayTextures_[2] = { VK_NULL_HANDLE, VK_NULL_HANDLE }; + uint32_t displayWidth_ = 0; + uint32_t displayHeight_ = 0; + bool displayInitialized_ = false; + bool haveEyes_ = false; + + VkCommandPool copyPool_ = VK_NULL_HANDLE; + VkCommandBuffer copyCmd_ = VK_NULL_HANDLE; + VkFence copyFence_ = VK_NULL_HANDLE; + }; + + bool GlfwImGuiCompositor::Initialize( RuntimeInstance * instance, RuntimeSession * session ) + { + if ( std::getenv( "XRSIM_NO_WINDOW" ) != nullptr ) + { + return false; + } + if ( instance == nullptr || session == nullptr || session->vkInstance == VK_NULL_HANDLE || + session->vkDevice == VK_NULL_HANDLE || session->vkPhysicalDevice == VK_NULL_HANDLE ) + { + return false; + } + instance_ = instance; + session_ = session; + windowThreadId_ = std::this_thread::get_id(); + + if ( glfwInit() != GLFW_TRUE ) + { + Log( "glfwInit failed" ); + return false; + } + glfwOwned_ = true; + + const SimulatorConfig & config = GetConfig(); + + glfwWindowHint( GLFW_CLIENT_API, GLFW_NO_API ); + window_ = glfwCreateWindow( + config.windowWidth, config.windowHeight, config.windowTitle.c_str(), nullptr, nullptr + ); + if ( window_ == nullptr ) + { + Log( "glfwCreateWindow failed" ); + Shutdown(); + return false; + } + + VkSurfaceKHR surface = VK_NULL_HANDLE; + VkResult surfaceResult = + glfwCreateWindowSurface( session->vkInstance, window_, nullptr, &surface ); + if ( surfaceResult != VK_SUCCESS ) + { + Log( "glfwCreateWindowSurface failed (%d)", (int)surfaceResult ); + Shutdown(); + return false; + } + + // Verify the app's queue family can render and present to our surface. + VkBool32 presentSupported = VK_FALSE; + vkGetPhysicalDeviceSurfaceSupportKHR( + session->vkPhysicalDevice, session->queueFamilyIndex, surface, &presentSupported + ); + uint32_t familyCount = 0; + vkGetPhysicalDeviceQueueFamilyProperties( session->vkPhysicalDevice, &familyCount, nullptr ); + std::vector families( familyCount ); + vkGetPhysicalDeviceQueueFamilyProperties( + session->vkPhysicalDevice, &familyCount, families.data() + ); + const bool graphicsSupported = + ( session->queueFamilyIndex < familyCount ) && + ( families[session->queueFamilyIndex].queueFlags & VK_QUEUE_GRAPHICS_BIT ) != 0; + if ( presentSupported == VK_FALSE || !graphicsSupported ) + { + Log( + "Queue family %u cannot both render and present to the simulator window; disabling " + "compositor", + session->queueFamilyIndex + ); + Shutdown(); + return false; + } + + IMGUI_CHECKVERSION(); + ImGui::CreateContext(); + contextCreated_ = true; + ImGuiIO & io = ImGui::GetIO(); + io.ConfigFlags |= ImGuiConfigFlags_DockingEnable; + io.IniFilename = "openxr_simulator_imgui.ini"; + ImGui::StyleColorsDark(); + + ImGui_ImplGlfw_InitForVulkan( window_, true ); + glfwBackendCreated_ = true; + + const VkFormat requestFormats[] = { VK_FORMAT_B8G8R8A8_UNORM, VK_FORMAT_R8G8B8A8_UNORM }; + + // Requested in priority order; first supported wins. "mailbox"/"immediate" do not cap the + // frame rate, "fifo" syncs to the monitor refresh. + VkPresentModeKHR requestModes[3]; + int requestModeCount = 0; + if ( config.presentMode == PresentMode::Fifo ) + { + requestModes[requestModeCount++] = VK_PRESENT_MODE_FIFO_KHR; + requestModes[requestModeCount++] = VK_PRESENT_MODE_MAILBOX_KHR; + } + else if ( config.presentMode == PresentMode::Immediate ) + { + requestModes[requestModeCount++] = VK_PRESENT_MODE_IMMEDIATE_KHR; + requestModes[requestModeCount++] = VK_PRESENT_MODE_MAILBOX_KHR; + requestModes[requestModeCount++] = VK_PRESENT_MODE_FIFO_KHR; + } + else + { + requestModes[requestModeCount++] = VK_PRESENT_MODE_MAILBOX_KHR; + requestModes[requestModeCount++] = VK_PRESENT_MODE_IMMEDIATE_KHR; + requestModes[requestModeCount++] = VK_PRESENT_MODE_FIFO_KHR; + } + + imguiWindow_.Surface = surface; + imguiWindow_.SurfaceFormat = ImGui_ImplVulkanH_SelectSurfaceFormat( + session->vkPhysicalDevice, surface, requestFormats, IM_ARRAYSIZE( requestFormats ), + VK_COLOR_SPACE_SRGB_NONLINEAR_KHR + ); + imguiWindow_.PresentMode = ImGui_ImplVulkanH_SelectPresentMode( + session->vkPhysicalDevice, surface, requestModes, requestModeCount + ); + imguiWindow_.ClearEnable = true; + imguiWindow_.ClearValue = { { { 0.06f, 0.06f, 0.08f, 1.0f } } }; + + ImGui_ImplVulkanH_CreateOrResizeWindow( + session->vkInstance, session->vkPhysicalDevice, session->vkDevice, &imguiWindow_, + session->queueFamilyIndex, nullptr, config.windowWidth, config.windowHeight, kMinImageCount + ); + swapchainCreated_ = true; + + const char * presentModeName = "FIFO (vsync)"; + if ( imguiWindow_.PresentMode == VK_PRESENT_MODE_MAILBOX_KHR ) + { + presentModeName = "MAILBOX"; + } + else if ( imguiWindow_.PresentMode == VK_PRESENT_MODE_IMMEDIATE_KHR ) + { + presentModeName = "IMMEDIATE"; + } + Log( + "Compositor window present mode: %s (requested %s)", presentModeName, + ToString( config.presentMode ) + ); + + VkDescriptorPoolSize poolSize{ VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 32 }; + VkDescriptorPoolCreateInfo poolInfo{ VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO }; + poolInfo.flags = VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT; + poolInfo.maxSets = 32; + poolInfo.poolSizeCount = 1; + poolInfo.pPoolSizes = &poolSize; + if ( vkCreateDescriptorPool( session->vkDevice, &poolInfo, nullptr, &descriptorPool_ ) != + VK_SUCCESS ) + { + Log( "Failed to create ImGui descriptor pool" ); + Shutdown(); + return false; + } + + ImGui_ImplVulkan_InitInfo initInfo{}; + initInfo.Instance = session->vkInstance; + initInfo.PhysicalDevice = session->vkPhysicalDevice; + initInfo.Device = session->vkDevice; + initInfo.QueueFamily = session->queueFamilyIndex; + initInfo.Queue = session->queue; + initInfo.DescriptorPool = descriptorPool_; + initInfo.RenderPass = imguiWindow_.RenderPass; + initInfo.MinImageCount = kMinImageCount; + initInfo.ImageCount = imguiWindow_.ImageCount; + initInfo.MSAASamples = VK_SAMPLE_COUNT_1_BIT; + if ( !ImGui_ImplVulkan_Init( &initInfo ) ) + { + Log( "ImGui_ImplVulkan_Init failed" ); + Shutdown(); + return false; + } + vulkanBackendCreated_ = true; + + VkSamplerCreateInfo samplerInfo{ VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO }; + samplerInfo.magFilter = VK_FILTER_LINEAR; + samplerInfo.minFilter = VK_FILTER_LINEAR; + samplerInfo.mipmapMode = VK_SAMPLER_MIPMAP_MODE_LINEAR; + samplerInfo.addressModeU = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE; + samplerInfo.addressModeV = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE; + samplerInfo.addressModeW = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE; + samplerInfo.maxLod = 1.0f; + vkCreateSampler( session->vkDevice, &samplerInfo, nullptr, &sampler_ ); + + VkCommandPoolCreateInfo copyPoolInfo{ VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO }; + copyPoolInfo.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT; + copyPoolInfo.queueFamilyIndex = session->queueFamilyIndex; + vkCreateCommandPool( session->vkDevice, ©PoolInfo, nullptr, ©Pool_ ); + + VkCommandBufferAllocateInfo cmdInfo{ VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO }; + cmdInfo.commandPool = copyPool_; + cmdInfo.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY; + cmdInfo.commandBufferCount = 1; + vkAllocateCommandBuffers( session->vkDevice, &cmdInfo, ©Cmd_ ); + + VkFenceCreateInfo fenceInfo{ VK_STRUCTURE_TYPE_FENCE_CREATE_INFO }; + fenceInfo.flags = VK_FENCE_CREATE_SIGNALED_BIT; + vkCreateFence( session->vkDevice, &fenceInfo, nullptr, ©Fence_ ); + + EnsureDisplayImages( kDisplayWidth, kDisplayHeight ); + + Log( "Compositor initialized (GLFW + ImGui docking)" ); + return true; + } + + void GlfwImGuiCompositor::DestroyDisplayImages() + { + if ( session_ == nullptr ) + { + return; + } + vkDeviceWaitIdle( session_->vkDevice ); + for ( int i = 0; i < 2; ++i ) + { + if ( displayTextures_[i] != VK_NULL_HANDLE ) + { + ImGui_ImplVulkan_RemoveTexture( displayTextures_[i] ); + displayTextures_[i] = VK_NULL_HANDLE; + } + if ( displayViews_[i] != VK_NULL_HANDLE ) + { + vkDestroyImageView( session_->vkDevice, displayViews_[i], nullptr ); + displayViews_[i] = VK_NULL_HANDLE; + } + if ( displayImages_[i] != VK_NULL_HANDLE ) + { + vkDestroyImage( session_->vkDevice, displayImages_[i], nullptr ); + displayImages_[i] = VK_NULL_HANDLE; + } + if ( displayMemory_[i] != VK_NULL_HANDLE ) + { + vkFreeMemory( session_->vkDevice, displayMemory_[i], nullptr ); + displayMemory_[i] = VK_NULL_HANDLE; + } + } + displayInitialized_ = false; + haveEyes_ = false; + } + + void GlfwImGuiCompositor::EnsureDisplayImages( uint32_t width, uint32_t height ) + { + if ( displayImages_[0] != VK_NULL_HANDLE && displayWidth_ == width && + displayHeight_ == height ) + { + return; + } + DestroyDisplayImages(); + + displayWidth_ = width; + displayHeight_ = height; + + VkImageCreateInfo imageInfo{ VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO }; + imageInfo.imageType = VK_IMAGE_TYPE_2D; + imageInfo.format = kDisplayFormat; + imageInfo.extent = { width, height, 1 }; + imageInfo.mipLevels = 1; + imageInfo.arrayLayers = 1; + imageInfo.samples = VK_SAMPLE_COUNT_1_BIT; + imageInfo.tiling = VK_IMAGE_TILING_OPTIMAL; + imageInfo.usage = VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT; + imageInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE; + imageInfo.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; + + for ( int i = 0; i < 2; ++i ) + { + vkCreateImage( session_->vkDevice, &imageInfo, nullptr, &displayImages_[i] ); + + VkMemoryRequirements requirements{}; + vkGetImageMemoryRequirements( session_->vkDevice, displayImages_[i], &requirements ); + VkPhysicalDeviceMemoryProperties memoryProperties{}; + vkGetPhysicalDeviceMemoryProperties( session_->vkPhysicalDevice, &memoryProperties ); + uint32_t memoryType = UINT32_MAX; + for ( uint32_t t = 0; t < memoryProperties.memoryTypeCount; ++t ) + { + if ( ( requirements.memoryTypeBits & ( 1u << t ) ) && + ( memoryProperties.memoryTypes[t].propertyFlags & + VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT ) ) + { + memoryType = t; + break; + } + } + VkMemoryAllocateInfo allocateInfo{ VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO }; + allocateInfo.allocationSize = requirements.size; + allocateInfo.memoryTypeIndex = memoryType; + vkAllocateMemory( session_->vkDevice, &allocateInfo, nullptr, &displayMemory_[i] ); + vkBindImageMemory( + session_->vkDevice, displayImages_[i], displayMemory_[i], 0 + ); + + VkImageViewCreateInfo viewInfo{ VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO }; + viewInfo.image = displayImages_[i]; + viewInfo.viewType = VK_IMAGE_VIEW_TYPE_2D; + viewInfo.format = kDisplayFormat; + viewInfo.subresourceRange = { VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1 }; + vkCreateImageView( session_->vkDevice, &viewInfo, nullptr, &displayViews_[i] ); + + displayTextures_[i] = ImGui_ImplVulkan_AddTexture( + sampler_, displayViews_[i], VK_IMAGE_LAYOUT_GENERAL + ); + } + displayInitialized_ = false; + } + + void GlfwImGuiCompositor::CopyEyes( + RuntimeSession * session, const PendingEye * eyes, uint32_t eyeCount + ) + { + if ( eyeCount == 0 ) + { + return; + } + + // The application may still be executing its frame on this queue. + vkQueueWaitIdle( session->queue ); + + vkWaitForFences( session->vkDevice, 1, ©Fence_, VK_TRUE, UINT64_MAX ); + vkResetFences( session->vkDevice, 1, ©Fence_ ); + vkResetCommandBuffer( copyCmd_, 0 ); + + VkCommandBufferBeginInfo beginInfo{ VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO }; + beginInfo.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT; + vkBeginCommandBuffer( copyCmd_, &beginInfo ); + + for ( uint32_t eye = 0; eye < eyeCount; ++eye ) + { + const VkImage xrImage = eyes[eye].image; + const uint32_t arrayLayer = eyes[eye].arrayLayer; + const uint32_t width = eyes[eye].width; + const uint32_t height = eyes[eye].height; + if ( xrImage == VK_NULL_HANDLE ) + { + continue; + } + EnsureDisplayImages( width, height ); + + TransitionImage( + copyCmd_, xrImage, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, + VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, + VK_PIPELINE_STAGE_TRANSFER_BIT, VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, + VK_ACCESS_TRANSFER_READ_BIT, 2 + ); + + if ( !displayInitialized_ ) + { + TransitionImage( + copyCmd_, displayImages_[eye], VK_IMAGE_LAYOUT_UNDEFINED, + VK_IMAGE_LAYOUT_GENERAL, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, + VK_PIPELINE_STAGE_TRANSFER_BIT, 0, VK_ACCESS_TRANSFER_WRITE_BIT, 1 + ); + } + else + { + TransitionImage( + copyCmd_, displayImages_[eye], VK_IMAGE_LAYOUT_GENERAL, + VK_IMAGE_LAYOUT_GENERAL, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, + VK_PIPELINE_STAGE_TRANSFER_BIT, VK_ACCESS_SHADER_READ_BIT, + VK_ACCESS_TRANSFER_WRITE_BIT, 1 + ); + } + + VkImageCopy region{}; + region.srcSubresource = { VK_IMAGE_ASPECT_COLOR_BIT, 0, arrayLayer, 1 }; + region.dstSubresource = { VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 1 }; + region.extent = { width, height, 1 }; + vkCmdCopyImage( + copyCmd_, xrImage, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, displayImages_[eye], + VK_IMAGE_LAYOUT_GENERAL, 1, ®ion + ); + + TransitionImage( + copyCmd_, displayImages_[eye], VK_IMAGE_LAYOUT_GENERAL, + VK_IMAGE_LAYOUT_GENERAL, VK_PIPELINE_STAGE_TRANSFER_BIT, + VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, VK_ACCESS_TRANSFER_WRITE_BIT, + VK_ACCESS_SHADER_READ_BIT, 1 + ); + + TransitionImage( + copyCmd_, xrImage, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, + VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_PIPELINE_STAGE_TRANSFER_BIT, + VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_ACCESS_TRANSFER_READ_BIT, + VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, 2 + ); + } + + vkEndCommandBuffer( copyCmd_ ); + + VkSubmitInfo submitInfo{ VK_STRUCTURE_TYPE_SUBMIT_INFO }; + submitInfo.commandBufferCount = 1; + submitInfo.pCommandBuffers = ©Cmd_; + vkQueueSubmit( session->queue, 1, &submitInfo, copyFence_ ); + + displayInitialized_ = true; + haveEyes_ = true; + } + + void GlfwImGuiCompositor::UpdateTracking() + { + ImGuiIO & io = ImGui::GetIO(); + TrackingState & tracking = GetTracking(); + + if ( !io.WantCaptureMouse && ImGui::IsMouseDown( ImGuiMouseButton_Right ) ) + { + tracking.yaw -= io.MouseDelta.x * 0.003f; + tracking.pitch -= io.MouseDelta.y * 0.003f; + tracking.pitch = std::max( -1.5f, std::min( 1.5f, tracking.pitch ) ); + } + + const float dt = std::min( io.DeltaTime, 0.1f ); + const float speed = kLookSpeed * dt; + const float forwardX = -std::sin( tracking.yaw ); + const float forwardZ = -std::cos( tracking.yaw ); + const float rightX = std::cos( tracking.yaw ); + const float rightZ = -std::sin( tracking.yaw ); + + if ( glfwGetKey( window_, GLFW_KEY_W ) == GLFW_PRESS ) + { + tracking.posX += forwardX * speed; + tracking.posZ += forwardZ * speed; + } + if ( glfwGetKey( window_, GLFW_KEY_S ) == GLFW_PRESS ) + { + tracking.posX -= forwardX * speed; + tracking.posZ -= forwardZ * speed; + } + if ( glfwGetKey( window_, GLFW_KEY_D ) == GLFW_PRESS ) + { + tracking.posX += rightX * speed; + tracking.posZ += rightZ * speed; + } + if ( glfwGetKey( window_, GLFW_KEY_A ) == GLFW_PRESS ) + { + tracking.posX -= rightX * speed; + tracking.posZ -= rightZ * speed; + } + if ( glfwGetKey( window_, GLFW_KEY_E ) == GLFW_PRESS ) + { + tracking.posY += speed; + } + if ( glfwGetKey( window_, GLFW_KEY_Q ) == GLFW_PRESS ) + { + tracking.posY -= speed; + } + + // ---- Emulated controllers ------------------------------------- + InputState & input = GetInputState(); + const XrQuaternionf headOrientation = GetHeadOrientation(); + const XrVector3f headPosition = GetHeadPosition(); + + auto keyDown = [&]( int key ) { return glfwGetKey( window_, key ) == GLFW_PRESS; }; + auto axis = [&]( int positive, int negative ) + { return ( keyDown( positive ) ? 1.0f : 0.0f ) - ( keyDown( negative ) ? 1.0f : 0.0f ); }; + auto handPose = [&]( float localX, float localY, float localZ ) + { + const XrVector3f offset = + RotateByQuaternion( headOrientation, XrVector3f{ localX, localY, localZ } ); + XrPosef pose{}; + pose.orientation = headOrientation; + pose.position = XrVector3f{ headPosition.x + offset.x, headPosition.y + offset.y, + headPosition.z + offset.z }; + return pose; + }; + + input.hands[0].active = true; + input.hands[1].active = true; + + { + ControllerState & left = input.hands[0]; + left.gripPose = handPose( 0.18f, -0.30f, -0.35f ); + left.aimPose = left.gripPose; + left.trigger = keyDown( GLFW_KEY_F ) ? 1.0f : 0.0f; + left.grip = keyDown( GLFW_KEY_G ) ? 1.0f : 0.0f; + left.thumbstick = XrVector2f{ axis( GLFW_KEY_L, GLFW_KEY_J ), axis( GLFW_KEY_I, GLFW_KEY_K ) }; + left.x = keyDown( GLFW_KEY_C ); + left.y = keyDown( GLFW_KEY_V ); + left.menu = keyDown( GLFW_KEY_TAB ); + left.stickClick = keyDown( GLFW_KEY_R ); + left.touch = left.trigger > 0.0f || left.grip > 0.0f; + } + { + ControllerState & right = input.hands[1]; + right.gripPose = handPose( -0.18f, -0.30f, -0.35f ); + right.aimPose = right.gripPose; + right.trigger = keyDown( GLFW_KEY_H ) ? 1.0f : 0.0f; + right.grip = keyDown( GLFW_KEY_U ) ? 1.0f : 0.0f; + right.thumbstick = XrVector2f{ axis( GLFW_KEY_RIGHT, GLFW_KEY_LEFT ), + axis( GLFW_KEY_UP, GLFW_KEY_DOWN ) }; + right.a = keyDown( GLFW_KEY_N ); + right.b = keyDown( GLFW_KEY_M ); + right.stickClick = keyDown( GLFW_KEY_O ); + right.touch = right.trigger > 0.0f || right.grip > 0.0f; + } + } + + void GlfwImGuiCompositor::DrawUi() + { + ImGui::DockSpaceOverViewport(); + + TrackingState & tracking = GetTracking(); + + ImGui::Begin( "Controls" ); + ImGui::TextUnformatted( "Head: right-drag look, WASD move, Q/E down/up" ); + ImGui::TextUnformatted( "Left hand: F trigger, G grip, IJKL stick, R stick-click, C/V buttons" ); + ImGui::TextUnformatted( "Right hand: H trigger, U grip, arrows stick, O stick-click, N/M buttons" ); + ImGui::TextUnformatted( "Menu: Tab" ); + ImGui::Separator(); + ImGui::SliderFloat( "Yaw", &tracking.yaw, -3.14f, 3.14f ); + ImGui::SliderFloat( "Pitch", &tracking.pitch, -1.5f, 1.5f ); + ImGui::SliderFloat( "IPD", &tracking.ipd, 0.04f, 0.09f, "%.3f m" ); + ImGui::DragFloat3( "Position", &tracking.posX, 0.01f ); + if ( ImGui::Button( "Reset" ) ) + { + tracking = TrackingState{}; + } + const SimulatorConfig & cfg = GetConfig(); + ImGui::Text( + "Headset: %s %ux%u @ %u Hz", cfg.systemName.c_str(), cfg.eyeWidth, cfg.eyeHeight, + cfg.refreshRateHz + ); + ImGui::Text( "Present mode: %s", ToString( cfg.presentMode ) ); + ImGui::Separator(); + ImGui::Text( "%.1f FPS", ImGui::GetIO().Framerate ); + ImGui::Text( "Queue: %u Device: %p", session_->queueFamilyIndex, (void *)session_->vkDevice ); + ImGui::End(); + + const SimulatorConfig & config = GetConfig(); + auto drawEye = [&]( const char * name, int index ) + { + ImGui::Begin( name ); + if ( haveEyes_ ) + { + ImGui::Image( + (ImTextureID)(uint64_t)displayTextures_[index], ImGui::GetContentRegionAvail() + ); + } + else + { + ImGui::TextUnformatted( "waiting for frames..." ); + } + ImGui::End(); + }; + + switch ( config.displayMode ) + { + case DisplayMode::SingleEyeLeft: drawEye( "Eye L", 0 ); break; + case DisplayMode::SingleEyeRight: drawEye( "Eye R", 1 ); break; + default: + drawEye( "Eye L", 0 ); + drawEye( "Eye R", 1 ); + break; + } + } + + void GlfwImGuiCompositor::PumpAndRender() + { + glfwPollEvents(); + + int frameWidth = 0, frameHeight = 0; + glfwGetFramebufferSize( window_, &frameWidth, &frameHeight ); + if ( frameWidth <= 0 || frameHeight <= 0 ) + { + return; + } + if ( frameWidth != imguiWindow_.Width || frameHeight != imguiWindow_.Height ) + { + ImGui_ImplVulkan_SetMinImageCount( kMinImageCount ); + ImGui_ImplVulkanH_CreateOrResizeWindow( + session_->vkInstance, session_->vkPhysicalDevice, session_->vkDevice, &imguiWindow_, + session_->queueFamilyIndex, nullptr, frameWidth, frameHeight, kMinImageCount + ); + imguiWindow_.FrameIndex = 0; + } + + ImGui_ImplVulkan_NewFrame(); + ImGui_ImplGlfw_NewFrame(); + ImGui::NewFrame(); + + UpdateTracking(); + DrawUi(); + + ImGui::Render(); + FrameRender( &imguiWindow_, session_->vkDevice, session_->queue ); + FramePresent( &imguiWindow_, session_->queue ); + } + + void GlfwImGuiCompositor::Present( + RuntimeSession * session, const XrCompositionLayerProjection * layer + ) + { + if ( window_ == nullptr ) + { + return; + } + + // Called from a background thread: only record the submitted images here. + if ( layer != nullptr && layer->viewCount > 0 ) + { + const uint32_t viewCount = layer->viewCount > 2 ? 2 : layer->viewCount; + PendingEye resolved[2]; + uint32_t resolvedCount = 0; + for ( uint32_t eye = 0; eye < viewCount; ++eye ) + { + const XrSwapchainSubImage & sub = layer->views[eye].subImage; + VkImage image = VK_NULL_HANDLE; + uint32_t arrayLayer = 0, width = 0, height = 0; + if ( ResolveSubImage( + sub.swapchain, sub, &image, &arrayLayer, &width, &height + ) ) + { + resolved[resolvedCount++] = PendingEye{ image, arrayLayer, width, height }; + } + } + if ( resolvedCount > 0 ) + { + std::lock_guard lock( pendingMutex_ ); + for ( uint32_t i = 0; i < resolvedCount; ++i ) + { + pendingEyes_[i] = resolved[i]; + } + pendingEyeCount_ = resolvedCount; + pendingValid_ = true; + } + } + + // If the caller happens to be the window thread, present immediately. + if ( std::this_thread::get_id() == windowThreadId_ ) + { + Pump( session ); + } + } + + void GlfwImGuiCompositor::Pump( RuntimeSession * session ) + { + if ( window_ == nullptr || std::this_thread::get_id() != windowThreadId_ ) + { + return; + } + + PendingEye eyes[2]; + uint32_t count = 0; + { + std::lock_guard lock( pendingMutex_ ); + if ( pendingValid_ ) + { + for ( uint32_t i = 0; i < pendingEyeCount_; ++i ) + { + eyes[i] = pendingEyes_[i]; + } + count = pendingEyeCount_; + pendingValid_ = false; + pendingEyeCount_ = 0; + } + } + + if ( count > 0 ) + { + CopyEyes( session, eyes, count ); + } + PumpAndRender(); + } + + void GlfwImGuiCompositor::Shutdown() + { + const bool hasDevice = + session_ != nullptr && session_->vkDevice != VK_NULL_HANDLE; + + if ( hasDevice ) + { + vkDeviceWaitIdle( session_->vkDevice ); + if ( vulkanBackendCreated_ ) + { + DestroyDisplayImages(); + } + if ( copyFence_ != VK_NULL_HANDLE ) + { + vkDestroyFence( session_->vkDevice, copyFence_, nullptr ); + copyFence_ = VK_NULL_HANDLE; + } + if ( copyPool_ != VK_NULL_HANDLE ) + { + vkDestroyCommandPool( session_->vkDevice, copyPool_, nullptr ); + copyPool_ = VK_NULL_HANDLE; + } + if ( sampler_ != VK_NULL_HANDLE ) + { + vkDestroySampler( session_->vkDevice, sampler_, nullptr ); + sampler_ = VK_NULL_HANDLE; + } + if ( vulkanBackendCreated_ ) + { + ImGui_ImplVulkan_Shutdown(); + vulkanBackendCreated_ = false; + } + if ( descriptorPool_ != VK_NULL_HANDLE ) + { + vkDestroyDescriptorPool( session_->vkDevice, descriptorPool_, nullptr ); + descriptorPool_ = VK_NULL_HANDLE; + } + if ( swapchainCreated_ ) + { + ImGui_ImplVulkanH_DestroyWindow( + session_->vkInstance, session_->vkDevice, &imguiWindow_, nullptr + ); + swapchainCreated_ = false; + } + } + + if ( glfwBackendCreated_ ) + { + ImGui_ImplGlfw_Shutdown(); + glfwBackendCreated_ = false; + } + if ( contextCreated_ ) + { + ImGui::DestroyContext(); + contextCreated_ = false; + } + + if ( window_ != nullptr ) + { + glfwDestroyWindow( window_ ); + window_ = nullptr; + } + if ( glfwOwned_ ) + { + glfwTerminate(); + glfwOwned_ = false; + } + + session_ = nullptr; + instance_ = nullptr; + } + } // namespace + + std::unique_ptr CreateCompositor() + { + return std::make_unique(); + } +} // namespace xrsim diff --git a/src/Compositor.h b/src/Compositor.h new file mode 100644 index 0000000..70d1881 --- /dev/null +++ b/src/Compositor.h @@ -0,0 +1,44 @@ +#pragma once + +#include "Runtime.h" + +#include + +namespace xrsim +{ + /** + * @brief Displays the eye images submitted by the application. + * + * The default implementation is a GLFW + Dear ImGui (docking) window. A no-op implementation + * is created when the compositor is disabled at build time or when XRSIM_NO_WINDOW is set. + */ + class Compositor + { + public: + virtual ~Compositor() = default; + + virtual bool Initialize( RuntimeInstance * instance, RuntimeSession * session ) = 0; + + virtual void Shutdown() = 0; + + /** + * @brief Records one submitted projection layer. + * + * May be called from any thread (the engine calls xrEndFrame on a background thread), so + * this must not touch the window / GLFW / ImGui. All window work happens in Pump(). + */ + virtual void Present( + RuntimeSession * session, const XrCompositionLayerProjection * layer + ) = 0; + + /** + * @brief Displays the most recently submitted frame. + * + * Must be called on the thread that created the window (the simulator pumps this from + * xrWaitFrame, which the engine calls on its main thread). No-op on other threads. + */ + virtual void Pump( RuntimeSession * session ) = 0; + }; + + std::unique_ptr CreateCompositor(); +} // namespace xrsim diff --git a/src/CompositorStub.cpp b/src/CompositorStub.cpp new file mode 100644 index 0000000..5689ff0 --- /dev/null +++ b/src/CompositorStub.cpp @@ -0,0 +1,21 @@ +#include "Compositor.h" + +namespace xrsim +{ + namespace + { + class NullCompositor : public Compositor + { + public: + bool Initialize( RuntimeInstance *, RuntimeSession * ) override { return true; } + void Shutdown() override {} + void Present( RuntimeSession *, const XrCompositionLayerProjection * ) override {} + void Pump( RuntimeSession * ) override {} + }; + } // namespace + + std::unique_ptr CreateCompositor() + { + return std::make_unique(); + } +} // namespace xrsim diff --git a/src/Config.cpp b/src/Config.cpp new file mode 100644 index 0000000..af1bb12 --- /dev/null +++ b/src/Config.cpp @@ -0,0 +1,193 @@ +#include "Config.h" + +#include +#include + +#include + +#ifdef _WIN32 +# ifndef WIN32_LEAN_AND_MEAN +# define WIN32_LEAN_AND_MEAN +# endif +# include +#endif + +namespace xrsim +{ + using nlohmann::json; + + namespace + { + std::string ModuleDirectory() + { +#ifdef _WIN32 + HMODULE module = nullptr; + GetModuleHandleExA( + GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, + reinterpret_cast( &ModuleDirectory ), &module + ); + char buffer[MAX_PATH] = {}; + DWORD length = GetModuleFileNameA( module, buffer, MAX_PATH ); + std::string path( buffer, length ); + const auto separator = path.find_last_of( "\\/" ); + if ( separator != std::string::npos ) + { + path.resize( separator + 1 ); + } + else + { + path.clear(); + } + return path; +#else + return std::string(); +#endif + } + + PresentMode ParsePresentMode( const std::string & value ) + { + if ( value == "fifo" || value == "vsync" ) + { + return PresentMode::Fifo; + } + if ( value == "immediate" ) + { + return PresentMode::Immediate; + } + return PresentMode::Mailbox; + } + + DisplayMode ParseDisplayMode( const std::string & value ) + { + if ( value == "singleEyeLeft" ) + { + return DisplayMode::SingleEyeLeft; + } + if ( value == "singleEyeRight" ) + { + return DisplayMode::SingleEyeRight; + } + return DisplayMode::SideBySide; + } + } // namespace + + const char * ToString( PresentMode mode ) + { + switch ( mode ) + { + case PresentMode::Fifo: return "fifo"; + case PresentMode::Immediate: return "immediate"; + default: return "mailbox"; + } + } + + const char * ToString( DisplayMode mode ) + { + switch ( mode ) + { + case DisplayMode::SingleEyeLeft: return "singleEyeLeft"; + case DisplayMode::SingleEyeRight: return "singleEyeRight"; + default: return "sideBySide"; + } + } + + std::string SimulatorConfig::ResolvePath() + { + if ( const char * env = std::getenv( "XRSIM_CONFIG" ) ) + { + if ( env[0] != '\0' ) + { + return env; + } + } + return ModuleDirectory() + "openxr_simulator_config.json"; + } + + SimulatorConfig SimulatorConfig::Load() + { + return LoadFrom( ResolvePath() ); + } + + SimulatorConfig SimulatorConfig::LoadFrom( const std::string & path ) + { + SimulatorConfig config; + std::ifstream file( path ); + if ( !file ) + { + return config; + } + + json root; + try + { + file >> root; + } + catch ( const std::exception & ) + { + return config; + } + + config.systemName = root.value( "systemName", config.systemName ); + config.vendorId = root.value( "vendorId", config.vendorId ); + + config.eyeWidth = root.value( "eyeWidth", config.eyeWidth ); + config.eyeHeight = root.value( "eyeHeight", config.eyeHeight ); + config.refreshRateHz = root.value( "refreshRateHz", config.refreshRateHz ); + + config.fovLeftDeg = root.value( "fovLeftDeg", config.fovLeftDeg ); + config.fovRightDeg = root.value( "fovRightDeg", config.fovRightDeg ); + config.fovUpDeg = root.value( "fovUpDeg", config.fovUpDeg ); + config.fovDownDeg = root.value( "fovDownDeg", config.fovDownDeg ); + + config.ipdMeters = root.value( "ipdMeters", config.ipdMeters ); + config.swapchainImageCount = root.value( "swapchainImageCount", config.swapchainImageCount ); + + config.windowTitle = root.value( "windowTitle", config.windowTitle ); + config.windowWidth = root.value( "windowWidth", config.windowWidth ); + config.windowHeight = root.value( "windowHeight", config.windowHeight ); + config.presentMode = ParsePresentMode( root.value( "presentMode", std::string( "mailbox" ) ) ); + config.displayMode = + ParseDisplayMode( root.value( "displayMode", std::string( "sideBySide" ) ) ); + + return config; + } + + bool SimulatorConfig::Save( const std::string & path ) const + { + json root; + root["systemName"] = systemName; + root["vendorId"] = vendorId; + + root["eyeWidth"] = eyeWidth; + root["eyeHeight"] = eyeHeight; + root["refreshRateHz"] = refreshRateHz; + + root["fovLeftDeg"] = fovLeftDeg; + root["fovRightDeg"] = fovRightDeg; + root["fovUpDeg"] = fovUpDeg; + root["fovDownDeg"] = fovDownDeg; + + root["ipdMeters"] = ipdMeters; + root["swapchainImageCount"] = swapchainImageCount; + + root["windowTitle"] = windowTitle; + root["windowWidth"] = windowWidth; + root["windowHeight"] = windowHeight; + root["presentMode"] = ToString( presentMode ); + root["displayMode"] = ToString( displayMode ); + + std::ofstream file( path ); + if ( !file ) + { + return false; + } + file << root.dump( 4 ) << std::endl; + return static_cast( file ); + } + + SimulatorConfig & GetConfig() + { + static SimulatorConfig config = SimulatorConfig::Load(); + return config; + } +} // namespace xrsim diff --git a/src/Config.h b/src/Config.h new file mode 100644 index 0000000..936f9e5 --- /dev/null +++ b/src/Config.h @@ -0,0 +1,71 @@ +#pragma once + +#include +#include + +namespace xrsim +{ + enum class PresentMode + { + Mailbox, // uncapped, no tearing + Immediate, // uncapped, may tear + Fifo, // vsync (caps to monitor refresh) + }; + + enum class DisplayMode + { + SideBySide, + SingleEyeLeft, + SingleEyeRight, + }; + + const char * ToString( PresentMode mode ); + const char * ToString( DisplayMode mode ); + + /** + * @brief Runtime configuration, read from a JSON file by the runtime DLL and written by the + * configurator application. + */ + struct SimulatorConfig + { + // Headset identity. + std::string systemName = "OpenXR Simulator"; + uint32_t vendorId = 0; + + // Per-eye render target and display timing. + uint32_t eyeWidth = 1280; + uint32_t eyeHeight = 1280; + uint32_t refreshRateHz = 90; + + // Field of view, per half-angle in degrees (left/right equal => symmetric). + float fovLeftDeg = 45.0f; + float fovRightDeg = 45.0f; + float fovUpDeg = 45.0f; + float fovDownDeg = 45.0f; + + float ipdMeters = 0.064f; + uint32_t swapchainImageCount = 3; + + // Compositor window. + std::string windowTitle = "OpenXR Simulator"; + int windowWidth = 1600; + int windowHeight = 900; + PresentMode presentMode = PresentMode::Mailbox; + DisplayMode displayMode = DisplayMode::SideBySide; + + /** @brief Loads the config from the resolved path (or defaults if absent). */ + static SimulatorConfig Load(); + + /** @brief Loads the config from an explicit path (or defaults if absent/invalid). */ + static SimulatorConfig LoadFrom( const std::string & path ); + + /** @brief Resolves the config path (XRSIM_CONFIG env, else /openxr_simulator_config.json). */ + static std::string ResolvePath(); + + /** @brief Writes the config to a path (creates parent-less file). */ + bool Save( const std::string & path ) const; + }; + + /** @brief Process-wide configuration, loaded once on first use. */ + SimulatorConfig & GetConfig(); +} // namespace xrsim diff --git a/src/HeadsetPresets.h b/src/HeadsetPresets.h new file mode 100644 index 0000000..39f29c3 --- /dev/null +++ b/src/HeadsetPresets.h @@ -0,0 +1,68 @@ +#pragma once + +#include +#include + +namespace xrsim +{ + /** + * @brief Built-in emulated headset presets. + * + * Resolution is the per-eye panel resolution (what the runtime advertises as + * recommendedImageRect*). Field of view is stored as per-direction half-angles in degrees and is + * an approximation of the rendered FoV; the runtime converts it to tangents for XrFovf. IPD is a + * typical/default value in metres. Values are approximate and tunable in the configurator. + */ + struct HeadsetPreset + { + const char * name; + uint32_t eyeWidth; + uint32_t eyeHeight; + uint32_t refreshRateHz; + float fovLeftDeg; + float fovRightDeg; + float fovUpDeg; + float fovDownDeg; + float ipdMeters; + }; + + inline constexpr std::array kHeadsetPresets = { { + // --- Generic --- + { "Generic 1280", 1280, 1280, 90, 45.0f, 45.0f, 45.0f, 45.0f, 0.064f }, + + // --- Meta / Oculus (Quest) --- + { "Meta Quest 2", 1832, 1920, 90, 52.0f, 52.0f, 49.0f, 49.0f, 0.063f }, + { "Meta Quest 3", 2064, 2208, 90, 54.0f, 54.0f, 49.0f, 49.0f, 0.063f }, + { "Meta Quest 3S", 1832, 1920, 90, 52.0f, 52.0f, 49.0f, 49.0f, 0.063f }, + { "Meta Quest Pro", 1800, 1920, 90, 53.0f, 53.0f, 48.0f, 48.0f, 0.063f }, + + // --- Valve --- + { "Valve Index", 1440, 1600, 120, 54.0f, 54.0f, 55.0f, 55.0f, 0.064f }, + { "Valve Steam Frame", 2160, 2160, 90, 52.0f, 52.0f, 48.0f, 48.0f, 0.063f }, + + // --- HTC --- + { "HTC Vive", 1080, 1200, 90, 50.0f, 50.0f, 50.0f, 50.0f, 0.064f }, + { "HTC Vive Pro 2", 2448, 2448, 90, 60.0f, 60.0f, 58.0f, 58.0f, 0.064f }, + { "HTC Vive Focus 3", 2448, 2448, 90, 54.0f, 54.0f, 54.0f, 54.0f, 0.064f }, + + // --- HP --- + { "HP Reverb G2", 2160, 2160, 90, 49.0f, 49.0f, 45.0f, 45.0f, 0.0635f }, + + // --- ByteDance Pico --- + { "Pico 4", 2160, 2160, 90, 52.0f, 52.0f, 51.0f, 51.0f, 0.063f }, + { "Pico 4 Ultra", 2160, 2160, 90, 52.0f, 52.0f, 51.0f, 51.0f, 0.063f }, + { "Pico Neo 3", 1832, 1920, 90, 49.0f, 49.0f, 49.0f, 49.0f, 0.0635f }, + + // --- Varjo --- + { "Varjo Aero", 2880, 2720, 90, 50.0f, 50.0f, 48.0f, 48.0f, 0.063f }, + { "Varjo XR-4", 3840, 3744, 90, 60.0f, 60.0f, 52.0f, 52.0f, 0.063f }, + + // --- Other PC VR --- + { "Pimax Crystal", 2880, 2880, 90, 60.0f, 60.0f, 50.0f, 50.0f, 0.064f }, + { "Bigscreen Beyond 2", 2560, 2560, 90, 47.0f, 47.0f, 45.0f, 45.0f, 0.063f }, + { "PlayStation VR2", 2000, 2040, 90, 55.0f, 55.0f, 50.0f, 50.0f, 0.063f }, + + // --- Android XR --- + { "Samsung Galaxy XR", 3552, 3840, 90, 54.0f, 54.0f, 50.0f, 50.0f, 0.063f }, + } }; +} // namespace xrsim diff --git a/src/Negotiation.cpp b/src/Negotiation.cpp new file mode 100644 index 0000000..b68e5f4 --- /dev/null +++ b/src/Negotiation.cpp @@ -0,0 +1,219 @@ +#include "Common.h" +#include "Runtime.h" + +#include "openxr/openxr_loader_negotiation.h" + +#include + +namespace +{ + template + bool Assign( PFN_xrVoidFunction * out, T function ) + { + *out = reinterpret_cast( function ); + return true; + } + + bool Fail( PFN_xrVoidFunction * out ) + { + *out = nullptr; + return false; + } +} // namespace + +namespace xrsim +{ + XrResult XRAPI_CALL GetInstanceProcAddr( + XrInstance /*instance*/, const char * name, PFN_xrVoidFunction * function + ) + { + if ( function == nullptr || name == nullptr ) + { + return XR_ERROR_VALIDATION_FAILURE; + } + + // Global functions (requested with XR_NULL_HANDLE). + if ( strcmp( name, "xrGetInstanceProcAddr" ) == 0 ) + return Assign( function, &GetInstanceProcAddr ) ? XR_SUCCESS : XR_ERROR_RUNTIME_FAILURE; + if ( strcmp( name, "xrEnumerateApiLayerProperties" ) == 0 ) + return Assign( function, &EnumerateApiLayerProperties ) ? XR_SUCCESS + : XR_ERROR_RUNTIME_FAILURE; + if ( strcmp( name, "xrEnumerateInstanceExtensionProperties" ) == 0 ) + return Assign( function, &EnumerateInstanceExtensionProperties ) + ? XR_SUCCESS + : XR_ERROR_RUNTIME_FAILURE; + if ( strcmp( name, "xrCreateInstance" ) == 0 ) + return Assign( function, &CreateInstance ) ? XR_SUCCESS : XR_ERROR_RUNTIME_FAILURE; + + // Instance functions. + if ( strcmp( name, "xrDestroyInstance" ) == 0 ) + return Assign( function, &DestroyInstance ) ? XR_SUCCESS : XR_ERROR_RUNTIME_FAILURE; + if ( strcmp( name, "xrGetInstanceProperties" ) == 0 ) + return Assign( function, &GetInstanceProperties ) ? XR_SUCCESS + : XR_ERROR_RUNTIME_FAILURE; + if ( strcmp( name, "xrGetSystem" ) == 0 ) + return Assign( function, &GetSystem ) ? XR_SUCCESS : XR_ERROR_RUNTIME_FAILURE; + if ( strcmp( name, "xrGetSystemProperties" ) == 0 ) + return Assign( function, &GetSystemProperties ) ? XR_SUCCESS : XR_ERROR_RUNTIME_FAILURE; + if ( strcmp( name, "xrEnumerateViewConfigurations" ) == 0 ) + return Assign( function, &EnumerateViewConfigurations ) ? XR_SUCCESS + : XR_ERROR_RUNTIME_FAILURE; + if ( strcmp( name, "xrEnumerateViewConfigurationViews" ) == 0 ) + return Assign( function, &EnumerateViewConfigurationViews ) ? XR_SUCCESS + : XR_ERROR_RUNTIME_FAILURE; + if ( strcmp( name, "xrEnumerateEnvironmentBlendModes" ) == 0 ) + return Assign( function, &EnumerateEnvironmentBlendModes ) ? XR_SUCCESS + : XR_ERROR_RUNTIME_FAILURE; + if ( strcmp( name, "xrEnumerateSwapchainFormats" ) == 0 ) + return Assign( function, &EnumerateSwapchainFormats ) ? XR_SUCCESS + : XR_ERROR_RUNTIME_FAILURE; + + // XR_KHR_vulkan_enable2. + if ( strcmp( name, "xrGetVulkanGraphicsRequirements2KHR" ) == 0 ) + return Assign( function, &GetVulkanGraphicsRequirements2KHR ) ? XR_SUCCESS + : XR_ERROR_RUNTIME_FAILURE; + if ( strcmp( name, "xrCreateVulkanInstanceKHR" ) == 0 ) + return Assign( function, &CreateVulkanInstanceKHR ) ? XR_SUCCESS + : XR_ERROR_RUNTIME_FAILURE; + if ( strcmp( name, "xrGetVulkanGraphicsDevice2KHR" ) == 0 ) + return Assign( function, &GetVulkanGraphicsDevice2KHR ) ? XR_SUCCESS + : XR_ERROR_RUNTIME_FAILURE; + if ( strcmp( name, "xrCreateVulkanDeviceKHR" ) == 0 ) + return Assign( function, &CreateVulkanDeviceKHR ) ? XR_SUCCESS + : XR_ERROR_RUNTIME_FAILURE; + + // Session. + if ( strcmp( name, "xrCreateSession" ) == 0 ) + return Assign( function, &CreateSession ) ? XR_SUCCESS : XR_ERROR_RUNTIME_FAILURE; + if ( strcmp( name, "xrDestroySession" ) == 0 ) + return Assign( function, &DestroySession ) ? XR_SUCCESS : XR_ERROR_RUNTIME_FAILURE; + if ( strcmp( name, "xrBeginSession" ) == 0 ) + return Assign( function, &BeginSession ) ? XR_SUCCESS : XR_ERROR_RUNTIME_FAILURE; + if ( strcmp( name, "xrEndSession" ) == 0 ) + return Assign( function, &EndSession ) ? XR_SUCCESS : XR_ERROR_RUNTIME_FAILURE; + if ( strcmp( name, "xrPollEvent" ) == 0 ) + return Assign( function, &PollEvent ) ? XR_SUCCESS : XR_ERROR_RUNTIME_FAILURE; + if ( strcmp( name, "xrCreateReferenceSpace" ) == 0 ) + return Assign( function, &CreateReferenceSpace ) ? XR_SUCCESS : XR_ERROR_RUNTIME_FAILURE; + if ( strcmp( name, "xrDestroySpace" ) == 0 ) + return Assign( function, &DestroySpace ) ? XR_SUCCESS : XR_ERROR_RUNTIME_FAILURE; + + // Swapchain. + if ( strcmp( name, "xrCreateSwapchain" ) == 0 ) + return Assign( function, &CreateSwapchain ) ? XR_SUCCESS : XR_ERROR_RUNTIME_FAILURE; + if ( strcmp( name, "xrDestroySwapchain" ) == 0 ) + return Assign( function, &DestroySwapchain ) ? XR_SUCCESS : XR_ERROR_RUNTIME_FAILURE; + if ( strcmp( name, "xrEnumerateSwapchainImages" ) == 0 ) + return Assign( function, &EnumerateSwapchainImages ) ? XR_SUCCESS + : XR_ERROR_RUNTIME_FAILURE; + if ( strcmp( name, "xrAcquireSwapchainImage" ) == 0 ) + return Assign( function, &AcquireSwapchainImage ) ? XR_SUCCESS + : XR_ERROR_RUNTIME_FAILURE; + if ( strcmp( name, "xrWaitSwapchainImage" ) == 0 ) + return Assign( function, &WaitSwapchainImage ) ? XR_SUCCESS : XR_ERROR_RUNTIME_FAILURE; + if ( strcmp( name, "xrReleaseSwapchainImage" ) == 0 ) + return Assign( function, &ReleaseSwapchainImage ) ? XR_SUCCESS + : XR_ERROR_RUNTIME_FAILURE; + + // Frame loop. + if ( strcmp( name, "xrWaitFrame" ) == 0 ) + return Assign( function, &WaitFrame ) ? XR_SUCCESS : XR_ERROR_RUNTIME_FAILURE; + if ( strcmp( name, "xrBeginFrame" ) == 0 ) + return Assign( function, &BeginFrame ) ? XR_SUCCESS : XR_ERROR_RUNTIME_FAILURE; + if ( strcmp( name, "xrEndFrame" ) == 0 ) + return Assign( function, &EndFrame ) ? XR_SUCCESS : XR_ERROR_RUNTIME_FAILURE; + if ( strcmp( name, "xrLocateViews" ) == 0 ) + return Assign( function, &LocateViews ) ? XR_SUCCESS : XR_ERROR_RUNTIME_FAILURE; + + // Paths. + if ( strcmp( name, "xrStringToPath" ) == 0 ) + return Assign( function, &StringToPath ) ? XR_SUCCESS : XR_ERROR_RUNTIME_FAILURE; + if ( strcmp( name, "xrPathToString" ) == 0 ) + return Assign( function, &PathToString ) ? XR_SUCCESS : XR_ERROR_RUNTIME_FAILURE; + + // Actions. + if ( strcmp( name, "xrCreateActionSet" ) == 0 ) + return Assign( function, &CreateActionSet ) ? XR_SUCCESS : XR_ERROR_RUNTIME_FAILURE; + if ( strcmp( name, "xrDestroyActionSet" ) == 0 ) + return Assign( function, &DestroyActionSet ) ? XR_SUCCESS : XR_ERROR_RUNTIME_FAILURE; + if ( strcmp( name, "xrCreateAction" ) == 0 ) + return Assign( function, &CreateAction ) ? XR_SUCCESS : XR_ERROR_RUNTIME_FAILURE; + if ( strcmp( name, "xrDestroyAction" ) == 0 ) + return Assign( function, &DestroyAction ) ? XR_SUCCESS : XR_ERROR_RUNTIME_FAILURE; + if ( strcmp( name, "xrSuggestInteractionProfileBindings" ) == 0 ) + return Assign( function, &SuggestInteractionProfileBindings ) ? XR_SUCCESS + : XR_ERROR_RUNTIME_FAILURE; + if ( strcmp( name, "xrAttachSessionActionSets" ) == 0 ) + return Assign( function, &AttachSessionActionSets ) ? XR_SUCCESS : XR_ERROR_RUNTIME_FAILURE; + if ( strcmp( name, "xrGetCurrentInteractionProfile" ) == 0 ) + return Assign( function, &GetCurrentInteractionProfile ) ? XR_SUCCESS + : XR_ERROR_RUNTIME_FAILURE; + if ( strcmp( name, "xrCreateActionSpace" ) == 0 ) + return Assign( function, &CreateActionSpace ) ? XR_SUCCESS : XR_ERROR_RUNTIME_FAILURE; + if ( strcmp( name, "xrLocateSpace" ) == 0 ) + return Assign( function, &LocateSpace ) ? XR_SUCCESS : XR_ERROR_RUNTIME_FAILURE; + if ( strcmp( name, "xrSyncActions" ) == 0 ) + return Assign( function, &SyncActions ) ? XR_SUCCESS : XR_ERROR_RUNTIME_FAILURE; + if ( strcmp( name, "xrGetActionStateBoolean" ) == 0 ) + return Assign( function, &GetActionStateBoolean ) ? XR_SUCCESS : XR_ERROR_RUNTIME_FAILURE; + if ( strcmp( name, "xrGetActionStateFloat" ) == 0 ) + return Assign( function, &GetActionStateFloat ) ? XR_SUCCESS : XR_ERROR_RUNTIME_FAILURE; + if ( strcmp( name, "xrGetActionStateVector2f" ) == 0 ) + return Assign( function, &GetActionStateVector2f ) ? XR_SUCCESS : XR_ERROR_RUNTIME_FAILURE; + if ( strcmp( name, "xrGetActionStatePose" ) == 0 ) + return Assign( function, &GetActionStatePose ) ? XR_SUCCESS : XR_ERROR_RUNTIME_FAILURE; + if ( strcmp( name, "xrApplyHapticFeedback" ) == 0 ) + return Assign( function, &ApplyHapticFeedback ) ? XR_SUCCESS : XR_ERROR_RUNTIME_FAILURE; + if ( strcmp( name, "xrStopHapticFeedback" ) == 0 ) + return Assign( function, &StopHapticFeedback ) ? XR_SUCCESS : XR_ERROR_RUNTIME_FAILURE; + + // The loader probes for every function it knows about when an instance is created, so + // missing functions are expected and intentionally not logged here. + return Fail( function ) ? XR_SUCCESS : XR_ERROR_FUNCTION_UNSUPPORTED; + } +} // namespace xrsim + +// --------------------------------------------------------------------------- +// Loader negotiation entry point. +// --------------------------------------------------------------------------- + +extern "C" +{ +#ifdef _WIN32 + __declspec( dllexport ) +#endif + XrResult XRAPI_CALL xrNegotiateLoaderRuntimeInterface( + const XrNegotiateLoaderInfo * loaderInfo, + XrNegotiateRuntimeRequest * runtimeRequest + ) + { + if ( loaderInfo == nullptr || runtimeRequest == nullptr ) + { + return XR_ERROR_INITIALIZATION_FAILED; + } + + if ( loaderInfo->structType != XR_LOADER_INTERFACE_STRUCT_LOADER_INFO || + loaderInfo->structVersion != XR_LOADER_INFO_STRUCT_VERSION || + loaderInfo->structSize != sizeof( XrNegotiateLoaderInfo ) ) + { + return XR_ERROR_INITIALIZATION_FAILED; + } + + // Our runtime only implements interface version 1. + if ( loaderInfo->minInterfaceVersion > XR_CURRENT_LOADER_RUNTIME_VERSION || + loaderInfo->maxInterfaceVersion < XR_CURRENT_LOADER_RUNTIME_VERSION ) + { + return XR_ERROR_INITIALIZATION_FAILED; + } + + runtimeRequest->structType = XR_LOADER_INTERFACE_STRUCT_RUNTIME_REQUEST; + runtimeRequest->structVersion = XR_RUNTIME_INFO_STRUCT_VERSION; + runtimeRequest->structSize = sizeof( XrNegotiateRuntimeRequest ); + runtimeRequest->runtimeInterfaceVersion = XR_CURRENT_LOADER_RUNTIME_VERSION; + runtimeRequest->runtimeApiVersion = XR_MAKE_VERSION( 1, 0, 28 ); + runtimeRequest->getInstanceProcAddr = xrsim::GetInstanceProcAddr; + + xrsim::Log( "Negotiated loader/runtime interface (api 1.0.28)" ); + return XR_SUCCESS; + } +} diff --git a/src/Runtime.cpp b/src/Runtime.cpp new file mode 100644 index 0000000..5452737 --- /dev/null +++ b/src/Runtime.cpp @@ -0,0 +1,1737 @@ +#include "Common.h" +#include "Compositor.h" +#include "Config.h" +#include "Runtime.h" + +#include +#include +#include +#include +#include +#include + +#define XRSIM_UNSUPPORTED( NAME ) \ + do \ + { \ + Log( "%s called (not implemented yet)", NAME ); \ + return XR_ERROR_FUNCTION_UNSUPPORTED; \ + } while ( 0 ) + +namespace +{ + constexpr float kPi = 3.14159265358979323846f; + + std::mutex g_mutex; + std::unordered_map g_instances; + std::unordered_map g_sessions; + std::unordered_map g_swapchains; + std::unordered_map g_spaces; + + struct ActionSetObj + { + xrsim::RuntimeInstance * instance = nullptr; + }; + struct ActionObj + { + XrActionSet set = XR_NULL_HANDLE; + XrActionType type = XR_ACTION_TYPE_BOOLEAN_INPUT; + std::string name; + }; + std::unordered_map g_actionSets; + std::unordered_map g_actions; + + ActionObj * GetAction( XrAction handle ) + { + std::lock_guard lock( g_mutex ); + const auto it = g_actions.find( handle ); + return it == g_actions.end() ? nullptr : it->second; + } + + int HandFromSubaction( XrPath subactionPath ) + { + static const XrPath left = xrsim::HashPath( "/user/hand/left" ); + static const XrPath right = xrsim::HashPath( "/user/hand/right" ); + if ( subactionPath == left ) + { + return 0; + } + if ( subactionPath == right ) + { + return 1; + } + return -1; + } + + // Paths are interned as stable 64-bit hashes (never 0). + std::unordered_map g_pathStrings; + + xrsim::TrackingState g_tracking; + xrsim::InputState g_input; + + bool EndsWith( const std::string & value, const char * suffix ) + { + const size_t length = strlen( suffix ); + return value.size() >= length && value.compare( value.size() - length, length, suffix ) == 0; + } + + /** + * @brief Classified control for an action, derived from its name suffix. + */ + enum class ControlKind + { + Other, + Trigger, + Grip, + Thumbstick, + StickClick, + ButtonA, + ButtonB, + ButtonX, + ButtonY, + Menu, + Touch, + PoseAim, + PoseGrip, + Haptic, + }; + + ControlKind ClassifyAction( const std::string & name, XrActionType type ) + { + if ( EndsWith( name, "haptic" ) || EndsWith( name, "/haptic" ) ) + return ControlKind::Haptic; + if ( EndsWith( name, "aim_pose" ) ) + return ControlKind::PoseAim; + if ( EndsWith( name, "grip_pose" ) ) + return ControlKind::PoseGrip; + + if ( EndsWith( name, "thumbstick_left_click" ) || EndsWith( name, "thumbstick_right_click" ) || + EndsWith( name, "thumbstick_click" ) || EndsWith( name, "trackpad_click" ) ) + return ControlKind::StickClick; + + if ( EndsWith( name, "thumbstick_left" ) || EndsWith( name, "thumbstick_right" ) || + EndsWith( name, "thumbstick" ) || EndsWith( name, "trackpad" ) ) + return type == XR_ACTION_TYPE_VECTOR2F_INPUT ? ControlKind::Thumbstick : ControlKind::StickClick; + + if ( EndsWith( name, "trigger_value" ) || EndsWith( name, "trigger_left_value" ) || + EndsWith( name, "trigger_right_value" ) ) + return ControlKind::Trigger; + if ( EndsWith( name, "trigger_click" ) || EndsWith( name, "trigger_touch" ) || + EndsWith( name, "trigger_proximity" ) ) + return ControlKind::Trigger; + if ( EndsWith( name, "select" ) || EndsWith( name, "select_click" ) ) + return ControlKind::Trigger; + + if ( EndsWith( name, "grip_value" ) || EndsWith( name, "grip_force" ) ) + return ControlKind::Grip; + if ( EndsWith( name, "grip_click" ) || EndsWith( name, "grip_touch" ) || + EndsWith( name, "squeeze_click" ) ) + return ControlKind::Grip; + + if ( EndsWith( name, "_touch" ) || EndsWith( name, "_proximity" ) ) + return ControlKind::Touch; + + if ( EndsWith( name, "_a_button" ) || EndsWith( name, "_a_click" ) || EndsWith( name, "_a" ) ) + return ControlKind::ButtonA; + if ( EndsWith( name, "_b_button" ) || EndsWith( name, "_b_click" ) || EndsWith( name, "_b" ) ) + return ControlKind::ButtonB; + if ( EndsWith( name, "_x_button" ) || EndsWith( name, "_x_click" ) || EndsWith( name, "_x" ) ) + return ControlKind::ButtonX; + if ( EndsWith( name, "_y_button" ) || EndsWith( name, "_y_click" ) || EndsWith( name, "_y" ) ) + return ControlKind::ButtonY; + + if ( EndsWith( name, "menu" ) ) + return ControlKind::Menu; + + return ControlKind::Other; + } + + int64_t NowNs() + { + return std::chrono::duration_cast( + std::chrono::steady_clock::now().time_since_epoch() + ) + .count(); + } + + template + Handle ToHandle( Object * object ) + { + return reinterpret_cast( object ); + } + + XrResult CopyString( char * destination, size_t destinationSize, const char * source ) + { + if ( destination == nullptr || destinationSize == 0 ) + { + return XR_ERROR_VALIDATION_FAILURE; + } + strncpy( destination, source, destinationSize - 1 ); + destination[destinationSize - 1] = '\0'; + return XR_SUCCESS; + } + + const XrGraphicsBindingVulkan2KHR * FindVulkanBinding( const void * next ) + { + for ( const void * node = next; node != nullptr; ) + { + const auto * base = reinterpret_cast( node ); + if ( base->type == XR_TYPE_GRAPHICS_BINDING_VULKAN2_KHR ) + { + return reinterpret_cast( node ); + } + node = base->next; + } + return nullptr; + } + + uint32_t FindMemoryType( VkPhysicalDevice physicalDevice, uint32_t typeBits, + VkMemoryPropertyFlags properties ) + { + VkPhysicalDeviceMemoryProperties memoryProperties{}; + vkGetPhysicalDeviceMemoryProperties( physicalDevice, &memoryProperties ); + for ( uint32_t i = 0; i < memoryProperties.memoryTypeCount; ++i ) + { + if ( ( typeBits & ( 1u << i ) ) != 0 && + ( memoryProperties.memoryTypes[i].propertyFlags & properties ) == properties ) + { + return i; + } + } + return UINT32_MAX; + } + + bool ImmediateSubmit( xrsim::RuntimeSession * session, const std::function & fn ) + { + VkCommandBufferAllocateInfo allocInfo{ VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO }; + allocInfo.commandPool = session->commandPool; + allocInfo.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY; + allocInfo.commandBufferCount = 1; + + VkCommandBuffer commandBuffer = VK_NULL_HANDLE; + if ( vkAllocateCommandBuffers( session->vkDevice, &allocInfo, &commandBuffer ) != VK_SUCCESS ) + { + return false; + } + + VkCommandBufferBeginInfo beginInfo{ VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO }; + beginInfo.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT; + vkBeginCommandBuffer( commandBuffer, &beginInfo ); + fn( commandBuffer ); + vkEndCommandBuffer( commandBuffer ); + + VkSubmitInfo submitInfo{ VK_STRUCTURE_TYPE_SUBMIT_INFO }; + submitInfo.commandBufferCount = 1; + submitInfo.pCommandBuffers = &commandBuffer; + vkQueueSubmit( session->queue, 1, &submitInfo, VK_NULL_HANDLE ); + vkQueueWaitIdle( session->queue ); + vkFreeCommandBuffers( session->vkDevice, session->commandPool, 1, &commandBuffer ); + return true; + } + + XrQuaternionf MultiplyQuat( const XrQuaternionf & a, const XrQuaternionf & b ) + { + return XrQuaternionf{ + a.w * b.x + a.x * b.w + a.y * b.z - a.z * b.y, + a.w * b.y - a.x * b.z + a.y * b.w + a.z * b.x, + a.w * b.z + a.x * b.y - a.y * b.x + a.z * b.w, + a.w * b.w - a.x * b.x - a.y * b.y - a.z * b.z, + }; + } +} // namespace + +namespace xrsim +{ + TrackingState & GetTracking() + { + return g_tracking; + } + + InputState & GetInputState() + { + return g_input; + } + + XrQuaternionf GetHeadOrientation() + { + const float halfYaw = g_tracking.yaw * 0.5f; + const float halfPitch = g_tracking.pitch * 0.5f; + const XrQuaternionf qYaw{ 0.0f, std::sin( halfYaw ), 0.0f, std::cos( halfYaw ) }; + const XrQuaternionf qPitch{ std::sin( halfPitch ), 0.0f, 0.0f, std::cos( halfPitch ) }; + return MultiplyQuat( qYaw, qPitch ); + } + + XrVector3f GetHeadPosition() + { + return XrVector3f{ g_tracking.posX, g_tracking.posY, g_tracking.posZ }; + } + + XrVector3f RotateByQuaternion( const XrQuaternionf & q, const XrVector3f & v ) + { + // v' = v + 2 * cross(q.xyz, cross(q.xyz, v) + q.w * v) + const XrVector3f u{ q.x, q.y, q.z }; + const XrVector3f uv{ u.y * v.z - u.z * v.y, u.z * v.x - u.x * v.z, u.x * v.y - u.y * v.x }; + const XrVector3f uuv{ u.y * uv.z - u.z * uv.y, u.z * uv.x - u.x * uv.z, u.x * uv.y - u.y * uv.x }; + return XrVector3f{ + v.x + 2.0f * ( q.w * uv.x + uuv.x ), + v.y + 2.0f * ( q.w * uv.y + uuv.y ), + v.z + 2.0f * ( q.w * uv.z + uuv.z ), + }; + } + + XrPath HashPath( const char * path ) + { + uint64_t hash = 1469598103934665603ULL; + for ( const char * c = path; c != nullptr && *c != '\0'; ++c ) + { + hash ^= static_cast( *c ); + hash *= 1099511628211ULL; + } + if ( hash == XR_NULL_PATH ) + { + hash = 1; + } + if ( path != nullptr ) + { + std::lock_guard lock( g_mutex ); + g_pathStrings[hash] = path; + } + return hash; + } + + RuntimeInstance * GetInstance( XrInstance handle ) + { + std::lock_guard lock( g_mutex ); + const auto it = g_instances.find( handle ); + return it == g_instances.end() ? nullptr : it->second; + } + + RuntimeSession * GetSession( XrSession handle ) + { + std::lock_guard lock( g_mutex ); + const auto it = g_sessions.find( handle ); + return it == g_sessions.end() ? nullptr : it->second; + } + + RuntimeSwapchain * GetSwapchain( XrSwapchain handle ) + { + std::lock_guard lock( g_mutex ); + const auto it = g_swapchains.find( handle ); + return it == g_swapchains.end() ? nullptr : it->second; + } + + RuntimeSpace * GetSpace( XrSpace handle ) + { + std::lock_guard lock( g_mutex ); + const auto it = g_spaces.find( handle ); + return it == g_spaces.end() ? nullptr : it->second; + } + + bool ResolveSubImage( + XrSwapchain swapchain, const XrSwapchainSubImage & subImage, VkImage * outImage, + uint32_t * outArrayLayer, uint32_t * outWidth, uint32_t * outHeight + ) + { + RuntimeSwapchain * runtime = GetSwapchain( swapchain ); + if ( runtime == nullptr || subImage.swapchain != swapchain ) + { + return false; + } + + // imageArrayIndex selects the array layer (eye) within the swapchain image. The image is + // the one currently acquired, or the last released one when called after + // xrReleaseSwapchainImage (the engine presents asynchronously). + const int32_t imageIndexSigned = + runtime->acquiredIndex >= 0 ? runtime->acquiredIndex : runtime->lastReleasedIndex; + const uint32_t imageIndex = static_cast( imageIndexSigned ); + if ( imageIndex >= runtime->images.size() ) + { + return false; + } + uint32_t arrayLayer = subImage.imageArrayIndex; + if ( arrayLayer >= runtime->arraySize ) + { + arrayLayer = 0; + } + + *outImage = runtime->images[imageIndex]; + *outArrayLayer = arrayLayer; + *outWidth = static_cast( subImage.imageRect.extent.width ); + *outHeight = static_cast( subImage.imageRect.extent.height ); + return true; + } + + void PushSessionStateEvent( XrInstance instance, XrSession session, XrSessionState state ) + { + RuntimeInstance * runtime = GetInstance( instance ); + if ( runtime == nullptr ) + { + return; + } + + XrEventDataBuffer buffer{}; + buffer.type = XR_TYPE_EVENT_DATA_SESSION_STATE_CHANGED; + auto * event = reinterpret_cast( &buffer ); + event->session = session; + event->state = state; + event->time = NowNs(); + + std::lock_guard lock( g_mutex ); + runtime->events.push_back( buffer ); + } + + // ---- global functions ------------------------------------------------- + + XrResult XRAPI_CALL EnumerateApiLayerProperties( + uint32_t /*propertyCapacityInput*/, uint32_t * propertyCountOutput, + XrApiLayerProperties * /*properties*/ + ) + { + if ( propertyCountOutput == nullptr ) + { + return XR_ERROR_VALIDATION_FAILURE; + } + *propertyCountOutput = 0; + return XR_SUCCESS; + } + + XrResult XRAPI_CALL EnumerateInstanceExtensionProperties( + const char * layerName, uint32_t propertyCapacityInput, uint32_t * propertyCountOutput, + XrExtensionProperties * properties + ) + { + if ( propertyCountOutput == nullptr ) + { + return XR_ERROR_VALIDATION_FAILURE; + } + if ( layerName != nullptr && layerName[0] != '\0' ) + { + *propertyCountOutput = 0; + return XR_SUCCESS; + } + + struct ExtensionDef + { + const char * name; + uint32_t version; + }; + static const ExtensionDef kExtensions[] = { + { XR_KHR_VULKAN_ENABLE2_EXTENSION_NAME, XR_KHR_vulkan_enable2_SPEC_VERSION }, + { XR_KHR_VULKAN_ENABLE_EXTENSION_NAME, XR_KHR_vulkan_enable_SPEC_VERSION }, + { XR_EXT_DEBUG_UTILS_EXTENSION_NAME, XR_EXT_debug_utils_SPEC_VERSION }, + }; + constexpr uint32_t kExtensionCount = sizeof( kExtensions ) / sizeof( kExtensions[0] ); + + *propertyCountOutput = kExtensionCount; + if ( propertyCapacityInput == 0 ) + { + return XR_SUCCESS; + } + if ( properties == nullptr || propertyCapacityInput < kExtensionCount ) + { + return XR_ERROR_SIZE_INSUFFICIENT; + } + + for ( uint32_t i = 0; i < kExtensionCount; ++i ) + { + properties[i].type = XR_TYPE_EXTENSION_PROPERTIES; + properties[i].next = nullptr; + properties[i].extensionVersion = kExtensions[i].version; + CopyString( properties[i].extensionName, XR_MAX_EXTENSION_NAME_SIZE, kExtensions[i].name ); + } + return XR_SUCCESS; + } + + XrResult XRAPI_CALL CreateInstance( + const XrInstanceCreateInfo * createInfo, XrInstance * instance + ) + { + if ( createInfo == nullptr || instance == nullptr ) + { + return XR_ERROR_VALIDATION_FAILURE; + } + + auto * runtime = new RuntimeInstance(); + runtime->applicationName = createInfo->applicationInfo.applicationName; + runtime->engineName = createInfo->applicationInfo.engineName; + for ( uint32_t i = 0; i < createInfo->enabledExtensionCount; ++i ) + { + runtime->enabledExtensions.emplace_back( createInfo->enabledExtensionNames[i] ); + } + runtime->handle = ToHandle( runtime ); + runtime->valid = true; + + { + std::lock_guard lock( g_mutex ); + g_instances[runtime->handle] = runtime; + } + + *instance = runtime->handle; + Log( "Created XrInstance (app='%s')", runtime->applicationName.c_str() ); + return XR_SUCCESS; + } + + // ---- instance functions ----------------------------------------------- + + XrResult XRAPI_CALL DestroyInstance( XrInstance instance ) + { + RuntimeInstance * runtime = GetInstance( instance ); + if ( runtime == nullptr ) + { + return XR_ERROR_HANDLE_INVALID; + } + if ( runtime->compositor ) + { + runtime->compositor->Shutdown(); + runtime->compositor.reset(); + } + { + std::lock_guard lock( g_mutex ); + g_instances.erase( instance ); + } + delete runtime; + Log( "Destroyed XrInstance" ); + return XR_SUCCESS; + } + + XrResult XRAPI_CALL GetInstanceProperties( XrInstance instance, XrInstanceProperties * properties ) + { + if ( GetInstance( instance ) == nullptr || properties == nullptr ) + { + return XR_ERROR_VALIDATION_FAILURE; + } + properties->runtimeVersion = XR_MAKE_VERSION( 0, 1, 0 ); + CopyString( properties->runtimeName, XR_MAX_RUNTIME_NAME_SIZE, "OpenXR Simulator" ); + return XR_SUCCESS; + } + + XrResult XRAPI_CALL GetSystem( + XrInstance instance, const XrSystemGetInfo * getInfo, XrSystemId * systemId + ) + { + if ( GetInstance( instance ) == nullptr || getInfo == nullptr || systemId == nullptr ) + { + return XR_ERROR_VALIDATION_FAILURE; + } + if ( getInfo->formFactor != XR_FORM_FACTOR_HEAD_MOUNTED_DISPLAY ) + { + return XR_ERROR_FORM_FACTOR_UNSUPPORTED; + } + *systemId = 1; + return XR_SUCCESS; + } + + XrResult XRAPI_CALL GetSystemProperties( + XrInstance instance, XrSystemId /*systemId*/, XrSystemProperties * properties + ) + { + if ( GetInstance( instance ) == nullptr || properties == nullptr ) + { + return XR_ERROR_VALIDATION_FAILURE; + } + const SimulatorConfig & config = GetConfig(); + CopyString( properties->systemName, XR_MAX_SYSTEM_NAME_SIZE, config.systemName.c_str() ); + properties->vendorId = config.vendorId; + properties->graphicsProperties.maxSwapchainImageWidth = config.eyeWidth; + properties->graphicsProperties.maxSwapchainImageHeight = config.eyeHeight; + properties->graphicsProperties.maxLayerCount = 1; + properties->trackingProperties.orientationTracking = XR_TRUE; + properties->trackingProperties.positionTracking = XR_TRUE; + return XR_SUCCESS; + } + + XrResult XRAPI_CALL EnumerateViewConfigurations( + XrInstance instance, XrSystemId /*systemId*/, uint32_t viewConfigurationTypeCapacityInput, + uint32_t * viewConfigurationTypeCountOutput, XrViewConfigurationType * viewConfigurationTypes + ) + { + if ( GetInstance( instance ) == nullptr || viewConfigurationTypeCountOutput == nullptr ) + { + return XR_ERROR_VALIDATION_FAILURE; + } + constexpr uint32_t kCount = 1; + *viewConfigurationTypeCountOutput = kCount; + if ( viewConfigurationTypeCapacityInput == 0 ) + { + return XR_SUCCESS; + } + if ( viewConfigurationTypes == nullptr || viewConfigurationTypeCapacityInput < kCount ) + { + return XR_ERROR_SIZE_INSUFFICIENT; + } + viewConfigurationTypes[0] = XR_VIEW_CONFIGURATION_TYPE_PRIMARY_STEREO; + return XR_SUCCESS; + } + + XrResult XRAPI_CALL EnumerateViewConfigurationViews( + XrInstance instance, XrSystemId /*systemId*/, XrViewConfigurationType viewConfigurationType, + uint32_t viewCapacityInput, uint32_t * viewCountOutput, XrViewConfigurationView * views + ) + { + if ( GetInstance( instance ) == nullptr || viewCountOutput == nullptr ) + { + return XR_ERROR_VALIDATION_FAILURE; + } + if ( viewConfigurationType != XR_VIEW_CONFIGURATION_TYPE_PRIMARY_STEREO ) + { + return XR_ERROR_VIEW_CONFIGURATION_TYPE_UNSUPPORTED; + } + + constexpr uint32_t kEyeCount = 2; + *viewCountOutput = kEyeCount; + if ( viewCapacityInput == 0 ) + { + return XR_SUCCESS; + } + if ( views == nullptr || viewCapacityInput < kEyeCount ) + { + return XR_ERROR_SIZE_INSUFFICIENT; + } + + const SimulatorConfig & config = GetConfig(); + for ( uint32_t i = 0; i < kEyeCount; ++i ) + { + views[i].type = XR_TYPE_VIEW_CONFIGURATION_VIEW; + views[i].next = nullptr; + views[i].maxImageRectWidth = config.eyeWidth; + views[i].maxImageRectHeight = config.eyeHeight; + views[i].maxSwapchainSampleCount = 1; + views[i].recommendedImageRectWidth = config.eyeWidth; + views[i].recommendedImageRectHeight = config.eyeHeight; + views[i].recommendedSwapchainSampleCount = 1; + } + return XR_SUCCESS; + } + + XrResult XRAPI_CALL EnumerateEnvironmentBlendModes( + XrInstance instance, XrSystemId /*systemId*/, XrViewConfigurationType viewConfigurationType, + uint32_t environmentBlendModeCapacityInput, uint32_t * environmentBlendModeCountOutput, + XrEnvironmentBlendMode * environmentBlendModes + ) + { + if ( GetInstance( instance ) == nullptr || environmentBlendModeCountOutput == nullptr ) + { + return XR_ERROR_VALIDATION_FAILURE; + } + if ( viewConfigurationType != XR_VIEW_CONFIGURATION_TYPE_PRIMARY_STEREO ) + { + return XR_ERROR_VIEW_CONFIGURATION_TYPE_UNSUPPORTED; + } + constexpr uint32_t kCount = 1; + *environmentBlendModeCountOutput = kCount; + if ( environmentBlendModeCapacityInput == 0 ) + { + return XR_SUCCESS; + } + if ( environmentBlendModes == nullptr || environmentBlendModeCapacityInput < kCount ) + { + return XR_ERROR_SIZE_INSUFFICIENT; + } + environmentBlendModes[0] = XR_ENVIRONMENT_BLEND_MODE_OPAQUE; + return XR_SUCCESS; + } + + XrResult XRAPI_CALL EnumerateSwapchainFormats( + XrSession session, uint32_t formatCapacityInput, uint32_t * formatCountOutput, int64_t * formats + ) + { + if ( GetSession( session ) == nullptr || formatCountOutput == nullptr ) + { + return XR_ERROR_VALIDATION_FAILURE; + } + static const int64_t kFormats[] = { + static_cast( VK_FORMAT_R8G8B8A8_SRGB ), + static_cast( VK_FORMAT_R8G8B8A8_UNORM ), + }; + constexpr uint32_t kCount = sizeof( kFormats ) / sizeof( kFormats[0] ); + + *formatCountOutput = kCount; + if ( formatCapacityInput == 0 ) + { + return XR_SUCCESS; + } + if ( formats == nullptr || formatCapacityInput < kCount ) + { + return XR_ERROR_SIZE_INSUFFICIENT; + } + for ( uint32_t i = 0; i < kCount; ++i ) + { + formats[i] = kFormats[i]; + } + return XR_SUCCESS; + } + + // ---- XR_KHR_vulkan_enable2 -------------------------------------------- + + XrResult XRAPI_CALL GetVulkanGraphicsRequirements2KHR( + XrInstance instance, XrSystemId /*systemId*/, + XrGraphicsRequirementsVulkanKHR * graphicsRequirements + ) + { + if ( GetInstance( instance ) == nullptr || graphicsRequirements == nullptr ) + { + return XR_ERROR_VALIDATION_FAILURE; + } + graphicsRequirements->minApiVersionSupported = XR_MAKE_VERSION( 1, 0, 0 ); + graphicsRequirements->maxApiVersionSupported = XR_MAKE_VERSION( 1, 4, 0 ); + return XR_SUCCESS; + } + + XrResult XRAPI_CALL CreateVulkanInstanceKHR( + XrInstance instance, const XrVulkanInstanceCreateInfoKHR * createInfo, + VkInstance * vulkanInstance, VkResult * vulkanResult + ) + { + RuntimeInstance * runtime = GetInstance( instance ); + if ( runtime == nullptr || createInfo == nullptr || createInfo->pfnGetInstanceProcAddr == nullptr || + createInfo->vulkanCreateInfo == nullptr || vulkanInstance == nullptr || + vulkanResult == nullptr ) + { + return XR_ERROR_VALIDATION_FAILURE; + } + + auto vkCreateInstance = reinterpret_cast( + createInfo->pfnGetInstanceProcAddr( VK_NULL_HANDLE, "vkCreateInstance" ) + ); + if ( vkCreateInstance == nullptr ) + { + return XR_ERROR_GRAPHICS_DEVICE_INVALID; + } + + // The compositor needs surface extensions on the instance; ensure they are present. + const VkInstanceCreateInfo & requested = *createInfo->vulkanCreateInfo; + std::vector extensions( + requested.ppEnabledExtensionNames, + requested.ppEnabledExtensionNames + requested.enabledExtensionCount + ); + auto addUnique = [&extensions]( const char * name ) + { + if ( std::find( extensions.begin(), extensions.end(), name ) == extensions.end() ) + { + extensions.push_back( name ); + } + }; + addUnique( VK_KHR_SURFACE_EXTENSION_NAME ); +#ifdef _WIN32 + addUnique( "VK_KHR_win32_surface" ); +#endif + + VkInstanceCreateInfo augmented = requested; + augmented.enabledExtensionCount = static_cast( extensions.size() ); + augmented.ppEnabledExtensionNames = extensions.data(); + + runtime->vkGetInstanceProcAddr = createInfo->pfnGetInstanceProcAddr; + *vulkanResult = vkCreateInstance( + &augmented, createInfo->vulkanAllocator, vulkanInstance + ); + if ( *vulkanResult != VK_SUCCESS ) + { + Log( "vkCreateInstance failed (%d)", static_cast( *vulkanResult ) ); + return XR_ERROR_RUNTIME_FAILURE; + } + + runtime->vkInstance = *vulkanInstance; + Log( "Created VkInstance on behalf of the application" ); + return XR_SUCCESS; + } + + XrResult XRAPI_CALL GetVulkanGraphicsDevice2KHR( + XrInstance instance, const XrVulkanGraphicsDeviceGetInfoKHR * getInfo, + VkPhysicalDevice * vulkanPhysicalDevice + ) + { + RuntimeInstance * runtime = GetInstance( instance ); + if ( runtime == nullptr || getInfo == nullptr || vulkanPhysicalDevice == nullptr ) + { + return XR_ERROR_VALIDATION_FAILURE; + } + if ( runtime->vkGetInstanceProcAddr == nullptr ) + { + return XR_ERROR_RUNTIME_FAILURE; + } + + auto vkEnumeratePhysicalDevices = reinterpret_cast( + runtime->vkGetInstanceProcAddr( getInfo->vulkanInstance, "vkEnumeratePhysicalDevices" ) + ); + auto vkGetPhysicalDeviceProperties = reinterpret_cast( + runtime->vkGetInstanceProcAddr( getInfo->vulkanInstance, "vkGetPhysicalDeviceProperties" ) + ); + if ( vkEnumeratePhysicalDevices == nullptr ) + { + return XR_ERROR_RUNTIME_FAILURE; + } + + uint32_t deviceCount = 0; + vkEnumeratePhysicalDevices( getInfo->vulkanInstance, &deviceCount, nullptr ); + if ( deviceCount == 0 ) + { + return XR_ERROR_GRAPHICS_DEVICE_INVALID; + } + std::vector devices( deviceCount ); + vkEnumeratePhysicalDevices( getInfo->vulkanInstance, &deviceCount, devices.data() ); + + VkPhysicalDevice chosen = devices[0]; + if ( vkGetPhysicalDeviceProperties != nullptr ) + { + for ( VkPhysicalDevice device : devices ) + { + VkPhysicalDeviceProperties props{}; + vkGetPhysicalDeviceProperties( device, &props ); + if ( props.deviceType == VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU ) + { + chosen = device; + break; + } + } + } + + runtime->vkPhysicalDevice = chosen; + *vulkanPhysicalDevice = chosen; + return XR_SUCCESS; + } + + XrResult XRAPI_CALL CreateVulkanDeviceKHR( + XrInstance instance, const XrVulkanDeviceCreateInfoKHR * createInfo, VkDevice * vulkanDevice, + VkResult * vulkanResult + ) + { + RuntimeInstance * runtime = GetInstance( instance ); + if ( runtime == nullptr || createInfo == nullptr || createInfo->vulkanCreateInfo == nullptr || + vulkanDevice == nullptr || vulkanResult == nullptr || + createInfo->pfnGetInstanceProcAddr == nullptr ) + { + return XR_ERROR_VALIDATION_FAILURE; + } + + auto vkCreateDevice = reinterpret_cast( + createInfo->pfnGetInstanceProcAddr( runtime->vkInstance, "vkCreateDevice" ) + ); + if ( vkCreateDevice == nullptr ) + { + return XR_ERROR_GRAPHICS_DEVICE_INVALID; + } + + // The compositor needs VK_KHR_swapchain on the device; ensure it is present. + const VkDeviceCreateInfo & requested = *createInfo->vulkanCreateInfo; + std::vector extensions( + requested.ppEnabledExtensionNames, + requested.ppEnabledExtensionNames + requested.enabledExtensionCount + ); + if ( std::find( extensions.begin(), extensions.end(), VK_KHR_SWAPCHAIN_EXTENSION_NAME ) == + extensions.end() ) + { + extensions.push_back( VK_KHR_SWAPCHAIN_EXTENSION_NAME ); + } + + VkDeviceCreateInfo augmented = requested; + augmented.enabledExtensionCount = static_cast( extensions.size() ); + augmented.ppEnabledExtensionNames = extensions.data(); + + *vulkanResult = vkCreateDevice( + createInfo->vulkanPhysicalDevice, &augmented, createInfo->vulkanAllocator, vulkanDevice + ); + if ( *vulkanResult != VK_SUCCESS ) + { + Log( "vkCreateDevice failed (%d)", static_cast( *vulkanResult ) ); + return XR_ERROR_RUNTIME_FAILURE; + } + + runtime->vkPhysicalDevice = createInfo->vulkanPhysicalDevice; + runtime->vkDevice = *vulkanDevice; + Log( "Created VkDevice on behalf of the application" ); + return XR_SUCCESS; + } + + // ---- session ---------------------------------------------------------- + + XrResult XRAPI_CALL CreateSession( + XrInstance instance, const XrSessionCreateInfo * createInfo, XrSession * session + ) + { + RuntimeInstance * runtime = GetInstance( instance ); + if ( runtime == nullptr || createInfo == nullptr || session == nullptr ) + { + return XR_ERROR_VALIDATION_FAILURE; + } + + auto * newSession = new RuntimeSession(); + newSession->instance = runtime; + newSession->systemId = createInfo->systemId; + newSession->handle = ToHandle( newSession ); + newSession->valid = true; + newSession->state = XR_SESSION_STATE_IDLE; + const SimulatorConfig & config = GetConfig(); + g_tracking.ipd = config.ipdMeters; + newSession->framePeriodNs = 1000000000LL / ( config.refreshRateHz == 0 ? 90u : config.refreshRateHz ); + newSession->nextDisplayTime = NowNs(); + + if ( const XrGraphicsBindingVulkan2KHR * binding = FindVulkanBinding( createInfo->next ) ) + { + newSession->vkInstance = binding->instance; + newSession->vkPhysicalDevice = binding->physicalDevice; + newSession->vkDevice = binding->device; + newSession->queueFamilyIndex = binding->queueFamilyIndex; + newSession->queueIndex = binding->queueIndex; + vkGetDeviceQueue( + binding->device, binding->queueFamilyIndex, binding->queueIndex, &newSession->queue + ); + } + + if ( newSession->vkDevice != VK_NULL_HANDLE ) + { + VkCommandPoolCreateInfo poolInfo{ VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO }; + poolInfo.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT; + poolInfo.queueFamilyIndex = newSession->queueFamilyIndex; + vkCreateCommandPool( newSession->vkDevice, &poolInfo, nullptr, &newSession->commandPool ); + } + + { + std::lock_guard lock( g_mutex ); + g_sessions[newSession->handle] = newSession; + runtime->events.clear(); + } + + *session = newSession->handle; + Log( + "Created XrSession (queue family %u, index %u)", newSession->queueFamilyIndex, + newSession->queueIndex + ); + + PushSessionStateEvent( instance, newSession->handle, XR_SESSION_STATE_READY ); + + if ( runtime->compositor == nullptr ) + { + runtime->compositor = CreateCompositor(); + if ( runtime->compositor && !runtime->compositor->Initialize( runtime, newSession ) ) + { + Log( "Compositor initialization failed; running without a window" ); + runtime->compositor->Shutdown(); + runtime->compositor.reset(); + } + } + return XR_SUCCESS; + } + + XrResult XRAPI_CALL DestroySession( XrSession session ) + { + RuntimeSession * runtime = GetSession( session ); + if ( runtime == nullptr ) + { + return XR_ERROR_HANDLE_INVALID; + } + + // Destroy swapchains first. + std::vector swapchains = runtime->swapchains; + for ( RuntimeSwapchain * swapchain : swapchains ) + { + DestroySwapchain( swapchain->handle ); + } + + if ( runtime->instance != nullptr && runtime->instance->compositor ) + { + runtime->instance->compositor->Shutdown(); + runtime->instance->compositor.reset(); + } + + if ( runtime->commandPool != VK_NULL_HANDLE ) + { + vkDestroyCommandPool( runtime->vkDevice, runtime->commandPool, nullptr ); + } + + { + std::lock_guard lock( g_mutex ); + g_sessions.erase( session ); + } + delete runtime; + Log( "Destroyed XrSession" ); + return XR_SUCCESS; + } + + XrResult XRAPI_CALL BeginSession( XrSession session, const XrSessionBeginInfo * /*beginInfo*/ ) + { + RuntimeSession * runtime = GetSession( session ); + if ( runtime == nullptr ) + { + return XR_ERROR_HANDLE_INVALID; + } + runtime->running = true; + runtime->state = XR_SESSION_STATE_SYNCHRONIZED; + PushSessionStateEvent( runtime->instance->handle, session, XR_SESSION_STATE_SYNCHRONIZED ); + PushSessionStateEvent( runtime->instance->handle, session, XR_SESSION_STATE_VISIBLE ); + PushSessionStateEvent( runtime->instance->handle, session, XR_SESSION_STATE_FOCUSED ); + runtime->state = XR_SESSION_STATE_FOCUSED; + Log( "BeginSession" ); + return XR_SUCCESS; + } + + XrResult XRAPI_CALL EndSession( XrSession session ) + { + RuntimeSession * runtime = GetSession( session ); + if ( runtime == nullptr ) + { + return XR_ERROR_HANDLE_INVALID; + } + runtime->running = false; + runtime->state = XR_SESSION_STATE_IDLE; + PushSessionStateEvent( runtime->instance->handle, session, XR_SESSION_STATE_STOPPING ); + PushSessionStateEvent( runtime->instance->handle, session, XR_SESSION_STATE_IDLE ); + Log( "EndSession" ); + return XR_SUCCESS; + } + + XrResult XRAPI_CALL PollEvent( XrInstance instance, XrEventDataBuffer * eventData ) + { + RuntimeInstance * runtime = GetInstance( instance ); + if ( runtime == nullptr || eventData == nullptr ) + { + return XR_ERROR_VALIDATION_FAILURE; + } + + std::lock_guard lock( g_mutex ); + if ( runtime->events.empty() ) + { + return XR_EVENT_UNAVAILABLE; + } + *eventData = runtime->events.front(); + runtime->events.pop_front(); + return XR_SUCCESS; + } + + XrResult XRAPI_CALL CreateReferenceSpace( + XrSession session, const XrReferenceSpaceCreateInfo * createInfo, XrSpace * space + ) + { + RuntimeSession * runtime = GetSession( session ); + if ( runtime == nullptr || createInfo == nullptr || space == nullptr ) + { + return XR_ERROR_VALIDATION_FAILURE; + } + + auto * newSpace = new RuntimeSpace(); + newSpace->session = runtime; + newSpace->refType = createInfo->referenceSpaceType; + newSpace->handle = ToHandle( newSpace ); + newSpace->valid = true; + + { + std::lock_guard lock( g_mutex ); + g_spaces[newSpace->handle] = newSpace; + } + *space = newSpace->handle; + return XR_SUCCESS; + } + + XrResult XRAPI_CALL DestroySpace( XrSpace space ) + { + RuntimeSpace * runtime = GetSpace( space ); + if ( runtime == nullptr ) + { + return XR_SUCCESS; + } + { + std::lock_guard lock( g_mutex ); + g_spaces.erase( space ); + } + delete runtime; + return XR_SUCCESS; + } + + // ---- swapchain -------------------------------------------------------- + + XrResult XRAPI_CALL CreateSwapchain( + XrSession session, const XrSwapchainCreateInfo * createInfo, XrSwapchain * swapchain + ) + { + RuntimeSession * runtime = GetSession( session ); + if ( runtime == nullptr || createInfo == nullptr || swapchain == nullptr || + runtime->vkDevice == VK_NULL_HANDLE ) + { + return XR_ERROR_VALIDATION_FAILURE; + } + + auto * sc = new RuntimeSwapchain(); + sc->session = runtime; + sc->createInfo = *createInfo; + sc->width = createInfo->width; + sc->height = createInfo->height; + sc->arraySize = createInfo->arraySize == 0 ? 1 : createInfo->arraySize; + sc->format = static_cast( createInfo->format ); + + VkImageCreateInfo imageInfo{ VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO }; + imageInfo.imageType = VK_IMAGE_TYPE_2D; + imageInfo.format = sc->format; + imageInfo.extent = { sc->width, sc->height, 1 }; + imageInfo.mipLevels = 1; + imageInfo.arrayLayers = sc->arraySize; + imageInfo.samples = VK_SAMPLE_COUNT_1_BIT; + imageInfo.tiling = VK_IMAGE_TILING_OPTIMAL; + imageInfo.usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT | + VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT; + imageInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE; + imageInfo.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; + + const uint32_t imageCount = std::clamp( GetConfig().swapchainImageCount, 1u, 8u ); + for ( uint32_t i = 0; i < imageCount; ++i ) + { + VkImage image = VK_NULL_HANDLE; + if ( vkCreateImage( runtime->vkDevice, &imageInfo, nullptr, &image ) != VK_SUCCESS ) + { + delete sc; + return XR_ERROR_RUNTIME_FAILURE; + } + + VkMemoryRequirements requirements{}; + vkGetImageMemoryRequirements( runtime->vkDevice, image, &requirements ); + const uint32_t memoryType = + FindMemoryType( runtime->vkPhysicalDevice, requirements.memoryTypeBits, + VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT ); + if ( memoryType == UINT32_MAX ) + { + vkDestroyImage( runtime->vkDevice, image, nullptr ); + delete sc; + return XR_ERROR_RUNTIME_FAILURE; + } + + VkMemoryAllocateInfo allocateInfo{ VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO }; + allocateInfo.allocationSize = requirements.size; + allocateInfo.memoryTypeIndex = memoryType; + + VkDeviceMemory memory = VK_NULL_HANDLE; + if ( vkAllocateMemory( runtime->vkDevice, &allocateInfo, nullptr, &memory ) != VK_SUCCESS || + vkBindImageMemory( runtime->vkDevice, image, memory, 0 ) != VK_SUCCESS ) + { + vkDestroyImage( runtime->vkDevice, image, nullptr ); + delete sc; + return XR_ERROR_RUNTIME_FAILURE; + } + + sc->images.push_back( image ); + sc->memories.push_back( memory ); + } + + // Move all images into COLOR_ATTACHMENT_OPTIMAL (the layout the app expects after acquire). + ImmediateSubmit( + runtime, + [&]( VkCommandBuffer cmd ) + { + std::vector barriers( imageCount ); + for ( uint32_t i = 0; i < imageCount; ++i ) + { + barriers[i].sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER; + barriers[i].oldLayout = VK_IMAGE_LAYOUT_UNDEFINED; + barriers[i].newLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; + barriers[i].srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; + barriers[i].dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; + barriers[i].image = sc->images[i]; + barriers[i].subresourceRange = { VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, sc->arraySize }; + barriers[i].srcAccessMask = 0; + barriers[i].dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT; + } + vkCmdPipelineBarrier( + cmd, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, + 0, 0, nullptr, 0, nullptr, imageCount, barriers.data() + ); + } + ); + + sc->handle = ToHandle( sc ); + { + std::lock_guard lock( g_mutex ); + g_swapchains[sc->handle] = sc; + } + runtime->swapchains.push_back( sc ); + + *swapchain = sc->handle; + Log( + "Created XrSwapchain %ux%u arraySize=%u format=%d (%u images)", sc->width, sc->height, + sc->arraySize, static_cast( sc->format ), imageCount + ); + return XR_SUCCESS; + } + + XrResult XRAPI_CALL DestroySwapchain( XrSwapchain swapchain ) + { + RuntimeSwapchain * sc = GetSwapchain( swapchain ); + if ( sc == nullptr ) + { + return XR_ERROR_HANDLE_INVALID; + } + + RuntimeSession * session = sc->session; + vkDeviceWaitIdle( session->vkDevice ); + for ( size_t i = 0; i < sc->images.size(); ++i ) + { + vkDestroyImage( session->vkDevice, sc->images[i], nullptr ); + vkFreeMemory( session->vkDevice, sc->memories[i], nullptr ); + } + + { + std::lock_guard lock( g_mutex ); + g_swapchains.erase( swapchain ); + auto & list = session->swapchains; + list.erase( std::remove( list.begin(), list.end(), sc ), list.end() ); + } + delete sc; + return XR_SUCCESS; + } + + XrResult XRAPI_CALL EnumerateSwapchainImages( + XrSwapchain swapchain, uint32_t imageCapacityInput, uint32_t * imageCountOutput, + XrSwapchainImageBaseHeader * images + ) + { + RuntimeSwapchain * sc = GetSwapchain( swapchain ); + if ( sc == nullptr || imageCountOutput == nullptr ) + { + return XR_ERROR_VALIDATION_FAILURE; + } + + const uint32_t count = static_cast( sc->images.size() ); + *imageCountOutput = count; + if ( imageCapacityInput == 0 ) + { + return XR_SUCCESS; + } + if ( images == nullptr || imageCapacityInput < count ) + { + return XR_ERROR_SIZE_INSUFFICIENT; + } + + auto * vkImages = reinterpret_cast( images ); + for ( uint32_t i = 0; i < count; ++i ) + { + vkImages[i].image = sc->images[i]; + } + return XR_SUCCESS; + } + + XrResult XRAPI_CALL AcquireSwapchainImage( + XrSwapchain swapchain, const XrSwapchainImageAcquireInfo * /*acquireInfo*/, uint32_t * index + ) + { + RuntimeSwapchain * sc = GetSwapchain( swapchain ); + if ( sc == nullptr || index == nullptr ) + { + return XR_ERROR_VALIDATION_FAILURE; + } + sc->acquiredIndex = static_cast( sc->nextImageIndex ); + sc->nextImageIndex = ( sc->nextImageIndex + 1 ) % static_cast( sc->images.size() ); + *index = static_cast( sc->acquiredIndex ); + return XR_SUCCESS; + } + + XrResult XRAPI_CALL WaitSwapchainImage( + XrSwapchain swapchain, const XrSwapchainImageWaitInfo * /*waitInfo*/ + ) + { + return GetSwapchain( swapchain ) == nullptr ? XR_ERROR_VALIDATION_FAILURE : XR_SUCCESS; + } + + XrResult XRAPI_CALL ReleaseSwapchainImage( + XrSwapchain swapchain, const XrSwapchainImageReleaseInfo * /*releaseInfo*/ + ) + { + RuntimeSwapchain * sc = GetSwapchain( swapchain ); + if ( sc == nullptr ) + { + return XR_ERROR_VALIDATION_FAILURE; + } + if ( sc->acquiredIndex >= 0 ) + { + sc->lastReleasedIndex = sc->acquiredIndex; + } + sc->acquiredIndex = -1; + return XR_SUCCESS; + } + + // ---- frame loop ------------------------------------------------------- + + XrResult XRAPI_CALL WaitFrame( + XrSession session, const XrFrameWaitInfo * /*frameWaitInfo*/, XrFrameState * frameState + ) + { + RuntimeSession * runtime = GetSession( session ); + if ( runtime == nullptr || frameState == nullptr ) + { + return XR_ERROR_VALIDATION_FAILURE; + } + + const int64_t now = NowNs(); + if ( runtime->nextDisplayTime > now ) + { + std::this_thread::sleep_for( std::chrono::nanoseconds( runtime->nextDisplayTime - now ) ); + } + + runtime->predictedDisplayTime = runtime->nextDisplayTime; + runtime->nextDisplayTime += runtime->framePeriodNs; + + frameState->predictedDisplayTime = runtime->predictedDisplayTime; + frameState->predictedDisplayPeriod = runtime->framePeriodNs; + frameState->shouldRender = XR_TRUE; + + // Display work only runs on the window-owning thread; this is a no-op otherwise. + if ( runtime->instance != nullptr && runtime->instance->compositor ) + { + runtime->instance->compositor->Pump( runtime ); + } + return XR_SUCCESS; + } + + XrResult XRAPI_CALL BeginFrame( XrSession session, const XrFrameBeginInfo * /*frameBeginInfo*/ ) + { + RuntimeSession * runtime = GetSession( session ); + if ( runtime == nullptr ) + { + return XR_ERROR_HANDLE_INVALID; + } + runtime->frameBegun = true; + + // The engine calls xrBeginFrame from its main thread, which is the window thread. + if ( runtime->instance != nullptr && runtime->instance->compositor ) + { + runtime->instance->compositor->Pump( runtime ); + } + return XR_SUCCESS; + } + + XrResult XRAPI_CALL EndFrame( XrSession session, const XrFrameEndInfo * frameEndInfo ) + { + RuntimeSession * runtime = GetSession( session ); + if ( runtime == nullptr ) + { + return XR_ERROR_HANDLE_INVALID; + } + runtime->frameBegun = false; + + if ( runtime->instance != nullptr && runtime->instance->compositor ) + { + const XrCompositionLayerProjection * projectionLayer = nullptr; + if ( frameEndInfo != nullptr ) + { + for ( uint32_t i = 0; i < frameEndInfo->layerCount; ++i ) + { + const XrCompositionLayerBaseHeader * base = frameEndInfo->layers[i]; + if ( base != nullptr && base->type == XR_TYPE_COMPOSITION_LAYER_PROJECTION ) + { + projectionLayer = reinterpret_cast( base ); + break; + } + } + } + runtime->instance->compositor->Present( runtime, projectionLayer ); + } + return XR_SUCCESS; + } + + XrResult XRAPI_CALL LocateViews( + XrSession session, const XrViewLocateInfo * /*viewLocateInfo*/, XrViewState * viewState, + uint32_t viewCapacityInput, uint32_t * viewCountOutput, XrView * views + ) + { + RuntimeSession * runtime = GetSession( session ); + if ( runtime == nullptr || viewState == nullptr || viewCountOutput == nullptr ) + { + return XR_ERROR_VALIDATION_FAILURE; + } + + constexpr uint32_t kEyeCount = 2; + *viewCountOutput = kEyeCount; + if ( viewCapacityInput == 0 ) + { + return XR_SUCCESS; + } + if ( views == nullptr || viewCapacityInput < kEyeCount ) + { + return XR_ERROR_SIZE_INSUFFICIENT; + } + + const TrackingState & tracking = GetTracking(); + const XrQuaternionf orientation = GetHeadOrientation(); + const XrVector3f head = GetHeadPosition(); + + // Right vector = yaw-rotated +X. Eye offset along it. + const float rightX = std::cos( tracking.yaw ); + const float rightZ = -std::sin( tracking.yaw ); + const float halfIpd = tracking.ipd * 0.5f; + + // XrFovf stores the tangents of the half-angles. + const SimulatorConfig & config = GetConfig(); + constexpr float deg2rad = kPi / 180.0f; + const float tanLeft = std::tan( config.fovLeftDeg * deg2rad ); + const float tanRight = std::tan( config.fovRightDeg * deg2rad ); + const float tanUp = std::tan( config.fovUpDeg * deg2rad ); + const float tanDown = std::tan( config.fovDownDeg * deg2rad ); + + for ( uint32_t eye = 0; eye < kEyeCount; ++eye ) + { + const float sign = ( eye == 0 ) ? -1.0f : 1.0f; + + views[eye].type = XR_TYPE_VIEW; + views[eye].next = nullptr; + views[eye].pose.orientation = orientation; + views[eye].pose.position = XrVector3f{ + head.x + sign * halfIpd * rightX, + head.y, + head.z + sign * halfIpd * rightZ, + }; + views[eye].fov = XrFovf{ -tanLeft, tanRight, tanUp, -tanDown }; + } + + viewState->viewStateFlags = XR_VIEW_STATE_ORIENTATION_VALID_BIT | + XR_VIEW_STATE_POSITION_VALID_BIT | + XR_VIEW_STATE_ORIENTATION_TRACKED_BIT | + XR_VIEW_STATE_POSITION_TRACKED_BIT; + return XR_SUCCESS; + } + + // ---- paths ------------------------------------------------------------ + + XrResult XRAPI_CALL StringToPath( XrInstance instance, const char * pathString, XrPath * path ) + { + if ( GetInstance( instance ) == nullptr || pathString == nullptr || path == nullptr ) + { + return XR_ERROR_VALIDATION_FAILURE; + } + *path = HashPath( pathString ); + return XR_SUCCESS; + } + + XrResult XRAPI_CALL PathToString( + XrInstance instance, XrPath path, uint32_t bufferCapacityInput, uint32_t * bufferCountOutput, + char * buffer + ) + { + if ( GetInstance( instance ) == nullptr || bufferCountOutput == nullptr ) + { + return XR_ERROR_VALIDATION_FAILURE; + } + + std::string value; + { + std::lock_guard lock( g_mutex ); + const auto it = g_pathStrings.find( path ); + if ( it != g_pathStrings.end() ) + { + value = it->second; + } + } + + const uint32_t required = static_cast( value.size() + 1 ); + *bufferCountOutput = required; + if ( bufferCapacityInput == 0 ) + { + return XR_SUCCESS; + } + if ( buffer == nullptr || bufferCapacityInput < required ) + { + return XR_ERROR_SIZE_INSUFFICIENT; + } + memcpy( buffer, value.c_str(), required ); + return XR_SUCCESS; + } + + // ---- actions ---------------------------------------------------------- + + XrResult XRAPI_CALL CreateActionSet( + XrInstance instance, const XrActionSetCreateInfo * createInfo, XrActionSet * actionSet + ) + { + if ( GetInstance( instance ) == nullptr || createInfo == nullptr || actionSet == nullptr ) + { + return XR_ERROR_VALIDATION_FAILURE; + } + auto * obj = new ActionSetObj(); + obj->instance = GetInstance( instance ); + const XrActionSet handle = ToHandle( obj ); + { + std::lock_guard lock( g_mutex ); + g_actionSets[handle] = obj; + } + *actionSet = handle; + return XR_SUCCESS; + } + + XrResult XRAPI_CALL DestroyActionSet( XrActionSet actionSet ) + { + std::lock_guard lock( g_mutex ); + const auto it = g_actionSets.find( actionSet ); + if ( it == g_actionSets.end() ) + { + return XR_SUCCESS; + } + delete it->second; + g_actionSets.erase( it ); + return XR_SUCCESS; + } + + XrResult XRAPI_CALL CreateAction( + XrActionSet actionSet, const XrActionCreateInfo * createInfo, XrAction * action + ) + { + if ( createInfo == nullptr || action == nullptr ) + { + return XR_ERROR_VALIDATION_FAILURE; + } + auto * obj = new ActionObj(); + obj->set = actionSet; + obj->type = createInfo->actionType; + obj->name = createInfo->actionName; + const XrAction handle = ToHandle( obj ); + { + std::lock_guard lock( g_mutex ); + g_actions[handle] = obj; + } + *action = handle; + return XR_SUCCESS; + } + + XrResult XRAPI_CALL DestroyAction( XrAction action ) + { + std::lock_guard lock( g_mutex ); + const auto it = g_actions.find( action ); + if ( it == g_actions.end() ) + { + return XR_SUCCESS; + } + delete it->second; + g_actions.erase( it ); + return XR_SUCCESS; + } + + XrResult XRAPI_CALL SuggestInteractionProfileBindings( + XrInstance instance, const XrInteractionProfileSuggestedBinding * /*suggestedBindings*/ + ) + { + // Bindings are accepted and ignored; emulated input is provided directly by state queries. + return GetInstance( instance ) == nullptr ? XR_ERROR_VALIDATION_FAILURE : XR_SUCCESS; + } + + XrResult XRAPI_CALL AttachSessionActionSets( + XrSession session, const XrSessionActionSetsAttachInfo * /*attachInfo*/ + ) + { + return GetSession( session ) == nullptr ? XR_ERROR_HANDLE_INVALID : XR_SUCCESS; + } + + XrResult XRAPI_CALL GetCurrentInteractionProfile( + XrSession session, XrPath topLevelUserPath, XrInteractionProfileState * interactionProfile + ) + { + if ( GetSession( session ) == nullptr || interactionProfile == nullptr ) + { + return XR_ERROR_VALIDATION_FAILURE; + } + + // Emulate an Oculus Touch controller for both hands so the app activates that profile and + // wires up the aim poses. + static const XrPath left = HashPath( "/user/hand/left" ); + static const XrPath right = HashPath( "/user/hand/right" ); + if ( topLevelUserPath == left || topLevelUserPath == right ) + { + interactionProfile->interactionProfile = + HashPath( "/interaction_profiles/oculus/touch_controller" ); + } + else + { + interactionProfile->interactionProfile = XR_NULL_PATH; + } + return XR_SUCCESS; + } + + XrResult XRAPI_CALL CreateActionSpace( + XrSession session, const XrActionSpaceCreateInfo * createInfo, XrSpace * space + ) + { + RuntimeSession * runtime = GetSession( session ); + if ( runtime == nullptr || createInfo == nullptr || space == nullptr ) + { + return XR_ERROR_VALIDATION_FAILURE; + } + auto * newSpace = new RuntimeSpace(); + newSpace->session = runtime; + newSpace->refType = XR_REFERENCE_SPACE_TYPE_LOCAL; + newSpace->actionSpace = true; + newSpace->action = createInfo->action; + newSpace->subactionPath = createInfo->subactionPath; + newSpace->poseInActionSpace = createInfo->poseInActionSpace; + newSpace->handle = ToHandle( newSpace ); + newSpace->valid = true; + { + std::lock_guard lock( g_mutex ); + g_spaces[newSpace->handle] = newSpace; + } + *space = newSpace->handle; + return XR_SUCCESS; + } + + XrResult XRAPI_CALL LocateSpace( + XrSpace space, XrSpace /*baseSpace*/, XrTime /*time*/, XrSpaceLocation * location + ) + { + RuntimeSpace * spaceState = GetSpace( space ); + if ( spaceState == nullptr || location == nullptr ) + { + return XR_ERROR_VALIDATION_FAILURE; + } + + if ( spaceState->actionSpace ) + { + int hand = HandFromSubaction( spaceState->subactionPath ); + if ( hand < 0 ) + { + hand = 0; + } + const ActionObj * action = GetAction( spaceState->action ); + const ControlKind kind = + action != nullptr ? ClassifyAction( action->name, action->type ) : ControlKind::Other; + location->pose = ( kind == ControlKind::PoseGrip ) ? g_input.hands[hand].gripPose + : g_input.hands[hand].aimPose; + } + else + { + location->pose.orientation = XrQuaternionf{ 0.0f, 0.0f, 0.0f, 1.0f }; + location->pose.position = XrVector3f{ 0.0f, 0.0f, 0.0f }; + } + + location->locationFlags = XR_SPACE_LOCATION_POSITION_VALID_BIT | + XR_SPACE_LOCATION_ORIENTATION_VALID_BIT | + XR_SPACE_LOCATION_POSITION_TRACKED_BIT | + XR_SPACE_LOCATION_ORIENTATION_TRACKED_BIT; + return XR_SUCCESS; + } + + XrResult XRAPI_CALL SyncActions( XrSession session, const XrActionsSyncInfo * /*syncInfo*/ ) + { + return GetSession( session ) == nullptr ? XR_ERROR_HANDLE_INVALID : XR_SUCCESS; + } + + XrResult XRAPI_CALL GetActionStateBoolean( + XrSession session, const XrActionStateGetInfo * getInfo, XrActionStateBoolean * state + ) + { + if ( GetSession( session ) == nullptr || getInfo == nullptr || state == nullptr ) + { + return XR_ERROR_VALIDATION_FAILURE; + } + + int hand = HandFromSubaction( getInfo->subactionPath ); + if ( hand < 0 ) + { + hand = 0; + } + const ActionObj * action = GetAction( getInfo->action ); + const ControlKind kind = + action != nullptr ? ClassifyAction( action->name, action->type ) : ControlKind::Other; + const ControllerState & controller = g_input.hands[hand]; + + bool value = false; + switch ( kind ) + { + case ControlKind::Trigger: value = controller.trigger > 0.5f; break; + case ControlKind::Grip: value = controller.grip > 0.5f; break; + case ControlKind::StickClick: value = controller.stickClick; break; + case ControlKind::ButtonA: value = controller.a; break; + case ControlKind::ButtonB: value = controller.b; break; + case ControlKind::ButtonX: value = controller.x; break; + case ControlKind::ButtonY: value = controller.y; break; + case ControlKind::Menu: value = controller.menu; break; + case ControlKind::Touch: value = controller.touch; break; + default: break; + } + + state->isActive = XR_TRUE; + state->currentState = value ? XR_TRUE : XR_FALSE; + state->changedSinceLastSync = XR_FALSE; + state->lastChangeTime = 0; + return XR_SUCCESS; + } + + XrResult XRAPI_CALL GetActionStateFloat( + XrSession session, const XrActionStateGetInfo * getInfo, XrActionStateFloat * state + ) + { + if ( GetSession( session ) == nullptr || getInfo == nullptr || state == nullptr ) + { + return XR_ERROR_VALIDATION_FAILURE; + } + + int hand = HandFromSubaction( getInfo->subactionPath ); + if ( hand < 0 ) + { + hand = 0; + } + const ActionObj * action = GetAction( getInfo->action ); + const ControlKind kind = + action != nullptr ? ClassifyAction( action->name, action->type ) : ControlKind::Other; + const ControllerState & controller = g_input.hands[hand]; + + float value = 0.0f; + if ( kind == ControlKind::Trigger ) + { + value = controller.trigger; + } + else if ( kind == ControlKind::Grip ) + { + value = controller.grip; + } + + state->isActive = XR_TRUE; + state->currentState = value; + state->changedSinceLastSync = XR_FALSE; + state->lastChangeTime = 0; + return XR_SUCCESS; + } + + XrResult XRAPI_CALL GetActionStateVector2f( + XrSession session, const XrActionStateGetInfo * getInfo, XrActionStateVector2f * state + ) + { + if ( GetSession( session ) == nullptr || getInfo == nullptr || state == nullptr ) + { + return XR_ERROR_VALIDATION_FAILURE; + } + + int hand = HandFromSubaction( getInfo->subactionPath ); + if ( hand < 0 ) + { + hand = 0; + } + const ActionObj * action = GetAction( getInfo->action ); + const ControlKind kind = + action != nullptr ? ClassifyAction( action->name, action->type ) : ControlKind::Other; + const ControllerState & controller = g_input.hands[hand]; + + state->isActive = XR_TRUE; + state->currentState = kind == ControlKind::Thumbstick ? controller.thumbstick + : XrVector2f{ 0.0f, 0.0f }; + state->changedSinceLastSync = XR_FALSE; + state->lastChangeTime = 0; + return XR_SUCCESS; + } + + XrResult XRAPI_CALL GetActionStatePose( + XrSession session, const XrActionStateGetInfo * /*getInfo*/, XrActionStatePose * state + ) + { + if ( GetSession( session ) == nullptr || state == nullptr ) + { + return XR_ERROR_VALIDATION_FAILURE; + } + state->isActive = XR_TRUE; + return XR_SUCCESS; + } + + XrResult XRAPI_CALL ApplyHapticFeedback( + XrSession session, const XrHapticActionInfo * /*hapticActionInfo*/, + const XrHapticBaseHeader * /*hapticFeedback*/ + ) + { + return GetSession( session ) == nullptr ? XR_ERROR_HANDLE_INVALID : XR_SUCCESS; + } + + XrResult XRAPI_CALL StopHapticFeedback( + XrSession session, const XrHapticActionInfo * /*hapticActionInfo*/ + ) + { + return GetSession( session ) == nullptr ? XR_ERROR_HANDLE_INVALID : XR_SUCCESS; + } +} // namespace xrsim diff --git a/src/Runtime.h b/src/Runtime.h new file mode 100644 index 0000000..de550f1 --- /dev/null +++ b/src/Runtime.h @@ -0,0 +1,392 @@ +#pragma once + +// Order matters: windows.h and vulkan.h must be visible before +// openxr_platform.h when the corresponding XR_USE_* macros are defined. + +#ifdef _WIN32 +# ifndef WIN32_LEAN_AND_MEAN +# define WIN32_LEAN_AND_MEAN +# endif +# ifndef NOMINMAX +# define NOMINMAX +# endif +# include +# include // IUnknown, used by XR_MSFT_* Win32 platform structs +#endif + +#include + +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +namespace xrsim +{ + class Compositor; + struct RuntimeInstance; + struct RuntimeSession; + struct RuntimeSwapchain; + struct RuntimeSpace; + + // ----------------------------------------------------------------------- + // Simulation state + // ----------------------------------------------------------------------- + + struct TrackingState + { + float yaw = 0.0f; // radians, positive = look left + float pitch = 0.0f; // radians, positive = look up + float posX = 0.0f; + float posY = 0.0f; + float posZ = 0.0f; + float ipd = 0.064f; // interpupillary distance in metres + }; + + TrackingState & GetTracking(); + + /** + * @brief Emulated state of one controller. + */ + struct ControllerState + { + bool active = false; + XrPosef gripPose{ { 0.0f, 0.0f, 0.0f, 1.0f }, { 0.0f, 0.0f, 0.0f } }; + XrPosef aimPose{ { 0.0f, 0.0f, 0.0f, 1.0f }, { 0.0f, 0.0f, 0.0f } }; + float trigger = 0.0f; + float grip = 0.0f; + XrVector2f thumbstick{ 0.0f, 0.0f }; + bool menu = false; + bool a = false; + bool b = false; + bool x = false; + bool y = false; + bool stickClick = false; + bool touch = false; + }; + + /** + * @brief Emulated input state for the simulator (index 0 = left, 1 = right). + */ + struct InputState + { + ControllerState hands[2]; + }; + + InputState & GetInputState(); + + /** @brief Head orientation derived from TrackingState (identity at rest). */ + XrQuaternionf GetHeadOrientation(); + + /** @brief Head position derived from TrackingState. */ + XrVector3f GetHeadPosition(); + + /** @brief Rotates a vector by a quaternion. */ + XrVector3f RotateByQuaternion( const XrQuaternionf & q, const XrVector3f & v ); + + /** @brief Interns a path string to its stable XrPath (and remembers the string). */ + XrPath HashPath( const char * path ); + + // ----------------------------------------------------------------------- + // Runtime objects + // ----------------------------------------------------------------------- + + struct RuntimeInstance + { + XrInstance handle = XR_NULL_HANDLE; + std::string applicationName; + std::string engineName; + std::vector enabledExtensions; + + PFN_vkGetInstanceProcAddr vkGetInstanceProcAddr = nullptr; + VkInstance vkInstance = VK_NULL_HANDLE; + VkPhysicalDevice vkPhysicalDevice = VK_NULL_HANDLE; + VkDevice vkDevice = VK_NULL_HANDLE; + + std::unique_ptr compositor; + + // Event queue (session-state changes). + std::deque events; + + bool valid = false; + }; + + struct RuntimeSwapchain + { + XrSwapchain handle = XR_NULL_HANDLE; + RuntimeSession * session = nullptr; + XrSwapchainCreateInfo createInfo{}; + + uint32_t width = 0; + uint32_t height = 0; + uint32_t arraySize = 0; + VkFormat format = VK_FORMAT_UNDEFINED; + + std::vector images; + std::vector memories; + + uint32_t nextImageIndex = 0; + int32_t acquiredIndex = -1; + int32_t lastReleasedIndex = 0; + bool valid = false; + }; + + struct RuntimeSpace + { + XrSpace handle = XR_NULL_HANDLE; + RuntimeSession * session = nullptr; + XrReferenceSpaceType refType = XR_REFERENCE_SPACE_TYPE_LOCAL; + bool actionSpace = false; + XrAction action = XR_NULL_HANDLE; + XrPath subactionPath = XR_NULL_PATH; + XrPosef poseInActionSpace{}; + bool valid = false; + }; + + struct RuntimeSession + { + XrSession handle = XR_NULL_HANDLE; + RuntimeInstance * instance = nullptr; + XrSystemId systemId = XR_NULL_SYSTEM_ID; + + VkInstance vkInstance = VK_NULL_HANDLE; + VkPhysicalDevice vkPhysicalDevice = VK_NULL_HANDLE; + VkDevice vkDevice = VK_NULL_HANDLE; + uint32_t queueFamilyIndex = 0; + uint32_t queueIndex = 0; + VkQueue queue = VK_NULL_HANDLE; + VkCommandPool commandPool = VK_NULL_HANDLE; + + XrSessionState state = XR_SESSION_STATE_UNKNOWN; + bool running = false; + + // Frame timing. + int64_t nextDisplayTime = 0; + int64_t framePeriodNs = 0; + XrTime predictedDisplayTime = 0; + bool frameBegun = false; + + // Swapchains created for this session. + std::vector swapchains; + + bool valid = false; + }; + + RuntimeInstance * GetInstance( XrInstance handle ); + RuntimeSession * GetSession( XrSession handle ); + RuntimeSwapchain * GetSwapchain( XrSwapchain handle ); + RuntimeSpace * GetSpace( XrSpace handle ); + + /** + * @brief Resolves a swapchain sub-image reference to a Vulkan image + layer. + */ + bool ResolveSubImage( + XrSwapchain swapchain, const XrSwapchainSubImage & subImage, VkImage * outImage, + uint32_t * outArrayLayer, uint32_t * outWidth, uint32_t * outHeight + ); + + /** @brief Pushes a session-state-changed event onto the instance's queue. */ + void PushSessionStateEvent( XrInstance instance, XrSession session, XrSessionState state ); + + /** + * @brief The single dispatch entry point handed to the loader. + */ + XrResult XRAPI_CALL GetInstanceProcAddr( + XrInstance instance, const char * name, PFN_xrVoidFunction * function + ); + + // ---- global functions ------------------------------------------------- + + XrResult XRAPI_CALL EnumerateApiLayerProperties( + uint32_t propertyCapacityInput, uint32_t * propertyCountOutput, + XrApiLayerProperties * properties + ); + + XrResult XRAPI_CALL EnumerateInstanceExtensionProperties( + const char * layerName, uint32_t propertyCapacityInput, uint32_t * propertyCountOutput, + XrExtensionProperties * properties + ); + + XrResult XRAPI_CALL CreateInstance( + const XrInstanceCreateInfo * createInfo, XrInstance * instance + ); + + // ---- instance functions ----------------------------------------------- + + XrResult XRAPI_CALL DestroyInstance( XrInstance instance ); + + XrResult XRAPI_CALL GetInstanceProperties( + XrInstance instance, XrInstanceProperties * properties + ); + + XrResult XRAPI_CALL GetSystem( + XrInstance instance, const XrSystemGetInfo * getInfo, XrSystemId * systemId + ); + + XrResult XRAPI_CALL GetSystemProperties( + XrInstance instance, XrSystemId systemId, XrSystemProperties * properties + ); + + XrResult XRAPI_CALL EnumerateViewConfigurations( + XrInstance instance, XrSystemId systemId, uint32_t viewConfigurationTypeCapacityInput, + uint32_t * viewConfigurationTypeCountOutput, XrViewConfigurationType * viewConfigurationTypes + ); + + XrResult XRAPI_CALL EnumerateViewConfigurationViews( + XrInstance instance, XrSystemId systemId, XrViewConfigurationType viewConfigurationType, + uint32_t viewCapacityInput, uint32_t * viewCountOutput, XrViewConfigurationView * views + ); + + XrResult XRAPI_CALL EnumerateEnvironmentBlendModes( + XrInstance instance, XrSystemId systemId, XrViewConfigurationType viewConfigurationType, + uint32_t environmentBlendModeCapacityInput, uint32_t * environmentBlendModeCountOutput, + XrEnvironmentBlendMode * environmentBlendModes + ); + + XrResult XRAPI_CALL EnumerateSwapchainFormats( + XrSession session, uint32_t formatCapacityInput, uint32_t * formatCountOutput, + int64_t * formats + ); + + // ---- XR_KHR_vulkan_enable2 -------------------------------------------- + + XrResult XRAPI_CALL GetVulkanGraphicsRequirements2KHR( + XrInstance instance, XrSystemId systemId, + XrGraphicsRequirementsVulkanKHR * graphicsRequirements + ); + + XrResult XRAPI_CALL CreateVulkanInstanceKHR( + XrInstance instance, const XrVulkanInstanceCreateInfoKHR * createInfo, + VkInstance * vulkanInstance, VkResult * vulkanResult + ); + + XrResult XRAPI_CALL GetVulkanGraphicsDevice2KHR( + XrInstance instance, const XrVulkanGraphicsDeviceGetInfoKHR * getInfo, + VkPhysicalDevice * vulkanPhysicalDevice + ); + + XrResult XRAPI_CALL CreateVulkanDeviceKHR( + XrInstance instance, const XrVulkanDeviceCreateInfoKHR * createInfo, VkDevice * vulkanDevice, + VkResult * vulkanResult + ); + + // ---- session ---------------------------------------------------------- + + XrResult XRAPI_CALL CreateSession( + XrInstance instance, const XrSessionCreateInfo * createInfo, XrSession * session + ); + + XrResult XRAPI_CALL DestroySession( XrSession session ); + + XrResult XRAPI_CALL BeginSession( XrSession session, const XrSessionBeginInfo * beginInfo ); + + XrResult XRAPI_CALL EndSession( XrSession session ); + + XrResult XRAPI_CALL PollEvent( XrInstance instance, XrEventDataBuffer * eventData ); + + XrResult XRAPI_CALL CreateReferenceSpace( + XrSession session, const XrReferenceSpaceCreateInfo * createInfo, XrSpace * space + ); + + XrResult XRAPI_CALL DestroySpace( XrSpace space ); + + // ---- swapchain -------------------------------------------------------- + + XrResult XRAPI_CALL CreateSwapchain( + XrSession session, const XrSwapchainCreateInfo * createInfo, XrSwapchain * swapchain + ); + + XrResult XRAPI_CALL DestroySwapchain( XrSwapchain swapchain ); + + XrResult XRAPI_CALL EnumerateSwapchainImages( + XrSwapchain swapchain, uint32_t imageCapacityInput, uint32_t * imageCountOutput, + XrSwapchainImageBaseHeader * images + ); + + XrResult XRAPI_CALL AcquireSwapchainImage( + XrSwapchain swapchain, const XrSwapchainImageAcquireInfo * acquireInfo, uint32_t * index + ); + + XrResult XRAPI_CALL WaitSwapchainImage( + XrSwapchain swapchain, const XrSwapchainImageWaitInfo * waitInfo + ); + + XrResult XRAPI_CALL ReleaseSwapchainImage( + XrSwapchain swapchain, const XrSwapchainImageReleaseInfo * releaseInfo + ); + + // ---- frame loop ------------------------------------------------------- + + XrResult XRAPI_CALL WaitFrame( + XrSession session, const XrFrameWaitInfo * frameWaitInfo, XrFrameState * frameState + ); + + XrResult XRAPI_CALL BeginFrame( XrSession session, const XrFrameBeginInfo * frameBeginInfo ); + + XrResult XRAPI_CALL EndFrame( XrSession session, const XrFrameEndInfo * frameEndInfo ); + + XrResult XRAPI_CALL LocateViews( + XrSession session, const XrViewLocateInfo * viewLocateInfo, XrViewState * viewState, + uint32_t viewCapacityInput, uint32_t * viewCountOutput, XrView * views + ); + + // ---- paths ------------------------------------------------------------ + + XrResult XRAPI_CALL StringToPath( XrInstance instance, const char * pathString, XrPath * path ); + XrResult XRAPI_CALL PathToString( + XrInstance instance, XrPath path, uint32_t bufferCapacityInput, uint32_t * bufferCountOutput, + char * buffer + ); + + // ---- actions ---------------------------------------------------------- + + XrResult XRAPI_CALL CreateActionSet( + XrInstance instance, const XrActionSetCreateInfo * createInfo, XrActionSet * actionSet + ); + XrResult XRAPI_CALL DestroyActionSet( XrActionSet actionSet ); + XrResult XRAPI_CALL CreateAction( + XrActionSet actionSet, const XrActionCreateInfo * createInfo, XrAction * action + ); + XrResult XRAPI_CALL DestroyAction( XrAction action ); + XrResult XRAPI_CALL SuggestInteractionProfileBindings( + XrInstance instance, const XrInteractionProfileSuggestedBinding * suggestedBindings + ); + XrResult XRAPI_CALL AttachSessionActionSets( + XrSession session, const XrSessionActionSetsAttachInfo * attachInfo + ); + XrResult XRAPI_CALL GetCurrentInteractionProfile( + XrSession session, XrPath topLevelUserPath, XrInteractionProfileState * interactionProfile + ); + XrResult XRAPI_CALL CreateActionSpace( + XrSession session, const XrActionSpaceCreateInfo * createInfo, XrSpace * space + ); + XrResult XRAPI_CALL LocateSpace( + XrSpace space, XrSpace baseSpace, XrTime time, XrSpaceLocation * location + ); + XrResult XRAPI_CALL SyncActions( XrSession session, const XrActionsSyncInfo * syncInfo ); + XrResult XRAPI_CALL GetActionStateBoolean( + XrSession session, const XrActionStateGetInfo * getInfo, XrActionStateBoolean * state + ); + XrResult XRAPI_CALL GetActionStateFloat( + XrSession session, const XrActionStateGetInfo * getInfo, XrActionStateFloat * state + ); + XrResult XRAPI_CALL GetActionStateVector2f( + XrSession session, const XrActionStateGetInfo * getInfo, XrActionStateVector2f * state + ); + XrResult XRAPI_CALL GetActionStatePose( + XrSession session, const XrActionStateGetInfo * getInfo, XrActionStatePose * state + ); + XrResult XRAPI_CALL ApplyHapticFeedback( + XrSession session, const XrHapticActionInfo * hapticActionInfo, + const XrHapticBaseHeader * hapticFeedback + ); + XrResult XRAPI_CALL StopHapticFeedback( + XrSession session, const XrHapticActionInfo * hapticActionInfo + ); +} // namespace xrsim diff --git a/third_party/openxr/openxr.h b/third_party/openxr/openxr.h new file mode 100644 index 0000000..5d953fb --- /dev/null +++ b/third_party/openxr/openxr.h @@ -0,0 +1,6135 @@ +#ifndef OPENXR_H_ +#define OPENXR_H_ 1 + +/* +** Copyright 2017-2023 The Khronos Group Inc. +** +** SPDX-License-Identifier: Apache-2.0 OR MIT +*/ + +/* +** This header is generated from the Khronos OpenXR XML API Registry. +** +*/ + + +#ifdef __cplusplus +extern "C" { +#endif + + + +#define XR_VERSION_1_0 1 +#include "openxr_platform_defines.h" +#define XR_MAKE_VERSION(major, minor, patch) \ + ((((major) & 0xffffULL) << 48) | (((minor) & 0xffffULL) << 32) | ((patch) & 0xffffffffULL)) + +// OpenXR current version number. +#define XR_CURRENT_API_VERSION XR_MAKE_VERSION(1, 0, 28) + +#define XR_VERSION_MAJOR(version) (uint16_t)(((uint64_t)(version) >> 48)& 0xffffULL) +#define XR_VERSION_MINOR(version) (uint16_t)(((uint64_t)(version) >> 32) & 0xffffULL) +#define XR_VERSION_PATCH(version) (uint32_t)((uint64_t)(version) & 0xffffffffULL) + +#define XR_MIN_COMPOSITION_LAYERS_SUPPORTED 16 + + +#if !defined(XR_NULL_HANDLE) +#if (XR_PTR_SIZE == 8) && XR_CPP_NULLPTR_SUPPORTED + #define XR_NULL_HANDLE nullptr +#else + #define XR_NULL_HANDLE 0 +#endif +#endif + + + +#define XR_NULL_SYSTEM_ID 0 + + +#define XR_NULL_PATH 0 + + +#define XR_SUCCEEDED(result) ((result) >= 0) + + +#define XR_FAILED(result) ((result) < 0) + + +#define XR_UNQUALIFIED_SUCCESS(result) ((result) == 0) + + +#define XR_NO_DURATION 0 + + +#define XR_INFINITE_DURATION 0x7fffffffffffffffLL + + +#define XR_MIN_HAPTIC_DURATION -1 + + +#define XR_FREQUENCY_UNSPECIFIED 0 + + +#define XR_MAX_EVENT_DATA_SIZE sizeof(XrEventDataBuffer) + + +#define XR_EXTENSION_ENUM_BASE 1000000000 + + +#define XR_EXTENSION_ENUM_STRIDE 1000 + + +#if !defined(XR_MAY_ALIAS) +#if defined(__clang__) || (defined(__GNUC__) && (__GNUC__ > 4)) +#define XR_MAY_ALIAS __attribute__((__may_alias__)) +#else +#define XR_MAY_ALIAS +#endif +#endif + + +#if !defined(XR_DEFINE_HANDLE) +#if (XR_PTR_SIZE == 8) + #define XR_DEFINE_HANDLE(object) typedef struct object##_T* object; +#else + #define XR_DEFINE_HANDLE(object) typedef uint64_t object; +#endif +#endif + + + +#if !defined(XR_DEFINE_ATOM) + #define XR_DEFINE_ATOM(object) typedef uint64_t object; +#endif + + +typedef uint64_t XrVersion; +typedef uint64_t XrFlags64; +XR_DEFINE_ATOM(XrSystemId) +typedef uint32_t XrBool32; +XR_DEFINE_ATOM(XrPath) +typedef int64_t XrTime; +typedef int64_t XrDuration; +XR_DEFINE_HANDLE(XrInstance) +XR_DEFINE_HANDLE(XrSession) +XR_DEFINE_HANDLE(XrSpace) +XR_DEFINE_HANDLE(XrAction) +XR_DEFINE_HANDLE(XrSwapchain) +XR_DEFINE_HANDLE(XrActionSet) +#define XR_TRUE 1 +#define XR_FALSE 0 +#define XR_MAX_EXTENSION_NAME_SIZE 128 +#define XR_MAX_API_LAYER_NAME_SIZE 256 +#define XR_MAX_API_LAYER_DESCRIPTION_SIZE 256 +#define XR_MAX_SYSTEM_NAME_SIZE 256 +#define XR_MAX_APPLICATION_NAME_SIZE 128 +#define XR_MAX_ENGINE_NAME_SIZE 128 +#define XR_MAX_RUNTIME_NAME_SIZE 128 +#define XR_MAX_PATH_LENGTH 256 +#define XR_MAX_STRUCTURE_NAME_SIZE 64 +#define XR_MAX_RESULT_STRING_SIZE 64 +#define XR_MAX_ACTION_SET_NAME_SIZE 64 +#define XR_MAX_LOCALIZED_ACTION_SET_NAME_SIZE 128 +#define XR_MAX_ACTION_NAME_SIZE 64 +#define XR_MAX_LOCALIZED_ACTION_NAME_SIZE 128 + +typedef enum XrResult { + XR_SUCCESS = 0, + XR_TIMEOUT_EXPIRED = 1, + XR_SESSION_LOSS_PENDING = 3, + XR_EVENT_UNAVAILABLE = 4, + XR_SPACE_BOUNDS_UNAVAILABLE = 7, + XR_SESSION_NOT_FOCUSED = 8, + XR_FRAME_DISCARDED = 9, + XR_ERROR_VALIDATION_FAILURE = -1, + XR_ERROR_RUNTIME_FAILURE = -2, + XR_ERROR_OUT_OF_MEMORY = -3, + XR_ERROR_API_VERSION_UNSUPPORTED = -4, + XR_ERROR_INITIALIZATION_FAILED = -6, + XR_ERROR_FUNCTION_UNSUPPORTED = -7, + XR_ERROR_FEATURE_UNSUPPORTED = -8, + XR_ERROR_EXTENSION_NOT_PRESENT = -9, + XR_ERROR_LIMIT_REACHED = -10, + XR_ERROR_SIZE_INSUFFICIENT = -11, + XR_ERROR_HANDLE_INVALID = -12, + XR_ERROR_INSTANCE_LOST = -13, + XR_ERROR_SESSION_RUNNING = -14, + XR_ERROR_SESSION_NOT_RUNNING = -16, + XR_ERROR_SESSION_LOST = -17, + XR_ERROR_SYSTEM_INVALID = -18, + XR_ERROR_PATH_INVALID = -19, + XR_ERROR_PATH_COUNT_EXCEEDED = -20, + XR_ERROR_PATH_FORMAT_INVALID = -21, + XR_ERROR_PATH_UNSUPPORTED = -22, + XR_ERROR_LAYER_INVALID = -23, + XR_ERROR_LAYER_LIMIT_EXCEEDED = -24, + XR_ERROR_SWAPCHAIN_RECT_INVALID = -25, + XR_ERROR_SWAPCHAIN_FORMAT_UNSUPPORTED = -26, + XR_ERROR_ACTION_TYPE_MISMATCH = -27, + XR_ERROR_SESSION_NOT_READY = -28, + XR_ERROR_SESSION_NOT_STOPPING = -29, + XR_ERROR_TIME_INVALID = -30, + XR_ERROR_REFERENCE_SPACE_UNSUPPORTED = -31, + XR_ERROR_FILE_ACCESS_ERROR = -32, + XR_ERROR_FILE_CONTENTS_INVALID = -33, + XR_ERROR_FORM_FACTOR_UNSUPPORTED = -34, + XR_ERROR_FORM_FACTOR_UNAVAILABLE = -35, + XR_ERROR_API_LAYER_NOT_PRESENT = -36, + XR_ERROR_CALL_ORDER_INVALID = -37, + XR_ERROR_GRAPHICS_DEVICE_INVALID = -38, + XR_ERROR_POSE_INVALID = -39, + XR_ERROR_INDEX_OUT_OF_RANGE = -40, + XR_ERROR_VIEW_CONFIGURATION_TYPE_UNSUPPORTED = -41, + XR_ERROR_ENVIRONMENT_BLEND_MODE_UNSUPPORTED = -42, + XR_ERROR_NAME_DUPLICATED = -44, + XR_ERROR_NAME_INVALID = -45, + XR_ERROR_ACTIONSET_NOT_ATTACHED = -46, + XR_ERROR_ACTIONSETS_ALREADY_ATTACHED = -47, + XR_ERROR_LOCALIZED_NAME_DUPLICATED = -48, + XR_ERROR_LOCALIZED_NAME_INVALID = -49, + XR_ERROR_GRAPHICS_REQUIREMENTS_CALL_MISSING = -50, + XR_ERROR_RUNTIME_UNAVAILABLE = -51, + XR_ERROR_ANDROID_THREAD_SETTINGS_ID_INVALID_KHR = -1000003000, + XR_ERROR_ANDROID_THREAD_SETTINGS_FAILURE_KHR = -1000003001, + XR_ERROR_CREATE_SPATIAL_ANCHOR_FAILED_MSFT = -1000039001, + XR_ERROR_SECONDARY_VIEW_CONFIGURATION_TYPE_NOT_ENABLED_MSFT = -1000053000, + XR_ERROR_CONTROLLER_MODEL_KEY_INVALID_MSFT = -1000055000, + XR_ERROR_REPROJECTION_MODE_UNSUPPORTED_MSFT = -1000066000, + XR_ERROR_COMPUTE_NEW_SCENE_NOT_COMPLETED_MSFT = -1000097000, + XR_ERROR_SCENE_COMPONENT_ID_INVALID_MSFT = -1000097001, + XR_ERROR_SCENE_COMPONENT_TYPE_MISMATCH_MSFT = -1000097002, + XR_ERROR_SCENE_MESH_BUFFER_ID_INVALID_MSFT = -1000097003, + XR_ERROR_SCENE_COMPUTE_FEATURE_INCOMPATIBLE_MSFT = -1000097004, + XR_ERROR_SCENE_COMPUTE_CONSISTENCY_MISMATCH_MSFT = -1000097005, + XR_ERROR_DISPLAY_REFRESH_RATE_UNSUPPORTED_FB = -1000101000, + XR_ERROR_COLOR_SPACE_UNSUPPORTED_FB = -1000108000, + XR_ERROR_SPACE_COMPONENT_NOT_SUPPORTED_FB = -1000113000, + XR_ERROR_SPACE_COMPONENT_NOT_ENABLED_FB = -1000113001, + XR_ERROR_SPACE_COMPONENT_STATUS_PENDING_FB = -1000113002, + XR_ERROR_SPACE_COMPONENT_STATUS_ALREADY_SET_FB = -1000113003, + XR_ERROR_UNEXPECTED_STATE_PASSTHROUGH_FB = -1000118000, + XR_ERROR_FEATURE_ALREADY_CREATED_PASSTHROUGH_FB = -1000118001, + XR_ERROR_FEATURE_REQUIRED_PASSTHROUGH_FB = -1000118002, + XR_ERROR_NOT_PERMITTED_PASSTHROUGH_FB = -1000118003, + XR_ERROR_INSUFFICIENT_RESOURCES_PASSTHROUGH_FB = -1000118004, + XR_ERROR_UNKNOWN_PASSTHROUGH_FB = -1000118050, + XR_ERROR_RENDER_MODEL_KEY_INVALID_FB = -1000119000, + XR_RENDER_MODEL_UNAVAILABLE_FB = 1000119020, + XR_ERROR_MARKER_NOT_TRACKED_VARJO = -1000124000, + XR_ERROR_MARKER_ID_INVALID_VARJO = -1000124001, + XR_ERROR_SPATIAL_ANCHOR_NAME_NOT_FOUND_MSFT = -1000142001, + XR_ERROR_SPATIAL_ANCHOR_NAME_INVALID_MSFT = -1000142002, + XR_ERROR_SPACE_MAPPING_INSUFFICIENT_FB = -1000169000, + XR_ERROR_SPACE_LOCALIZATION_FAILED_FB = -1000169001, + XR_ERROR_SPACE_NETWORK_TIMEOUT_FB = -1000169002, + XR_ERROR_SPACE_NETWORK_REQUEST_FAILED_FB = -1000169003, + XR_ERROR_SPACE_CLOUD_STORAGE_DISABLED_FB = -1000169004, + XR_ERROR_PASSTHROUGH_COLOR_LUT_BUFFER_SIZE_MISMATCH_META = -1000266000, + XR_ERROR_HINT_ALREADY_SET_QCOM = -1000306000, + XR_ERROR_SPACE_NOT_LOCATABLE_EXT = -1000429000, + XR_ERROR_PLANE_DETECTION_PERMISSION_DENIED_EXT = -1000429001, + XR_RESULT_MAX_ENUM = 0x7FFFFFFF +} XrResult; + +typedef enum XrStructureType { + XR_TYPE_UNKNOWN = 0, + XR_TYPE_API_LAYER_PROPERTIES = 1, + XR_TYPE_EXTENSION_PROPERTIES = 2, + XR_TYPE_INSTANCE_CREATE_INFO = 3, + XR_TYPE_SYSTEM_GET_INFO = 4, + XR_TYPE_SYSTEM_PROPERTIES = 5, + XR_TYPE_VIEW_LOCATE_INFO = 6, + XR_TYPE_VIEW = 7, + XR_TYPE_SESSION_CREATE_INFO = 8, + XR_TYPE_SWAPCHAIN_CREATE_INFO = 9, + XR_TYPE_SESSION_BEGIN_INFO = 10, + XR_TYPE_VIEW_STATE = 11, + XR_TYPE_FRAME_END_INFO = 12, + XR_TYPE_HAPTIC_VIBRATION = 13, + XR_TYPE_EVENT_DATA_BUFFER = 16, + XR_TYPE_EVENT_DATA_INSTANCE_LOSS_PENDING = 17, + XR_TYPE_EVENT_DATA_SESSION_STATE_CHANGED = 18, + XR_TYPE_ACTION_STATE_BOOLEAN = 23, + XR_TYPE_ACTION_STATE_FLOAT = 24, + XR_TYPE_ACTION_STATE_VECTOR2F = 25, + XR_TYPE_ACTION_STATE_POSE = 27, + XR_TYPE_ACTION_SET_CREATE_INFO = 28, + XR_TYPE_ACTION_CREATE_INFO = 29, + XR_TYPE_INSTANCE_PROPERTIES = 32, + XR_TYPE_FRAME_WAIT_INFO = 33, + XR_TYPE_COMPOSITION_LAYER_PROJECTION = 35, + XR_TYPE_COMPOSITION_LAYER_QUAD = 36, + XR_TYPE_REFERENCE_SPACE_CREATE_INFO = 37, + XR_TYPE_ACTION_SPACE_CREATE_INFO = 38, + XR_TYPE_EVENT_DATA_REFERENCE_SPACE_CHANGE_PENDING = 40, + XR_TYPE_VIEW_CONFIGURATION_VIEW = 41, + XR_TYPE_SPACE_LOCATION = 42, + XR_TYPE_SPACE_VELOCITY = 43, + XR_TYPE_FRAME_STATE = 44, + XR_TYPE_VIEW_CONFIGURATION_PROPERTIES = 45, + XR_TYPE_FRAME_BEGIN_INFO = 46, + XR_TYPE_COMPOSITION_LAYER_PROJECTION_VIEW = 48, + XR_TYPE_EVENT_DATA_EVENTS_LOST = 49, + XR_TYPE_INTERACTION_PROFILE_SUGGESTED_BINDING = 51, + XR_TYPE_EVENT_DATA_INTERACTION_PROFILE_CHANGED = 52, + XR_TYPE_INTERACTION_PROFILE_STATE = 53, + XR_TYPE_SWAPCHAIN_IMAGE_ACQUIRE_INFO = 55, + XR_TYPE_SWAPCHAIN_IMAGE_WAIT_INFO = 56, + XR_TYPE_SWAPCHAIN_IMAGE_RELEASE_INFO = 57, + XR_TYPE_ACTION_STATE_GET_INFO = 58, + XR_TYPE_HAPTIC_ACTION_INFO = 59, + XR_TYPE_SESSION_ACTION_SETS_ATTACH_INFO = 60, + XR_TYPE_ACTIONS_SYNC_INFO = 61, + XR_TYPE_BOUND_SOURCES_FOR_ACTION_ENUMERATE_INFO = 62, + XR_TYPE_INPUT_SOURCE_LOCALIZED_NAME_GET_INFO = 63, + XR_TYPE_COMPOSITION_LAYER_CUBE_KHR = 1000006000, + XR_TYPE_INSTANCE_CREATE_INFO_ANDROID_KHR = 1000008000, + XR_TYPE_COMPOSITION_LAYER_DEPTH_INFO_KHR = 1000010000, + XR_TYPE_VULKAN_SWAPCHAIN_FORMAT_LIST_CREATE_INFO_KHR = 1000014000, + XR_TYPE_EVENT_DATA_PERF_SETTINGS_EXT = 1000015000, + XR_TYPE_COMPOSITION_LAYER_CYLINDER_KHR = 1000017000, + XR_TYPE_COMPOSITION_LAYER_EQUIRECT_KHR = 1000018000, + XR_TYPE_DEBUG_UTILS_OBJECT_NAME_INFO_EXT = 1000019000, + XR_TYPE_DEBUG_UTILS_MESSENGER_CALLBACK_DATA_EXT = 1000019001, + XR_TYPE_DEBUG_UTILS_MESSENGER_CREATE_INFO_EXT = 1000019002, + XR_TYPE_DEBUG_UTILS_LABEL_EXT = 1000019003, + XR_TYPE_GRAPHICS_BINDING_OPENGL_WIN32_KHR = 1000023000, + XR_TYPE_GRAPHICS_BINDING_OPENGL_XLIB_KHR = 1000023001, + XR_TYPE_GRAPHICS_BINDING_OPENGL_XCB_KHR = 1000023002, + XR_TYPE_GRAPHICS_BINDING_OPENGL_WAYLAND_KHR = 1000023003, + XR_TYPE_SWAPCHAIN_IMAGE_OPENGL_KHR = 1000023004, + XR_TYPE_GRAPHICS_REQUIREMENTS_OPENGL_KHR = 1000023005, + XR_TYPE_GRAPHICS_BINDING_OPENGL_ES_ANDROID_KHR = 1000024001, + XR_TYPE_SWAPCHAIN_IMAGE_OPENGL_ES_KHR = 1000024002, + XR_TYPE_GRAPHICS_REQUIREMENTS_OPENGL_ES_KHR = 1000024003, + XR_TYPE_GRAPHICS_BINDING_VULKAN_KHR = 1000025000, + XR_TYPE_SWAPCHAIN_IMAGE_VULKAN_KHR = 1000025001, + XR_TYPE_GRAPHICS_REQUIREMENTS_VULKAN_KHR = 1000025002, + XR_TYPE_GRAPHICS_BINDING_D3D11_KHR = 1000027000, + XR_TYPE_SWAPCHAIN_IMAGE_D3D11_KHR = 1000027001, + XR_TYPE_GRAPHICS_REQUIREMENTS_D3D11_KHR = 1000027002, + XR_TYPE_GRAPHICS_BINDING_D3D12_KHR = 1000028000, + XR_TYPE_SWAPCHAIN_IMAGE_D3D12_KHR = 1000028001, + XR_TYPE_GRAPHICS_REQUIREMENTS_D3D12_KHR = 1000028002, + XR_TYPE_SYSTEM_EYE_GAZE_INTERACTION_PROPERTIES_EXT = 1000030000, + XR_TYPE_EYE_GAZE_SAMPLE_TIME_EXT = 1000030001, + XR_TYPE_VISIBILITY_MASK_KHR = 1000031000, + XR_TYPE_EVENT_DATA_VISIBILITY_MASK_CHANGED_KHR = 1000031001, + XR_TYPE_SESSION_CREATE_INFO_OVERLAY_EXTX = 1000033000, + XR_TYPE_EVENT_DATA_MAIN_SESSION_VISIBILITY_CHANGED_EXTX = 1000033003, + XR_TYPE_COMPOSITION_LAYER_COLOR_SCALE_BIAS_KHR = 1000034000, + XR_TYPE_SPATIAL_ANCHOR_CREATE_INFO_MSFT = 1000039000, + XR_TYPE_SPATIAL_ANCHOR_SPACE_CREATE_INFO_MSFT = 1000039001, + XR_TYPE_COMPOSITION_LAYER_IMAGE_LAYOUT_FB = 1000040000, + XR_TYPE_COMPOSITION_LAYER_ALPHA_BLEND_FB = 1000041001, + XR_TYPE_VIEW_CONFIGURATION_DEPTH_RANGE_EXT = 1000046000, + XR_TYPE_GRAPHICS_BINDING_EGL_MNDX = 1000048004, + XR_TYPE_SPATIAL_GRAPH_NODE_SPACE_CREATE_INFO_MSFT = 1000049000, + XR_TYPE_SPATIAL_GRAPH_STATIC_NODE_BINDING_CREATE_INFO_MSFT = 1000049001, + XR_TYPE_SPATIAL_GRAPH_NODE_BINDING_PROPERTIES_GET_INFO_MSFT = 1000049002, + XR_TYPE_SPATIAL_GRAPH_NODE_BINDING_PROPERTIES_MSFT = 1000049003, + XR_TYPE_SYSTEM_HAND_TRACKING_PROPERTIES_EXT = 1000051000, + XR_TYPE_HAND_TRACKER_CREATE_INFO_EXT = 1000051001, + XR_TYPE_HAND_JOINTS_LOCATE_INFO_EXT = 1000051002, + XR_TYPE_HAND_JOINT_LOCATIONS_EXT = 1000051003, + XR_TYPE_HAND_JOINT_VELOCITIES_EXT = 1000051004, + XR_TYPE_SYSTEM_HAND_TRACKING_MESH_PROPERTIES_MSFT = 1000052000, + XR_TYPE_HAND_MESH_SPACE_CREATE_INFO_MSFT = 1000052001, + XR_TYPE_HAND_MESH_UPDATE_INFO_MSFT = 1000052002, + XR_TYPE_HAND_MESH_MSFT = 1000052003, + XR_TYPE_HAND_POSE_TYPE_INFO_MSFT = 1000052004, + XR_TYPE_SECONDARY_VIEW_CONFIGURATION_SESSION_BEGIN_INFO_MSFT = 1000053000, + XR_TYPE_SECONDARY_VIEW_CONFIGURATION_STATE_MSFT = 1000053001, + XR_TYPE_SECONDARY_VIEW_CONFIGURATION_FRAME_STATE_MSFT = 1000053002, + XR_TYPE_SECONDARY_VIEW_CONFIGURATION_FRAME_END_INFO_MSFT = 1000053003, + XR_TYPE_SECONDARY_VIEW_CONFIGURATION_LAYER_INFO_MSFT = 1000053004, + XR_TYPE_SECONDARY_VIEW_CONFIGURATION_SWAPCHAIN_CREATE_INFO_MSFT = 1000053005, + XR_TYPE_CONTROLLER_MODEL_KEY_STATE_MSFT = 1000055000, + XR_TYPE_CONTROLLER_MODEL_NODE_PROPERTIES_MSFT = 1000055001, + XR_TYPE_CONTROLLER_MODEL_PROPERTIES_MSFT = 1000055002, + XR_TYPE_CONTROLLER_MODEL_NODE_STATE_MSFT = 1000055003, + XR_TYPE_CONTROLLER_MODEL_STATE_MSFT = 1000055004, + XR_TYPE_VIEW_CONFIGURATION_VIEW_FOV_EPIC = 1000059000, + XR_TYPE_HOLOGRAPHIC_WINDOW_ATTACHMENT_MSFT = 1000063000, + XR_TYPE_COMPOSITION_LAYER_REPROJECTION_INFO_MSFT = 1000066000, + XR_TYPE_COMPOSITION_LAYER_REPROJECTION_PLANE_OVERRIDE_MSFT = 1000066001, + XR_TYPE_ANDROID_SURFACE_SWAPCHAIN_CREATE_INFO_FB = 1000070000, + XR_TYPE_COMPOSITION_LAYER_SECURE_CONTENT_FB = 1000072000, + XR_TYPE_BODY_TRACKER_CREATE_INFO_FB = 1000076001, + XR_TYPE_BODY_JOINTS_LOCATE_INFO_FB = 1000076002, + XR_TYPE_SYSTEM_BODY_TRACKING_PROPERTIES_FB = 1000076004, + XR_TYPE_BODY_JOINT_LOCATIONS_FB = 1000076005, + XR_TYPE_BODY_SKELETON_FB = 1000076006, + XR_TYPE_INTERACTION_PROFILE_DPAD_BINDING_EXT = 1000078000, + XR_TYPE_INTERACTION_PROFILE_ANALOG_THRESHOLD_VALVE = 1000079000, + XR_TYPE_HAND_JOINTS_MOTION_RANGE_INFO_EXT = 1000080000, + XR_TYPE_LOADER_INIT_INFO_ANDROID_KHR = 1000089000, + XR_TYPE_VULKAN_INSTANCE_CREATE_INFO_KHR = 1000090000, + XR_TYPE_VULKAN_DEVICE_CREATE_INFO_KHR = 1000090001, + XR_TYPE_VULKAN_GRAPHICS_DEVICE_GET_INFO_KHR = 1000090003, + XR_TYPE_COMPOSITION_LAYER_EQUIRECT2_KHR = 1000091000, + XR_TYPE_SCENE_OBSERVER_CREATE_INFO_MSFT = 1000097000, + XR_TYPE_SCENE_CREATE_INFO_MSFT = 1000097001, + XR_TYPE_NEW_SCENE_COMPUTE_INFO_MSFT = 1000097002, + XR_TYPE_VISUAL_MESH_COMPUTE_LOD_INFO_MSFT = 1000097003, + XR_TYPE_SCENE_COMPONENTS_MSFT = 1000097004, + XR_TYPE_SCENE_COMPONENTS_GET_INFO_MSFT = 1000097005, + XR_TYPE_SCENE_COMPONENT_LOCATIONS_MSFT = 1000097006, + XR_TYPE_SCENE_COMPONENTS_LOCATE_INFO_MSFT = 1000097007, + XR_TYPE_SCENE_OBJECTS_MSFT = 1000097008, + XR_TYPE_SCENE_COMPONENT_PARENT_FILTER_INFO_MSFT = 1000097009, + XR_TYPE_SCENE_OBJECT_TYPES_FILTER_INFO_MSFT = 1000097010, + XR_TYPE_SCENE_PLANES_MSFT = 1000097011, + XR_TYPE_SCENE_PLANE_ALIGNMENT_FILTER_INFO_MSFT = 1000097012, + XR_TYPE_SCENE_MESHES_MSFT = 1000097013, + XR_TYPE_SCENE_MESH_BUFFERS_GET_INFO_MSFT = 1000097014, + XR_TYPE_SCENE_MESH_BUFFERS_MSFT = 1000097015, + XR_TYPE_SCENE_MESH_VERTEX_BUFFER_MSFT = 1000097016, + XR_TYPE_SCENE_MESH_INDICES_UINT32_MSFT = 1000097017, + XR_TYPE_SCENE_MESH_INDICES_UINT16_MSFT = 1000097018, + XR_TYPE_SERIALIZED_SCENE_FRAGMENT_DATA_GET_INFO_MSFT = 1000098000, + XR_TYPE_SCENE_DESERIALIZE_INFO_MSFT = 1000098001, + XR_TYPE_EVENT_DATA_DISPLAY_REFRESH_RATE_CHANGED_FB = 1000101000, + XR_TYPE_VIVE_TRACKER_PATHS_HTCX = 1000103000, + XR_TYPE_EVENT_DATA_VIVE_TRACKER_CONNECTED_HTCX = 1000103001, + XR_TYPE_SYSTEM_FACIAL_TRACKING_PROPERTIES_HTC = 1000104000, + XR_TYPE_FACIAL_TRACKER_CREATE_INFO_HTC = 1000104001, + XR_TYPE_FACIAL_EXPRESSIONS_HTC = 1000104002, + XR_TYPE_SYSTEM_COLOR_SPACE_PROPERTIES_FB = 1000108000, + XR_TYPE_HAND_TRACKING_MESH_FB = 1000110001, + XR_TYPE_HAND_TRACKING_SCALE_FB = 1000110003, + XR_TYPE_HAND_TRACKING_AIM_STATE_FB = 1000111001, + XR_TYPE_HAND_TRACKING_CAPSULES_STATE_FB = 1000112000, + XR_TYPE_SYSTEM_SPATIAL_ENTITY_PROPERTIES_FB = 1000113004, + XR_TYPE_SPATIAL_ANCHOR_CREATE_INFO_FB = 1000113003, + XR_TYPE_SPACE_COMPONENT_STATUS_SET_INFO_FB = 1000113007, + XR_TYPE_SPACE_COMPONENT_STATUS_FB = 1000113001, + XR_TYPE_EVENT_DATA_SPATIAL_ANCHOR_CREATE_COMPLETE_FB = 1000113005, + XR_TYPE_EVENT_DATA_SPACE_SET_STATUS_COMPLETE_FB = 1000113006, + XR_TYPE_FOVEATION_PROFILE_CREATE_INFO_FB = 1000114000, + XR_TYPE_SWAPCHAIN_CREATE_INFO_FOVEATION_FB = 1000114001, + XR_TYPE_SWAPCHAIN_STATE_FOVEATION_FB = 1000114002, + XR_TYPE_FOVEATION_LEVEL_PROFILE_CREATE_INFO_FB = 1000115000, + XR_TYPE_KEYBOARD_SPACE_CREATE_INFO_FB = 1000116009, + XR_TYPE_KEYBOARD_TRACKING_QUERY_FB = 1000116004, + XR_TYPE_SYSTEM_KEYBOARD_TRACKING_PROPERTIES_FB = 1000116002, + XR_TYPE_TRIANGLE_MESH_CREATE_INFO_FB = 1000117001, + XR_TYPE_SYSTEM_PASSTHROUGH_PROPERTIES_FB = 1000118000, + XR_TYPE_PASSTHROUGH_CREATE_INFO_FB = 1000118001, + XR_TYPE_PASSTHROUGH_LAYER_CREATE_INFO_FB = 1000118002, + XR_TYPE_COMPOSITION_LAYER_PASSTHROUGH_FB = 1000118003, + XR_TYPE_GEOMETRY_INSTANCE_CREATE_INFO_FB = 1000118004, + XR_TYPE_GEOMETRY_INSTANCE_TRANSFORM_FB = 1000118005, + XR_TYPE_SYSTEM_PASSTHROUGH_PROPERTIES2_FB = 1000118006, + XR_TYPE_PASSTHROUGH_STYLE_FB = 1000118020, + XR_TYPE_PASSTHROUGH_COLOR_MAP_MONO_TO_RGBA_FB = 1000118021, + XR_TYPE_PASSTHROUGH_COLOR_MAP_MONO_TO_MONO_FB = 1000118022, + XR_TYPE_PASSTHROUGH_BRIGHTNESS_CONTRAST_SATURATION_FB = 1000118023, + XR_TYPE_EVENT_DATA_PASSTHROUGH_STATE_CHANGED_FB = 1000118030, + XR_TYPE_RENDER_MODEL_PATH_INFO_FB = 1000119000, + XR_TYPE_RENDER_MODEL_PROPERTIES_FB = 1000119001, + XR_TYPE_RENDER_MODEL_BUFFER_FB = 1000119002, + XR_TYPE_RENDER_MODEL_LOAD_INFO_FB = 1000119003, + XR_TYPE_SYSTEM_RENDER_MODEL_PROPERTIES_FB = 1000119004, + XR_TYPE_RENDER_MODEL_CAPABILITIES_REQUEST_FB = 1000119005, + XR_TYPE_BINDING_MODIFICATIONS_KHR = 1000120000, + XR_TYPE_VIEW_LOCATE_FOVEATED_RENDERING_VARJO = 1000121000, + XR_TYPE_FOVEATED_VIEW_CONFIGURATION_VIEW_VARJO = 1000121001, + XR_TYPE_SYSTEM_FOVEATED_RENDERING_PROPERTIES_VARJO = 1000121002, + XR_TYPE_COMPOSITION_LAYER_DEPTH_TEST_VARJO = 1000122000, + XR_TYPE_SYSTEM_MARKER_TRACKING_PROPERTIES_VARJO = 1000124000, + XR_TYPE_EVENT_DATA_MARKER_TRACKING_UPDATE_VARJO = 1000124001, + XR_TYPE_MARKER_SPACE_CREATE_INFO_VARJO = 1000124002, + XR_TYPE_FRAME_END_INFO_ML = 1000135000, + XR_TYPE_GLOBAL_DIMMER_FRAME_END_INFO_ML = 1000136000, + XR_TYPE_COORDINATE_SPACE_CREATE_INFO_ML = 1000137000, + XR_TYPE_SPATIAL_ANCHOR_PERSISTENCE_INFO_MSFT = 1000142000, + XR_TYPE_SPATIAL_ANCHOR_FROM_PERSISTED_ANCHOR_CREATE_INFO_MSFT = 1000142001, + XR_TYPE_SPACE_QUERY_INFO_FB = 1000156001, + XR_TYPE_SPACE_QUERY_RESULTS_FB = 1000156002, + XR_TYPE_SPACE_STORAGE_LOCATION_FILTER_INFO_FB = 1000156003, + XR_TYPE_SPACE_UUID_FILTER_INFO_FB = 1000156054, + XR_TYPE_SPACE_COMPONENT_FILTER_INFO_FB = 1000156052, + XR_TYPE_EVENT_DATA_SPACE_QUERY_RESULTS_AVAILABLE_FB = 1000156103, + XR_TYPE_EVENT_DATA_SPACE_QUERY_COMPLETE_FB = 1000156104, + XR_TYPE_SPACE_SAVE_INFO_FB = 1000158000, + XR_TYPE_SPACE_ERASE_INFO_FB = 1000158001, + XR_TYPE_EVENT_DATA_SPACE_SAVE_COMPLETE_FB = 1000158106, + XR_TYPE_EVENT_DATA_SPACE_ERASE_COMPLETE_FB = 1000158107, + XR_TYPE_SWAPCHAIN_IMAGE_FOVEATION_VULKAN_FB = 1000160000, + XR_TYPE_SWAPCHAIN_STATE_ANDROID_SURFACE_DIMENSIONS_FB = 1000161000, + XR_TYPE_SWAPCHAIN_STATE_SAMPLER_OPENGL_ES_FB = 1000162000, + XR_TYPE_SWAPCHAIN_STATE_SAMPLER_VULKAN_FB = 1000163000, + XR_TYPE_SPACE_SHARE_INFO_FB = 1000169001, + XR_TYPE_EVENT_DATA_SPACE_SHARE_COMPLETE_FB = 1000169002, + XR_TYPE_COMPOSITION_LAYER_SPACE_WARP_INFO_FB = 1000171000, + XR_TYPE_SYSTEM_SPACE_WARP_PROPERTIES_FB = 1000171001, + XR_TYPE_HAPTIC_AMPLITUDE_ENVELOPE_VIBRATION_FB = 1000173001, + XR_TYPE_SEMANTIC_LABELS_FB = 1000175000, + XR_TYPE_ROOM_LAYOUT_FB = 1000175001, + XR_TYPE_BOUNDARY_2D_FB = 1000175002, + XR_TYPE_SEMANTIC_LABELS_SUPPORT_INFO_FB = 1000175010, + XR_TYPE_DIGITAL_LENS_CONTROL_ALMALENCE = 1000196000, + XR_TYPE_EVENT_DATA_SCENE_CAPTURE_COMPLETE_FB = 1000198001, + XR_TYPE_SCENE_CAPTURE_REQUEST_INFO_FB = 1000198050, + XR_TYPE_SPACE_CONTAINER_FB = 1000199000, + XR_TYPE_FOVEATION_EYE_TRACKED_PROFILE_CREATE_INFO_META = 1000200000, + XR_TYPE_FOVEATION_EYE_TRACKED_STATE_META = 1000200001, + XR_TYPE_SYSTEM_FOVEATION_EYE_TRACKED_PROPERTIES_META = 1000200002, + XR_TYPE_SYSTEM_FACE_TRACKING_PROPERTIES_FB = 1000201004, + XR_TYPE_FACE_TRACKER_CREATE_INFO_FB = 1000201005, + XR_TYPE_FACE_EXPRESSION_INFO_FB = 1000201002, + XR_TYPE_FACE_EXPRESSION_WEIGHTS_FB = 1000201006, + XR_TYPE_EYE_TRACKER_CREATE_INFO_FB = 1000202001, + XR_TYPE_EYE_GAZES_INFO_FB = 1000202002, + XR_TYPE_EYE_GAZES_FB = 1000202003, + XR_TYPE_SYSTEM_EYE_TRACKING_PROPERTIES_FB = 1000202004, + XR_TYPE_PASSTHROUGH_KEYBOARD_HANDS_INTENSITY_FB = 1000203002, + XR_TYPE_COMPOSITION_LAYER_SETTINGS_FB = 1000204000, + XR_TYPE_HAPTIC_PCM_VIBRATION_FB = 1000209001, + XR_TYPE_DEVICE_PCM_SAMPLE_RATE_STATE_FB = 1000209002, + XR_TYPE_COMPOSITION_LAYER_DEPTH_TEST_FB = 1000212000, + XR_TYPE_LOCAL_DIMMING_FRAME_END_INFO_META = 1000216000, + XR_TYPE_SYSTEM_VIRTUAL_KEYBOARD_PROPERTIES_META = 1000219001, + XR_TYPE_VIRTUAL_KEYBOARD_CREATE_INFO_META = 1000219002, + XR_TYPE_VIRTUAL_KEYBOARD_SPACE_CREATE_INFO_META = 1000219003, + XR_TYPE_VIRTUAL_KEYBOARD_LOCATION_INFO_META = 1000219004, + XR_TYPE_VIRTUAL_KEYBOARD_MODEL_VISIBILITY_SET_INFO_META = 1000219005, + XR_TYPE_VIRTUAL_KEYBOARD_ANIMATION_STATE_META = 1000219006, + XR_TYPE_VIRTUAL_KEYBOARD_MODEL_ANIMATION_STATES_META = 1000219007, + XR_TYPE_VIRTUAL_KEYBOARD_TEXTURE_DATA_META = 1000219009, + XR_TYPE_VIRTUAL_KEYBOARD_INPUT_INFO_META = 1000219010, + XR_TYPE_VIRTUAL_KEYBOARD_TEXT_CONTEXT_CHANGE_INFO_META = 1000219011, + XR_TYPE_EVENT_DATA_VIRTUAL_KEYBOARD_COMMIT_TEXT_META = 1000219014, + XR_TYPE_EVENT_DATA_VIRTUAL_KEYBOARD_BACKSPACE_META = 1000219015, + XR_TYPE_EVENT_DATA_VIRTUAL_KEYBOARD_ENTER_META = 1000219016, + XR_TYPE_EVENT_DATA_VIRTUAL_KEYBOARD_SHOWN_META = 1000219017, + XR_TYPE_EVENT_DATA_VIRTUAL_KEYBOARD_HIDDEN_META = 1000219018, + XR_TYPE_EXTERNAL_CAMERA_OCULUS = 1000226000, + XR_TYPE_VULKAN_SWAPCHAIN_CREATE_INFO_META = 1000227000, + XR_TYPE_PERFORMANCE_METRICS_STATE_META = 1000232001, + XR_TYPE_PERFORMANCE_METRICS_COUNTER_META = 1000232002, + XR_TYPE_SPACE_LIST_SAVE_INFO_FB = 1000238000, + XR_TYPE_EVENT_DATA_SPACE_LIST_SAVE_COMPLETE_FB = 1000238001, + XR_TYPE_SPACE_USER_CREATE_INFO_FB = 1000241001, + XR_TYPE_SYSTEM_HEADSET_ID_PROPERTIES_META = 1000245000, + XR_TYPE_SYSTEM_PASSTHROUGH_COLOR_LUT_PROPERTIES_META = 1000266000, + XR_TYPE_PASSTHROUGH_COLOR_LUT_CREATE_INFO_META = 1000266001, + XR_TYPE_PASSTHROUGH_COLOR_LUT_UPDATE_INFO_META = 1000266002, + XR_TYPE_PASSTHROUGH_COLOR_MAP_LUT_META = 1000266100, + XR_TYPE_PASSTHROUGH_COLOR_MAP_INTERPOLATED_LUT_META = 1000266101, + XR_TYPE_PASSTHROUGH_CREATE_INFO_HTC = 1000317001, + XR_TYPE_PASSTHROUGH_COLOR_HTC = 1000317002, + XR_TYPE_PASSTHROUGH_MESH_TRANSFORM_INFO_HTC = 1000317003, + XR_TYPE_COMPOSITION_LAYER_PASSTHROUGH_HTC = 1000317004, + XR_TYPE_FOVEATION_APPLY_INFO_HTC = 1000318000, + XR_TYPE_FOVEATION_DYNAMIC_MODE_INFO_HTC = 1000318001, + XR_TYPE_FOVEATION_CUSTOM_MODE_INFO_HTC = 1000318002, + XR_TYPE_ACTIVE_ACTION_SET_PRIORITIES_EXT = 1000373000, + XR_TYPE_SYSTEM_FORCE_FEEDBACK_CURL_PROPERTIES_MNDX = 1000375000, + XR_TYPE_FORCE_FEEDBACK_CURL_APPLY_LOCATIONS_MNDX = 1000375001, + XR_TYPE_HAND_TRACKING_DATA_SOURCE_INFO_EXT = 1000428000, + XR_TYPE_HAND_TRACKING_DATA_SOURCE_STATE_EXT = 1000428001, + XR_TYPE_PLANE_DETECTOR_CREATE_INFO_EXT = 1000429001, + XR_TYPE_PLANE_DETECTOR_BEGIN_INFO_EXT = 1000429002, + XR_TYPE_PLANE_DETECTOR_GET_INFO_EXT = 1000429003, + XR_TYPE_PLANE_DETECTOR_LOCATIONS_EXT = 1000429004, + XR_TYPE_PLANE_DETECTOR_LOCATION_EXT = 1000429005, + XR_TYPE_PLANE_DETECTOR_POLYGON_BUFFER_EXT = 1000429006, + XR_TYPE_SYSTEM_PLANE_DETECTION_PROPERTIES_EXT = 1000429007, + XR_TYPE_GRAPHICS_BINDING_VULKAN2_KHR = XR_TYPE_GRAPHICS_BINDING_VULKAN_KHR, + XR_TYPE_SWAPCHAIN_IMAGE_VULKAN2_KHR = XR_TYPE_SWAPCHAIN_IMAGE_VULKAN_KHR, + XR_TYPE_GRAPHICS_REQUIREMENTS_VULKAN2_KHR = XR_TYPE_GRAPHICS_REQUIREMENTS_VULKAN_KHR, + XR_TYPE_DEVICE_PCM_SAMPLE_RATE_GET_INFO_FB = XR_TYPE_DEVICE_PCM_SAMPLE_RATE_STATE_FB, + XR_STRUCTURE_TYPE_MAX_ENUM = 0x7FFFFFFF +} XrStructureType; + +typedef enum XrFormFactor { + XR_FORM_FACTOR_HEAD_MOUNTED_DISPLAY = 1, + XR_FORM_FACTOR_HANDHELD_DISPLAY = 2, + XR_FORM_FACTOR_MAX_ENUM = 0x7FFFFFFF +} XrFormFactor; + +typedef enum XrViewConfigurationType { + XR_VIEW_CONFIGURATION_TYPE_PRIMARY_MONO = 1, + XR_VIEW_CONFIGURATION_TYPE_PRIMARY_STEREO = 2, + XR_VIEW_CONFIGURATION_TYPE_PRIMARY_QUAD_VARJO = 1000037000, + XR_VIEW_CONFIGURATION_TYPE_SECONDARY_MONO_FIRST_PERSON_OBSERVER_MSFT = 1000054000, + XR_VIEW_CONFIGURATION_TYPE_MAX_ENUM = 0x7FFFFFFF +} XrViewConfigurationType; + +typedef enum XrEnvironmentBlendMode { + XR_ENVIRONMENT_BLEND_MODE_OPAQUE = 1, + XR_ENVIRONMENT_BLEND_MODE_ADDITIVE = 2, + XR_ENVIRONMENT_BLEND_MODE_ALPHA_BLEND = 3, + XR_ENVIRONMENT_BLEND_MODE_MAX_ENUM = 0x7FFFFFFF +} XrEnvironmentBlendMode; + +typedef enum XrReferenceSpaceType { + XR_REFERENCE_SPACE_TYPE_VIEW = 1, + XR_REFERENCE_SPACE_TYPE_LOCAL = 2, + XR_REFERENCE_SPACE_TYPE_STAGE = 3, + XR_REFERENCE_SPACE_TYPE_UNBOUNDED_MSFT = 1000038000, + XR_REFERENCE_SPACE_TYPE_COMBINED_EYE_VARJO = 1000121000, + XR_REFERENCE_SPACE_TYPE_LOCAL_FLOOR_EXT = 1000426000, + XR_REFERENCE_SPACE_TYPE_MAX_ENUM = 0x7FFFFFFF +} XrReferenceSpaceType; + +typedef enum XrActionType { + XR_ACTION_TYPE_BOOLEAN_INPUT = 1, + XR_ACTION_TYPE_FLOAT_INPUT = 2, + XR_ACTION_TYPE_VECTOR2F_INPUT = 3, + XR_ACTION_TYPE_POSE_INPUT = 4, + XR_ACTION_TYPE_VIBRATION_OUTPUT = 100, + XR_ACTION_TYPE_MAX_ENUM = 0x7FFFFFFF +} XrActionType; + +typedef enum XrEyeVisibility { + XR_EYE_VISIBILITY_BOTH = 0, + XR_EYE_VISIBILITY_LEFT = 1, + XR_EYE_VISIBILITY_RIGHT = 2, + XR_EYE_VISIBILITY_MAX_ENUM = 0x7FFFFFFF +} XrEyeVisibility; + +typedef enum XrSessionState { + XR_SESSION_STATE_UNKNOWN = 0, + XR_SESSION_STATE_IDLE = 1, + XR_SESSION_STATE_READY = 2, + XR_SESSION_STATE_SYNCHRONIZED = 3, + XR_SESSION_STATE_VISIBLE = 4, + XR_SESSION_STATE_FOCUSED = 5, + XR_SESSION_STATE_STOPPING = 6, + XR_SESSION_STATE_LOSS_PENDING = 7, + XR_SESSION_STATE_EXITING = 8, + XR_SESSION_STATE_MAX_ENUM = 0x7FFFFFFF +} XrSessionState; + +typedef enum XrObjectType { + XR_OBJECT_TYPE_UNKNOWN = 0, + XR_OBJECT_TYPE_INSTANCE = 1, + XR_OBJECT_TYPE_SESSION = 2, + XR_OBJECT_TYPE_SWAPCHAIN = 3, + XR_OBJECT_TYPE_SPACE = 4, + XR_OBJECT_TYPE_ACTION_SET = 5, + XR_OBJECT_TYPE_ACTION = 6, + XR_OBJECT_TYPE_DEBUG_UTILS_MESSENGER_EXT = 1000019000, + XR_OBJECT_TYPE_SPATIAL_ANCHOR_MSFT = 1000039000, + XR_OBJECT_TYPE_SPATIAL_GRAPH_NODE_BINDING_MSFT = 1000049000, + XR_OBJECT_TYPE_HAND_TRACKER_EXT = 1000051000, + XR_OBJECT_TYPE_BODY_TRACKER_FB = 1000076000, + XR_OBJECT_TYPE_SCENE_OBSERVER_MSFT = 1000097000, + XR_OBJECT_TYPE_SCENE_MSFT = 1000097001, + XR_OBJECT_TYPE_FACIAL_TRACKER_HTC = 1000104000, + XR_OBJECT_TYPE_FOVEATION_PROFILE_FB = 1000114000, + XR_OBJECT_TYPE_TRIANGLE_MESH_FB = 1000117000, + XR_OBJECT_TYPE_PASSTHROUGH_FB = 1000118000, + XR_OBJECT_TYPE_PASSTHROUGH_LAYER_FB = 1000118002, + XR_OBJECT_TYPE_GEOMETRY_INSTANCE_FB = 1000118004, + XR_OBJECT_TYPE_SPATIAL_ANCHOR_STORE_CONNECTION_MSFT = 1000142000, + XR_OBJECT_TYPE_FACE_TRACKER_FB = 1000201000, + XR_OBJECT_TYPE_EYE_TRACKER_FB = 1000202000, + XR_OBJECT_TYPE_VIRTUAL_KEYBOARD_META = 1000219000, + XR_OBJECT_TYPE_SPACE_USER_FB = 1000241000, + XR_OBJECT_TYPE_PASSTHROUGH_COLOR_LUT_META = 1000266000, + XR_OBJECT_TYPE_PASSTHROUGH_HTC = 1000317000, + XR_OBJECT_TYPE_PLANE_DETECTOR_EXT = 1000429000, + XR_OBJECT_TYPE_MAX_ENUM = 0x7FFFFFFF +} XrObjectType; +typedef XrFlags64 XrInstanceCreateFlags; + +// Flag bits for XrInstanceCreateFlags + +typedef XrFlags64 XrSessionCreateFlags; + +// Flag bits for XrSessionCreateFlags + +typedef XrFlags64 XrSpaceVelocityFlags; + +// Flag bits for XrSpaceVelocityFlags +static const XrSpaceVelocityFlags XR_SPACE_VELOCITY_LINEAR_VALID_BIT = 0x00000001; +static const XrSpaceVelocityFlags XR_SPACE_VELOCITY_ANGULAR_VALID_BIT = 0x00000002; + +typedef XrFlags64 XrSpaceLocationFlags; + +// Flag bits for XrSpaceLocationFlags +static const XrSpaceLocationFlags XR_SPACE_LOCATION_ORIENTATION_VALID_BIT = 0x00000001; +static const XrSpaceLocationFlags XR_SPACE_LOCATION_POSITION_VALID_BIT = 0x00000002; +static const XrSpaceLocationFlags XR_SPACE_LOCATION_ORIENTATION_TRACKED_BIT = 0x00000004; +static const XrSpaceLocationFlags XR_SPACE_LOCATION_POSITION_TRACKED_BIT = 0x00000008; + +typedef XrFlags64 XrSwapchainCreateFlags; + +// Flag bits for XrSwapchainCreateFlags +static const XrSwapchainCreateFlags XR_SWAPCHAIN_CREATE_PROTECTED_CONTENT_BIT = 0x00000001; +static const XrSwapchainCreateFlags XR_SWAPCHAIN_CREATE_STATIC_IMAGE_BIT = 0x00000002; + +typedef XrFlags64 XrSwapchainUsageFlags; + +// Flag bits for XrSwapchainUsageFlags +static const XrSwapchainUsageFlags XR_SWAPCHAIN_USAGE_COLOR_ATTACHMENT_BIT = 0x00000001; +static const XrSwapchainUsageFlags XR_SWAPCHAIN_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT = 0x00000002; +static const XrSwapchainUsageFlags XR_SWAPCHAIN_USAGE_UNORDERED_ACCESS_BIT = 0x00000004; +static const XrSwapchainUsageFlags XR_SWAPCHAIN_USAGE_TRANSFER_SRC_BIT = 0x00000008; +static const XrSwapchainUsageFlags XR_SWAPCHAIN_USAGE_TRANSFER_DST_BIT = 0x00000010; +static const XrSwapchainUsageFlags XR_SWAPCHAIN_USAGE_SAMPLED_BIT = 0x00000020; +static const XrSwapchainUsageFlags XR_SWAPCHAIN_USAGE_MUTABLE_FORMAT_BIT = 0x00000040; +static const XrSwapchainUsageFlags XR_SWAPCHAIN_USAGE_INPUT_ATTACHMENT_BIT_MND = 0x00000080; +static const XrSwapchainUsageFlags XR_SWAPCHAIN_USAGE_INPUT_ATTACHMENT_BIT_KHR = 0x00000080; // alias of XR_SWAPCHAIN_USAGE_INPUT_ATTACHMENT_BIT_MND + +typedef XrFlags64 XrCompositionLayerFlags; + +// Flag bits for XrCompositionLayerFlags +static const XrCompositionLayerFlags XR_COMPOSITION_LAYER_CORRECT_CHROMATIC_ABERRATION_BIT = 0x00000001; +static const XrCompositionLayerFlags XR_COMPOSITION_LAYER_BLEND_TEXTURE_SOURCE_ALPHA_BIT = 0x00000002; +static const XrCompositionLayerFlags XR_COMPOSITION_LAYER_UNPREMULTIPLIED_ALPHA_BIT = 0x00000004; + +typedef XrFlags64 XrViewStateFlags; + +// Flag bits for XrViewStateFlags +static const XrViewStateFlags XR_VIEW_STATE_ORIENTATION_VALID_BIT = 0x00000001; +static const XrViewStateFlags XR_VIEW_STATE_POSITION_VALID_BIT = 0x00000002; +static const XrViewStateFlags XR_VIEW_STATE_ORIENTATION_TRACKED_BIT = 0x00000004; +static const XrViewStateFlags XR_VIEW_STATE_POSITION_TRACKED_BIT = 0x00000008; + +typedef XrFlags64 XrInputSourceLocalizedNameFlags; + +// Flag bits for XrInputSourceLocalizedNameFlags +static const XrInputSourceLocalizedNameFlags XR_INPUT_SOURCE_LOCALIZED_NAME_USER_PATH_BIT = 0x00000001; +static const XrInputSourceLocalizedNameFlags XR_INPUT_SOURCE_LOCALIZED_NAME_INTERACTION_PROFILE_BIT = 0x00000002; +static const XrInputSourceLocalizedNameFlags XR_INPUT_SOURCE_LOCALIZED_NAME_COMPONENT_BIT = 0x00000004; + +typedef void (XRAPI_PTR *PFN_xrVoidFunction)(void); +typedef struct XrApiLayerProperties { + XrStructureType type; + void* XR_MAY_ALIAS next; + char layerName[XR_MAX_API_LAYER_NAME_SIZE]; + XrVersion specVersion; + uint32_t layerVersion; + char description[XR_MAX_API_LAYER_DESCRIPTION_SIZE]; +} XrApiLayerProperties; + +typedef struct XrExtensionProperties { + XrStructureType type; + void* XR_MAY_ALIAS next; + char extensionName[XR_MAX_EXTENSION_NAME_SIZE]; + uint32_t extensionVersion; +} XrExtensionProperties; + +typedef struct XrApplicationInfo { + char applicationName[XR_MAX_APPLICATION_NAME_SIZE]; + uint32_t applicationVersion; + char engineName[XR_MAX_ENGINE_NAME_SIZE]; + uint32_t engineVersion; + XrVersion apiVersion; +} XrApplicationInfo; + +typedef struct XrInstanceCreateInfo { + XrStructureType type; + const void* XR_MAY_ALIAS next; + XrInstanceCreateFlags createFlags; + XrApplicationInfo applicationInfo; + uint32_t enabledApiLayerCount; + const char* const* enabledApiLayerNames; + uint32_t enabledExtensionCount; + const char* const* enabledExtensionNames; +} XrInstanceCreateInfo; + +typedef struct XrInstanceProperties { + XrStructureType type; + void* XR_MAY_ALIAS next; + XrVersion runtimeVersion; + char runtimeName[XR_MAX_RUNTIME_NAME_SIZE]; +} XrInstanceProperties; + +typedef struct XrEventDataBuffer { + XrStructureType type; + const void* XR_MAY_ALIAS next; + uint8_t varying[4000]; +} XrEventDataBuffer; + +typedef struct XrSystemGetInfo { + XrStructureType type; + const void* XR_MAY_ALIAS next; + XrFormFactor formFactor; +} XrSystemGetInfo; + +typedef struct XrSystemGraphicsProperties { + uint32_t maxSwapchainImageHeight; + uint32_t maxSwapchainImageWidth; + uint32_t maxLayerCount; +} XrSystemGraphicsProperties; + +typedef struct XrSystemTrackingProperties { + XrBool32 orientationTracking; + XrBool32 positionTracking; +} XrSystemTrackingProperties; + +typedef struct XrSystemProperties { + XrStructureType type; + void* XR_MAY_ALIAS next; + XrSystemId systemId; + uint32_t vendorId; + char systemName[XR_MAX_SYSTEM_NAME_SIZE]; + XrSystemGraphicsProperties graphicsProperties; + XrSystemTrackingProperties trackingProperties; +} XrSystemProperties; + +typedef struct XrSessionCreateInfo { + XrStructureType type; + const void* XR_MAY_ALIAS next; + XrSessionCreateFlags createFlags; + XrSystemId systemId; +} XrSessionCreateInfo; + +typedef struct XrVector3f { + float x; + float y; + float z; +} XrVector3f; + +// XrSpaceVelocity extends XrSpaceLocation +typedef struct XrSpaceVelocity { + XrStructureType type; + void* XR_MAY_ALIAS next; + XrSpaceVelocityFlags velocityFlags; + XrVector3f linearVelocity; + XrVector3f angularVelocity; +} XrSpaceVelocity; + +typedef struct XrQuaternionf { + float x; + float y; + float z; + float w; +} XrQuaternionf; + +typedef struct XrPosef { + XrQuaternionf orientation; + XrVector3f position; +} XrPosef; + +typedef struct XrReferenceSpaceCreateInfo { + XrStructureType type; + const void* XR_MAY_ALIAS next; + XrReferenceSpaceType referenceSpaceType; + XrPosef poseInReferenceSpace; +} XrReferenceSpaceCreateInfo; + +typedef struct XrExtent2Df { + float width; + float height; +} XrExtent2Df; + +typedef struct XrActionSpaceCreateInfo { + XrStructureType type; + const void* XR_MAY_ALIAS next; + XrAction action; + XrPath subactionPath; + XrPosef poseInActionSpace; +} XrActionSpaceCreateInfo; + +typedef struct XrSpaceLocation { + XrStructureType type; + void* XR_MAY_ALIAS next; + XrSpaceLocationFlags locationFlags; + XrPosef pose; +} XrSpaceLocation; + +typedef struct XrViewConfigurationProperties { + XrStructureType type; + void* XR_MAY_ALIAS next; + XrViewConfigurationType viewConfigurationType; + XrBool32 fovMutable; +} XrViewConfigurationProperties; + +typedef struct XrViewConfigurationView { + XrStructureType type; + void* XR_MAY_ALIAS next; + uint32_t recommendedImageRectWidth; + uint32_t maxImageRectWidth; + uint32_t recommendedImageRectHeight; + uint32_t maxImageRectHeight; + uint32_t recommendedSwapchainSampleCount; + uint32_t maxSwapchainSampleCount; +} XrViewConfigurationView; + +typedef struct XrSwapchainCreateInfo { + XrStructureType type; + const void* XR_MAY_ALIAS next; + XrSwapchainCreateFlags createFlags; + XrSwapchainUsageFlags usageFlags; + int64_t format; + uint32_t sampleCount; + uint32_t width; + uint32_t height; + uint32_t faceCount; + uint32_t arraySize; + uint32_t mipCount; +} XrSwapchainCreateInfo; + +typedef struct XR_MAY_ALIAS XrSwapchainImageBaseHeader { + XrStructureType type; + void* XR_MAY_ALIAS next; +} XrSwapchainImageBaseHeader; + +typedef struct XrSwapchainImageAcquireInfo { + XrStructureType type; + const void* XR_MAY_ALIAS next; +} XrSwapchainImageAcquireInfo; + +typedef struct XrSwapchainImageWaitInfo { + XrStructureType type; + const void* XR_MAY_ALIAS next; + XrDuration timeout; +} XrSwapchainImageWaitInfo; + +typedef struct XrSwapchainImageReleaseInfo { + XrStructureType type; + const void* XR_MAY_ALIAS next; +} XrSwapchainImageReleaseInfo; + +typedef struct XrSessionBeginInfo { + XrStructureType type; + const void* XR_MAY_ALIAS next; + XrViewConfigurationType primaryViewConfigurationType; +} XrSessionBeginInfo; + +typedef struct XrFrameWaitInfo { + XrStructureType type; + const void* XR_MAY_ALIAS next; +} XrFrameWaitInfo; + +typedef struct XrFrameState { + XrStructureType type; + void* XR_MAY_ALIAS next; + XrTime predictedDisplayTime; + XrDuration predictedDisplayPeriod; + XrBool32 shouldRender; +} XrFrameState; + +typedef struct XrFrameBeginInfo { + XrStructureType type; + const void* XR_MAY_ALIAS next; +} XrFrameBeginInfo; + +typedef struct XR_MAY_ALIAS XrCompositionLayerBaseHeader { + XrStructureType type; + const void* XR_MAY_ALIAS next; + XrCompositionLayerFlags layerFlags; + XrSpace space; +} XrCompositionLayerBaseHeader; + +typedef struct XrFrameEndInfo { + XrStructureType type; + const void* XR_MAY_ALIAS next; + XrTime displayTime; + XrEnvironmentBlendMode environmentBlendMode; + uint32_t layerCount; + const XrCompositionLayerBaseHeader* const* layers; +} XrFrameEndInfo; + +typedef struct XrViewLocateInfo { + XrStructureType type; + const void* XR_MAY_ALIAS next; + XrViewConfigurationType viewConfigurationType; + XrTime displayTime; + XrSpace space; +} XrViewLocateInfo; + +typedef struct XrViewState { + XrStructureType type; + void* XR_MAY_ALIAS next; + XrViewStateFlags viewStateFlags; +} XrViewState; + +typedef struct XrFovf { + float angleLeft; + float angleRight; + float angleUp; + float angleDown; +} XrFovf; + +typedef struct XrView { + XrStructureType type; + void* XR_MAY_ALIAS next; + XrPosef pose; + XrFovf fov; +} XrView; + +typedef struct XrActionSetCreateInfo { + XrStructureType type; + const void* XR_MAY_ALIAS next; + char actionSetName[XR_MAX_ACTION_SET_NAME_SIZE]; + char localizedActionSetName[XR_MAX_LOCALIZED_ACTION_SET_NAME_SIZE]; + uint32_t priority; +} XrActionSetCreateInfo; + +typedef struct XrActionCreateInfo { + XrStructureType type; + const void* XR_MAY_ALIAS next; + char actionName[XR_MAX_ACTION_NAME_SIZE]; + XrActionType actionType; + uint32_t countSubactionPaths; + const XrPath* subactionPaths; + char localizedActionName[XR_MAX_LOCALIZED_ACTION_NAME_SIZE]; +} XrActionCreateInfo; + +typedef struct XrActionSuggestedBinding { + XrAction action; + XrPath binding; +} XrActionSuggestedBinding; + +typedef struct XrInteractionProfileSuggestedBinding { + XrStructureType type; + const void* XR_MAY_ALIAS next; + XrPath interactionProfile; + uint32_t countSuggestedBindings; + const XrActionSuggestedBinding* suggestedBindings; +} XrInteractionProfileSuggestedBinding; + +typedef struct XrSessionActionSetsAttachInfo { + XrStructureType type; + const void* XR_MAY_ALIAS next; + uint32_t countActionSets; + const XrActionSet* actionSets; +} XrSessionActionSetsAttachInfo; + +typedef struct XrInteractionProfileState { + XrStructureType type; + void* XR_MAY_ALIAS next; + XrPath interactionProfile; +} XrInteractionProfileState; + +typedef struct XrActionStateGetInfo { + XrStructureType type; + const void* XR_MAY_ALIAS next; + XrAction action; + XrPath subactionPath; +} XrActionStateGetInfo; + +typedef struct XrActionStateBoolean { + XrStructureType type; + void* XR_MAY_ALIAS next; + XrBool32 currentState; + XrBool32 changedSinceLastSync; + XrTime lastChangeTime; + XrBool32 isActive; +} XrActionStateBoolean; + +typedef struct XrActionStateFloat { + XrStructureType type; + void* XR_MAY_ALIAS next; + float currentState; + XrBool32 changedSinceLastSync; + XrTime lastChangeTime; + XrBool32 isActive; +} XrActionStateFloat; + +typedef struct XrVector2f { + float x; + float y; +} XrVector2f; + +typedef struct XrActionStateVector2f { + XrStructureType type; + void* XR_MAY_ALIAS next; + XrVector2f currentState; + XrBool32 changedSinceLastSync; + XrTime lastChangeTime; + XrBool32 isActive; +} XrActionStateVector2f; + +typedef struct XrActionStatePose { + XrStructureType type; + void* XR_MAY_ALIAS next; + XrBool32 isActive; +} XrActionStatePose; + +typedef struct XrActiveActionSet { + XrActionSet actionSet; + XrPath subactionPath; +} XrActiveActionSet; + +typedef struct XrActionsSyncInfo { + XrStructureType type; + const void* XR_MAY_ALIAS next; + uint32_t countActiveActionSets; + const XrActiveActionSet* activeActionSets; +} XrActionsSyncInfo; + +typedef struct XrBoundSourcesForActionEnumerateInfo { + XrStructureType type; + const void* XR_MAY_ALIAS next; + XrAction action; +} XrBoundSourcesForActionEnumerateInfo; + +typedef struct XrInputSourceLocalizedNameGetInfo { + XrStructureType type; + const void* XR_MAY_ALIAS next; + XrPath sourcePath; + XrInputSourceLocalizedNameFlags whichComponents; +} XrInputSourceLocalizedNameGetInfo; + +typedef struct XrHapticActionInfo { + XrStructureType type; + const void* XR_MAY_ALIAS next; + XrAction action; + XrPath subactionPath; +} XrHapticActionInfo; + +typedef struct XR_MAY_ALIAS XrHapticBaseHeader { + XrStructureType type; + const void* XR_MAY_ALIAS next; +} XrHapticBaseHeader; + +typedef struct XR_MAY_ALIAS XrBaseInStructure { + XrStructureType type; + const struct XrBaseInStructure* next; +} XrBaseInStructure; + +typedef struct XR_MAY_ALIAS XrBaseOutStructure { + XrStructureType type; + struct XrBaseOutStructure* next; +} XrBaseOutStructure; + +typedef struct XrOffset2Di { + int32_t x; + int32_t y; +} XrOffset2Di; + +typedef struct XrExtent2Di { + int32_t width; + int32_t height; +} XrExtent2Di; + +typedef struct XrRect2Di { + XrOffset2Di offset; + XrExtent2Di extent; +} XrRect2Di; + +typedef struct XrSwapchainSubImage { + XrSwapchain swapchain; + XrRect2Di imageRect; + uint32_t imageArrayIndex; +} XrSwapchainSubImage; + +typedef struct XrCompositionLayerProjectionView { + XrStructureType type; + const void* XR_MAY_ALIAS next; + XrPosef pose; + XrFovf fov; + XrSwapchainSubImage subImage; +} XrCompositionLayerProjectionView; + +typedef struct XrCompositionLayerProjection { + XrStructureType type; + const void* XR_MAY_ALIAS next; + XrCompositionLayerFlags layerFlags; + XrSpace space; + uint32_t viewCount; + const XrCompositionLayerProjectionView* views; +} XrCompositionLayerProjection; + +typedef struct XrCompositionLayerQuad { + XrStructureType type; + const void* XR_MAY_ALIAS next; + XrCompositionLayerFlags layerFlags; + XrSpace space; + XrEyeVisibility eyeVisibility; + XrSwapchainSubImage subImage; + XrPosef pose; + XrExtent2Df size; +} XrCompositionLayerQuad; + +typedef struct XR_MAY_ALIAS XrEventDataBaseHeader { + XrStructureType type; + const void* XR_MAY_ALIAS next; +} XrEventDataBaseHeader; + +typedef struct XrEventDataEventsLost { + XrStructureType type; + const void* XR_MAY_ALIAS next; + uint32_t lostEventCount; +} XrEventDataEventsLost; + +typedef struct XrEventDataInstanceLossPending { + XrStructureType type; + const void* XR_MAY_ALIAS next; + XrTime lossTime; +} XrEventDataInstanceLossPending; + +typedef struct XrEventDataSessionStateChanged { + XrStructureType type; + const void* XR_MAY_ALIAS next; + XrSession session; + XrSessionState state; + XrTime time; +} XrEventDataSessionStateChanged; + +typedef struct XrEventDataReferenceSpaceChangePending { + XrStructureType type; + const void* XR_MAY_ALIAS next; + XrSession session; + XrReferenceSpaceType referenceSpaceType; + XrTime changeTime; + XrBool32 poseValid; + XrPosef poseInPreviousSpace; +} XrEventDataReferenceSpaceChangePending; + +typedef struct XrEventDataInteractionProfileChanged { + XrStructureType type; + const void* XR_MAY_ALIAS next; + XrSession session; +} XrEventDataInteractionProfileChanged; + +typedef struct XrHapticVibration { + XrStructureType type; + const void* XR_MAY_ALIAS next; + XrDuration duration; + float frequency; + float amplitude; +} XrHapticVibration; + +typedef struct XrOffset2Df { + float x; + float y; +} XrOffset2Df; + +typedef struct XrRect2Df { + XrOffset2Df offset; + XrExtent2Df extent; +} XrRect2Df; + +typedef struct XrVector4f { + float x; + float y; + float z; + float w; +} XrVector4f; + +typedef struct XrColor4f { + float r; + float g; + float b; + float a; +} XrColor4f; + +typedef XrResult (XRAPI_PTR *PFN_xrGetInstanceProcAddr)(XrInstance instance, const char* name, PFN_xrVoidFunction* function); +typedef XrResult (XRAPI_PTR *PFN_xrEnumerateApiLayerProperties)(uint32_t propertyCapacityInput, uint32_t* propertyCountOutput, XrApiLayerProperties* properties); +typedef XrResult (XRAPI_PTR *PFN_xrEnumerateInstanceExtensionProperties)(const char* layerName, uint32_t propertyCapacityInput, uint32_t* propertyCountOutput, XrExtensionProperties* properties); +typedef XrResult (XRAPI_PTR *PFN_xrCreateInstance)(const XrInstanceCreateInfo* createInfo, XrInstance* instance); +typedef XrResult (XRAPI_PTR *PFN_xrDestroyInstance)(XrInstance instance); +typedef XrResult (XRAPI_PTR *PFN_xrGetInstanceProperties)(XrInstance instance, XrInstanceProperties* instanceProperties); +typedef XrResult (XRAPI_PTR *PFN_xrPollEvent)(XrInstance instance, XrEventDataBuffer* eventData); +typedef XrResult (XRAPI_PTR *PFN_xrResultToString)(XrInstance instance, XrResult value, char buffer[XR_MAX_RESULT_STRING_SIZE]); +typedef XrResult (XRAPI_PTR *PFN_xrStructureTypeToString)(XrInstance instance, XrStructureType value, char buffer[XR_MAX_STRUCTURE_NAME_SIZE]); +typedef XrResult (XRAPI_PTR *PFN_xrGetSystem)(XrInstance instance, const XrSystemGetInfo* getInfo, XrSystemId* systemId); +typedef XrResult (XRAPI_PTR *PFN_xrGetSystemProperties)(XrInstance instance, XrSystemId systemId, XrSystemProperties* properties); +typedef XrResult (XRAPI_PTR *PFN_xrEnumerateEnvironmentBlendModes)(XrInstance instance, XrSystemId systemId, XrViewConfigurationType viewConfigurationType, uint32_t environmentBlendModeCapacityInput, uint32_t* environmentBlendModeCountOutput, XrEnvironmentBlendMode* environmentBlendModes); +typedef XrResult (XRAPI_PTR *PFN_xrCreateSession)(XrInstance instance, const XrSessionCreateInfo* createInfo, XrSession* session); +typedef XrResult (XRAPI_PTR *PFN_xrDestroySession)(XrSession session); +typedef XrResult (XRAPI_PTR *PFN_xrEnumerateReferenceSpaces)(XrSession session, uint32_t spaceCapacityInput, uint32_t* spaceCountOutput, XrReferenceSpaceType* spaces); +typedef XrResult (XRAPI_PTR *PFN_xrCreateReferenceSpace)(XrSession session, const XrReferenceSpaceCreateInfo* createInfo, XrSpace* space); +typedef XrResult (XRAPI_PTR *PFN_xrGetReferenceSpaceBoundsRect)(XrSession session, XrReferenceSpaceType referenceSpaceType, XrExtent2Df* bounds); +typedef XrResult (XRAPI_PTR *PFN_xrCreateActionSpace)(XrSession session, const XrActionSpaceCreateInfo* createInfo, XrSpace* space); +typedef XrResult (XRAPI_PTR *PFN_xrLocateSpace)(XrSpace space, XrSpace baseSpace, XrTime time, XrSpaceLocation* location); +typedef XrResult (XRAPI_PTR *PFN_xrDestroySpace)(XrSpace space); +typedef XrResult (XRAPI_PTR *PFN_xrEnumerateViewConfigurations)(XrInstance instance, XrSystemId systemId, uint32_t viewConfigurationTypeCapacityInput, uint32_t* viewConfigurationTypeCountOutput, XrViewConfigurationType* viewConfigurationTypes); +typedef XrResult (XRAPI_PTR *PFN_xrGetViewConfigurationProperties)(XrInstance instance, XrSystemId systemId, XrViewConfigurationType viewConfigurationType, XrViewConfigurationProperties* configurationProperties); +typedef XrResult (XRAPI_PTR *PFN_xrEnumerateViewConfigurationViews)(XrInstance instance, XrSystemId systemId, XrViewConfigurationType viewConfigurationType, uint32_t viewCapacityInput, uint32_t* viewCountOutput, XrViewConfigurationView* views); +typedef XrResult (XRAPI_PTR *PFN_xrEnumerateSwapchainFormats)(XrSession session, uint32_t formatCapacityInput, uint32_t* formatCountOutput, int64_t* formats); +typedef XrResult (XRAPI_PTR *PFN_xrCreateSwapchain)(XrSession session, const XrSwapchainCreateInfo* createInfo, XrSwapchain* swapchain); +typedef XrResult (XRAPI_PTR *PFN_xrDestroySwapchain)(XrSwapchain swapchain); +typedef XrResult (XRAPI_PTR *PFN_xrEnumerateSwapchainImages)(XrSwapchain swapchain, uint32_t imageCapacityInput, uint32_t* imageCountOutput, XrSwapchainImageBaseHeader* images); +typedef XrResult (XRAPI_PTR *PFN_xrAcquireSwapchainImage)(XrSwapchain swapchain, const XrSwapchainImageAcquireInfo* acquireInfo, uint32_t* index); +typedef XrResult (XRAPI_PTR *PFN_xrWaitSwapchainImage)(XrSwapchain swapchain, const XrSwapchainImageWaitInfo* waitInfo); +typedef XrResult (XRAPI_PTR *PFN_xrReleaseSwapchainImage)(XrSwapchain swapchain, const XrSwapchainImageReleaseInfo* releaseInfo); +typedef XrResult (XRAPI_PTR *PFN_xrBeginSession)(XrSession session, const XrSessionBeginInfo* beginInfo); +typedef XrResult (XRAPI_PTR *PFN_xrEndSession)(XrSession session); +typedef XrResult (XRAPI_PTR *PFN_xrRequestExitSession)(XrSession session); +typedef XrResult (XRAPI_PTR *PFN_xrWaitFrame)(XrSession session, const XrFrameWaitInfo* frameWaitInfo, XrFrameState* frameState); +typedef XrResult (XRAPI_PTR *PFN_xrBeginFrame)(XrSession session, const XrFrameBeginInfo* frameBeginInfo); +typedef XrResult (XRAPI_PTR *PFN_xrEndFrame)(XrSession session, const XrFrameEndInfo* frameEndInfo); +typedef XrResult (XRAPI_PTR *PFN_xrLocateViews)(XrSession session, const XrViewLocateInfo* viewLocateInfo, XrViewState* viewState, uint32_t viewCapacityInput, uint32_t* viewCountOutput, XrView* views); +typedef XrResult (XRAPI_PTR *PFN_xrStringToPath)(XrInstance instance, const char* pathString, XrPath* path); +typedef XrResult (XRAPI_PTR *PFN_xrPathToString)(XrInstance instance, XrPath path, uint32_t bufferCapacityInput, uint32_t* bufferCountOutput, char* buffer); +typedef XrResult (XRAPI_PTR *PFN_xrCreateActionSet)(XrInstance instance, const XrActionSetCreateInfo* createInfo, XrActionSet* actionSet); +typedef XrResult (XRAPI_PTR *PFN_xrDestroyActionSet)(XrActionSet actionSet); +typedef XrResult (XRAPI_PTR *PFN_xrCreateAction)(XrActionSet actionSet, const XrActionCreateInfo* createInfo, XrAction* action); +typedef XrResult (XRAPI_PTR *PFN_xrDestroyAction)(XrAction action); +typedef XrResult (XRAPI_PTR *PFN_xrSuggestInteractionProfileBindings)(XrInstance instance, const XrInteractionProfileSuggestedBinding* suggestedBindings); +typedef XrResult (XRAPI_PTR *PFN_xrAttachSessionActionSets)(XrSession session, const XrSessionActionSetsAttachInfo* attachInfo); +typedef XrResult (XRAPI_PTR *PFN_xrGetCurrentInteractionProfile)(XrSession session, XrPath topLevelUserPath, XrInteractionProfileState* interactionProfile); +typedef XrResult (XRAPI_PTR *PFN_xrGetActionStateBoolean)(XrSession session, const XrActionStateGetInfo* getInfo, XrActionStateBoolean* state); +typedef XrResult (XRAPI_PTR *PFN_xrGetActionStateFloat)(XrSession session, const XrActionStateGetInfo* getInfo, XrActionStateFloat* state); +typedef XrResult (XRAPI_PTR *PFN_xrGetActionStateVector2f)(XrSession session, const XrActionStateGetInfo* getInfo, XrActionStateVector2f* state); +typedef XrResult (XRAPI_PTR *PFN_xrGetActionStatePose)(XrSession session, const XrActionStateGetInfo* getInfo, XrActionStatePose* state); +typedef XrResult (XRAPI_PTR *PFN_xrSyncActions)(XrSession session, const XrActionsSyncInfo* syncInfo); +typedef XrResult (XRAPI_PTR *PFN_xrEnumerateBoundSourcesForAction)(XrSession session, const XrBoundSourcesForActionEnumerateInfo* enumerateInfo, uint32_t sourceCapacityInput, uint32_t* sourceCountOutput, XrPath* sources); +typedef XrResult (XRAPI_PTR *PFN_xrGetInputSourceLocalizedName)(XrSession session, const XrInputSourceLocalizedNameGetInfo* getInfo, uint32_t bufferCapacityInput, uint32_t* bufferCountOutput, char* buffer); +typedef XrResult (XRAPI_PTR *PFN_xrApplyHapticFeedback)(XrSession session, const XrHapticActionInfo* hapticActionInfo, const XrHapticBaseHeader* hapticFeedback); +typedef XrResult (XRAPI_PTR *PFN_xrStopHapticFeedback)(XrSession session, const XrHapticActionInfo* hapticActionInfo); + +#ifndef XR_NO_PROTOTYPES +XRAPI_ATTR XrResult XRAPI_CALL xrGetInstanceProcAddr( + XrInstance instance, + const char* name, + PFN_xrVoidFunction* function); + +XRAPI_ATTR XrResult XRAPI_CALL xrEnumerateApiLayerProperties( + uint32_t propertyCapacityInput, + uint32_t* propertyCountOutput, + XrApiLayerProperties* properties); + +XRAPI_ATTR XrResult XRAPI_CALL xrEnumerateInstanceExtensionProperties( + const char* layerName, + uint32_t propertyCapacityInput, + uint32_t* propertyCountOutput, + XrExtensionProperties* properties); + +XRAPI_ATTR XrResult XRAPI_CALL xrCreateInstance( + const XrInstanceCreateInfo* createInfo, + XrInstance* instance); + +XRAPI_ATTR XrResult XRAPI_CALL xrDestroyInstance( + XrInstance instance); + +XRAPI_ATTR XrResult XRAPI_CALL xrGetInstanceProperties( + XrInstance instance, + XrInstanceProperties* instanceProperties); + +XRAPI_ATTR XrResult XRAPI_CALL xrPollEvent( + XrInstance instance, + XrEventDataBuffer* eventData); + +XRAPI_ATTR XrResult XRAPI_CALL xrResultToString( + XrInstance instance, + XrResult value, + char buffer[XR_MAX_RESULT_STRING_SIZE]); + +XRAPI_ATTR XrResult XRAPI_CALL xrStructureTypeToString( + XrInstance instance, + XrStructureType value, + char buffer[XR_MAX_STRUCTURE_NAME_SIZE]); + +XRAPI_ATTR XrResult XRAPI_CALL xrGetSystem( + XrInstance instance, + const XrSystemGetInfo* getInfo, + XrSystemId* systemId); + +XRAPI_ATTR XrResult XRAPI_CALL xrGetSystemProperties( + XrInstance instance, + XrSystemId systemId, + XrSystemProperties* properties); + +XRAPI_ATTR XrResult XRAPI_CALL xrEnumerateEnvironmentBlendModes( + XrInstance instance, + XrSystemId systemId, + XrViewConfigurationType viewConfigurationType, + uint32_t environmentBlendModeCapacityInput, + uint32_t* environmentBlendModeCountOutput, + XrEnvironmentBlendMode* environmentBlendModes); + +XRAPI_ATTR XrResult XRAPI_CALL xrCreateSession( + XrInstance instance, + const XrSessionCreateInfo* createInfo, + XrSession* session); + +XRAPI_ATTR XrResult XRAPI_CALL xrDestroySession( + XrSession session); + +XRAPI_ATTR XrResult XRAPI_CALL xrEnumerateReferenceSpaces( + XrSession session, + uint32_t spaceCapacityInput, + uint32_t* spaceCountOutput, + XrReferenceSpaceType* spaces); + +XRAPI_ATTR XrResult XRAPI_CALL xrCreateReferenceSpace( + XrSession session, + const XrReferenceSpaceCreateInfo* createInfo, + XrSpace* space); + +XRAPI_ATTR XrResult XRAPI_CALL xrGetReferenceSpaceBoundsRect( + XrSession session, + XrReferenceSpaceType referenceSpaceType, + XrExtent2Df* bounds); + +XRAPI_ATTR XrResult XRAPI_CALL xrCreateActionSpace( + XrSession session, + const XrActionSpaceCreateInfo* createInfo, + XrSpace* space); + +XRAPI_ATTR XrResult XRAPI_CALL xrLocateSpace( + XrSpace space, + XrSpace baseSpace, + XrTime time, + XrSpaceLocation* location); + +XRAPI_ATTR XrResult XRAPI_CALL xrDestroySpace( + XrSpace space); + +XRAPI_ATTR XrResult XRAPI_CALL xrEnumerateViewConfigurations( + XrInstance instance, + XrSystemId systemId, + uint32_t viewConfigurationTypeCapacityInput, + uint32_t* viewConfigurationTypeCountOutput, + XrViewConfigurationType* viewConfigurationTypes); + +XRAPI_ATTR XrResult XRAPI_CALL xrGetViewConfigurationProperties( + XrInstance instance, + XrSystemId systemId, + XrViewConfigurationType viewConfigurationType, + XrViewConfigurationProperties* configurationProperties); + +XRAPI_ATTR XrResult XRAPI_CALL xrEnumerateViewConfigurationViews( + XrInstance instance, + XrSystemId systemId, + XrViewConfigurationType viewConfigurationType, + uint32_t viewCapacityInput, + uint32_t* viewCountOutput, + XrViewConfigurationView* views); + +XRAPI_ATTR XrResult XRAPI_CALL xrEnumerateSwapchainFormats( + XrSession session, + uint32_t formatCapacityInput, + uint32_t* formatCountOutput, + int64_t* formats); + +XRAPI_ATTR XrResult XRAPI_CALL xrCreateSwapchain( + XrSession session, + const XrSwapchainCreateInfo* createInfo, + XrSwapchain* swapchain); + +XRAPI_ATTR XrResult XRAPI_CALL xrDestroySwapchain( + XrSwapchain swapchain); + +XRAPI_ATTR XrResult XRAPI_CALL xrEnumerateSwapchainImages( + XrSwapchain swapchain, + uint32_t imageCapacityInput, + uint32_t* imageCountOutput, + XrSwapchainImageBaseHeader* images); + +XRAPI_ATTR XrResult XRAPI_CALL xrAcquireSwapchainImage( + XrSwapchain swapchain, + const XrSwapchainImageAcquireInfo* acquireInfo, + uint32_t* index); + +XRAPI_ATTR XrResult XRAPI_CALL xrWaitSwapchainImage( + XrSwapchain swapchain, + const XrSwapchainImageWaitInfo* waitInfo); + +XRAPI_ATTR XrResult XRAPI_CALL xrReleaseSwapchainImage( + XrSwapchain swapchain, + const XrSwapchainImageReleaseInfo* releaseInfo); + +XRAPI_ATTR XrResult XRAPI_CALL xrBeginSession( + XrSession session, + const XrSessionBeginInfo* beginInfo); + +XRAPI_ATTR XrResult XRAPI_CALL xrEndSession( + XrSession session); + +XRAPI_ATTR XrResult XRAPI_CALL xrRequestExitSession( + XrSession session); + +XRAPI_ATTR XrResult XRAPI_CALL xrWaitFrame( + XrSession session, + const XrFrameWaitInfo* frameWaitInfo, + XrFrameState* frameState); + +XRAPI_ATTR XrResult XRAPI_CALL xrBeginFrame( + XrSession session, + const XrFrameBeginInfo* frameBeginInfo); + +XRAPI_ATTR XrResult XRAPI_CALL xrEndFrame( + XrSession session, + const XrFrameEndInfo* frameEndInfo); + +XRAPI_ATTR XrResult XRAPI_CALL xrLocateViews( + XrSession session, + const XrViewLocateInfo* viewLocateInfo, + XrViewState* viewState, + uint32_t viewCapacityInput, + uint32_t* viewCountOutput, + XrView* views); + +XRAPI_ATTR XrResult XRAPI_CALL xrStringToPath( + XrInstance instance, + const char* pathString, + XrPath* path); + +XRAPI_ATTR XrResult XRAPI_CALL xrPathToString( + XrInstance instance, + XrPath path, + uint32_t bufferCapacityInput, + uint32_t* bufferCountOutput, + char* buffer); + +XRAPI_ATTR XrResult XRAPI_CALL xrCreateActionSet( + XrInstance instance, + const XrActionSetCreateInfo* createInfo, + XrActionSet* actionSet); + +XRAPI_ATTR XrResult XRAPI_CALL xrDestroyActionSet( + XrActionSet actionSet); + +XRAPI_ATTR XrResult XRAPI_CALL xrCreateAction( + XrActionSet actionSet, + const XrActionCreateInfo* createInfo, + XrAction* action); + +XRAPI_ATTR XrResult XRAPI_CALL xrDestroyAction( + XrAction action); + +XRAPI_ATTR XrResult XRAPI_CALL xrSuggestInteractionProfileBindings( + XrInstance instance, + const XrInteractionProfileSuggestedBinding* suggestedBindings); + +XRAPI_ATTR XrResult XRAPI_CALL xrAttachSessionActionSets( + XrSession session, + const XrSessionActionSetsAttachInfo* attachInfo); + +XRAPI_ATTR XrResult XRAPI_CALL xrGetCurrentInteractionProfile( + XrSession session, + XrPath topLevelUserPath, + XrInteractionProfileState* interactionProfile); + +XRAPI_ATTR XrResult XRAPI_CALL xrGetActionStateBoolean( + XrSession session, + const XrActionStateGetInfo* getInfo, + XrActionStateBoolean* state); + +XRAPI_ATTR XrResult XRAPI_CALL xrGetActionStateFloat( + XrSession session, + const XrActionStateGetInfo* getInfo, + XrActionStateFloat* state); + +XRAPI_ATTR XrResult XRAPI_CALL xrGetActionStateVector2f( + XrSession session, + const XrActionStateGetInfo* getInfo, + XrActionStateVector2f* state); + +XRAPI_ATTR XrResult XRAPI_CALL xrGetActionStatePose( + XrSession session, + const XrActionStateGetInfo* getInfo, + XrActionStatePose* state); + +XRAPI_ATTR XrResult XRAPI_CALL xrSyncActions( + XrSession session, + const XrActionsSyncInfo* syncInfo); + +XRAPI_ATTR XrResult XRAPI_CALL xrEnumerateBoundSourcesForAction( + XrSession session, + const XrBoundSourcesForActionEnumerateInfo* enumerateInfo, + uint32_t sourceCapacityInput, + uint32_t* sourceCountOutput, + XrPath* sources); + +XRAPI_ATTR XrResult XRAPI_CALL xrGetInputSourceLocalizedName( + XrSession session, + const XrInputSourceLocalizedNameGetInfo* getInfo, + uint32_t bufferCapacityInput, + uint32_t* bufferCountOutput, + char* buffer); + +XRAPI_ATTR XrResult XRAPI_CALL xrApplyHapticFeedback( + XrSession session, + const XrHapticActionInfo* hapticActionInfo, + const XrHapticBaseHeader* hapticFeedback); + +XRAPI_ATTR XrResult XRAPI_CALL xrStopHapticFeedback( + XrSession session, + const XrHapticActionInfo* hapticActionInfo); +#endif /* !XR_NO_PROTOTYPES */ + + +#define XR_KHR_composition_layer_cube 1 +#define XR_KHR_composition_layer_cube_SPEC_VERSION 8 +#define XR_KHR_COMPOSITION_LAYER_CUBE_EXTENSION_NAME "XR_KHR_composition_layer_cube" +typedef struct XrCompositionLayerCubeKHR { + XrStructureType type; + const void* XR_MAY_ALIAS next; + XrCompositionLayerFlags layerFlags; + XrSpace space; + XrEyeVisibility eyeVisibility; + XrSwapchain swapchain; + uint32_t imageArrayIndex; + XrQuaternionf orientation; +} XrCompositionLayerCubeKHR; + + + +#define XR_KHR_composition_layer_depth 1 +#define XR_KHR_composition_layer_depth_SPEC_VERSION 6 +#define XR_KHR_COMPOSITION_LAYER_DEPTH_EXTENSION_NAME "XR_KHR_composition_layer_depth" +// XrCompositionLayerDepthInfoKHR extends XrCompositionLayerProjectionView +typedef struct XrCompositionLayerDepthInfoKHR { + XrStructureType type; + const void* XR_MAY_ALIAS next; + XrSwapchainSubImage subImage; + float minDepth; + float maxDepth; + float nearZ; + float farZ; +} XrCompositionLayerDepthInfoKHR; + + + +#define XR_KHR_composition_layer_cylinder 1 +#define XR_KHR_composition_layer_cylinder_SPEC_VERSION 4 +#define XR_KHR_COMPOSITION_LAYER_CYLINDER_EXTENSION_NAME "XR_KHR_composition_layer_cylinder" +typedef struct XrCompositionLayerCylinderKHR { + XrStructureType type; + const void* XR_MAY_ALIAS next; + XrCompositionLayerFlags layerFlags; + XrSpace space; + XrEyeVisibility eyeVisibility; + XrSwapchainSubImage subImage; + XrPosef pose; + float radius; + float centralAngle; + float aspectRatio; +} XrCompositionLayerCylinderKHR; + + + +#define XR_KHR_composition_layer_equirect 1 +#define XR_KHR_composition_layer_equirect_SPEC_VERSION 3 +#define XR_KHR_COMPOSITION_LAYER_EQUIRECT_EXTENSION_NAME "XR_KHR_composition_layer_equirect" +typedef struct XrCompositionLayerEquirectKHR { + XrStructureType type; + const void* XR_MAY_ALIAS next; + XrCompositionLayerFlags layerFlags; + XrSpace space; + XrEyeVisibility eyeVisibility; + XrSwapchainSubImage subImage; + XrPosef pose; + float radius; + XrVector2f scale; + XrVector2f bias; +} XrCompositionLayerEquirectKHR; + + + +#define XR_KHR_visibility_mask 1 +#define XR_KHR_visibility_mask_SPEC_VERSION 2 +#define XR_KHR_VISIBILITY_MASK_EXTENSION_NAME "XR_KHR_visibility_mask" + +typedef enum XrVisibilityMaskTypeKHR { + XR_VISIBILITY_MASK_TYPE_HIDDEN_TRIANGLE_MESH_KHR = 1, + XR_VISIBILITY_MASK_TYPE_VISIBLE_TRIANGLE_MESH_KHR = 2, + XR_VISIBILITY_MASK_TYPE_LINE_LOOP_KHR = 3, + XR_VISIBILITY_MASK_TYPE_MAX_ENUM_KHR = 0x7FFFFFFF +} XrVisibilityMaskTypeKHR; +typedef struct XrVisibilityMaskKHR { + XrStructureType type; + void* XR_MAY_ALIAS next; + uint32_t vertexCapacityInput; + uint32_t vertexCountOutput; + XrVector2f* vertices; + uint32_t indexCapacityInput; + uint32_t indexCountOutput; + uint32_t* indices; +} XrVisibilityMaskKHR; + +typedef struct XrEventDataVisibilityMaskChangedKHR { + XrStructureType type; + const void* XR_MAY_ALIAS next; + XrSession session; + XrViewConfigurationType viewConfigurationType; + uint32_t viewIndex; +} XrEventDataVisibilityMaskChangedKHR; + +typedef XrResult (XRAPI_PTR *PFN_xrGetVisibilityMaskKHR)(XrSession session, XrViewConfigurationType viewConfigurationType, uint32_t viewIndex, XrVisibilityMaskTypeKHR visibilityMaskType, XrVisibilityMaskKHR* visibilityMask); + +#ifndef XR_NO_PROTOTYPES +#ifdef XR_EXTENSION_PROTOTYPES +XRAPI_ATTR XrResult XRAPI_CALL xrGetVisibilityMaskKHR( + XrSession session, + XrViewConfigurationType viewConfigurationType, + uint32_t viewIndex, + XrVisibilityMaskTypeKHR visibilityMaskType, + XrVisibilityMaskKHR* visibilityMask); +#endif /* XR_EXTENSION_PROTOTYPES */ +#endif /* !XR_NO_PROTOTYPES */ + + +#define XR_KHR_composition_layer_color_scale_bias 1 +#define XR_KHR_composition_layer_color_scale_bias_SPEC_VERSION 5 +#define XR_KHR_COMPOSITION_LAYER_COLOR_SCALE_BIAS_EXTENSION_NAME "XR_KHR_composition_layer_color_scale_bias" +// XrCompositionLayerColorScaleBiasKHR extends XrCompositionLayerBaseHeader +typedef struct XrCompositionLayerColorScaleBiasKHR { + XrStructureType type; + const void* XR_MAY_ALIAS next; + XrColor4f colorScale; + XrColor4f colorBias; +} XrCompositionLayerColorScaleBiasKHR; + + + +#define XR_KHR_loader_init 1 +#define XR_KHR_loader_init_SPEC_VERSION 1 +#define XR_KHR_LOADER_INIT_EXTENSION_NAME "XR_KHR_loader_init" +typedef struct XR_MAY_ALIAS XrLoaderInitInfoBaseHeaderKHR { + XrStructureType type; + const void* XR_MAY_ALIAS next; +} XrLoaderInitInfoBaseHeaderKHR; + +typedef XrResult (XRAPI_PTR *PFN_xrInitializeLoaderKHR)(const XrLoaderInitInfoBaseHeaderKHR* loaderInitInfo); + +#ifndef XR_NO_PROTOTYPES +#ifdef XR_EXTENSION_PROTOTYPES +XRAPI_ATTR XrResult XRAPI_CALL xrInitializeLoaderKHR( + const XrLoaderInitInfoBaseHeaderKHR* loaderInitInfo); +#endif /* XR_EXTENSION_PROTOTYPES */ +#endif /* !XR_NO_PROTOTYPES */ + + +#define XR_KHR_composition_layer_equirect2 1 +#define XR_KHR_composition_layer_equirect2_SPEC_VERSION 1 +#define XR_KHR_COMPOSITION_LAYER_EQUIRECT2_EXTENSION_NAME "XR_KHR_composition_layer_equirect2" +typedef struct XrCompositionLayerEquirect2KHR { + XrStructureType type; + const void* XR_MAY_ALIAS next; + XrCompositionLayerFlags layerFlags; + XrSpace space; + XrEyeVisibility eyeVisibility; + XrSwapchainSubImage subImage; + XrPosef pose; + float radius; + float centralHorizontalAngle; + float upperVerticalAngle; + float lowerVerticalAngle; +} XrCompositionLayerEquirect2KHR; + + + +#define XR_KHR_binding_modification 1 +#define XR_KHR_binding_modification_SPEC_VERSION 1 +#define XR_KHR_BINDING_MODIFICATION_EXTENSION_NAME "XR_KHR_binding_modification" +typedef struct XR_MAY_ALIAS XrBindingModificationBaseHeaderKHR { + XrStructureType type; + const void* XR_MAY_ALIAS next; +} XrBindingModificationBaseHeaderKHR; + +// XrBindingModificationsKHR extends XrInteractionProfileSuggestedBinding +typedef struct XrBindingModificationsKHR { + XrStructureType type; + const void* XR_MAY_ALIAS next; + uint32_t bindingModificationCount; + const XrBindingModificationBaseHeaderKHR* const* bindingModifications; +} XrBindingModificationsKHR; + + + +#define XR_KHR_swapchain_usage_input_attachment_bit 1 +#define XR_KHR_swapchain_usage_input_attachment_bit_SPEC_VERSION 3 +#define XR_KHR_SWAPCHAIN_USAGE_INPUT_ATTACHMENT_BIT_EXTENSION_NAME "XR_KHR_swapchain_usage_input_attachment_bit" + + +#define XR_EXT_performance_settings 1 +#define XR_EXT_performance_settings_SPEC_VERSION 4 +#define XR_EXT_PERFORMANCE_SETTINGS_EXTENSION_NAME "XR_EXT_performance_settings" + +typedef enum XrPerfSettingsDomainEXT { + XR_PERF_SETTINGS_DOMAIN_CPU_EXT = 1, + XR_PERF_SETTINGS_DOMAIN_GPU_EXT = 2, + XR_PERF_SETTINGS_DOMAIN_MAX_ENUM_EXT = 0x7FFFFFFF +} XrPerfSettingsDomainEXT; + +typedef enum XrPerfSettingsSubDomainEXT { + XR_PERF_SETTINGS_SUB_DOMAIN_COMPOSITING_EXT = 1, + XR_PERF_SETTINGS_SUB_DOMAIN_RENDERING_EXT = 2, + XR_PERF_SETTINGS_SUB_DOMAIN_THERMAL_EXT = 3, + XR_PERF_SETTINGS_SUB_DOMAIN_MAX_ENUM_EXT = 0x7FFFFFFF +} XrPerfSettingsSubDomainEXT; + +typedef enum XrPerfSettingsLevelEXT { + XR_PERF_SETTINGS_LEVEL_POWER_SAVINGS_EXT = 0, + XR_PERF_SETTINGS_LEVEL_SUSTAINED_LOW_EXT = 25, + XR_PERF_SETTINGS_LEVEL_SUSTAINED_HIGH_EXT = 50, + XR_PERF_SETTINGS_LEVEL_BOOST_EXT = 75, + XR_PERF_SETTINGS_LEVEL_MAX_ENUM_EXT = 0x7FFFFFFF +} XrPerfSettingsLevelEXT; + +typedef enum XrPerfSettingsNotificationLevelEXT { + XR_PERF_SETTINGS_NOTIF_LEVEL_NORMAL_EXT = 0, + XR_PERF_SETTINGS_NOTIF_LEVEL_WARNING_EXT = 25, + XR_PERF_SETTINGS_NOTIF_LEVEL_IMPAIRED_EXT = 75, + XR_PERF_SETTINGS_NOTIFICATION_LEVEL_MAX_ENUM_EXT = 0x7FFFFFFF +} XrPerfSettingsNotificationLevelEXT; +typedef struct XrEventDataPerfSettingsEXT { + XrStructureType type; + const void* XR_MAY_ALIAS next; + XrPerfSettingsDomainEXT domain; + XrPerfSettingsSubDomainEXT subDomain; + XrPerfSettingsNotificationLevelEXT fromLevel; + XrPerfSettingsNotificationLevelEXT toLevel; +} XrEventDataPerfSettingsEXT; + +typedef XrResult (XRAPI_PTR *PFN_xrPerfSettingsSetPerformanceLevelEXT)(XrSession session, XrPerfSettingsDomainEXT domain, XrPerfSettingsLevelEXT level); + +#ifndef XR_NO_PROTOTYPES +#ifdef XR_EXTENSION_PROTOTYPES +XRAPI_ATTR XrResult XRAPI_CALL xrPerfSettingsSetPerformanceLevelEXT( + XrSession session, + XrPerfSettingsDomainEXT domain, + XrPerfSettingsLevelEXT level); +#endif /* XR_EXTENSION_PROTOTYPES */ +#endif /* !XR_NO_PROTOTYPES */ + + +#define XR_EXT_thermal_query 1 +#define XR_EXT_thermal_query_SPEC_VERSION 2 +#define XR_EXT_THERMAL_QUERY_EXTENSION_NAME "XR_EXT_thermal_query" +typedef XrResult (XRAPI_PTR *PFN_xrThermalGetTemperatureTrendEXT)(XrSession session, XrPerfSettingsDomainEXT domain, XrPerfSettingsNotificationLevelEXT* notificationLevel, float* tempHeadroom, float* tempSlope); + +#ifndef XR_NO_PROTOTYPES +#ifdef XR_EXTENSION_PROTOTYPES +XRAPI_ATTR XrResult XRAPI_CALL xrThermalGetTemperatureTrendEXT( + XrSession session, + XrPerfSettingsDomainEXT domain, + XrPerfSettingsNotificationLevelEXT* notificationLevel, + float* tempHeadroom, + float* tempSlope); +#endif /* XR_EXTENSION_PROTOTYPES */ +#endif /* !XR_NO_PROTOTYPES */ + + +#define XR_EXT_debug_utils 1 +XR_DEFINE_HANDLE(XrDebugUtilsMessengerEXT) +#define XR_EXT_debug_utils_SPEC_VERSION 4 +#define XR_EXT_DEBUG_UTILS_EXTENSION_NAME "XR_EXT_debug_utils" +typedef XrFlags64 XrDebugUtilsMessageSeverityFlagsEXT; + +// Flag bits for XrDebugUtilsMessageSeverityFlagsEXT +static const XrDebugUtilsMessageSeverityFlagsEXT XR_DEBUG_UTILS_MESSAGE_SEVERITY_VERBOSE_BIT_EXT = 0x00000001; +static const XrDebugUtilsMessageSeverityFlagsEXT XR_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT = 0x00000010; +static const XrDebugUtilsMessageSeverityFlagsEXT XR_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT = 0x00000100; +static const XrDebugUtilsMessageSeverityFlagsEXT XR_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT = 0x00001000; + +typedef XrFlags64 XrDebugUtilsMessageTypeFlagsEXT; + +// Flag bits for XrDebugUtilsMessageTypeFlagsEXT +static const XrDebugUtilsMessageTypeFlagsEXT XR_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT = 0x00000001; +static const XrDebugUtilsMessageTypeFlagsEXT XR_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT = 0x00000002; +static const XrDebugUtilsMessageTypeFlagsEXT XR_DEBUG_UTILS_MESSAGE_TYPE_PERFORMANCE_BIT_EXT = 0x00000004; +static const XrDebugUtilsMessageTypeFlagsEXT XR_DEBUG_UTILS_MESSAGE_TYPE_CONFORMANCE_BIT_EXT = 0x00000008; + +typedef struct XrDebugUtilsObjectNameInfoEXT { + XrStructureType type; + const void* XR_MAY_ALIAS next; + XrObjectType objectType; + uint64_t objectHandle; + const char* objectName; +} XrDebugUtilsObjectNameInfoEXT; + +typedef struct XrDebugUtilsLabelEXT { + XrStructureType type; + const void* XR_MAY_ALIAS next; + const char* labelName; +} XrDebugUtilsLabelEXT; + +typedef struct XrDebugUtilsMessengerCallbackDataEXT { + XrStructureType type; + const void* XR_MAY_ALIAS next; + const char* messageId; + const char* functionName; + const char* message; + uint32_t objectCount; + XrDebugUtilsObjectNameInfoEXT* objects; + uint32_t sessionLabelCount; + XrDebugUtilsLabelEXT* sessionLabels; +} XrDebugUtilsMessengerCallbackDataEXT; + +typedef XrBool32 (XRAPI_PTR *PFN_xrDebugUtilsMessengerCallbackEXT)( + XrDebugUtilsMessageSeverityFlagsEXT messageSeverity, + XrDebugUtilsMessageTypeFlagsEXT messageTypes, + const XrDebugUtilsMessengerCallbackDataEXT* callbackData, + void* userData); + + +// XrDebugUtilsMessengerCreateInfoEXT extends XrInstanceCreateInfo +typedef struct XrDebugUtilsMessengerCreateInfoEXT { + XrStructureType type; + const void* XR_MAY_ALIAS next; + XrDebugUtilsMessageSeverityFlagsEXT messageSeverities; + XrDebugUtilsMessageTypeFlagsEXT messageTypes; + PFN_xrDebugUtilsMessengerCallbackEXT userCallback; + void* XR_MAY_ALIAS userData; +} XrDebugUtilsMessengerCreateInfoEXT; + +typedef XrResult (XRAPI_PTR *PFN_xrSetDebugUtilsObjectNameEXT)(XrInstance instance, const XrDebugUtilsObjectNameInfoEXT* nameInfo); +typedef XrResult (XRAPI_PTR *PFN_xrCreateDebugUtilsMessengerEXT)(XrInstance instance, const XrDebugUtilsMessengerCreateInfoEXT* createInfo, XrDebugUtilsMessengerEXT* messenger); +typedef XrResult (XRAPI_PTR *PFN_xrDestroyDebugUtilsMessengerEXT)(XrDebugUtilsMessengerEXT messenger); +typedef XrResult (XRAPI_PTR *PFN_xrSubmitDebugUtilsMessageEXT)(XrInstance instance, XrDebugUtilsMessageSeverityFlagsEXT messageSeverity, XrDebugUtilsMessageTypeFlagsEXT messageTypes, const XrDebugUtilsMessengerCallbackDataEXT* callbackData); +typedef XrResult (XRAPI_PTR *PFN_xrSessionBeginDebugUtilsLabelRegionEXT)(XrSession session, const XrDebugUtilsLabelEXT* labelInfo); +typedef XrResult (XRAPI_PTR *PFN_xrSessionEndDebugUtilsLabelRegionEXT)(XrSession session); +typedef XrResult (XRAPI_PTR *PFN_xrSessionInsertDebugUtilsLabelEXT)(XrSession session, const XrDebugUtilsLabelEXT* labelInfo); + +#ifndef XR_NO_PROTOTYPES +#ifdef XR_EXTENSION_PROTOTYPES +XRAPI_ATTR XrResult XRAPI_CALL xrSetDebugUtilsObjectNameEXT( + XrInstance instance, + const XrDebugUtilsObjectNameInfoEXT* nameInfo); + +XRAPI_ATTR XrResult XRAPI_CALL xrCreateDebugUtilsMessengerEXT( + XrInstance instance, + const XrDebugUtilsMessengerCreateInfoEXT* createInfo, + XrDebugUtilsMessengerEXT* messenger); + +XRAPI_ATTR XrResult XRAPI_CALL xrDestroyDebugUtilsMessengerEXT( + XrDebugUtilsMessengerEXT messenger); + +XRAPI_ATTR XrResult XRAPI_CALL xrSubmitDebugUtilsMessageEXT( + XrInstance instance, + XrDebugUtilsMessageSeverityFlagsEXT messageSeverity, + XrDebugUtilsMessageTypeFlagsEXT messageTypes, + const XrDebugUtilsMessengerCallbackDataEXT* callbackData); + +XRAPI_ATTR XrResult XRAPI_CALL xrSessionBeginDebugUtilsLabelRegionEXT( + XrSession session, + const XrDebugUtilsLabelEXT* labelInfo); + +XRAPI_ATTR XrResult XRAPI_CALL xrSessionEndDebugUtilsLabelRegionEXT( + XrSession session); + +XRAPI_ATTR XrResult XRAPI_CALL xrSessionInsertDebugUtilsLabelEXT( + XrSession session, + const XrDebugUtilsLabelEXT* labelInfo); +#endif /* XR_EXTENSION_PROTOTYPES */ +#endif /* !XR_NO_PROTOTYPES */ + + +#define XR_EXT_eye_gaze_interaction 1 +#define XR_EXT_eye_gaze_interaction_SPEC_VERSION 2 +#define XR_EXT_EYE_GAZE_INTERACTION_EXTENSION_NAME "XR_EXT_eye_gaze_interaction" +// XrSystemEyeGazeInteractionPropertiesEXT extends XrSystemProperties +typedef struct XrSystemEyeGazeInteractionPropertiesEXT { + XrStructureType type; + void* XR_MAY_ALIAS next; + XrBool32 supportsEyeGazeInteraction; +} XrSystemEyeGazeInteractionPropertiesEXT; + +// XrEyeGazeSampleTimeEXT extends XrSpaceLocation +typedef struct XrEyeGazeSampleTimeEXT { + XrStructureType type; + void* XR_MAY_ALIAS next; + XrTime time; +} XrEyeGazeSampleTimeEXT; + + + +#define XR_EXTX_overlay 1 +#define XR_EXTX_overlay_SPEC_VERSION 5 +#define XR_EXTX_OVERLAY_EXTENSION_NAME "XR_EXTX_overlay" +typedef XrFlags64 XrOverlaySessionCreateFlagsEXTX; + +// Flag bits for XrOverlaySessionCreateFlagsEXTX + +typedef XrFlags64 XrOverlayMainSessionFlagsEXTX; + +// Flag bits for XrOverlayMainSessionFlagsEXTX +static const XrOverlayMainSessionFlagsEXTX XR_OVERLAY_MAIN_SESSION_ENABLED_COMPOSITION_LAYER_INFO_DEPTH_BIT_EXTX = 0x00000001; + +// XrSessionCreateInfoOverlayEXTX extends XrSessionCreateInfo +typedef struct XrSessionCreateInfoOverlayEXTX { + XrStructureType type; + const void* XR_MAY_ALIAS next; + XrOverlaySessionCreateFlagsEXTX createFlags; + uint32_t sessionLayersPlacement; +} XrSessionCreateInfoOverlayEXTX; + +typedef struct XrEventDataMainSessionVisibilityChangedEXTX { + XrStructureType type; + const void* XR_MAY_ALIAS next; + XrBool32 visible; + XrOverlayMainSessionFlagsEXTX flags; +} XrEventDataMainSessionVisibilityChangedEXTX; + + + +#define XR_VARJO_quad_views 1 +#define XR_VARJO_quad_views_SPEC_VERSION 1 +#define XR_VARJO_QUAD_VIEWS_EXTENSION_NAME "XR_VARJO_quad_views" + + +#define XR_MSFT_unbounded_reference_space 1 +#define XR_MSFT_unbounded_reference_space_SPEC_VERSION 1 +#define XR_MSFT_UNBOUNDED_REFERENCE_SPACE_EXTENSION_NAME "XR_MSFT_unbounded_reference_space" + + +#define XR_MSFT_spatial_anchor 1 +XR_DEFINE_HANDLE(XrSpatialAnchorMSFT) +#define XR_MSFT_spatial_anchor_SPEC_VERSION 2 +#define XR_MSFT_SPATIAL_ANCHOR_EXTENSION_NAME "XR_MSFT_spatial_anchor" +typedef struct XrSpatialAnchorCreateInfoMSFT { + XrStructureType type; + const void* XR_MAY_ALIAS next; + XrSpace space; + XrPosef pose; + XrTime time; +} XrSpatialAnchorCreateInfoMSFT; + +typedef struct XrSpatialAnchorSpaceCreateInfoMSFT { + XrStructureType type; + const void* XR_MAY_ALIAS next; + XrSpatialAnchorMSFT anchor; + XrPosef poseInAnchorSpace; +} XrSpatialAnchorSpaceCreateInfoMSFT; + +typedef XrResult (XRAPI_PTR *PFN_xrCreateSpatialAnchorMSFT)(XrSession session, const XrSpatialAnchorCreateInfoMSFT* createInfo, XrSpatialAnchorMSFT* anchor); +typedef XrResult (XRAPI_PTR *PFN_xrCreateSpatialAnchorSpaceMSFT)(XrSession session, const XrSpatialAnchorSpaceCreateInfoMSFT* createInfo, XrSpace* space); +typedef XrResult (XRAPI_PTR *PFN_xrDestroySpatialAnchorMSFT)(XrSpatialAnchorMSFT anchor); + +#ifndef XR_NO_PROTOTYPES +#ifdef XR_EXTENSION_PROTOTYPES +XRAPI_ATTR XrResult XRAPI_CALL xrCreateSpatialAnchorMSFT( + XrSession session, + const XrSpatialAnchorCreateInfoMSFT* createInfo, + XrSpatialAnchorMSFT* anchor); + +XRAPI_ATTR XrResult XRAPI_CALL xrCreateSpatialAnchorSpaceMSFT( + XrSession session, + const XrSpatialAnchorSpaceCreateInfoMSFT* createInfo, + XrSpace* space); + +XRAPI_ATTR XrResult XRAPI_CALL xrDestroySpatialAnchorMSFT( + XrSpatialAnchorMSFT anchor); +#endif /* XR_EXTENSION_PROTOTYPES */ +#endif /* !XR_NO_PROTOTYPES */ + + +#define XR_FB_composition_layer_image_layout 1 +#define XR_FB_composition_layer_image_layout_SPEC_VERSION 1 +#define XR_FB_COMPOSITION_LAYER_IMAGE_LAYOUT_EXTENSION_NAME "XR_FB_composition_layer_image_layout" +typedef XrFlags64 XrCompositionLayerImageLayoutFlagsFB; + +// Flag bits for XrCompositionLayerImageLayoutFlagsFB +static const XrCompositionLayerImageLayoutFlagsFB XR_COMPOSITION_LAYER_IMAGE_LAYOUT_VERTICAL_FLIP_BIT_FB = 0x00000001; + +// XrCompositionLayerImageLayoutFB extends XrCompositionLayerBaseHeader +typedef struct XrCompositionLayerImageLayoutFB { + XrStructureType type; + void* XR_MAY_ALIAS next; + XrCompositionLayerImageLayoutFlagsFB flags; +} XrCompositionLayerImageLayoutFB; + + + +#define XR_FB_composition_layer_alpha_blend 1 +#define XR_FB_composition_layer_alpha_blend_SPEC_VERSION 2 +#define XR_FB_COMPOSITION_LAYER_ALPHA_BLEND_EXTENSION_NAME "XR_FB_composition_layer_alpha_blend" + +typedef enum XrBlendFactorFB { + XR_BLEND_FACTOR_ZERO_FB = 0, + XR_BLEND_FACTOR_ONE_FB = 1, + XR_BLEND_FACTOR_SRC_ALPHA_FB = 2, + XR_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA_FB = 3, + XR_BLEND_FACTOR_DST_ALPHA_FB = 4, + XR_BLEND_FACTOR_ONE_MINUS_DST_ALPHA_FB = 5, + XR_BLEND_FACTOR_MAX_ENUM_FB = 0x7FFFFFFF +} XrBlendFactorFB; +// XrCompositionLayerAlphaBlendFB extends XrCompositionLayerBaseHeader +typedef struct XrCompositionLayerAlphaBlendFB { + XrStructureType type; + void* XR_MAY_ALIAS next; + XrBlendFactorFB srcFactorColor; + XrBlendFactorFB dstFactorColor; + XrBlendFactorFB srcFactorAlpha; + XrBlendFactorFB dstFactorAlpha; +} XrCompositionLayerAlphaBlendFB; + + + +#define XR_MND_headless 1 +#define XR_MND_headless_SPEC_VERSION 2 +#define XR_MND_HEADLESS_EXTENSION_NAME "XR_MND_headless" + + +#define XR_OCULUS_android_session_state_enable 1 +#define XR_OCULUS_android_session_state_enable_SPEC_VERSION 1 +#define XR_OCULUS_ANDROID_SESSION_STATE_ENABLE_EXTENSION_NAME "XR_OCULUS_android_session_state_enable" + + +#define XR_EXT_view_configuration_depth_range 1 +#define XR_EXT_view_configuration_depth_range_SPEC_VERSION 1 +#define XR_EXT_VIEW_CONFIGURATION_DEPTH_RANGE_EXTENSION_NAME "XR_EXT_view_configuration_depth_range" +// XrViewConfigurationDepthRangeEXT extends XrViewConfigurationView +typedef struct XrViewConfigurationDepthRangeEXT { + XrStructureType type; + void* XR_MAY_ALIAS next; + float recommendedNearZ; + float minNearZ; + float recommendedFarZ; + float maxFarZ; +} XrViewConfigurationDepthRangeEXT; + + + +#define XR_EXT_conformance_automation 1 +#define XR_EXT_conformance_automation_SPEC_VERSION 3 +#define XR_EXT_CONFORMANCE_AUTOMATION_EXTENSION_NAME "XR_EXT_conformance_automation" +typedef XrResult (XRAPI_PTR *PFN_xrSetInputDeviceActiveEXT)(XrSession session, XrPath interactionProfile, XrPath topLevelPath, XrBool32 isActive); +typedef XrResult (XRAPI_PTR *PFN_xrSetInputDeviceStateBoolEXT)(XrSession session, XrPath topLevelPath, XrPath inputSourcePath, XrBool32 state); +typedef XrResult (XRAPI_PTR *PFN_xrSetInputDeviceStateFloatEXT)(XrSession session, XrPath topLevelPath, XrPath inputSourcePath, float state); +typedef XrResult (XRAPI_PTR *PFN_xrSetInputDeviceStateVector2fEXT)(XrSession session, XrPath topLevelPath, XrPath inputSourcePath, XrVector2f state); +typedef XrResult (XRAPI_PTR *PFN_xrSetInputDeviceLocationEXT)(XrSession session, XrPath topLevelPath, XrPath inputSourcePath, XrSpace space, XrPosef pose); + +#ifndef XR_NO_PROTOTYPES +#ifdef XR_EXTENSION_PROTOTYPES +XRAPI_ATTR XrResult XRAPI_CALL xrSetInputDeviceActiveEXT( + XrSession session, + XrPath interactionProfile, + XrPath topLevelPath, + XrBool32 isActive); + +XRAPI_ATTR XrResult XRAPI_CALL xrSetInputDeviceStateBoolEXT( + XrSession session, + XrPath topLevelPath, + XrPath inputSourcePath, + XrBool32 state); + +XRAPI_ATTR XrResult XRAPI_CALL xrSetInputDeviceStateFloatEXT( + XrSession session, + XrPath topLevelPath, + XrPath inputSourcePath, + float state); + +XRAPI_ATTR XrResult XRAPI_CALL xrSetInputDeviceStateVector2fEXT( + XrSession session, + XrPath topLevelPath, + XrPath inputSourcePath, + XrVector2f state); + +XRAPI_ATTR XrResult XRAPI_CALL xrSetInputDeviceLocationEXT( + XrSession session, + XrPath topLevelPath, + XrPath inputSourcePath, + XrSpace space, + XrPosef pose); +#endif /* XR_EXTENSION_PROTOTYPES */ +#endif /* !XR_NO_PROTOTYPES */ + + +#define XR_MSFT_spatial_graph_bridge 1 +XR_DEFINE_HANDLE(XrSpatialGraphNodeBindingMSFT) +#define XR_MSFT_spatial_graph_bridge_SPEC_VERSION 2 +#define XR_MSFT_SPATIAL_GRAPH_BRIDGE_EXTENSION_NAME "XR_MSFT_spatial_graph_bridge" +#define XR_GUID_SIZE_MSFT 16 + +typedef enum XrSpatialGraphNodeTypeMSFT { + XR_SPATIAL_GRAPH_NODE_TYPE_STATIC_MSFT = 1, + XR_SPATIAL_GRAPH_NODE_TYPE_DYNAMIC_MSFT = 2, + XR_SPATIAL_GRAPH_NODE_TYPE_MAX_ENUM_MSFT = 0x7FFFFFFF +} XrSpatialGraphNodeTypeMSFT; +typedef struct XrSpatialGraphNodeSpaceCreateInfoMSFT { + XrStructureType type; + const void* XR_MAY_ALIAS next; + XrSpatialGraphNodeTypeMSFT nodeType; + uint8_t nodeId[XR_GUID_SIZE_MSFT]; + XrPosef pose; +} XrSpatialGraphNodeSpaceCreateInfoMSFT; + +typedef struct XrSpatialGraphStaticNodeBindingCreateInfoMSFT { + XrStructureType type; + const void* XR_MAY_ALIAS next; + XrSpace space; + XrPosef poseInSpace; + XrTime time; +} XrSpatialGraphStaticNodeBindingCreateInfoMSFT; + +typedef struct XrSpatialGraphNodeBindingPropertiesGetInfoMSFT { + XrStructureType type; + const void* XR_MAY_ALIAS next; +} XrSpatialGraphNodeBindingPropertiesGetInfoMSFT; + +typedef struct XrSpatialGraphNodeBindingPropertiesMSFT { + XrStructureType type; + void* XR_MAY_ALIAS next; + uint8_t nodeId[XR_GUID_SIZE_MSFT]; + XrPosef poseInNodeSpace; +} XrSpatialGraphNodeBindingPropertiesMSFT; + +typedef XrResult (XRAPI_PTR *PFN_xrCreateSpatialGraphNodeSpaceMSFT)(XrSession session, const XrSpatialGraphNodeSpaceCreateInfoMSFT* createInfo, XrSpace* space); +typedef XrResult (XRAPI_PTR *PFN_xrTryCreateSpatialGraphStaticNodeBindingMSFT)(XrSession session, const XrSpatialGraphStaticNodeBindingCreateInfoMSFT* createInfo, XrSpatialGraphNodeBindingMSFT* nodeBinding); +typedef XrResult (XRAPI_PTR *PFN_xrDestroySpatialGraphNodeBindingMSFT)(XrSpatialGraphNodeBindingMSFT nodeBinding); +typedef XrResult (XRAPI_PTR *PFN_xrGetSpatialGraphNodeBindingPropertiesMSFT)(XrSpatialGraphNodeBindingMSFT nodeBinding, const XrSpatialGraphNodeBindingPropertiesGetInfoMSFT* getInfo, XrSpatialGraphNodeBindingPropertiesMSFT* properties); + +#ifndef XR_NO_PROTOTYPES +#ifdef XR_EXTENSION_PROTOTYPES +XRAPI_ATTR XrResult XRAPI_CALL xrCreateSpatialGraphNodeSpaceMSFT( + XrSession session, + const XrSpatialGraphNodeSpaceCreateInfoMSFT* createInfo, + XrSpace* space); + +XRAPI_ATTR XrResult XRAPI_CALL xrTryCreateSpatialGraphStaticNodeBindingMSFT( + XrSession session, + const XrSpatialGraphStaticNodeBindingCreateInfoMSFT* createInfo, + XrSpatialGraphNodeBindingMSFT* nodeBinding); + +XRAPI_ATTR XrResult XRAPI_CALL xrDestroySpatialGraphNodeBindingMSFT( + XrSpatialGraphNodeBindingMSFT nodeBinding); + +XRAPI_ATTR XrResult XRAPI_CALL xrGetSpatialGraphNodeBindingPropertiesMSFT( + XrSpatialGraphNodeBindingMSFT nodeBinding, + const XrSpatialGraphNodeBindingPropertiesGetInfoMSFT* getInfo, + XrSpatialGraphNodeBindingPropertiesMSFT* properties); +#endif /* XR_EXTENSION_PROTOTYPES */ +#endif /* !XR_NO_PROTOTYPES */ + + +#define XR_MSFT_hand_interaction 1 +#define XR_MSFT_hand_interaction_SPEC_VERSION 1 +#define XR_MSFT_HAND_INTERACTION_EXTENSION_NAME "XR_MSFT_hand_interaction" + + +#define XR_EXT_hand_tracking 1 + +#define XR_HAND_JOINT_COUNT_EXT 26 + +XR_DEFINE_HANDLE(XrHandTrackerEXT) +#define XR_EXT_hand_tracking_SPEC_VERSION 4 +#define XR_EXT_HAND_TRACKING_EXTENSION_NAME "XR_EXT_hand_tracking" + +typedef enum XrHandEXT { + XR_HAND_LEFT_EXT = 1, + XR_HAND_RIGHT_EXT = 2, + XR_HAND_MAX_ENUM_EXT = 0x7FFFFFFF +} XrHandEXT; + +typedef enum XrHandJointEXT { + XR_HAND_JOINT_PALM_EXT = 0, + XR_HAND_JOINT_WRIST_EXT = 1, + XR_HAND_JOINT_THUMB_METACARPAL_EXT = 2, + XR_HAND_JOINT_THUMB_PROXIMAL_EXT = 3, + XR_HAND_JOINT_THUMB_DISTAL_EXT = 4, + XR_HAND_JOINT_THUMB_TIP_EXT = 5, + XR_HAND_JOINT_INDEX_METACARPAL_EXT = 6, + XR_HAND_JOINT_INDEX_PROXIMAL_EXT = 7, + XR_HAND_JOINT_INDEX_INTERMEDIATE_EXT = 8, + XR_HAND_JOINT_INDEX_DISTAL_EXT = 9, + XR_HAND_JOINT_INDEX_TIP_EXT = 10, + XR_HAND_JOINT_MIDDLE_METACARPAL_EXT = 11, + XR_HAND_JOINT_MIDDLE_PROXIMAL_EXT = 12, + XR_HAND_JOINT_MIDDLE_INTERMEDIATE_EXT = 13, + XR_HAND_JOINT_MIDDLE_DISTAL_EXT = 14, + XR_HAND_JOINT_MIDDLE_TIP_EXT = 15, + XR_HAND_JOINT_RING_METACARPAL_EXT = 16, + XR_HAND_JOINT_RING_PROXIMAL_EXT = 17, + XR_HAND_JOINT_RING_INTERMEDIATE_EXT = 18, + XR_HAND_JOINT_RING_DISTAL_EXT = 19, + XR_HAND_JOINT_RING_TIP_EXT = 20, + XR_HAND_JOINT_LITTLE_METACARPAL_EXT = 21, + XR_HAND_JOINT_LITTLE_PROXIMAL_EXT = 22, + XR_HAND_JOINT_LITTLE_INTERMEDIATE_EXT = 23, + XR_HAND_JOINT_LITTLE_DISTAL_EXT = 24, + XR_HAND_JOINT_LITTLE_TIP_EXT = 25, + XR_HAND_JOINT_MAX_ENUM_EXT = 0x7FFFFFFF +} XrHandJointEXT; + +typedef enum XrHandJointSetEXT { + XR_HAND_JOINT_SET_DEFAULT_EXT = 0, + XR_HAND_JOINT_SET_HAND_WITH_FOREARM_ULTRALEAP = 1000149000, + XR_HAND_JOINT_SET_MAX_ENUM_EXT = 0x7FFFFFFF +} XrHandJointSetEXT; +// XrSystemHandTrackingPropertiesEXT extends XrSystemProperties +typedef struct XrSystemHandTrackingPropertiesEXT { + XrStructureType type; + void* XR_MAY_ALIAS next; + XrBool32 supportsHandTracking; +} XrSystemHandTrackingPropertiesEXT; + +typedef struct XrHandTrackerCreateInfoEXT { + XrStructureType type; + const void* XR_MAY_ALIAS next; + XrHandEXT hand; + XrHandJointSetEXT handJointSet; +} XrHandTrackerCreateInfoEXT; + +typedef struct XrHandJointsLocateInfoEXT { + XrStructureType type; + const void* XR_MAY_ALIAS next; + XrSpace baseSpace; + XrTime time; +} XrHandJointsLocateInfoEXT; + +typedef struct XrHandJointLocationEXT { + XrSpaceLocationFlags locationFlags; + XrPosef pose; + float radius; +} XrHandJointLocationEXT; + +typedef struct XrHandJointVelocityEXT { + XrSpaceVelocityFlags velocityFlags; + XrVector3f linearVelocity; + XrVector3f angularVelocity; +} XrHandJointVelocityEXT; + +typedef struct XrHandJointLocationsEXT { + XrStructureType type; + void* XR_MAY_ALIAS next; + XrBool32 isActive; + uint32_t jointCount; + XrHandJointLocationEXT* jointLocations; +} XrHandJointLocationsEXT; + +// XrHandJointVelocitiesEXT extends XrHandJointLocationsEXT +typedef struct XrHandJointVelocitiesEXT { + XrStructureType type; + void* XR_MAY_ALIAS next; + uint32_t jointCount; + XrHandJointVelocityEXT* jointVelocities; +} XrHandJointVelocitiesEXT; + +typedef XrResult (XRAPI_PTR *PFN_xrCreateHandTrackerEXT)(XrSession session, const XrHandTrackerCreateInfoEXT* createInfo, XrHandTrackerEXT* handTracker); +typedef XrResult (XRAPI_PTR *PFN_xrDestroyHandTrackerEXT)(XrHandTrackerEXT handTracker); +typedef XrResult (XRAPI_PTR *PFN_xrLocateHandJointsEXT)(XrHandTrackerEXT handTracker, const XrHandJointsLocateInfoEXT* locateInfo, XrHandJointLocationsEXT* locations); + +#ifndef XR_NO_PROTOTYPES +#ifdef XR_EXTENSION_PROTOTYPES +XRAPI_ATTR XrResult XRAPI_CALL xrCreateHandTrackerEXT( + XrSession session, + const XrHandTrackerCreateInfoEXT* createInfo, + XrHandTrackerEXT* handTracker); + +XRAPI_ATTR XrResult XRAPI_CALL xrDestroyHandTrackerEXT( + XrHandTrackerEXT handTracker); + +XRAPI_ATTR XrResult XRAPI_CALL xrLocateHandJointsEXT( + XrHandTrackerEXT handTracker, + const XrHandJointsLocateInfoEXT* locateInfo, + XrHandJointLocationsEXT* locations); +#endif /* XR_EXTENSION_PROTOTYPES */ +#endif /* !XR_NO_PROTOTYPES */ + + +#define XR_MSFT_hand_tracking_mesh 1 +#define XR_MSFT_hand_tracking_mesh_SPEC_VERSION 4 +#define XR_MSFT_HAND_TRACKING_MESH_EXTENSION_NAME "XR_MSFT_hand_tracking_mesh" + +typedef enum XrHandPoseTypeMSFT { + XR_HAND_POSE_TYPE_TRACKED_MSFT = 0, + XR_HAND_POSE_TYPE_REFERENCE_OPEN_PALM_MSFT = 1, + XR_HAND_POSE_TYPE_MAX_ENUM_MSFT = 0x7FFFFFFF +} XrHandPoseTypeMSFT; +// XrSystemHandTrackingMeshPropertiesMSFT extends XrSystemProperties +typedef struct XrSystemHandTrackingMeshPropertiesMSFT { + XrStructureType type; + void* XR_MAY_ALIAS next; + XrBool32 supportsHandTrackingMesh; + uint32_t maxHandMeshIndexCount; + uint32_t maxHandMeshVertexCount; +} XrSystemHandTrackingMeshPropertiesMSFT; + +typedef struct XrHandMeshSpaceCreateInfoMSFT { + XrStructureType type; + const void* XR_MAY_ALIAS next; + XrHandPoseTypeMSFT handPoseType; + XrPosef poseInHandMeshSpace; +} XrHandMeshSpaceCreateInfoMSFT; + +typedef struct XrHandMeshUpdateInfoMSFT { + XrStructureType type; + const void* XR_MAY_ALIAS next; + XrTime time; + XrHandPoseTypeMSFT handPoseType; +} XrHandMeshUpdateInfoMSFT; + +typedef struct XrHandMeshIndexBufferMSFT { + uint32_t indexBufferKey; + uint32_t indexCapacityInput; + uint32_t indexCountOutput; + uint32_t* indices; +} XrHandMeshIndexBufferMSFT; + +typedef struct XrHandMeshVertexMSFT { + XrVector3f position; + XrVector3f normal; +} XrHandMeshVertexMSFT; + +typedef struct XrHandMeshVertexBufferMSFT { + XrTime vertexUpdateTime; + uint32_t vertexCapacityInput; + uint32_t vertexCountOutput; + XrHandMeshVertexMSFT* vertices; +} XrHandMeshVertexBufferMSFT; + +typedef struct XrHandMeshMSFT { + XrStructureType type; + void* XR_MAY_ALIAS next; + XrBool32 isActive; + XrBool32 indexBufferChanged; + XrBool32 vertexBufferChanged; + XrHandMeshIndexBufferMSFT indexBuffer; + XrHandMeshVertexBufferMSFT vertexBuffer; +} XrHandMeshMSFT; + +// XrHandPoseTypeInfoMSFT extends XrHandTrackerCreateInfoEXT +typedef struct XrHandPoseTypeInfoMSFT { + XrStructureType type; + const void* XR_MAY_ALIAS next; + XrHandPoseTypeMSFT handPoseType; +} XrHandPoseTypeInfoMSFT; + +typedef XrResult (XRAPI_PTR *PFN_xrCreateHandMeshSpaceMSFT)(XrHandTrackerEXT handTracker, const XrHandMeshSpaceCreateInfoMSFT* createInfo, XrSpace* space); +typedef XrResult (XRAPI_PTR *PFN_xrUpdateHandMeshMSFT)(XrHandTrackerEXT handTracker, const XrHandMeshUpdateInfoMSFT* updateInfo, XrHandMeshMSFT* handMesh); + +#ifndef XR_NO_PROTOTYPES +#ifdef XR_EXTENSION_PROTOTYPES +XRAPI_ATTR XrResult XRAPI_CALL xrCreateHandMeshSpaceMSFT( + XrHandTrackerEXT handTracker, + const XrHandMeshSpaceCreateInfoMSFT* createInfo, + XrSpace* space); + +XRAPI_ATTR XrResult XRAPI_CALL xrUpdateHandMeshMSFT( + XrHandTrackerEXT handTracker, + const XrHandMeshUpdateInfoMSFT* updateInfo, + XrHandMeshMSFT* handMesh); +#endif /* XR_EXTENSION_PROTOTYPES */ +#endif /* !XR_NO_PROTOTYPES */ + + +#define XR_MSFT_secondary_view_configuration 1 +#define XR_MSFT_secondary_view_configuration_SPEC_VERSION 1 +#define XR_MSFT_SECONDARY_VIEW_CONFIGURATION_EXTENSION_NAME "XR_MSFT_secondary_view_configuration" +// XrSecondaryViewConfigurationSessionBeginInfoMSFT extends XrSessionBeginInfo +typedef struct XrSecondaryViewConfigurationSessionBeginInfoMSFT { + XrStructureType type; + const void* XR_MAY_ALIAS next; + uint32_t viewConfigurationCount; + const XrViewConfigurationType* enabledViewConfigurationTypes; +} XrSecondaryViewConfigurationSessionBeginInfoMSFT; + +typedef struct XrSecondaryViewConfigurationStateMSFT { + XrStructureType type; + void* XR_MAY_ALIAS next; + XrViewConfigurationType viewConfigurationType; + XrBool32 active; +} XrSecondaryViewConfigurationStateMSFT; + +// XrSecondaryViewConfigurationFrameStateMSFT extends XrFrameState +typedef struct XrSecondaryViewConfigurationFrameStateMSFT { + XrStructureType type; + void* XR_MAY_ALIAS next; + uint32_t viewConfigurationCount; + XrSecondaryViewConfigurationStateMSFT* viewConfigurationStates; +} XrSecondaryViewConfigurationFrameStateMSFT; + +typedef struct XrSecondaryViewConfigurationLayerInfoMSFT { + XrStructureType type; + const void* XR_MAY_ALIAS next; + XrViewConfigurationType viewConfigurationType; + XrEnvironmentBlendMode environmentBlendMode; + uint32_t layerCount; + const XrCompositionLayerBaseHeader* const* layers; +} XrSecondaryViewConfigurationLayerInfoMSFT; + +// XrSecondaryViewConfigurationFrameEndInfoMSFT extends XrFrameEndInfo +typedef struct XrSecondaryViewConfigurationFrameEndInfoMSFT { + XrStructureType type; + const void* XR_MAY_ALIAS next; + uint32_t viewConfigurationCount; + const XrSecondaryViewConfigurationLayerInfoMSFT* viewConfigurationLayersInfo; +} XrSecondaryViewConfigurationFrameEndInfoMSFT; + +// XrSecondaryViewConfigurationSwapchainCreateInfoMSFT extends XrSwapchainCreateInfo +typedef struct XrSecondaryViewConfigurationSwapchainCreateInfoMSFT { + XrStructureType type; + const void* XR_MAY_ALIAS next; + XrViewConfigurationType viewConfigurationType; +} XrSecondaryViewConfigurationSwapchainCreateInfoMSFT; + + + +#define XR_MSFT_first_person_observer 1 +#define XR_MSFT_first_person_observer_SPEC_VERSION 1 +#define XR_MSFT_FIRST_PERSON_OBSERVER_EXTENSION_NAME "XR_MSFT_first_person_observer" + + +#define XR_MSFT_controller_model 1 + +#define XR_NULL_CONTROLLER_MODEL_KEY_MSFT 0 + +XR_DEFINE_ATOM(XrControllerModelKeyMSFT) +#define XR_MSFT_controller_model_SPEC_VERSION 2 +#define XR_MSFT_CONTROLLER_MODEL_EXTENSION_NAME "XR_MSFT_controller_model" +#define XR_MAX_CONTROLLER_MODEL_NODE_NAME_SIZE_MSFT 64 +typedef struct XrControllerModelKeyStateMSFT { + XrStructureType type; + void* XR_MAY_ALIAS next; + XrControllerModelKeyMSFT modelKey; +} XrControllerModelKeyStateMSFT; + +typedef struct XrControllerModelNodePropertiesMSFT { + XrStructureType type; + void* XR_MAY_ALIAS next; + char parentNodeName[XR_MAX_CONTROLLER_MODEL_NODE_NAME_SIZE_MSFT]; + char nodeName[XR_MAX_CONTROLLER_MODEL_NODE_NAME_SIZE_MSFT]; +} XrControllerModelNodePropertiesMSFT; + +typedef struct XrControllerModelPropertiesMSFT { + XrStructureType type; + void* XR_MAY_ALIAS next; + uint32_t nodeCapacityInput; + uint32_t nodeCountOutput; + XrControllerModelNodePropertiesMSFT* nodeProperties; +} XrControllerModelPropertiesMSFT; + +typedef struct XrControllerModelNodeStateMSFT { + XrStructureType type; + void* XR_MAY_ALIAS next; + XrPosef nodePose; +} XrControllerModelNodeStateMSFT; + +typedef struct XrControllerModelStateMSFT { + XrStructureType type; + void* XR_MAY_ALIAS next; + uint32_t nodeCapacityInput; + uint32_t nodeCountOutput; + XrControllerModelNodeStateMSFT* nodeStates; +} XrControllerModelStateMSFT; + +typedef XrResult (XRAPI_PTR *PFN_xrGetControllerModelKeyMSFT)(XrSession session, XrPath topLevelUserPath, XrControllerModelKeyStateMSFT* controllerModelKeyState); +typedef XrResult (XRAPI_PTR *PFN_xrLoadControllerModelMSFT)(XrSession session, XrControllerModelKeyMSFT modelKey, uint32_t bufferCapacityInput, uint32_t* bufferCountOutput, uint8_t* buffer); +typedef XrResult (XRAPI_PTR *PFN_xrGetControllerModelPropertiesMSFT)(XrSession session, XrControllerModelKeyMSFT modelKey, XrControllerModelPropertiesMSFT* properties); +typedef XrResult (XRAPI_PTR *PFN_xrGetControllerModelStateMSFT)(XrSession session, XrControllerModelKeyMSFT modelKey, XrControllerModelStateMSFT* state); + +#ifndef XR_NO_PROTOTYPES +#ifdef XR_EXTENSION_PROTOTYPES +XRAPI_ATTR XrResult XRAPI_CALL xrGetControllerModelKeyMSFT( + XrSession session, + XrPath topLevelUserPath, + XrControllerModelKeyStateMSFT* controllerModelKeyState); + +XRAPI_ATTR XrResult XRAPI_CALL xrLoadControllerModelMSFT( + XrSession session, + XrControllerModelKeyMSFT modelKey, + uint32_t bufferCapacityInput, + uint32_t* bufferCountOutput, + uint8_t* buffer); + +XRAPI_ATTR XrResult XRAPI_CALL xrGetControllerModelPropertiesMSFT( + XrSession session, + XrControllerModelKeyMSFT modelKey, + XrControllerModelPropertiesMSFT* properties); + +XRAPI_ATTR XrResult XRAPI_CALL xrGetControllerModelStateMSFT( + XrSession session, + XrControllerModelKeyMSFT modelKey, + XrControllerModelStateMSFT* state); +#endif /* XR_EXTENSION_PROTOTYPES */ +#endif /* !XR_NO_PROTOTYPES */ + + +#define XR_EXT_win32_appcontainer_compatible 1 +#define XR_EXT_win32_appcontainer_compatible_SPEC_VERSION 1 +#define XR_EXT_WIN32_APPCONTAINER_COMPATIBLE_EXTENSION_NAME "XR_EXT_win32_appcontainer_compatible" + + +#define XR_EPIC_view_configuration_fov 1 +#define XR_EPIC_view_configuration_fov_SPEC_VERSION 2 +#define XR_EPIC_VIEW_CONFIGURATION_FOV_EXTENSION_NAME "XR_EPIC_view_configuration_fov" +// XrViewConfigurationViewFovEPIC extends XrViewConfigurationView +typedef struct XrViewConfigurationViewFovEPIC { + XrStructureType type; + const void* XR_MAY_ALIAS next; + XrFovf recommendedFov; + XrFovf maxMutableFov; +} XrViewConfigurationViewFovEPIC; + + + +#define XR_MSFT_composition_layer_reprojection 1 +#define XR_MSFT_composition_layer_reprojection_SPEC_VERSION 1 +#define XR_MSFT_COMPOSITION_LAYER_REPROJECTION_EXTENSION_NAME "XR_MSFT_composition_layer_reprojection" + +typedef enum XrReprojectionModeMSFT { + XR_REPROJECTION_MODE_DEPTH_MSFT = 1, + XR_REPROJECTION_MODE_PLANAR_FROM_DEPTH_MSFT = 2, + XR_REPROJECTION_MODE_PLANAR_MANUAL_MSFT = 3, + XR_REPROJECTION_MODE_ORIENTATION_ONLY_MSFT = 4, + XR_REPROJECTION_MODE_MAX_ENUM_MSFT = 0x7FFFFFFF +} XrReprojectionModeMSFT; +// XrCompositionLayerReprojectionInfoMSFT extends XrCompositionLayerProjection +typedef struct XrCompositionLayerReprojectionInfoMSFT { + XrStructureType type; + const void* XR_MAY_ALIAS next; + XrReprojectionModeMSFT reprojectionMode; +} XrCompositionLayerReprojectionInfoMSFT; + +// XrCompositionLayerReprojectionPlaneOverrideMSFT extends XrCompositionLayerProjection +typedef struct XrCompositionLayerReprojectionPlaneOverrideMSFT { + XrStructureType type; + const void* XR_MAY_ALIAS next; + XrVector3f position; + XrVector3f normal; + XrVector3f velocity; +} XrCompositionLayerReprojectionPlaneOverrideMSFT; + +typedef XrResult (XRAPI_PTR *PFN_xrEnumerateReprojectionModesMSFT)(XrInstance instance, XrSystemId systemId, XrViewConfigurationType viewConfigurationType, uint32_t modeCapacityInput, uint32_t* modeCountOutput, XrReprojectionModeMSFT* modes); + +#ifndef XR_NO_PROTOTYPES +#ifdef XR_EXTENSION_PROTOTYPES +XRAPI_ATTR XrResult XRAPI_CALL xrEnumerateReprojectionModesMSFT( + XrInstance instance, + XrSystemId systemId, + XrViewConfigurationType viewConfigurationType, + uint32_t modeCapacityInput, + uint32_t* modeCountOutput, + XrReprojectionModeMSFT* modes); +#endif /* XR_EXTENSION_PROTOTYPES */ +#endif /* !XR_NO_PROTOTYPES */ + + +#define XR_HUAWEI_controller_interaction 1 +#define XR_HUAWEI_controller_interaction_SPEC_VERSION 1 +#define XR_HUAWEI_CONTROLLER_INTERACTION_EXTENSION_NAME "XR_HUAWEI_controller_interaction" + + +#define XR_FB_swapchain_update_state 1 +#define XR_FB_swapchain_update_state_SPEC_VERSION 3 +#define XR_FB_SWAPCHAIN_UPDATE_STATE_EXTENSION_NAME "XR_FB_swapchain_update_state" +typedef struct XR_MAY_ALIAS XrSwapchainStateBaseHeaderFB { + XrStructureType type; + void* XR_MAY_ALIAS next; +} XrSwapchainStateBaseHeaderFB; + +typedef XrResult (XRAPI_PTR *PFN_xrUpdateSwapchainFB)(XrSwapchain swapchain, const XrSwapchainStateBaseHeaderFB* state); +typedef XrResult (XRAPI_PTR *PFN_xrGetSwapchainStateFB)(XrSwapchain swapchain, XrSwapchainStateBaseHeaderFB* state); + +#ifndef XR_NO_PROTOTYPES +#ifdef XR_EXTENSION_PROTOTYPES +XRAPI_ATTR XrResult XRAPI_CALL xrUpdateSwapchainFB( + XrSwapchain swapchain, + const XrSwapchainStateBaseHeaderFB* state); + +XRAPI_ATTR XrResult XRAPI_CALL xrGetSwapchainStateFB( + XrSwapchain swapchain, + XrSwapchainStateBaseHeaderFB* state); +#endif /* XR_EXTENSION_PROTOTYPES */ +#endif /* !XR_NO_PROTOTYPES */ + + +#define XR_FB_composition_layer_secure_content 1 +#define XR_FB_composition_layer_secure_content_SPEC_VERSION 1 +#define XR_FB_COMPOSITION_LAYER_SECURE_CONTENT_EXTENSION_NAME "XR_FB_composition_layer_secure_content" +typedef XrFlags64 XrCompositionLayerSecureContentFlagsFB; + +// Flag bits for XrCompositionLayerSecureContentFlagsFB +static const XrCompositionLayerSecureContentFlagsFB XR_COMPOSITION_LAYER_SECURE_CONTENT_EXCLUDE_LAYER_BIT_FB = 0x00000001; +static const XrCompositionLayerSecureContentFlagsFB XR_COMPOSITION_LAYER_SECURE_CONTENT_REPLACE_LAYER_BIT_FB = 0x00000002; + +// XrCompositionLayerSecureContentFB extends XrCompositionLayerBaseHeader +typedef struct XrCompositionLayerSecureContentFB { + XrStructureType type; + const void* XR_MAY_ALIAS next; + XrCompositionLayerSecureContentFlagsFB flags; +} XrCompositionLayerSecureContentFB; + + + +#define XR_FB_body_tracking 1 +XR_DEFINE_HANDLE(XrBodyTrackerFB) +#define XR_FB_body_tracking_SPEC_VERSION 1 +#define XR_FB_BODY_TRACKING_EXTENSION_NAME "XR_FB_body_tracking" + +typedef enum XrBodyJointFB { + XR_BODY_JOINT_ROOT_FB = 0, + XR_BODY_JOINT_HIPS_FB = 1, + XR_BODY_JOINT_SPINE_LOWER_FB = 2, + XR_BODY_JOINT_SPINE_MIDDLE_FB = 3, + XR_BODY_JOINT_SPINE_UPPER_FB = 4, + XR_BODY_JOINT_CHEST_FB = 5, + XR_BODY_JOINT_NECK_FB = 6, + XR_BODY_JOINT_HEAD_FB = 7, + XR_BODY_JOINT_LEFT_SHOULDER_FB = 8, + XR_BODY_JOINT_LEFT_SCAPULA_FB = 9, + XR_BODY_JOINT_LEFT_ARM_UPPER_FB = 10, + XR_BODY_JOINT_LEFT_ARM_LOWER_FB = 11, + XR_BODY_JOINT_LEFT_HAND_WRIST_TWIST_FB = 12, + XR_BODY_JOINT_RIGHT_SHOULDER_FB = 13, + XR_BODY_JOINT_RIGHT_SCAPULA_FB = 14, + XR_BODY_JOINT_RIGHT_ARM_UPPER_FB = 15, + XR_BODY_JOINT_RIGHT_ARM_LOWER_FB = 16, + XR_BODY_JOINT_RIGHT_HAND_WRIST_TWIST_FB = 17, + XR_BODY_JOINT_LEFT_HAND_PALM_FB = 18, + XR_BODY_JOINT_LEFT_HAND_WRIST_FB = 19, + XR_BODY_JOINT_LEFT_HAND_THUMB_METACARPAL_FB = 20, + XR_BODY_JOINT_LEFT_HAND_THUMB_PROXIMAL_FB = 21, + XR_BODY_JOINT_LEFT_HAND_THUMB_DISTAL_FB = 22, + XR_BODY_JOINT_LEFT_HAND_THUMB_TIP_FB = 23, + XR_BODY_JOINT_LEFT_HAND_INDEX_METACARPAL_FB = 24, + XR_BODY_JOINT_LEFT_HAND_INDEX_PROXIMAL_FB = 25, + XR_BODY_JOINT_LEFT_HAND_INDEX_INTERMEDIATE_FB = 26, + XR_BODY_JOINT_LEFT_HAND_INDEX_DISTAL_FB = 27, + XR_BODY_JOINT_LEFT_HAND_INDEX_TIP_FB = 28, + XR_BODY_JOINT_LEFT_HAND_MIDDLE_METACARPAL_FB = 29, + XR_BODY_JOINT_LEFT_HAND_MIDDLE_PROXIMAL_FB = 30, + XR_BODY_JOINT_LEFT_HAND_MIDDLE_INTERMEDIATE_FB = 31, + XR_BODY_JOINT_LEFT_HAND_MIDDLE_DISTAL_FB = 32, + XR_BODY_JOINT_LEFT_HAND_MIDDLE_TIP_FB = 33, + XR_BODY_JOINT_LEFT_HAND_RING_METACARPAL_FB = 34, + XR_BODY_JOINT_LEFT_HAND_RING_PROXIMAL_FB = 35, + XR_BODY_JOINT_LEFT_HAND_RING_INTERMEDIATE_FB = 36, + XR_BODY_JOINT_LEFT_HAND_RING_DISTAL_FB = 37, + XR_BODY_JOINT_LEFT_HAND_RING_TIP_FB = 38, + XR_BODY_JOINT_LEFT_HAND_LITTLE_METACARPAL_FB = 39, + XR_BODY_JOINT_LEFT_HAND_LITTLE_PROXIMAL_FB = 40, + XR_BODY_JOINT_LEFT_HAND_LITTLE_INTERMEDIATE_FB = 41, + XR_BODY_JOINT_LEFT_HAND_LITTLE_DISTAL_FB = 42, + XR_BODY_JOINT_LEFT_HAND_LITTLE_TIP_FB = 43, + XR_BODY_JOINT_RIGHT_HAND_PALM_FB = 44, + XR_BODY_JOINT_RIGHT_HAND_WRIST_FB = 45, + XR_BODY_JOINT_RIGHT_HAND_THUMB_METACARPAL_FB = 46, + XR_BODY_JOINT_RIGHT_HAND_THUMB_PROXIMAL_FB = 47, + XR_BODY_JOINT_RIGHT_HAND_THUMB_DISTAL_FB = 48, + XR_BODY_JOINT_RIGHT_HAND_THUMB_TIP_FB = 49, + XR_BODY_JOINT_RIGHT_HAND_INDEX_METACARPAL_FB = 50, + XR_BODY_JOINT_RIGHT_HAND_INDEX_PROXIMAL_FB = 51, + XR_BODY_JOINT_RIGHT_HAND_INDEX_INTERMEDIATE_FB = 52, + XR_BODY_JOINT_RIGHT_HAND_INDEX_DISTAL_FB = 53, + XR_BODY_JOINT_RIGHT_HAND_INDEX_TIP_FB = 54, + XR_BODY_JOINT_RIGHT_HAND_MIDDLE_METACARPAL_FB = 55, + XR_BODY_JOINT_RIGHT_HAND_MIDDLE_PROXIMAL_FB = 56, + XR_BODY_JOINT_RIGHT_HAND_MIDDLE_INTERMEDIATE_FB = 57, + XR_BODY_JOINT_RIGHT_HAND_MIDDLE_DISTAL_FB = 58, + XR_BODY_JOINT_RIGHT_HAND_MIDDLE_TIP_FB = 59, + XR_BODY_JOINT_RIGHT_HAND_RING_METACARPAL_FB = 60, + XR_BODY_JOINT_RIGHT_HAND_RING_PROXIMAL_FB = 61, + XR_BODY_JOINT_RIGHT_HAND_RING_INTERMEDIATE_FB = 62, + XR_BODY_JOINT_RIGHT_HAND_RING_DISTAL_FB = 63, + XR_BODY_JOINT_RIGHT_HAND_RING_TIP_FB = 64, + XR_BODY_JOINT_RIGHT_HAND_LITTLE_METACARPAL_FB = 65, + XR_BODY_JOINT_RIGHT_HAND_LITTLE_PROXIMAL_FB = 66, + XR_BODY_JOINT_RIGHT_HAND_LITTLE_INTERMEDIATE_FB = 67, + XR_BODY_JOINT_RIGHT_HAND_LITTLE_DISTAL_FB = 68, + XR_BODY_JOINT_RIGHT_HAND_LITTLE_TIP_FB = 69, + XR_BODY_JOINT_COUNT_FB = 70, + XR_BODY_JOINT_NONE_FB = -1, + XR_BODY_JOINT_MAX_ENUM_FB = 0x7FFFFFFF +} XrBodyJointFB; + +typedef enum XrBodyJointSetFB { + XR_BODY_JOINT_SET_DEFAULT_FB = 0, + XR_BODY_JOINT_SET_MAX_ENUM_FB = 0x7FFFFFFF +} XrBodyJointSetFB; +typedef struct XrBodyJointLocationFB { + XrSpaceLocationFlags locationFlags; + XrPosef pose; +} XrBodyJointLocationFB; + +// XrSystemBodyTrackingPropertiesFB extends XrSystemProperties +typedef struct XrSystemBodyTrackingPropertiesFB { + XrStructureType type; + void* XR_MAY_ALIAS next; + XrBool32 supportsBodyTracking; +} XrSystemBodyTrackingPropertiesFB; + +typedef struct XrBodyTrackerCreateInfoFB { + XrStructureType type; + const void* XR_MAY_ALIAS next; + XrBodyJointSetFB bodyJointSet; +} XrBodyTrackerCreateInfoFB; + +typedef struct XrBodySkeletonJointFB { + int32_t joint; + int32_t parentJoint; + XrPosef pose; +} XrBodySkeletonJointFB; + +typedef struct XrBodySkeletonFB { + XrStructureType type; + void* XR_MAY_ALIAS next; + uint32_t jointCount; + XrBodySkeletonJointFB* joints; +} XrBodySkeletonFB; + +typedef struct XrBodyJointsLocateInfoFB { + XrStructureType type; + const void* XR_MAY_ALIAS next; + XrSpace baseSpace; + XrTime time; +} XrBodyJointsLocateInfoFB; + +typedef struct XrBodyJointLocationsFB { + XrStructureType type; + void* XR_MAY_ALIAS next; + XrBool32 isActive; + float confidence; + uint32_t jointCount; + XrBodyJointLocationFB* jointLocations; + uint32_t skeletonChangedCount; + XrTime time; +} XrBodyJointLocationsFB; + +typedef XrResult (XRAPI_PTR *PFN_xrCreateBodyTrackerFB)(XrSession session, const XrBodyTrackerCreateInfoFB* createInfo, XrBodyTrackerFB* bodyTracker); +typedef XrResult (XRAPI_PTR *PFN_xrDestroyBodyTrackerFB)(XrBodyTrackerFB bodyTracker); +typedef XrResult (XRAPI_PTR *PFN_xrLocateBodyJointsFB)(XrBodyTrackerFB bodyTracker, const XrBodyJointsLocateInfoFB* locateInfo, XrBodyJointLocationsFB* locations); +typedef XrResult (XRAPI_PTR *PFN_xrGetBodySkeletonFB)(XrBodyTrackerFB bodyTracker, XrBodySkeletonFB* skeleton); + +#ifndef XR_NO_PROTOTYPES +#ifdef XR_EXTENSION_PROTOTYPES +XRAPI_ATTR XrResult XRAPI_CALL xrCreateBodyTrackerFB( + XrSession session, + const XrBodyTrackerCreateInfoFB* createInfo, + XrBodyTrackerFB* bodyTracker); + +XRAPI_ATTR XrResult XRAPI_CALL xrDestroyBodyTrackerFB( + XrBodyTrackerFB bodyTracker); + +XRAPI_ATTR XrResult XRAPI_CALL xrLocateBodyJointsFB( + XrBodyTrackerFB bodyTracker, + const XrBodyJointsLocateInfoFB* locateInfo, + XrBodyJointLocationsFB* locations); + +XRAPI_ATTR XrResult XRAPI_CALL xrGetBodySkeletonFB( + XrBodyTrackerFB bodyTracker, + XrBodySkeletonFB* skeleton); +#endif /* XR_EXTENSION_PROTOTYPES */ +#endif /* !XR_NO_PROTOTYPES */ + + +#define XR_EXT_dpad_binding 1 +#define XR_EXT_dpad_binding_SPEC_VERSION 1 +#define XR_EXT_DPAD_BINDING_EXTENSION_NAME "XR_EXT_dpad_binding" +typedef struct XrInteractionProfileDpadBindingEXT { + XrStructureType type; + const void* XR_MAY_ALIAS next; + XrPath binding; + XrActionSet actionSet; + float forceThreshold; + float forceThresholdReleased; + float centerRegion; + float wedgeAngle; + XrBool32 isSticky; + const XrHapticBaseHeader* onHaptic; + const XrHapticBaseHeader* offHaptic; +} XrInteractionProfileDpadBindingEXT; + + + +#define XR_VALVE_analog_threshold 1 +#define XR_VALVE_analog_threshold_SPEC_VERSION 2 +#define XR_VALVE_ANALOG_THRESHOLD_EXTENSION_NAME "XR_VALVE_analog_threshold" +typedef struct XrInteractionProfileAnalogThresholdVALVE { + XrStructureType type; + const void* XR_MAY_ALIAS next; + XrAction action; + XrPath binding; + float onThreshold; + float offThreshold; + const XrHapticBaseHeader* onHaptic; + const XrHapticBaseHeader* offHaptic; +} XrInteractionProfileAnalogThresholdVALVE; + + + +#define XR_EXT_hand_joints_motion_range 1 +#define XR_EXT_hand_joints_motion_range_SPEC_VERSION 1 +#define XR_EXT_HAND_JOINTS_MOTION_RANGE_EXTENSION_NAME "XR_EXT_hand_joints_motion_range" + +typedef enum XrHandJointsMotionRangeEXT { + XR_HAND_JOINTS_MOTION_RANGE_UNOBSTRUCTED_EXT = 1, + XR_HAND_JOINTS_MOTION_RANGE_CONFORMING_TO_CONTROLLER_EXT = 2, + XR_HAND_JOINTS_MOTION_RANGE_MAX_ENUM_EXT = 0x7FFFFFFF +} XrHandJointsMotionRangeEXT; +// XrHandJointsMotionRangeInfoEXT extends XrHandJointsLocateInfoEXT +typedef struct XrHandJointsMotionRangeInfoEXT { + XrStructureType type; + const void* XR_MAY_ALIAS next; + XrHandJointsMotionRangeEXT handJointsMotionRange; +} XrHandJointsMotionRangeInfoEXT; + + + +#define XR_EXT_samsung_odyssey_controller 1 +#define XR_EXT_samsung_odyssey_controller_SPEC_VERSION 1 +#define XR_EXT_SAMSUNG_ODYSSEY_CONTROLLER_EXTENSION_NAME "XR_EXT_samsung_odyssey_controller" + + +#define XR_EXT_hp_mixed_reality_controller 1 +#define XR_EXT_hp_mixed_reality_controller_SPEC_VERSION 1 +#define XR_EXT_HP_MIXED_REALITY_CONTROLLER_EXTENSION_NAME "XR_EXT_hp_mixed_reality_controller" + + +#define XR_MND_swapchain_usage_input_attachment_bit 1 +#define XR_MND_swapchain_usage_input_attachment_bit_SPEC_VERSION 2 +#define XR_MND_SWAPCHAIN_USAGE_INPUT_ATTACHMENT_BIT_EXTENSION_NAME "XR_MND_swapchain_usage_input_attachment_bit" + + +#define XR_MSFT_scene_understanding 1 + + XR_DEFINE_HANDLE(XrSceneObserverMSFT) + + + XR_DEFINE_HANDLE(XrSceneMSFT) + +#define XR_MSFT_scene_understanding_SPEC_VERSION 2 +#define XR_MSFT_SCENE_UNDERSTANDING_EXTENSION_NAME "XR_MSFT_scene_understanding" + +typedef enum XrSceneComputeFeatureMSFT { + XR_SCENE_COMPUTE_FEATURE_PLANE_MSFT = 1, + XR_SCENE_COMPUTE_FEATURE_PLANE_MESH_MSFT = 2, + XR_SCENE_COMPUTE_FEATURE_VISUAL_MESH_MSFT = 3, + XR_SCENE_COMPUTE_FEATURE_COLLIDER_MESH_MSFT = 4, + XR_SCENE_COMPUTE_FEATURE_SERIALIZE_SCENE_MSFT = 1000098000, + XR_SCENE_COMPUTE_FEATURE_MAX_ENUM_MSFT = 0x7FFFFFFF +} XrSceneComputeFeatureMSFT; + +typedef enum XrSceneComputeConsistencyMSFT { + XR_SCENE_COMPUTE_CONSISTENCY_SNAPSHOT_COMPLETE_MSFT = 1, + XR_SCENE_COMPUTE_CONSISTENCY_SNAPSHOT_INCOMPLETE_FAST_MSFT = 2, + XR_SCENE_COMPUTE_CONSISTENCY_OCCLUSION_OPTIMIZED_MSFT = 3, + XR_SCENE_COMPUTE_CONSISTENCY_MAX_ENUM_MSFT = 0x7FFFFFFF +} XrSceneComputeConsistencyMSFT; + +typedef enum XrMeshComputeLodMSFT { + XR_MESH_COMPUTE_LOD_COARSE_MSFT = 1, + XR_MESH_COMPUTE_LOD_MEDIUM_MSFT = 2, + XR_MESH_COMPUTE_LOD_FINE_MSFT = 3, + XR_MESH_COMPUTE_LOD_UNLIMITED_MSFT = 4, + XR_MESH_COMPUTE_LOD_MAX_ENUM_MSFT = 0x7FFFFFFF +} XrMeshComputeLodMSFT; + +typedef enum XrSceneComponentTypeMSFT { + XR_SCENE_COMPONENT_TYPE_INVALID_MSFT = -1, + XR_SCENE_COMPONENT_TYPE_OBJECT_MSFT = 1, + XR_SCENE_COMPONENT_TYPE_PLANE_MSFT = 2, + XR_SCENE_COMPONENT_TYPE_VISUAL_MESH_MSFT = 3, + XR_SCENE_COMPONENT_TYPE_COLLIDER_MESH_MSFT = 4, + XR_SCENE_COMPONENT_TYPE_SERIALIZED_SCENE_FRAGMENT_MSFT = 1000098000, + XR_SCENE_COMPONENT_TYPE_MAX_ENUM_MSFT = 0x7FFFFFFF +} XrSceneComponentTypeMSFT; + +typedef enum XrSceneObjectTypeMSFT { + XR_SCENE_OBJECT_TYPE_UNCATEGORIZED_MSFT = -1, + XR_SCENE_OBJECT_TYPE_BACKGROUND_MSFT = 1, + XR_SCENE_OBJECT_TYPE_WALL_MSFT = 2, + XR_SCENE_OBJECT_TYPE_FLOOR_MSFT = 3, + XR_SCENE_OBJECT_TYPE_CEILING_MSFT = 4, + XR_SCENE_OBJECT_TYPE_PLATFORM_MSFT = 5, + XR_SCENE_OBJECT_TYPE_INFERRED_MSFT = 6, + XR_SCENE_OBJECT_TYPE_MAX_ENUM_MSFT = 0x7FFFFFFF +} XrSceneObjectTypeMSFT; + +typedef enum XrScenePlaneAlignmentTypeMSFT { + XR_SCENE_PLANE_ALIGNMENT_TYPE_NON_ORTHOGONAL_MSFT = 0, + XR_SCENE_PLANE_ALIGNMENT_TYPE_HORIZONTAL_MSFT = 1, + XR_SCENE_PLANE_ALIGNMENT_TYPE_VERTICAL_MSFT = 2, + XR_SCENE_PLANE_ALIGNMENT_TYPE_MAX_ENUM_MSFT = 0x7FFFFFFF +} XrScenePlaneAlignmentTypeMSFT; + +typedef enum XrSceneComputeStateMSFT { + XR_SCENE_COMPUTE_STATE_NONE_MSFT = 0, + XR_SCENE_COMPUTE_STATE_UPDATING_MSFT = 1, + XR_SCENE_COMPUTE_STATE_COMPLETED_MSFT = 2, + XR_SCENE_COMPUTE_STATE_COMPLETED_WITH_ERROR_MSFT = 3, + XR_SCENE_COMPUTE_STATE_MAX_ENUM_MSFT = 0x7FFFFFFF +} XrSceneComputeStateMSFT; +typedef struct XrUuidMSFT { + uint8_t bytes[16]; +} XrUuidMSFT; + +typedef struct XrSceneObserverCreateInfoMSFT { + XrStructureType type; + const void* XR_MAY_ALIAS next; +} XrSceneObserverCreateInfoMSFT; + +typedef struct XrSceneCreateInfoMSFT { + XrStructureType type; + const void* XR_MAY_ALIAS next; +} XrSceneCreateInfoMSFT; + +typedef struct XrSceneSphereBoundMSFT { + XrVector3f center; + float radius; +} XrSceneSphereBoundMSFT; + +typedef struct XrSceneOrientedBoxBoundMSFT { + XrPosef pose; + XrVector3f extents; +} XrSceneOrientedBoxBoundMSFT; + +typedef struct XrSceneFrustumBoundMSFT { + XrPosef pose; + XrFovf fov; + float farDistance; +} XrSceneFrustumBoundMSFT; + +typedef struct XrSceneBoundsMSFT { + XrSpace space; + XrTime time; + uint32_t sphereCount; + const XrSceneSphereBoundMSFT* spheres; + uint32_t boxCount; + const XrSceneOrientedBoxBoundMSFT* boxes; + uint32_t frustumCount; + const XrSceneFrustumBoundMSFT* frustums; +} XrSceneBoundsMSFT; + +typedef struct XrNewSceneComputeInfoMSFT { + XrStructureType type; + const void* XR_MAY_ALIAS next; + uint32_t requestedFeatureCount; + const XrSceneComputeFeatureMSFT* requestedFeatures; + XrSceneComputeConsistencyMSFT consistency; + XrSceneBoundsMSFT bounds; +} XrNewSceneComputeInfoMSFT; + +// XrVisualMeshComputeLodInfoMSFT extends XrNewSceneComputeInfoMSFT +typedef struct XrVisualMeshComputeLodInfoMSFT { + XrStructureType type; + const void* XR_MAY_ALIAS next; + XrMeshComputeLodMSFT lod; +} XrVisualMeshComputeLodInfoMSFT; + +typedef struct XrSceneComponentMSFT { + XrSceneComponentTypeMSFT componentType; + XrUuidMSFT id; + XrUuidMSFT parentId; + XrTime updateTime; +} XrSceneComponentMSFT; + +typedef struct XrSceneComponentsMSFT { + XrStructureType type; + void* XR_MAY_ALIAS next; + uint32_t componentCapacityInput; + uint32_t componentCountOutput; + XrSceneComponentMSFT* components; +} XrSceneComponentsMSFT; + +typedef struct XrSceneComponentsGetInfoMSFT { + XrStructureType type; + const void* XR_MAY_ALIAS next; + XrSceneComponentTypeMSFT componentType; +} XrSceneComponentsGetInfoMSFT; + +typedef struct XrSceneComponentLocationMSFT { + XrSpaceLocationFlags flags; + XrPosef pose; +} XrSceneComponentLocationMSFT; + +typedef struct XrSceneComponentLocationsMSFT { + XrStructureType type; + void* XR_MAY_ALIAS next; + uint32_t locationCount; + XrSceneComponentLocationMSFT* locations; +} XrSceneComponentLocationsMSFT; + +typedef struct XrSceneComponentsLocateInfoMSFT { + XrStructureType type; + const void* XR_MAY_ALIAS next; + XrSpace baseSpace; + XrTime time; + uint32_t componentIdCount; + const XrUuidMSFT* componentIds; +} XrSceneComponentsLocateInfoMSFT; + +typedef struct XrSceneObjectMSFT { + XrSceneObjectTypeMSFT objectType; +} XrSceneObjectMSFT; + +// XrSceneObjectsMSFT extends XrSceneComponentsMSFT +typedef struct XrSceneObjectsMSFT { + XrStructureType type; + void* XR_MAY_ALIAS next; + uint32_t sceneObjectCount; + XrSceneObjectMSFT* sceneObjects; +} XrSceneObjectsMSFT; + +// XrSceneComponentParentFilterInfoMSFT extends XrSceneComponentsGetInfoMSFT +typedef struct XrSceneComponentParentFilterInfoMSFT { + XrStructureType type; + const void* XR_MAY_ALIAS next; + XrUuidMSFT parentId; +} XrSceneComponentParentFilterInfoMSFT; + +// XrSceneObjectTypesFilterInfoMSFT extends XrSceneComponentsGetInfoMSFT +typedef struct XrSceneObjectTypesFilterInfoMSFT { + XrStructureType type; + const void* XR_MAY_ALIAS next; + uint32_t objectTypeCount; + const XrSceneObjectTypeMSFT* objectTypes; +} XrSceneObjectTypesFilterInfoMSFT; + +typedef struct XrScenePlaneMSFT { + XrScenePlaneAlignmentTypeMSFT alignment; + XrExtent2Df size; + uint64_t meshBufferId; + XrBool32 supportsIndicesUint16; +} XrScenePlaneMSFT; + +// XrScenePlanesMSFT extends XrSceneComponentsMSFT +typedef struct XrScenePlanesMSFT { + XrStructureType type; + void* XR_MAY_ALIAS next; + uint32_t scenePlaneCount; + XrScenePlaneMSFT* scenePlanes; +} XrScenePlanesMSFT; + +// XrScenePlaneAlignmentFilterInfoMSFT extends XrSceneComponentsGetInfoMSFT +typedef struct XrScenePlaneAlignmentFilterInfoMSFT { + XrStructureType type; + const void* XR_MAY_ALIAS next; + uint32_t alignmentCount; + const XrScenePlaneAlignmentTypeMSFT* alignments; +} XrScenePlaneAlignmentFilterInfoMSFT; + +typedef struct XrSceneMeshMSFT { + uint64_t meshBufferId; + XrBool32 supportsIndicesUint16; +} XrSceneMeshMSFT; + +// XrSceneMeshesMSFT extends XrSceneComponentsMSFT +typedef struct XrSceneMeshesMSFT { + XrStructureType type; + void* XR_MAY_ALIAS next; + uint32_t sceneMeshCount; + XrSceneMeshMSFT* sceneMeshes; +} XrSceneMeshesMSFT; + +typedef struct XrSceneMeshBuffersGetInfoMSFT { + XrStructureType type; + const void* XR_MAY_ALIAS next; + uint64_t meshBufferId; +} XrSceneMeshBuffersGetInfoMSFT; + +typedef struct XrSceneMeshBuffersMSFT { + XrStructureType type; + void* XR_MAY_ALIAS next; +} XrSceneMeshBuffersMSFT; + +typedef struct XrSceneMeshVertexBufferMSFT { + XrStructureType type; + void* XR_MAY_ALIAS next; + uint32_t vertexCapacityInput; + uint32_t vertexCountOutput; + XrVector3f* vertices; +} XrSceneMeshVertexBufferMSFT; + +typedef struct XrSceneMeshIndicesUint32MSFT { + XrStructureType type; + void* XR_MAY_ALIAS next; + uint32_t indexCapacityInput; + uint32_t indexCountOutput; + uint32_t* indices; +} XrSceneMeshIndicesUint32MSFT; + +typedef struct XrSceneMeshIndicesUint16MSFT { + XrStructureType type; + void* XR_MAY_ALIAS next; + uint32_t indexCapacityInput; + uint32_t indexCountOutput; + uint16_t* indices; +} XrSceneMeshIndicesUint16MSFT; + +typedef XrResult (XRAPI_PTR *PFN_xrEnumerateSceneComputeFeaturesMSFT)(XrInstance instance, XrSystemId systemId, uint32_t featureCapacityInput, uint32_t* featureCountOutput, XrSceneComputeFeatureMSFT* features); +typedef XrResult (XRAPI_PTR *PFN_xrCreateSceneObserverMSFT)(XrSession session, const XrSceneObserverCreateInfoMSFT* createInfo, XrSceneObserverMSFT* sceneObserver); +typedef XrResult (XRAPI_PTR *PFN_xrDestroySceneObserverMSFT)(XrSceneObserverMSFT sceneObserver); +typedef XrResult (XRAPI_PTR *PFN_xrCreateSceneMSFT)(XrSceneObserverMSFT sceneObserver, const XrSceneCreateInfoMSFT* createInfo, XrSceneMSFT* scene); +typedef XrResult (XRAPI_PTR *PFN_xrDestroySceneMSFT)(XrSceneMSFT scene); +typedef XrResult (XRAPI_PTR *PFN_xrComputeNewSceneMSFT)(XrSceneObserverMSFT sceneObserver, const XrNewSceneComputeInfoMSFT* computeInfo); +typedef XrResult (XRAPI_PTR *PFN_xrGetSceneComputeStateMSFT)(XrSceneObserverMSFT sceneObserver, XrSceneComputeStateMSFT* state); +typedef XrResult (XRAPI_PTR *PFN_xrGetSceneComponentsMSFT)(XrSceneMSFT scene, const XrSceneComponentsGetInfoMSFT* getInfo, XrSceneComponentsMSFT* components); +typedef XrResult (XRAPI_PTR *PFN_xrLocateSceneComponentsMSFT)(XrSceneMSFT scene, const XrSceneComponentsLocateInfoMSFT* locateInfo, XrSceneComponentLocationsMSFT* locations); +typedef XrResult (XRAPI_PTR *PFN_xrGetSceneMeshBuffersMSFT)(XrSceneMSFT scene, const XrSceneMeshBuffersGetInfoMSFT* getInfo, XrSceneMeshBuffersMSFT* buffers); + +#ifndef XR_NO_PROTOTYPES +#ifdef XR_EXTENSION_PROTOTYPES +XRAPI_ATTR XrResult XRAPI_CALL xrEnumerateSceneComputeFeaturesMSFT( + XrInstance instance, + XrSystemId systemId, + uint32_t featureCapacityInput, + uint32_t* featureCountOutput, + XrSceneComputeFeatureMSFT* features); + +XRAPI_ATTR XrResult XRAPI_CALL xrCreateSceneObserverMSFT( + XrSession session, + const XrSceneObserverCreateInfoMSFT* createInfo, + XrSceneObserverMSFT* sceneObserver); + +XRAPI_ATTR XrResult XRAPI_CALL xrDestroySceneObserverMSFT( + XrSceneObserverMSFT sceneObserver); + +XRAPI_ATTR XrResult XRAPI_CALL xrCreateSceneMSFT( + XrSceneObserverMSFT sceneObserver, + const XrSceneCreateInfoMSFT* createInfo, + XrSceneMSFT* scene); + +XRAPI_ATTR XrResult XRAPI_CALL xrDestroySceneMSFT( + XrSceneMSFT scene); + +XRAPI_ATTR XrResult XRAPI_CALL xrComputeNewSceneMSFT( + XrSceneObserverMSFT sceneObserver, + const XrNewSceneComputeInfoMSFT* computeInfo); + +XRAPI_ATTR XrResult XRAPI_CALL xrGetSceneComputeStateMSFT( + XrSceneObserverMSFT sceneObserver, + XrSceneComputeStateMSFT* state); + +XRAPI_ATTR XrResult XRAPI_CALL xrGetSceneComponentsMSFT( + XrSceneMSFT scene, + const XrSceneComponentsGetInfoMSFT* getInfo, + XrSceneComponentsMSFT* components); + +XRAPI_ATTR XrResult XRAPI_CALL xrLocateSceneComponentsMSFT( + XrSceneMSFT scene, + const XrSceneComponentsLocateInfoMSFT* locateInfo, + XrSceneComponentLocationsMSFT* locations); + +XRAPI_ATTR XrResult XRAPI_CALL xrGetSceneMeshBuffersMSFT( + XrSceneMSFT scene, + const XrSceneMeshBuffersGetInfoMSFT* getInfo, + XrSceneMeshBuffersMSFT* buffers); +#endif /* XR_EXTENSION_PROTOTYPES */ +#endif /* !XR_NO_PROTOTYPES */ + + +#define XR_MSFT_scene_understanding_serialization 1 +#define XR_MSFT_scene_understanding_serialization_SPEC_VERSION 2 +#define XR_MSFT_SCENE_UNDERSTANDING_SERIALIZATION_EXTENSION_NAME "XR_MSFT_scene_understanding_serialization" +typedef struct XrSerializedSceneFragmentDataGetInfoMSFT { + XrStructureType type; + const void* XR_MAY_ALIAS next; + XrUuidMSFT sceneFragmentId; +} XrSerializedSceneFragmentDataGetInfoMSFT; + +typedef struct XrDeserializeSceneFragmentMSFT { + uint32_t bufferSize; + const uint8_t* buffer; +} XrDeserializeSceneFragmentMSFT; + +typedef struct XrSceneDeserializeInfoMSFT { + XrStructureType type; + const void* XR_MAY_ALIAS next; + uint32_t fragmentCount; + const XrDeserializeSceneFragmentMSFT* fragments; +} XrSceneDeserializeInfoMSFT; + +typedef XrResult (XRAPI_PTR *PFN_xrDeserializeSceneMSFT)(XrSceneObserverMSFT sceneObserver, const XrSceneDeserializeInfoMSFT* deserializeInfo); +typedef XrResult (XRAPI_PTR *PFN_xrGetSerializedSceneFragmentDataMSFT)(XrSceneMSFT scene, const XrSerializedSceneFragmentDataGetInfoMSFT* getInfo, uint32_t countInput, uint32_t* readOutput, uint8_t* buffer); + +#ifndef XR_NO_PROTOTYPES +#ifdef XR_EXTENSION_PROTOTYPES +XRAPI_ATTR XrResult XRAPI_CALL xrDeserializeSceneMSFT( + XrSceneObserverMSFT sceneObserver, + const XrSceneDeserializeInfoMSFT* deserializeInfo); + +XRAPI_ATTR XrResult XRAPI_CALL xrGetSerializedSceneFragmentDataMSFT( + XrSceneMSFT scene, + const XrSerializedSceneFragmentDataGetInfoMSFT* getInfo, + uint32_t countInput, + uint32_t* readOutput, + uint8_t* buffer); +#endif /* XR_EXTENSION_PROTOTYPES */ +#endif /* !XR_NO_PROTOTYPES */ + + +#define XR_FB_display_refresh_rate 1 +#define XR_FB_display_refresh_rate_SPEC_VERSION 1 +#define XR_FB_DISPLAY_REFRESH_RATE_EXTENSION_NAME "XR_FB_display_refresh_rate" +typedef struct XrEventDataDisplayRefreshRateChangedFB { + XrStructureType type; + const void* XR_MAY_ALIAS next; + float fromDisplayRefreshRate; + float toDisplayRefreshRate; +} XrEventDataDisplayRefreshRateChangedFB; + +typedef XrResult (XRAPI_PTR *PFN_xrEnumerateDisplayRefreshRatesFB)(XrSession session, uint32_t displayRefreshRateCapacityInput, uint32_t* displayRefreshRateCountOutput, float* displayRefreshRates); +typedef XrResult (XRAPI_PTR *PFN_xrGetDisplayRefreshRateFB)(XrSession session, float* displayRefreshRate); +typedef XrResult (XRAPI_PTR *PFN_xrRequestDisplayRefreshRateFB)(XrSession session, float displayRefreshRate); + +#ifndef XR_NO_PROTOTYPES +#ifdef XR_EXTENSION_PROTOTYPES +XRAPI_ATTR XrResult XRAPI_CALL xrEnumerateDisplayRefreshRatesFB( + XrSession session, + uint32_t displayRefreshRateCapacityInput, + uint32_t* displayRefreshRateCountOutput, + float* displayRefreshRates); + +XRAPI_ATTR XrResult XRAPI_CALL xrGetDisplayRefreshRateFB( + XrSession session, + float* displayRefreshRate); + +XRAPI_ATTR XrResult XRAPI_CALL xrRequestDisplayRefreshRateFB( + XrSession session, + float displayRefreshRate); +#endif /* XR_EXTENSION_PROTOTYPES */ +#endif /* !XR_NO_PROTOTYPES */ + + +#define XR_HTC_vive_cosmos_controller_interaction 1 +#define XR_HTC_vive_cosmos_controller_interaction_SPEC_VERSION 1 +#define XR_HTC_VIVE_COSMOS_CONTROLLER_INTERACTION_EXTENSION_NAME "XR_HTC_vive_cosmos_controller_interaction" + + +#define XR_HTCX_vive_tracker_interaction 1 +#define XR_HTCX_vive_tracker_interaction_SPEC_VERSION 2 +#define XR_HTCX_VIVE_TRACKER_INTERACTION_EXTENSION_NAME "XR_HTCX_vive_tracker_interaction" +typedef struct XrViveTrackerPathsHTCX { + XrStructureType type; + void* XR_MAY_ALIAS next; + XrPath persistentPath; + XrPath rolePath; +} XrViveTrackerPathsHTCX; + +typedef struct XrEventDataViveTrackerConnectedHTCX { + XrStructureType type; + const void* XR_MAY_ALIAS next; + XrViveTrackerPathsHTCX* paths; +} XrEventDataViveTrackerConnectedHTCX; + +typedef XrResult (XRAPI_PTR *PFN_xrEnumerateViveTrackerPathsHTCX)(XrInstance instance, uint32_t pathCapacityInput, uint32_t* pathCountOutput, XrViveTrackerPathsHTCX* paths); + +#ifndef XR_NO_PROTOTYPES +#ifdef XR_EXTENSION_PROTOTYPES +XRAPI_ATTR XrResult XRAPI_CALL xrEnumerateViveTrackerPathsHTCX( + XrInstance instance, + uint32_t pathCapacityInput, + uint32_t* pathCountOutput, + XrViveTrackerPathsHTCX* paths); +#endif /* XR_EXTENSION_PROTOTYPES */ +#endif /* !XR_NO_PROTOTYPES */ + + +#define XR_HTC_facial_tracking 1 + +#define XR_FACIAL_EXPRESSION_EYE_COUNT_HTC 14 + + +#define XR_FACIAL_EXPRESSION_LIP_COUNT_HTC 37 + +XR_DEFINE_HANDLE(XrFacialTrackerHTC) +#define XR_HTC_facial_tracking_SPEC_VERSION 2 +#define XR_HTC_FACIAL_TRACKING_EXTENSION_NAME "XR_HTC_facial_tracking" + +typedef enum XrEyeExpressionHTC { + XR_EYE_EXPRESSION_LEFT_BLINK_HTC = 0, + XR_EYE_EXPRESSION_LEFT_WIDE_HTC = 1, + XR_EYE_EXPRESSION_RIGHT_BLINK_HTC = 2, + XR_EYE_EXPRESSION_RIGHT_WIDE_HTC = 3, + XR_EYE_EXPRESSION_LEFT_SQUEEZE_HTC = 4, + XR_EYE_EXPRESSION_RIGHT_SQUEEZE_HTC = 5, + XR_EYE_EXPRESSION_LEFT_DOWN_HTC = 6, + XR_EYE_EXPRESSION_RIGHT_DOWN_HTC = 7, + XR_EYE_EXPRESSION_LEFT_OUT_HTC = 8, + XR_EYE_EXPRESSION_RIGHT_IN_HTC = 9, + XR_EYE_EXPRESSION_LEFT_IN_HTC = 10, + XR_EYE_EXPRESSION_RIGHT_OUT_HTC = 11, + XR_EYE_EXPRESSION_LEFT_UP_HTC = 12, + XR_EYE_EXPRESSION_RIGHT_UP_HTC = 13, + XR_EYE_EXPRESSION_MAX_ENUM_HTC = 0x7FFFFFFF +} XrEyeExpressionHTC; + +typedef enum XrLipExpressionHTC { + XR_LIP_EXPRESSION_JAW_RIGHT_HTC = 0, + XR_LIP_EXPRESSION_JAW_LEFT_HTC = 1, + XR_LIP_EXPRESSION_JAW_FORWARD_HTC = 2, + XR_LIP_EXPRESSION_JAW_OPEN_HTC = 3, + XR_LIP_EXPRESSION_MOUTH_APE_SHAPE_HTC = 4, + XR_LIP_EXPRESSION_MOUTH_UPPER_RIGHT_HTC = 5, + XR_LIP_EXPRESSION_MOUTH_UPPER_LEFT_HTC = 6, + XR_LIP_EXPRESSION_MOUTH_LOWER_RIGHT_HTC = 7, + XR_LIP_EXPRESSION_MOUTH_LOWER_LEFT_HTC = 8, + XR_LIP_EXPRESSION_MOUTH_UPPER_OVERTURN_HTC = 9, + XR_LIP_EXPRESSION_MOUTH_LOWER_OVERTURN_HTC = 10, + XR_LIP_EXPRESSION_MOUTH_POUT_HTC = 11, + XR_LIP_EXPRESSION_MOUTH_SMILE_RIGHT_HTC = 12, + XR_LIP_EXPRESSION_MOUTH_SMILE_LEFT_HTC = 13, + XR_LIP_EXPRESSION_MOUTH_SAD_RIGHT_HTC = 14, + XR_LIP_EXPRESSION_MOUTH_SAD_LEFT_HTC = 15, + XR_LIP_EXPRESSION_CHEEK_PUFF_RIGHT_HTC = 16, + XR_LIP_EXPRESSION_CHEEK_PUFF_LEFT_HTC = 17, + XR_LIP_EXPRESSION_CHEEK_SUCK_HTC = 18, + XR_LIP_EXPRESSION_MOUTH_UPPER_UPRIGHT_HTC = 19, + XR_LIP_EXPRESSION_MOUTH_UPPER_UPLEFT_HTC = 20, + XR_LIP_EXPRESSION_MOUTH_LOWER_DOWNRIGHT_HTC = 21, + XR_LIP_EXPRESSION_MOUTH_LOWER_DOWNLEFT_HTC = 22, + XR_LIP_EXPRESSION_MOUTH_UPPER_INSIDE_HTC = 23, + XR_LIP_EXPRESSION_MOUTH_LOWER_INSIDE_HTC = 24, + XR_LIP_EXPRESSION_MOUTH_LOWER_OVERLAY_HTC = 25, + XR_LIP_EXPRESSION_TONGUE_LONGSTEP1_HTC = 26, + XR_LIP_EXPRESSION_TONGUE_LEFT_HTC = 27, + XR_LIP_EXPRESSION_TONGUE_RIGHT_HTC = 28, + XR_LIP_EXPRESSION_TONGUE_UP_HTC = 29, + XR_LIP_EXPRESSION_TONGUE_DOWN_HTC = 30, + XR_LIP_EXPRESSION_TONGUE_ROLL_HTC = 31, + XR_LIP_EXPRESSION_TONGUE_LONGSTEP2_HTC = 32, + XR_LIP_EXPRESSION_TONGUE_UPRIGHT_MORPH_HTC = 33, + XR_LIP_EXPRESSION_TONGUE_UPLEFT_MORPH_HTC = 34, + XR_LIP_EXPRESSION_TONGUE_DOWNRIGHT_MORPH_HTC = 35, + XR_LIP_EXPRESSION_TONGUE_DOWNLEFT_MORPH_HTC = 36, + XR_LIP_EXPRESSION_MAX_ENUM_HTC = 0x7FFFFFFF +} XrLipExpressionHTC; + +typedef enum XrFacialTrackingTypeHTC { + XR_FACIAL_TRACKING_TYPE_EYE_DEFAULT_HTC = 1, + XR_FACIAL_TRACKING_TYPE_LIP_DEFAULT_HTC = 2, + XR_FACIAL_TRACKING_TYPE_MAX_ENUM_HTC = 0x7FFFFFFF +} XrFacialTrackingTypeHTC; +// XrSystemFacialTrackingPropertiesHTC extends XrSystemProperties +typedef struct XrSystemFacialTrackingPropertiesHTC { + XrStructureType type; + void* XR_MAY_ALIAS next; + XrBool32 supportEyeFacialTracking; + XrBool32 supportLipFacialTracking; +} XrSystemFacialTrackingPropertiesHTC; + +typedef struct XrFacialExpressionsHTC { + XrStructureType type; + const void* XR_MAY_ALIAS next; + XrBool32 isActive; + XrTime sampleTime; + uint32_t expressionCount; + float* expressionWeightings; +} XrFacialExpressionsHTC; + +typedef struct XrFacialTrackerCreateInfoHTC { + XrStructureType type; + const void* XR_MAY_ALIAS next; + XrFacialTrackingTypeHTC facialTrackingType; +} XrFacialTrackerCreateInfoHTC; + +typedef XrResult (XRAPI_PTR *PFN_xrCreateFacialTrackerHTC)(XrSession session, const XrFacialTrackerCreateInfoHTC* createInfo, XrFacialTrackerHTC* facialTracker); +typedef XrResult (XRAPI_PTR *PFN_xrDestroyFacialTrackerHTC)(XrFacialTrackerHTC facialTracker); +typedef XrResult (XRAPI_PTR *PFN_xrGetFacialExpressionsHTC)(XrFacialTrackerHTC facialTracker, XrFacialExpressionsHTC* facialExpressions); + +#ifndef XR_NO_PROTOTYPES +#ifdef XR_EXTENSION_PROTOTYPES +XRAPI_ATTR XrResult XRAPI_CALL xrCreateFacialTrackerHTC( + XrSession session, + const XrFacialTrackerCreateInfoHTC* createInfo, + XrFacialTrackerHTC* facialTracker); + +XRAPI_ATTR XrResult XRAPI_CALL xrDestroyFacialTrackerHTC( + XrFacialTrackerHTC facialTracker); + +XRAPI_ATTR XrResult XRAPI_CALL xrGetFacialExpressionsHTC( + XrFacialTrackerHTC facialTracker, + XrFacialExpressionsHTC* facialExpressions); +#endif /* XR_EXTENSION_PROTOTYPES */ +#endif /* !XR_NO_PROTOTYPES */ + + +#define XR_HTC_vive_focus3_controller_interaction 1 +#define XR_HTC_vive_focus3_controller_interaction_SPEC_VERSION 2 +#define XR_HTC_VIVE_FOCUS3_CONTROLLER_INTERACTION_EXTENSION_NAME "XR_HTC_vive_focus3_controller_interaction" + + +#define XR_HTC_hand_interaction 1 +#define XR_HTC_hand_interaction_SPEC_VERSION 1 +#define XR_HTC_HAND_INTERACTION_EXTENSION_NAME "XR_HTC_hand_interaction" + + +#define XR_HTC_vive_wrist_tracker_interaction 1 +#define XR_HTC_vive_wrist_tracker_interaction_SPEC_VERSION 1 +#define XR_HTC_VIVE_WRIST_TRACKER_INTERACTION_EXTENSION_NAME "XR_HTC_vive_wrist_tracker_interaction" + + +#define XR_FB_color_space 1 +#define XR_FB_color_space_SPEC_VERSION 3 +#define XR_FB_COLOR_SPACE_EXTENSION_NAME "XR_FB_color_space" + +typedef enum XrColorSpaceFB { + XR_COLOR_SPACE_UNMANAGED_FB = 0, + XR_COLOR_SPACE_REC2020_FB = 1, + XR_COLOR_SPACE_REC709_FB = 2, + XR_COLOR_SPACE_RIFT_CV1_FB = 3, + XR_COLOR_SPACE_RIFT_S_FB = 4, + XR_COLOR_SPACE_QUEST_FB = 5, + XR_COLOR_SPACE_P3_FB = 6, + XR_COLOR_SPACE_ADOBE_RGB_FB = 7, + XR_COLOR_SPACE_MAX_ENUM_FB = 0x7FFFFFFF +} XrColorSpaceFB; +// XrSystemColorSpacePropertiesFB extends XrSystemProperties +typedef struct XrSystemColorSpacePropertiesFB { + XrStructureType type; + void* XR_MAY_ALIAS next; + XrColorSpaceFB colorSpace; +} XrSystemColorSpacePropertiesFB; + +typedef XrResult (XRAPI_PTR *PFN_xrEnumerateColorSpacesFB)(XrSession session, uint32_t colorSpaceCapacityInput, uint32_t* colorSpaceCountOutput, XrColorSpaceFB* colorSpaces); +typedef XrResult (XRAPI_PTR *PFN_xrSetColorSpaceFB)(XrSession session, const XrColorSpaceFB colorspace); + +#ifndef XR_NO_PROTOTYPES +#ifdef XR_EXTENSION_PROTOTYPES +XRAPI_ATTR XrResult XRAPI_CALL xrEnumerateColorSpacesFB( + XrSession session, + uint32_t colorSpaceCapacityInput, + uint32_t* colorSpaceCountOutput, + XrColorSpaceFB* colorSpaces); + +XRAPI_ATTR XrResult XRAPI_CALL xrSetColorSpaceFB( + XrSession session, + const XrColorSpaceFB colorspace); +#endif /* XR_EXTENSION_PROTOTYPES */ +#endif /* !XR_NO_PROTOTYPES */ + + +#define XR_FB_hand_tracking_mesh 1 +#define XR_FB_hand_tracking_mesh_SPEC_VERSION 3 +#define XR_FB_HAND_TRACKING_MESH_EXTENSION_NAME "XR_FB_hand_tracking_mesh" +typedef struct XrVector4sFB { + int16_t x; + int16_t y; + int16_t z; + int16_t w; +} XrVector4sFB; + +typedef struct XrHandTrackingMeshFB { + XrStructureType type; + void* XR_MAY_ALIAS next; + uint32_t jointCapacityInput; + uint32_t jointCountOutput; + XrPosef* jointBindPoses; + float* jointRadii; + XrHandJointEXT* jointParents; + uint32_t vertexCapacityInput; + uint32_t vertexCountOutput; + XrVector3f* vertexPositions; + XrVector3f* vertexNormals; + XrVector2f* vertexUVs; + XrVector4sFB* vertexBlendIndices; + XrVector4f* vertexBlendWeights; + uint32_t indexCapacityInput; + uint32_t indexCountOutput; + int16_t* indices; +} XrHandTrackingMeshFB; + +// XrHandTrackingScaleFB extends XrHandJointLocationsEXT +typedef struct XrHandTrackingScaleFB { + XrStructureType type; + void* XR_MAY_ALIAS next; + float sensorOutput; + float currentOutput; + XrBool32 overrideHandScale; + float overrideValueInput; +} XrHandTrackingScaleFB; + +typedef XrResult (XRAPI_PTR *PFN_xrGetHandMeshFB)(XrHandTrackerEXT handTracker, XrHandTrackingMeshFB* mesh); + +#ifndef XR_NO_PROTOTYPES +#ifdef XR_EXTENSION_PROTOTYPES +XRAPI_ATTR XrResult XRAPI_CALL xrGetHandMeshFB( + XrHandTrackerEXT handTracker, + XrHandTrackingMeshFB* mesh); +#endif /* XR_EXTENSION_PROTOTYPES */ +#endif /* !XR_NO_PROTOTYPES */ + + +#define XR_FB_hand_tracking_aim 1 +#define XR_FB_hand_tracking_aim_SPEC_VERSION 2 +#define XR_FB_HAND_TRACKING_AIM_EXTENSION_NAME "XR_FB_hand_tracking_aim" +typedef XrFlags64 XrHandTrackingAimFlagsFB; + +// Flag bits for XrHandTrackingAimFlagsFB +static const XrHandTrackingAimFlagsFB XR_HAND_TRACKING_AIM_COMPUTED_BIT_FB = 0x00000001; +static const XrHandTrackingAimFlagsFB XR_HAND_TRACKING_AIM_VALID_BIT_FB = 0x00000002; +static const XrHandTrackingAimFlagsFB XR_HAND_TRACKING_AIM_INDEX_PINCHING_BIT_FB = 0x00000004; +static const XrHandTrackingAimFlagsFB XR_HAND_TRACKING_AIM_MIDDLE_PINCHING_BIT_FB = 0x00000008; +static const XrHandTrackingAimFlagsFB XR_HAND_TRACKING_AIM_RING_PINCHING_BIT_FB = 0x00000010; +static const XrHandTrackingAimFlagsFB XR_HAND_TRACKING_AIM_LITTLE_PINCHING_BIT_FB = 0x00000020; +static const XrHandTrackingAimFlagsFB XR_HAND_TRACKING_AIM_SYSTEM_GESTURE_BIT_FB = 0x00000040; +static const XrHandTrackingAimFlagsFB XR_HAND_TRACKING_AIM_DOMINANT_HAND_BIT_FB = 0x00000080; +static const XrHandTrackingAimFlagsFB XR_HAND_TRACKING_AIM_MENU_PRESSED_BIT_FB = 0x00000100; + +// XrHandTrackingAimStateFB extends XrHandJointLocationsEXT +typedef struct XrHandTrackingAimStateFB { + XrStructureType type; + void* XR_MAY_ALIAS next; + XrHandTrackingAimFlagsFB status; + XrPosef aimPose; + float pinchStrengthIndex; + float pinchStrengthMiddle; + float pinchStrengthRing; + float pinchStrengthLittle; +} XrHandTrackingAimStateFB; + + + +#define XR_FB_hand_tracking_capsules 1 +#define XR_HAND_TRACKING_CAPSULE_POINT_COUNT_FB 2 +#define XR_HAND_TRACKING_CAPSULE_COUNT_FB 19 +#define XR_FB_hand_tracking_capsules_SPEC_VERSION 3 +#define XR_FB_HAND_TRACKING_CAPSULES_EXTENSION_NAME "XR_FB_hand_tracking_capsules" +#define XR_FB_HAND_TRACKING_CAPSULE_POINT_COUNT XR_HAND_TRACKING_CAPSULE_POINT_COUNT_FB +#define XR_FB_HAND_TRACKING_CAPSULE_COUNT XR_HAND_TRACKING_CAPSULE_COUNT_FB +typedef struct XrHandCapsuleFB { + XrVector3f points[XR_HAND_TRACKING_CAPSULE_POINT_COUNT_FB]; + float radius; + XrHandJointEXT joint; +} XrHandCapsuleFB; + +// XrHandTrackingCapsulesStateFB extends XrHandJointLocationsEXT +typedef struct XrHandTrackingCapsulesStateFB { + XrStructureType type; + void* XR_MAY_ALIAS next; + XrHandCapsuleFB capsules[XR_HAND_TRACKING_CAPSULE_COUNT_FB]; +} XrHandTrackingCapsulesStateFB; + + + +#define XR_FB_spatial_entity 1 +XR_DEFINE_ATOM(XrAsyncRequestIdFB) +#define XR_UUID_SIZE_EXT 16 +#define XR_FB_spatial_entity_SPEC_VERSION 2 +#define XR_FB_SPATIAL_ENTITY_EXTENSION_NAME "XR_FB_spatial_entity" + +typedef enum XrSpaceComponentTypeFB { + XR_SPACE_COMPONENT_TYPE_LOCATABLE_FB = 0, + XR_SPACE_COMPONENT_TYPE_STORABLE_FB = 1, + XR_SPACE_COMPONENT_TYPE_SHARABLE_FB = 2, + XR_SPACE_COMPONENT_TYPE_BOUNDED_2D_FB = 3, + XR_SPACE_COMPONENT_TYPE_BOUNDED_3D_FB = 4, + XR_SPACE_COMPONENT_TYPE_SEMANTIC_LABELS_FB = 5, + XR_SPACE_COMPONENT_TYPE_ROOM_LAYOUT_FB = 6, + XR_SPACE_COMPONENT_TYPE_SPACE_CONTAINER_FB = 7, + XR_SPACE_COMPONENT_TYPE_MAX_ENUM_FB = 0x7FFFFFFF +} XrSpaceComponentTypeFB; +// XrSystemSpatialEntityPropertiesFB extends XrSystemProperties +typedef struct XrSystemSpatialEntityPropertiesFB { + XrStructureType type; + const void* XR_MAY_ALIAS next; + XrBool32 supportsSpatialEntity; +} XrSystemSpatialEntityPropertiesFB; + +typedef struct XrSpatialAnchorCreateInfoFB { + XrStructureType type; + const void* XR_MAY_ALIAS next; + XrSpace space; + XrPosef poseInSpace; + XrTime time; +} XrSpatialAnchorCreateInfoFB; + +typedef struct XrSpaceComponentStatusSetInfoFB { + XrStructureType type; + const void* XR_MAY_ALIAS next; + XrSpaceComponentTypeFB componentType; + XrBool32 enabled; + XrDuration timeout; +} XrSpaceComponentStatusSetInfoFB; + +typedef struct XrSpaceComponentStatusFB { + XrStructureType type; + void* XR_MAY_ALIAS next; + XrBool32 enabled; + XrBool32 changePending; +} XrSpaceComponentStatusFB; + +typedef struct XrUuidEXT { + uint8_t data[XR_UUID_SIZE_EXT]; +} XrUuidEXT; + +typedef struct XrEventDataSpatialAnchorCreateCompleteFB { + XrStructureType type; + const void* XR_MAY_ALIAS next; + XrAsyncRequestIdFB requestId; + XrResult result; + XrSpace space; + XrUuidEXT uuid; +} XrEventDataSpatialAnchorCreateCompleteFB; + +typedef struct XrEventDataSpaceSetStatusCompleteFB { + XrStructureType type; + const void* XR_MAY_ALIAS next; + XrAsyncRequestIdFB requestId; + XrResult result; + XrSpace space; + XrUuidEXT uuid; + XrSpaceComponentTypeFB componentType; + XrBool32 enabled; +} XrEventDataSpaceSetStatusCompleteFB; + +typedef XrResult (XRAPI_PTR *PFN_xrCreateSpatialAnchorFB)(XrSession session, const XrSpatialAnchorCreateInfoFB* info, XrAsyncRequestIdFB* requestId); +typedef XrResult (XRAPI_PTR *PFN_xrGetSpaceUuidFB)(XrSpace space, XrUuidEXT* uuid); +typedef XrResult (XRAPI_PTR *PFN_xrEnumerateSpaceSupportedComponentsFB)(XrSpace space, uint32_t componentTypeCapacityInput, uint32_t* componentTypeCountOutput, XrSpaceComponentTypeFB* componentTypes); +typedef XrResult (XRAPI_PTR *PFN_xrSetSpaceComponentStatusFB)(XrSpace space, const XrSpaceComponentStatusSetInfoFB* info, XrAsyncRequestIdFB* requestId); +typedef XrResult (XRAPI_PTR *PFN_xrGetSpaceComponentStatusFB)(XrSpace space, XrSpaceComponentTypeFB componentType, XrSpaceComponentStatusFB* status); + +#ifndef XR_NO_PROTOTYPES +#ifdef XR_EXTENSION_PROTOTYPES +XRAPI_ATTR XrResult XRAPI_CALL xrCreateSpatialAnchorFB( + XrSession session, + const XrSpatialAnchorCreateInfoFB* info, + XrAsyncRequestIdFB* requestId); + +XRAPI_ATTR XrResult XRAPI_CALL xrGetSpaceUuidFB( + XrSpace space, + XrUuidEXT* uuid); + +XRAPI_ATTR XrResult XRAPI_CALL xrEnumerateSpaceSupportedComponentsFB( + XrSpace space, + uint32_t componentTypeCapacityInput, + uint32_t* componentTypeCountOutput, + XrSpaceComponentTypeFB* componentTypes); + +XRAPI_ATTR XrResult XRAPI_CALL xrSetSpaceComponentStatusFB( + XrSpace space, + const XrSpaceComponentStatusSetInfoFB* info, + XrAsyncRequestIdFB* requestId); + +XRAPI_ATTR XrResult XRAPI_CALL xrGetSpaceComponentStatusFB( + XrSpace space, + XrSpaceComponentTypeFB componentType, + XrSpaceComponentStatusFB* status); +#endif /* XR_EXTENSION_PROTOTYPES */ +#endif /* !XR_NO_PROTOTYPES */ + + +#define XR_FB_foveation 1 +XR_DEFINE_HANDLE(XrFoveationProfileFB) +#define XR_FB_foveation_SPEC_VERSION 1 +#define XR_FB_FOVEATION_EXTENSION_NAME "XR_FB_foveation" +typedef XrFlags64 XrSwapchainCreateFoveationFlagsFB; + +// Flag bits for XrSwapchainCreateFoveationFlagsFB +static const XrSwapchainCreateFoveationFlagsFB XR_SWAPCHAIN_CREATE_FOVEATION_SCALED_BIN_BIT_FB = 0x00000001; +static const XrSwapchainCreateFoveationFlagsFB XR_SWAPCHAIN_CREATE_FOVEATION_FRAGMENT_DENSITY_MAP_BIT_FB = 0x00000002; + +typedef XrFlags64 XrSwapchainStateFoveationFlagsFB; + +// Flag bits for XrSwapchainStateFoveationFlagsFB + +typedef struct XrFoveationProfileCreateInfoFB { + XrStructureType type; + void* XR_MAY_ALIAS next; +} XrFoveationProfileCreateInfoFB; + +// XrSwapchainCreateInfoFoveationFB extends XrSwapchainCreateInfo +typedef struct XrSwapchainCreateInfoFoveationFB { + XrStructureType type; + void* XR_MAY_ALIAS next; + XrSwapchainCreateFoveationFlagsFB flags; +} XrSwapchainCreateInfoFoveationFB; + +typedef struct XrSwapchainStateFoveationFB { + XrStructureType type; + void* XR_MAY_ALIAS next; + XrSwapchainStateFoveationFlagsFB flags; + XrFoveationProfileFB profile; +} XrSwapchainStateFoveationFB; + +typedef XrResult (XRAPI_PTR *PFN_xrCreateFoveationProfileFB)(XrSession session, const XrFoveationProfileCreateInfoFB* createInfo, XrFoveationProfileFB* profile); +typedef XrResult (XRAPI_PTR *PFN_xrDestroyFoveationProfileFB)(XrFoveationProfileFB profile); + +#ifndef XR_NO_PROTOTYPES +#ifdef XR_EXTENSION_PROTOTYPES +XRAPI_ATTR XrResult XRAPI_CALL xrCreateFoveationProfileFB( + XrSession session, + const XrFoveationProfileCreateInfoFB* createInfo, + XrFoveationProfileFB* profile); + +XRAPI_ATTR XrResult XRAPI_CALL xrDestroyFoveationProfileFB( + XrFoveationProfileFB profile); +#endif /* XR_EXTENSION_PROTOTYPES */ +#endif /* !XR_NO_PROTOTYPES */ + + +#define XR_FB_foveation_configuration 1 +#define XR_FB_foveation_configuration_SPEC_VERSION 1 +#define XR_FB_FOVEATION_CONFIGURATION_EXTENSION_NAME "XR_FB_foveation_configuration" + +typedef enum XrFoveationLevelFB { + XR_FOVEATION_LEVEL_NONE_FB = 0, + XR_FOVEATION_LEVEL_LOW_FB = 1, + XR_FOVEATION_LEVEL_MEDIUM_FB = 2, + XR_FOVEATION_LEVEL_HIGH_FB = 3, + XR_FOVEATION_LEVEL_MAX_ENUM_FB = 0x7FFFFFFF +} XrFoveationLevelFB; + +typedef enum XrFoveationDynamicFB { + XR_FOVEATION_DYNAMIC_DISABLED_FB = 0, + XR_FOVEATION_DYNAMIC_LEVEL_ENABLED_FB = 1, + XR_FOVEATION_DYNAMIC_MAX_ENUM_FB = 0x7FFFFFFF +} XrFoveationDynamicFB; +// XrFoveationLevelProfileCreateInfoFB extends XrFoveationProfileCreateInfoFB +typedef struct XrFoveationLevelProfileCreateInfoFB { + XrStructureType type; + void* XR_MAY_ALIAS next; + XrFoveationLevelFB level; + float verticalOffset; + XrFoveationDynamicFB dynamic; +} XrFoveationLevelProfileCreateInfoFB; + + + +#define XR_FB_keyboard_tracking 1 +#define XR_FB_keyboard_tracking_SPEC_VERSION 1 +#define XR_FB_KEYBOARD_TRACKING_EXTENSION_NAME "XR_FB_keyboard_tracking" +#define XR_MAX_KEYBOARD_TRACKING_NAME_SIZE_FB 128 +typedef XrFlags64 XrKeyboardTrackingFlagsFB; + +// Flag bits for XrKeyboardTrackingFlagsFB +static const XrKeyboardTrackingFlagsFB XR_KEYBOARD_TRACKING_EXISTS_BIT_FB = 0x00000001; +static const XrKeyboardTrackingFlagsFB XR_KEYBOARD_TRACKING_LOCAL_BIT_FB = 0x00000002; +static const XrKeyboardTrackingFlagsFB XR_KEYBOARD_TRACKING_REMOTE_BIT_FB = 0x00000004; +static const XrKeyboardTrackingFlagsFB XR_KEYBOARD_TRACKING_CONNECTED_BIT_FB = 0x00000008; + +typedef XrFlags64 XrKeyboardTrackingQueryFlagsFB; + +// Flag bits for XrKeyboardTrackingQueryFlagsFB +static const XrKeyboardTrackingQueryFlagsFB XR_KEYBOARD_TRACKING_QUERY_LOCAL_BIT_FB = 0x00000002; +static const XrKeyboardTrackingQueryFlagsFB XR_KEYBOARD_TRACKING_QUERY_REMOTE_BIT_FB = 0x00000004; + +// XrSystemKeyboardTrackingPropertiesFB extends XrSystemProperties +typedef struct XrSystemKeyboardTrackingPropertiesFB { + XrStructureType type; + void* XR_MAY_ALIAS next; + XrBool32 supportsKeyboardTracking; +} XrSystemKeyboardTrackingPropertiesFB; + +typedef struct XrKeyboardTrackingDescriptionFB { + uint64_t trackedKeyboardId; + XrVector3f size; + XrKeyboardTrackingFlagsFB flags; + char name[XR_MAX_KEYBOARD_TRACKING_NAME_SIZE_FB]; +} XrKeyboardTrackingDescriptionFB; + +typedef struct XrKeyboardSpaceCreateInfoFB { + XrStructureType type; + void* XR_MAY_ALIAS next; + uint64_t trackedKeyboardId; +} XrKeyboardSpaceCreateInfoFB; + +typedef struct XrKeyboardTrackingQueryFB { + XrStructureType type; + void* XR_MAY_ALIAS next; + XrKeyboardTrackingQueryFlagsFB flags; +} XrKeyboardTrackingQueryFB; + +typedef XrResult (XRAPI_PTR *PFN_xrQuerySystemTrackedKeyboardFB)(XrSession session, const XrKeyboardTrackingQueryFB* queryInfo, XrKeyboardTrackingDescriptionFB* keyboard); +typedef XrResult (XRAPI_PTR *PFN_xrCreateKeyboardSpaceFB)(XrSession session, const XrKeyboardSpaceCreateInfoFB* createInfo, XrSpace* keyboardSpace); + +#ifndef XR_NO_PROTOTYPES +#ifdef XR_EXTENSION_PROTOTYPES +XRAPI_ATTR XrResult XRAPI_CALL xrQuerySystemTrackedKeyboardFB( + XrSession session, + const XrKeyboardTrackingQueryFB* queryInfo, + XrKeyboardTrackingDescriptionFB* keyboard); + +XRAPI_ATTR XrResult XRAPI_CALL xrCreateKeyboardSpaceFB( + XrSession session, + const XrKeyboardSpaceCreateInfoFB* createInfo, + XrSpace* keyboardSpace); +#endif /* XR_EXTENSION_PROTOTYPES */ +#endif /* !XR_NO_PROTOTYPES */ + + +#define XR_FB_triangle_mesh 1 +XR_DEFINE_HANDLE(XrTriangleMeshFB) +#define XR_FB_triangle_mesh_SPEC_VERSION 2 +#define XR_FB_TRIANGLE_MESH_EXTENSION_NAME "XR_FB_triangle_mesh" + +typedef enum XrWindingOrderFB { + XR_WINDING_ORDER_UNKNOWN_FB = 0, + XR_WINDING_ORDER_CW_FB = 1, + XR_WINDING_ORDER_CCW_FB = 2, + XR_WINDING_ORDER_MAX_ENUM_FB = 0x7FFFFFFF +} XrWindingOrderFB; +typedef XrFlags64 XrTriangleMeshFlagsFB; + +// Flag bits for XrTriangleMeshFlagsFB +static const XrTriangleMeshFlagsFB XR_TRIANGLE_MESH_MUTABLE_BIT_FB = 0x00000001; + +typedef struct XrTriangleMeshCreateInfoFB { + XrStructureType type; + const void* XR_MAY_ALIAS next; + XrTriangleMeshFlagsFB flags; + XrWindingOrderFB windingOrder; + uint32_t vertexCount; + const XrVector3f* vertexBuffer; + uint32_t triangleCount; + const uint32_t* indexBuffer; +} XrTriangleMeshCreateInfoFB; + +typedef XrResult (XRAPI_PTR *PFN_xrCreateTriangleMeshFB)(XrSession session, const XrTriangleMeshCreateInfoFB* createInfo, XrTriangleMeshFB* outTriangleMesh); +typedef XrResult (XRAPI_PTR *PFN_xrDestroyTriangleMeshFB)(XrTriangleMeshFB mesh); +typedef XrResult (XRAPI_PTR *PFN_xrTriangleMeshGetVertexBufferFB)(XrTriangleMeshFB mesh, XrVector3f** outVertexBuffer); +typedef XrResult (XRAPI_PTR *PFN_xrTriangleMeshGetIndexBufferFB)(XrTriangleMeshFB mesh, uint32_t** outIndexBuffer); +typedef XrResult (XRAPI_PTR *PFN_xrTriangleMeshBeginUpdateFB)(XrTriangleMeshFB mesh); +typedef XrResult (XRAPI_PTR *PFN_xrTriangleMeshEndUpdateFB)(XrTriangleMeshFB mesh, uint32_t vertexCount, uint32_t triangleCount); +typedef XrResult (XRAPI_PTR *PFN_xrTriangleMeshBeginVertexBufferUpdateFB)(XrTriangleMeshFB mesh, uint32_t* outVertexCount); +typedef XrResult (XRAPI_PTR *PFN_xrTriangleMeshEndVertexBufferUpdateFB)(XrTriangleMeshFB mesh); + +#ifndef XR_NO_PROTOTYPES +#ifdef XR_EXTENSION_PROTOTYPES +XRAPI_ATTR XrResult XRAPI_CALL xrCreateTriangleMeshFB( + XrSession session, + const XrTriangleMeshCreateInfoFB* createInfo, + XrTriangleMeshFB* outTriangleMesh); + +XRAPI_ATTR XrResult XRAPI_CALL xrDestroyTriangleMeshFB( + XrTriangleMeshFB mesh); + +XRAPI_ATTR XrResult XRAPI_CALL xrTriangleMeshGetVertexBufferFB( + XrTriangleMeshFB mesh, + XrVector3f** outVertexBuffer); + +XRAPI_ATTR XrResult XRAPI_CALL xrTriangleMeshGetIndexBufferFB( + XrTriangleMeshFB mesh, + uint32_t** outIndexBuffer); + +XRAPI_ATTR XrResult XRAPI_CALL xrTriangleMeshBeginUpdateFB( + XrTriangleMeshFB mesh); + +XRAPI_ATTR XrResult XRAPI_CALL xrTriangleMeshEndUpdateFB( + XrTriangleMeshFB mesh, + uint32_t vertexCount, + uint32_t triangleCount); + +XRAPI_ATTR XrResult XRAPI_CALL xrTriangleMeshBeginVertexBufferUpdateFB( + XrTriangleMeshFB mesh, + uint32_t* outVertexCount); + +XRAPI_ATTR XrResult XRAPI_CALL xrTriangleMeshEndVertexBufferUpdateFB( + XrTriangleMeshFB mesh); +#endif /* XR_EXTENSION_PROTOTYPES */ +#endif /* !XR_NO_PROTOTYPES */ + + +#define XR_FB_passthrough 1 +XR_DEFINE_HANDLE(XrPassthroughFB) +XR_DEFINE_HANDLE(XrPassthroughLayerFB) +XR_DEFINE_HANDLE(XrGeometryInstanceFB) +#define XR_FB_passthrough_SPEC_VERSION 3 +#define XR_FB_PASSTHROUGH_EXTENSION_NAME "XR_FB_passthrough" +#define XR_PASSTHROUGH_COLOR_MAP_MONO_SIZE_FB 256 + +typedef enum XrPassthroughLayerPurposeFB { + XR_PASSTHROUGH_LAYER_PURPOSE_RECONSTRUCTION_FB = 0, + XR_PASSTHROUGH_LAYER_PURPOSE_PROJECTED_FB = 1, + XR_PASSTHROUGH_LAYER_PURPOSE_TRACKED_KEYBOARD_HANDS_FB = 1000203001, + XR_PASSTHROUGH_LAYER_PURPOSE_TRACKED_KEYBOARD_MASKED_HANDS_FB = 1000203002, + XR_PASSTHROUGH_LAYER_PURPOSE_MAX_ENUM_FB = 0x7FFFFFFF +} XrPassthroughLayerPurposeFB; +typedef XrFlags64 XrPassthroughCapabilityFlagsFB; + +// Flag bits for XrPassthroughCapabilityFlagsFB +static const XrPassthroughCapabilityFlagsFB XR_PASSTHROUGH_CAPABILITY_BIT_FB = 0x00000001; +static const XrPassthroughCapabilityFlagsFB XR_PASSTHROUGH_CAPABILITY_COLOR_BIT_FB = 0x00000002; +static const XrPassthroughCapabilityFlagsFB XR_PASSTHROUGH_CAPABILITY_LAYER_DEPTH_BIT_FB = 0x00000004; + +typedef XrFlags64 XrPassthroughFlagsFB; + +// Flag bits for XrPassthroughFlagsFB +static const XrPassthroughFlagsFB XR_PASSTHROUGH_IS_RUNNING_AT_CREATION_BIT_FB = 0x00000001; +static const XrPassthroughFlagsFB XR_PASSTHROUGH_LAYER_DEPTH_BIT_FB = 0x00000002; + +typedef XrFlags64 XrPassthroughStateChangedFlagsFB; + +// Flag bits for XrPassthroughStateChangedFlagsFB +static const XrPassthroughStateChangedFlagsFB XR_PASSTHROUGH_STATE_CHANGED_REINIT_REQUIRED_BIT_FB = 0x00000001; +static const XrPassthroughStateChangedFlagsFB XR_PASSTHROUGH_STATE_CHANGED_NON_RECOVERABLE_ERROR_BIT_FB = 0x00000002; +static const XrPassthroughStateChangedFlagsFB XR_PASSTHROUGH_STATE_CHANGED_RECOVERABLE_ERROR_BIT_FB = 0x00000004; +static const XrPassthroughStateChangedFlagsFB XR_PASSTHROUGH_STATE_CHANGED_RESTORED_ERROR_BIT_FB = 0x00000008; + +// XrSystemPassthroughPropertiesFB extends XrSystemProperties +typedef struct XrSystemPassthroughPropertiesFB { + XrStructureType type; + const void* XR_MAY_ALIAS next; + XrBool32 supportsPassthrough; +} XrSystemPassthroughPropertiesFB; + +// XrSystemPassthroughProperties2FB extends XrSystemProperties +typedef struct XrSystemPassthroughProperties2FB { + XrStructureType type; + const void* XR_MAY_ALIAS next; + XrPassthroughCapabilityFlagsFB capabilities; +} XrSystemPassthroughProperties2FB; + +typedef struct XrPassthroughCreateInfoFB { + XrStructureType type; + const void* XR_MAY_ALIAS next; + XrPassthroughFlagsFB flags; +} XrPassthroughCreateInfoFB; + +typedef struct XrPassthroughLayerCreateInfoFB { + XrStructureType type; + const void* XR_MAY_ALIAS next; + XrPassthroughFB passthrough; + XrPassthroughFlagsFB flags; + XrPassthroughLayerPurposeFB purpose; +} XrPassthroughLayerCreateInfoFB; + +// XrCompositionLayerPassthroughFB extends XrCompositionLayerBaseHeader +typedef struct XrCompositionLayerPassthroughFB { + XrStructureType type; + const void* XR_MAY_ALIAS next; + XrCompositionLayerFlags flags; + XrSpace space; + XrPassthroughLayerFB layerHandle; +} XrCompositionLayerPassthroughFB; + +typedef struct XrGeometryInstanceCreateInfoFB { + XrStructureType type; + const void* XR_MAY_ALIAS next; + XrPassthroughLayerFB layer; + XrTriangleMeshFB mesh; + XrSpace baseSpace; + XrPosef pose; + XrVector3f scale; +} XrGeometryInstanceCreateInfoFB; + +typedef struct XrGeometryInstanceTransformFB { + XrStructureType type; + const void* XR_MAY_ALIAS next; + XrSpace baseSpace; + XrTime time; + XrPosef pose; + XrVector3f scale; +} XrGeometryInstanceTransformFB; + +typedef struct XrPassthroughStyleFB { + XrStructureType type; + const void* XR_MAY_ALIAS next; + float textureOpacityFactor; + XrColor4f edgeColor; +} XrPassthroughStyleFB; + +// XrPassthroughColorMapMonoToRgbaFB extends XrPassthroughStyleFB +typedef struct XrPassthroughColorMapMonoToRgbaFB { + XrStructureType type; + const void* XR_MAY_ALIAS next; + XrColor4f textureColorMap[XR_PASSTHROUGH_COLOR_MAP_MONO_SIZE_FB]; +} XrPassthroughColorMapMonoToRgbaFB; + +// XrPassthroughColorMapMonoToMonoFB extends XrPassthroughStyleFB +typedef struct XrPassthroughColorMapMonoToMonoFB { + XrStructureType type; + const void* XR_MAY_ALIAS next; + uint8_t textureColorMap[XR_PASSTHROUGH_COLOR_MAP_MONO_SIZE_FB]; +} XrPassthroughColorMapMonoToMonoFB; + +// XrPassthroughBrightnessContrastSaturationFB extends XrPassthroughStyleFB +typedef struct XrPassthroughBrightnessContrastSaturationFB { + XrStructureType type; + const void* XR_MAY_ALIAS next; + float brightness; + float contrast; + float saturation; +} XrPassthroughBrightnessContrastSaturationFB; + +typedef struct XrEventDataPassthroughStateChangedFB { + XrStructureType type; + const void* XR_MAY_ALIAS next; + XrPassthroughStateChangedFlagsFB flags; +} XrEventDataPassthroughStateChangedFB; + +typedef XrResult (XRAPI_PTR *PFN_xrCreatePassthroughFB)(XrSession session, const XrPassthroughCreateInfoFB* createInfo, XrPassthroughFB* outPassthrough); +typedef XrResult (XRAPI_PTR *PFN_xrDestroyPassthroughFB)(XrPassthroughFB passthrough); +typedef XrResult (XRAPI_PTR *PFN_xrPassthroughStartFB)(XrPassthroughFB passthrough); +typedef XrResult (XRAPI_PTR *PFN_xrPassthroughPauseFB)(XrPassthroughFB passthrough); +typedef XrResult (XRAPI_PTR *PFN_xrCreatePassthroughLayerFB)(XrSession session, const XrPassthroughLayerCreateInfoFB* createInfo, XrPassthroughLayerFB* outLayer); +typedef XrResult (XRAPI_PTR *PFN_xrDestroyPassthroughLayerFB)(XrPassthroughLayerFB layer); +typedef XrResult (XRAPI_PTR *PFN_xrPassthroughLayerPauseFB)(XrPassthroughLayerFB layer); +typedef XrResult (XRAPI_PTR *PFN_xrPassthroughLayerResumeFB)(XrPassthroughLayerFB layer); +typedef XrResult (XRAPI_PTR *PFN_xrPassthroughLayerSetStyleFB)(XrPassthroughLayerFB layer, const XrPassthroughStyleFB* style); +typedef XrResult (XRAPI_PTR *PFN_xrCreateGeometryInstanceFB)(XrSession session, const XrGeometryInstanceCreateInfoFB* createInfo, XrGeometryInstanceFB* outGeometryInstance); +typedef XrResult (XRAPI_PTR *PFN_xrDestroyGeometryInstanceFB)(XrGeometryInstanceFB instance); +typedef XrResult (XRAPI_PTR *PFN_xrGeometryInstanceSetTransformFB)(XrGeometryInstanceFB instance, const XrGeometryInstanceTransformFB* transformation); + +#ifndef XR_NO_PROTOTYPES +#ifdef XR_EXTENSION_PROTOTYPES +XRAPI_ATTR XrResult XRAPI_CALL xrCreatePassthroughFB( + XrSession session, + const XrPassthroughCreateInfoFB* createInfo, + XrPassthroughFB* outPassthrough); + +XRAPI_ATTR XrResult XRAPI_CALL xrDestroyPassthroughFB( + XrPassthroughFB passthrough); + +XRAPI_ATTR XrResult XRAPI_CALL xrPassthroughStartFB( + XrPassthroughFB passthrough); + +XRAPI_ATTR XrResult XRAPI_CALL xrPassthroughPauseFB( + XrPassthroughFB passthrough); + +XRAPI_ATTR XrResult XRAPI_CALL xrCreatePassthroughLayerFB( + XrSession session, + const XrPassthroughLayerCreateInfoFB* createInfo, + XrPassthroughLayerFB* outLayer); + +XRAPI_ATTR XrResult XRAPI_CALL xrDestroyPassthroughLayerFB( + XrPassthroughLayerFB layer); + +XRAPI_ATTR XrResult XRAPI_CALL xrPassthroughLayerPauseFB( + XrPassthroughLayerFB layer); + +XRAPI_ATTR XrResult XRAPI_CALL xrPassthroughLayerResumeFB( + XrPassthroughLayerFB layer); + +XRAPI_ATTR XrResult XRAPI_CALL xrPassthroughLayerSetStyleFB( + XrPassthroughLayerFB layer, + const XrPassthroughStyleFB* style); + +XRAPI_ATTR XrResult XRAPI_CALL xrCreateGeometryInstanceFB( + XrSession session, + const XrGeometryInstanceCreateInfoFB* createInfo, + XrGeometryInstanceFB* outGeometryInstance); + +XRAPI_ATTR XrResult XRAPI_CALL xrDestroyGeometryInstanceFB( + XrGeometryInstanceFB instance); + +XRAPI_ATTR XrResult XRAPI_CALL xrGeometryInstanceSetTransformFB( + XrGeometryInstanceFB instance, + const XrGeometryInstanceTransformFB* transformation); +#endif /* XR_EXTENSION_PROTOTYPES */ +#endif /* !XR_NO_PROTOTYPES */ + + +#define XR_FB_render_model 1 + +#define XR_NULL_RENDER_MODEL_KEY_FB 0 + +XR_DEFINE_ATOM(XrRenderModelKeyFB) +#define XR_FB_render_model_SPEC_VERSION 4 +#define XR_FB_RENDER_MODEL_EXTENSION_NAME "XR_FB_render_model" +#define XR_MAX_RENDER_MODEL_NAME_SIZE_FB 64 +typedef XrFlags64 XrRenderModelFlagsFB; + +// Flag bits for XrRenderModelFlagsFB +static const XrRenderModelFlagsFB XR_RENDER_MODEL_SUPPORTS_GLTF_2_0_SUBSET_1_BIT_FB = 0x00000001; +static const XrRenderModelFlagsFB XR_RENDER_MODEL_SUPPORTS_GLTF_2_0_SUBSET_2_BIT_FB = 0x00000002; + +typedef struct XrRenderModelPathInfoFB { + XrStructureType type; + void* XR_MAY_ALIAS next; + XrPath path; +} XrRenderModelPathInfoFB; + +typedef struct XrRenderModelPropertiesFB { + XrStructureType type; + void* XR_MAY_ALIAS next; + uint32_t vendorId; + char modelName[XR_MAX_RENDER_MODEL_NAME_SIZE_FB]; + XrRenderModelKeyFB modelKey; + uint32_t modelVersion; + XrRenderModelFlagsFB flags; +} XrRenderModelPropertiesFB; + +typedef struct XrRenderModelBufferFB { + XrStructureType type; + void* XR_MAY_ALIAS next; + uint32_t bufferCapacityInput; + uint32_t bufferCountOutput; + uint8_t* buffer; +} XrRenderModelBufferFB; + +typedef struct XrRenderModelLoadInfoFB { + XrStructureType type; + void* XR_MAY_ALIAS next; + XrRenderModelKeyFB modelKey; +} XrRenderModelLoadInfoFB; + +// XrSystemRenderModelPropertiesFB extends XrSystemProperties +typedef struct XrSystemRenderModelPropertiesFB { + XrStructureType type; + void* XR_MAY_ALIAS next; + XrBool32 supportsRenderModelLoading; +} XrSystemRenderModelPropertiesFB; + +// XrRenderModelCapabilitiesRequestFB extends XrSystemProperties +typedef struct XrRenderModelCapabilitiesRequestFB { + XrStructureType type; + void* XR_MAY_ALIAS next; + XrRenderModelFlagsFB flags; +} XrRenderModelCapabilitiesRequestFB; + +typedef XrResult (XRAPI_PTR *PFN_xrEnumerateRenderModelPathsFB)(XrSession session, uint32_t pathCapacityInput, uint32_t* pathCountOutput, XrRenderModelPathInfoFB* paths); +typedef XrResult (XRAPI_PTR *PFN_xrGetRenderModelPropertiesFB)(XrSession session, XrPath path, XrRenderModelPropertiesFB* properties); +typedef XrResult (XRAPI_PTR *PFN_xrLoadRenderModelFB)(XrSession session, const XrRenderModelLoadInfoFB* info, XrRenderModelBufferFB* buffer); + +#ifndef XR_NO_PROTOTYPES +#ifdef XR_EXTENSION_PROTOTYPES +XRAPI_ATTR XrResult XRAPI_CALL xrEnumerateRenderModelPathsFB( + XrSession session, + uint32_t pathCapacityInput, + uint32_t* pathCountOutput, + XrRenderModelPathInfoFB* paths); + +XRAPI_ATTR XrResult XRAPI_CALL xrGetRenderModelPropertiesFB( + XrSession session, + XrPath path, + XrRenderModelPropertiesFB* properties); + +XRAPI_ATTR XrResult XRAPI_CALL xrLoadRenderModelFB( + XrSession session, + const XrRenderModelLoadInfoFB* info, + XrRenderModelBufferFB* buffer); +#endif /* XR_EXTENSION_PROTOTYPES */ +#endif /* !XR_NO_PROTOTYPES */ + + +#define XR_VARJO_foveated_rendering 1 +#define XR_VARJO_foveated_rendering_SPEC_VERSION 3 +#define XR_VARJO_FOVEATED_RENDERING_EXTENSION_NAME "XR_VARJO_foveated_rendering" +// XrViewLocateFoveatedRenderingVARJO extends XrViewLocateInfo +typedef struct XrViewLocateFoveatedRenderingVARJO { + XrStructureType type; + const void* XR_MAY_ALIAS next; + XrBool32 foveatedRenderingActive; +} XrViewLocateFoveatedRenderingVARJO; + +// XrFoveatedViewConfigurationViewVARJO extends XrViewConfigurationView +typedef struct XrFoveatedViewConfigurationViewVARJO { + XrStructureType type; + void* XR_MAY_ALIAS next; + XrBool32 foveatedRenderingActive; +} XrFoveatedViewConfigurationViewVARJO; + +// XrSystemFoveatedRenderingPropertiesVARJO extends XrSystemProperties +typedef struct XrSystemFoveatedRenderingPropertiesVARJO { + XrStructureType type; + void* XR_MAY_ALIAS next; + XrBool32 supportsFoveatedRendering; +} XrSystemFoveatedRenderingPropertiesVARJO; + + + +#define XR_VARJO_composition_layer_depth_test 1 +#define XR_VARJO_composition_layer_depth_test_SPEC_VERSION 2 +#define XR_VARJO_COMPOSITION_LAYER_DEPTH_TEST_EXTENSION_NAME "XR_VARJO_composition_layer_depth_test" +// XrCompositionLayerDepthTestVARJO extends XrCompositionLayerProjection +typedef struct XrCompositionLayerDepthTestVARJO { + XrStructureType type; + const void* XR_MAY_ALIAS next; + float depthTestRangeNearZ; + float depthTestRangeFarZ; +} XrCompositionLayerDepthTestVARJO; + + + +#define XR_VARJO_environment_depth_estimation 1 +#define XR_VARJO_environment_depth_estimation_SPEC_VERSION 1 +#define XR_VARJO_ENVIRONMENT_DEPTH_ESTIMATION_EXTENSION_NAME "XR_VARJO_environment_depth_estimation" +typedef XrResult (XRAPI_PTR *PFN_xrSetEnvironmentDepthEstimationVARJO)(XrSession session, XrBool32 enabled); + +#ifndef XR_NO_PROTOTYPES +#ifdef XR_EXTENSION_PROTOTYPES +XRAPI_ATTR XrResult XRAPI_CALL xrSetEnvironmentDepthEstimationVARJO( + XrSession session, + XrBool32 enabled); +#endif /* XR_EXTENSION_PROTOTYPES */ +#endif /* !XR_NO_PROTOTYPES */ + + +#define XR_VARJO_marker_tracking 1 +#define XR_VARJO_marker_tracking_SPEC_VERSION 1 +#define XR_VARJO_MARKER_TRACKING_EXTENSION_NAME "XR_VARJO_marker_tracking" +// XrSystemMarkerTrackingPropertiesVARJO extends XrSystemProperties +typedef struct XrSystemMarkerTrackingPropertiesVARJO { + XrStructureType type; + void* XR_MAY_ALIAS next; + XrBool32 supportsMarkerTracking; +} XrSystemMarkerTrackingPropertiesVARJO; + +typedef struct XrEventDataMarkerTrackingUpdateVARJO { + XrStructureType type; + const void* XR_MAY_ALIAS next; + uint64_t markerId; + XrBool32 isActive; + XrBool32 isPredicted; + XrTime time; +} XrEventDataMarkerTrackingUpdateVARJO; + +typedef struct XrMarkerSpaceCreateInfoVARJO { + XrStructureType type; + const void* XR_MAY_ALIAS next; + uint64_t markerId; + XrPosef poseInMarkerSpace; +} XrMarkerSpaceCreateInfoVARJO; + +typedef XrResult (XRAPI_PTR *PFN_xrSetMarkerTrackingVARJO)(XrSession session, XrBool32 enabled); +typedef XrResult (XRAPI_PTR *PFN_xrSetMarkerTrackingTimeoutVARJO)(XrSession session, uint64_t markerId, XrDuration timeout); +typedef XrResult (XRAPI_PTR *PFN_xrSetMarkerTrackingPredictionVARJO)(XrSession session, uint64_t markerId, XrBool32 enabled); +typedef XrResult (XRAPI_PTR *PFN_xrGetMarkerSizeVARJO)(XrSession session, uint64_t markerId, XrExtent2Df* size); +typedef XrResult (XRAPI_PTR *PFN_xrCreateMarkerSpaceVARJO)(XrSession session, const XrMarkerSpaceCreateInfoVARJO* createInfo, XrSpace* space); + +#ifndef XR_NO_PROTOTYPES +#ifdef XR_EXTENSION_PROTOTYPES +XRAPI_ATTR XrResult XRAPI_CALL xrSetMarkerTrackingVARJO( + XrSession session, + XrBool32 enabled); + +XRAPI_ATTR XrResult XRAPI_CALL xrSetMarkerTrackingTimeoutVARJO( + XrSession session, + uint64_t markerId, + XrDuration timeout); + +XRAPI_ATTR XrResult XRAPI_CALL xrSetMarkerTrackingPredictionVARJO( + XrSession session, + uint64_t markerId, + XrBool32 enabled); + +XRAPI_ATTR XrResult XRAPI_CALL xrGetMarkerSizeVARJO( + XrSession session, + uint64_t markerId, + XrExtent2Df* size); + +XRAPI_ATTR XrResult XRAPI_CALL xrCreateMarkerSpaceVARJO( + XrSession session, + const XrMarkerSpaceCreateInfoVARJO* createInfo, + XrSpace* space); +#endif /* XR_EXTENSION_PROTOTYPES */ +#endif /* !XR_NO_PROTOTYPES */ + + +#define XR_VARJO_view_offset 1 +#define XR_VARJO_view_offset_SPEC_VERSION 1 +#define XR_VARJO_VIEW_OFFSET_EXTENSION_NAME "XR_VARJO_view_offset" +typedef XrResult (XRAPI_PTR *PFN_xrSetViewOffsetVARJO)(XrSession session, float offset); + +#ifndef XR_NO_PROTOTYPES +#ifdef XR_EXTENSION_PROTOTYPES +XRAPI_ATTR XrResult XRAPI_CALL xrSetViewOffsetVARJO( + XrSession session, + float offset); +#endif /* XR_EXTENSION_PROTOTYPES */ +#endif /* !XR_NO_PROTOTYPES */ + + +#define XR_ML_ml2_controller_interaction 1 +#define XR_ML_ml2_controller_interaction_SPEC_VERSION 1 +#define XR_ML_ML2_CONTROLLER_INTERACTION_EXTENSION_NAME "XR_ML_ml2_controller_interaction" + + +#define XR_ML_frame_end_info 1 +#define XR_ML_frame_end_info_SPEC_VERSION 1 +#define XR_ML_FRAME_END_INFO_EXTENSION_NAME "XR_ML_frame_end_info" +typedef XrFlags64 XrFrameEndInfoFlagsML; + +// Flag bits for XrFrameEndInfoFlagsML +static const XrFrameEndInfoFlagsML XR_FRAME_END_INFO_PROTECTED_BIT_ML = 0x00000001; +static const XrFrameEndInfoFlagsML XR_FRAME_END_INFO_VIGNETTE_BIT_ML = 0x00000002; + +// XrFrameEndInfoML extends XrFrameEndInfo +typedef struct XrFrameEndInfoML { + XrStructureType type; + const void* XR_MAY_ALIAS next; + float focusDistance; + XrFrameEndInfoFlagsML flags; +} XrFrameEndInfoML; + + + +#define XR_ML_global_dimmer 1 +#define XR_ML_global_dimmer_SPEC_VERSION 1 +#define XR_ML_GLOBAL_DIMMER_EXTENSION_NAME "XR_ML_global_dimmer" +typedef XrFlags64 XrGlobalDimmerFrameEndInfoFlagsML; + +// Flag bits for XrGlobalDimmerFrameEndInfoFlagsML +static const XrGlobalDimmerFrameEndInfoFlagsML XR_GLOBAL_DIMMER_FRAME_END_INFO_ENABLED_BIT_ML = 0x00000001; + +// XrGlobalDimmerFrameEndInfoML extends XrFrameEndInfo +typedef struct XrGlobalDimmerFrameEndInfoML { + XrStructureType type; + const void* XR_MAY_ALIAS next; + float dimmerValue; + XrGlobalDimmerFrameEndInfoFlagsML flags; +} XrGlobalDimmerFrameEndInfoML; + + + +#define XR_MSFT_spatial_anchor_persistence 1 +XR_DEFINE_HANDLE(XrSpatialAnchorStoreConnectionMSFT) +#define XR_MAX_SPATIAL_ANCHOR_NAME_SIZE_MSFT 256 +#define XR_MSFT_spatial_anchor_persistence_SPEC_VERSION 2 +#define XR_MSFT_SPATIAL_ANCHOR_PERSISTENCE_EXTENSION_NAME "XR_MSFT_spatial_anchor_persistence" +typedef struct XrSpatialAnchorPersistenceNameMSFT { + char name[XR_MAX_SPATIAL_ANCHOR_NAME_SIZE_MSFT]; +} XrSpatialAnchorPersistenceNameMSFT; + +typedef struct XrSpatialAnchorPersistenceInfoMSFT { + XrStructureType type; + const void* XR_MAY_ALIAS next; + XrSpatialAnchorPersistenceNameMSFT spatialAnchorPersistenceName; + XrSpatialAnchorMSFT spatialAnchor; +} XrSpatialAnchorPersistenceInfoMSFT; + +typedef struct XrSpatialAnchorFromPersistedAnchorCreateInfoMSFT { + XrStructureType type; + const void* XR_MAY_ALIAS next; + XrSpatialAnchorStoreConnectionMSFT spatialAnchorStore; + XrSpatialAnchorPersistenceNameMSFT spatialAnchorPersistenceName; +} XrSpatialAnchorFromPersistedAnchorCreateInfoMSFT; + +typedef XrResult (XRAPI_PTR *PFN_xrCreateSpatialAnchorStoreConnectionMSFT)(XrSession session, XrSpatialAnchorStoreConnectionMSFT* spatialAnchorStore); +typedef XrResult (XRAPI_PTR *PFN_xrDestroySpatialAnchorStoreConnectionMSFT)(XrSpatialAnchorStoreConnectionMSFT spatialAnchorStore); +typedef XrResult (XRAPI_PTR *PFN_xrPersistSpatialAnchorMSFT)(XrSpatialAnchorStoreConnectionMSFT spatialAnchorStore, const XrSpatialAnchorPersistenceInfoMSFT* spatialAnchorPersistenceInfo); +typedef XrResult (XRAPI_PTR *PFN_xrEnumeratePersistedSpatialAnchorNamesMSFT)(XrSpatialAnchorStoreConnectionMSFT spatialAnchorStore, uint32_t spatialAnchorNamesCapacityInput, uint32_t* spatialAnchorNamesCountOutput, XrSpatialAnchorPersistenceNameMSFT* persistedAnchorNames); +typedef XrResult (XRAPI_PTR *PFN_xrCreateSpatialAnchorFromPersistedNameMSFT)(XrSession session, const XrSpatialAnchorFromPersistedAnchorCreateInfoMSFT* spatialAnchorCreateInfo, XrSpatialAnchorMSFT* spatialAnchor); +typedef XrResult (XRAPI_PTR *PFN_xrUnpersistSpatialAnchorMSFT)(XrSpatialAnchorStoreConnectionMSFT spatialAnchorStore, const XrSpatialAnchorPersistenceNameMSFT* spatialAnchorPersistenceName); +typedef XrResult (XRAPI_PTR *PFN_xrClearSpatialAnchorStoreMSFT)(XrSpatialAnchorStoreConnectionMSFT spatialAnchorStore); + +#ifndef XR_NO_PROTOTYPES +#ifdef XR_EXTENSION_PROTOTYPES +XRAPI_ATTR XrResult XRAPI_CALL xrCreateSpatialAnchorStoreConnectionMSFT( + XrSession session, + XrSpatialAnchorStoreConnectionMSFT* spatialAnchorStore); + +XRAPI_ATTR XrResult XRAPI_CALL xrDestroySpatialAnchorStoreConnectionMSFT( + XrSpatialAnchorStoreConnectionMSFT spatialAnchorStore); + +XRAPI_ATTR XrResult XRAPI_CALL xrPersistSpatialAnchorMSFT( + XrSpatialAnchorStoreConnectionMSFT spatialAnchorStore, + const XrSpatialAnchorPersistenceInfoMSFT* spatialAnchorPersistenceInfo); + +XRAPI_ATTR XrResult XRAPI_CALL xrEnumeratePersistedSpatialAnchorNamesMSFT( + XrSpatialAnchorStoreConnectionMSFT spatialAnchorStore, + uint32_t spatialAnchorNamesCapacityInput, + uint32_t* spatialAnchorNamesCountOutput, + XrSpatialAnchorPersistenceNameMSFT* persistedAnchorNames); + +XRAPI_ATTR XrResult XRAPI_CALL xrCreateSpatialAnchorFromPersistedNameMSFT( + XrSession session, + const XrSpatialAnchorFromPersistedAnchorCreateInfoMSFT* spatialAnchorCreateInfo, + XrSpatialAnchorMSFT* spatialAnchor); + +XRAPI_ATTR XrResult XRAPI_CALL xrUnpersistSpatialAnchorMSFT( + XrSpatialAnchorStoreConnectionMSFT spatialAnchorStore, + const XrSpatialAnchorPersistenceNameMSFT* spatialAnchorPersistenceName); + +XRAPI_ATTR XrResult XRAPI_CALL xrClearSpatialAnchorStoreMSFT( + XrSpatialAnchorStoreConnectionMSFT spatialAnchorStore); +#endif /* XR_EXTENSION_PROTOTYPES */ +#endif /* !XR_NO_PROTOTYPES */ + + +#define XR_ULTRALEAP_hand_tracking_forearm 1 + +#define XR_HAND_FOREARM_JOINT_COUNT_ULTRALEAP 27 + +#define XR_ULTRALEAP_hand_tracking_forearm_SPEC_VERSION 1 +#define XR_ULTRALEAP_HAND_TRACKING_FOREARM_EXTENSION_NAME "XR_ULTRALEAP_hand_tracking_forearm" + +typedef enum XrHandForearmJointULTRALEAP { + XR_HAND_FOREARM_JOINT_PALM_ULTRALEAP = 0, + XR_HAND_FOREARM_JOINT_WRIST_ULTRALEAP = 1, + XR_HAND_FOREARM_JOINT_THUMB_METACARPAL_ULTRALEAP = 2, + XR_HAND_FOREARM_JOINT_THUMB_PROXIMAL_ULTRALEAP = 3, + XR_HAND_FOREARM_JOINT_THUMB_DISTAL_ULTRALEAP = 4, + XR_HAND_FOREARM_JOINT_THUMB_TIP_ULTRALEAP = 5, + XR_HAND_FOREARM_JOINT_INDEX_METACARPAL_ULTRALEAP = 6, + XR_HAND_FOREARM_JOINT_INDEX_PROXIMAL_ULTRALEAP = 7, + XR_HAND_FOREARM_JOINT_INDEX_INTERMEDIATE_ULTRALEAP = 8, + XR_HAND_FOREARM_JOINT_INDEX_DISTAL_ULTRALEAP = 9, + XR_HAND_FOREARM_JOINT_INDEX_TIP_ULTRALEAP = 10, + XR_HAND_FOREARM_JOINT_MIDDLE_METACARPAL_ULTRALEAP = 11, + XR_HAND_FOREARM_JOINT_MIDDLE_PROXIMAL_ULTRALEAP = 12, + XR_HAND_FOREARM_JOINT_MIDDLE_INTERMEDIATE_ULTRALEAP = 13, + XR_HAND_FOREARM_JOINT_MIDDLE_DISTAL_ULTRALEAP = 14, + XR_HAND_FOREARM_JOINT_MIDDLE_TIP_ULTRALEAP = 15, + XR_HAND_FOREARM_JOINT_RING_METACARPAL_ULTRALEAP = 16, + XR_HAND_FOREARM_JOINT_RING_PROXIMAL_ULTRALEAP = 17, + XR_HAND_FOREARM_JOINT_RING_INTERMEDIATE_ULTRALEAP = 18, + XR_HAND_FOREARM_JOINT_RING_DISTAL_ULTRALEAP = 19, + XR_HAND_FOREARM_JOINT_RING_TIP_ULTRALEAP = 20, + XR_HAND_FOREARM_JOINT_LITTLE_METACARPAL_ULTRALEAP = 21, + XR_HAND_FOREARM_JOINT_LITTLE_PROXIMAL_ULTRALEAP = 22, + XR_HAND_FOREARM_JOINT_LITTLE_INTERMEDIATE_ULTRALEAP = 23, + XR_HAND_FOREARM_JOINT_LITTLE_DISTAL_ULTRALEAP = 24, + XR_HAND_FOREARM_JOINT_LITTLE_TIP_ULTRALEAP = 25, + XR_HAND_FOREARM_JOINT_ELBOW_ULTRALEAP = 26, + XR_HAND_FOREARM_JOINT_MAX_ENUM_ULTRALEAP = 0x7FFFFFFF +} XrHandForearmJointULTRALEAP; + + +#define XR_FB_spatial_entity_query 1 +#define XR_FB_spatial_entity_query_SPEC_VERSION 1 +#define XR_FB_SPATIAL_ENTITY_QUERY_EXTENSION_NAME "XR_FB_spatial_entity_query" + +typedef enum XrSpaceQueryActionFB { + XR_SPACE_QUERY_ACTION_LOAD_FB = 0, + XR_SPACE_QUERY_ACTION_MAX_ENUM_FB = 0x7FFFFFFF +} XrSpaceQueryActionFB; + +typedef enum XrSpaceStorageLocationFB { + XR_SPACE_STORAGE_LOCATION_INVALID_FB = 0, + XR_SPACE_STORAGE_LOCATION_LOCAL_FB = 1, + XR_SPACE_STORAGE_LOCATION_CLOUD_FB = 2, + XR_SPACE_STORAGE_LOCATION_MAX_ENUM_FB = 0x7FFFFFFF +} XrSpaceStorageLocationFB; +typedef struct XR_MAY_ALIAS XrSpaceQueryInfoBaseHeaderFB { + XrStructureType type; + const void* XR_MAY_ALIAS next; +} XrSpaceQueryInfoBaseHeaderFB; + +typedef struct XR_MAY_ALIAS XrSpaceFilterInfoBaseHeaderFB { + XrStructureType type; + const void* XR_MAY_ALIAS next; +} XrSpaceFilterInfoBaseHeaderFB; + +typedef struct XrSpaceQueryInfoFB { + XrStructureType type; + const void* XR_MAY_ALIAS next; + XrSpaceQueryActionFB queryAction; + uint32_t maxResultCount; + XrDuration timeout; + const XrSpaceFilterInfoBaseHeaderFB* filter; + const XrSpaceFilterInfoBaseHeaderFB* excludeFilter; +} XrSpaceQueryInfoFB; + +// XrSpaceStorageLocationFilterInfoFB extends XrSpaceFilterInfoBaseHeaderFB +typedef struct XrSpaceStorageLocationFilterInfoFB { + XrStructureType type; + const void* XR_MAY_ALIAS next; + XrSpaceStorageLocationFB location; +} XrSpaceStorageLocationFilterInfoFB; + +typedef struct XrSpaceUuidFilterInfoFB { + XrStructureType type; + const void* XR_MAY_ALIAS next; + uint32_t uuidCount; + XrUuidEXT* uuids; +} XrSpaceUuidFilterInfoFB; + +typedef struct XrSpaceComponentFilterInfoFB { + XrStructureType type; + const void* XR_MAY_ALIAS next; + XrSpaceComponentTypeFB componentType; +} XrSpaceComponentFilterInfoFB; + +typedef struct XrSpaceQueryResultFB { + XrSpace space; + XrUuidEXT uuid; +} XrSpaceQueryResultFB; + +typedef struct XrSpaceQueryResultsFB { + XrStructureType type; + void* XR_MAY_ALIAS next; + uint32_t resultCapacityInput; + uint32_t resultCountOutput; + XrSpaceQueryResultFB* results; +} XrSpaceQueryResultsFB; + +typedef struct XrEventDataSpaceQueryResultsAvailableFB { + XrStructureType type; + const void* XR_MAY_ALIAS next; + XrAsyncRequestIdFB requestId; +} XrEventDataSpaceQueryResultsAvailableFB; + +typedef struct XrEventDataSpaceQueryCompleteFB { + XrStructureType type; + const void* XR_MAY_ALIAS next; + XrAsyncRequestIdFB requestId; + XrResult result; +} XrEventDataSpaceQueryCompleteFB; + +typedef XrResult (XRAPI_PTR *PFN_xrQuerySpacesFB)(XrSession session, const XrSpaceQueryInfoBaseHeaderFB* info, XrAsyncRequestIdFB* requestId); +typedef XrResult (XRAPI_PTR *PFN_xrRetrieveSpaceQueryResultsFB)(XrSession session, XrAsyncRequestIdFB requestId, XrSpaceQueryResultsFB* results); + +#ifndef XR_NO_PROTOTYPES +#ifdef XR_EXTENSION_PROTOTYPES +XRAPI_ATTR XrResult XRAPI_CALL xrQuerySpacesFB( + XrSession session, + const XrSpaceQueryInfoBaseHeaderFB* info, + XrAsyncRequestIdFB* requestId); + +XRAPI_ATTR XrResult XRAPI_CALL xrRetrieveSpaceQueryResultsFB( + XrSession session, + XrAsyncRequestIdFB requestId, + XrSpaceQueryResultsFB* results); +#endif /* XR_EXTENSION_PROTOTYPES */ +#endif /* !XR_NO_PROTOTYPES */ + + +#define XR_FB_spatial_entity_storage 1 +#define XR_FB_spatial_entity_storage_SPEC_VERSION 1 +#define XR_FB_SPATIAL_ENTITY_STORAGE_EXTENSION_NAME "XR_FB_spatial_entity_storage" + +typedef enum XrSpacePersistenceModeFB { + XR_SPACE_PERSISTENCE_MODE_INVALID_FB = 0, + XR_SPACE_PERSISTENCE_MODE_INDEFINITE_FB = 1, + XR_SPACE_PERSISTENCE_MODE_MAX_ENUM_FB = 0x7FFFFFFF +} XrSpacePersistenceModeFB; +typedef struct XrSpaceSaveInfoFB { + XrStructureType type; + const void* XR_MAY_ALIAS next; + XrSpace space; + XrSpaceStorageLocationFB location; + XrSpacePersistenceModeFB persistenceMode; +} XrSpaceSaveInfoFB; + +typedef struct XrSpaceEraseInfoFB { + XrStructureType type; + const void* XR_MAY_ALIAS next; + XrSpace space; + XrSpaceStorageLocationFB location; +} XrSpaceEraseInfoFB; + +typedef struct XrEventDataSpaceSaveCompleteFB { + XrStructureType type; + const void* XR_MAY_ALIAS next; + XrAsyncRequestIdFB requestId; + XrResult result; + XrSpace space; + XrUuidEXT uuid; + XrSpaceStorageLocationFB location; +} XrEventDataSpaceSaveCompleteFB; + +typedef struct XrEventDataSpaceEraseCompleteFB { + XrStructureType type; + const void* XR_MAY_ALIAS next; + XrAsyncRequestIdFB requestId; + XrResult result; + XrSpace space; + XrUuidEXT uuid; + XrSpaceStorageLocationFB location; +} XrEventDataSpaceEraseCompleteFB; + +typedef XrResult (XRAPI_PTR *PFN_xrSaveSpaceFB)(XrSession session, const XrSpaceSaveInfoFB* info, XrAsyncRequestIdFB* requestId); +typedef XrResult (XRAPI_PTR *PFN_xrEraseSpaceFB)(XrSession session, const XrSpaceEraseInfoFB* info, XrAsyncRequestIdFB* requestId); + +#ifndef XR_NO_PROTOTYPES +#ifdef XR_EXTENSION_PROTOTYPES +XRAPI_ATTR XrResult XRAPI_CALL xrSaveSpaceFB( + XrSession session, + const XrSpaceSaveInfoFB* info, + XrAsyncRequestIdFB* requestId); + +XRAPI_ATTR XrResult XRAPI_CALL xrEraseSpaceFB( + XrSession session, + const XrSpaceEraseInfoFB* info, + XrAsyncRequestIdFB* requestId); +#endif /* XR_EXTENSION_PROTOTYPES */ +#endif /* !XR_NO_PROTOTYPES */ + + +#define XR_FB_touch_controller_pro 1 +#define XR_FB_touch_controller_pro_SPEC_VERSION 1 +#define XR_FB_TOUCH_CONTROLLER_PRO_EXTENSION_NAME "XR_FB_touch_controller_pro" + + +#define XR_FB_spatial_entity_sharing 1 +XR_DEFINE_HANDLE(XrSpaceUserFB) +#define XR_FB_spatial_entity_sharing_SPEC_VERSION 1 +#define XR_FB_SPATIAL_ENTITY_SHARING_EXTENSION_NAME "XR_FB_spatial_entity_sharing" +typedef struct XrSpaceShareInfoFB { + XrStructureType type; + const void* XR_MAY_ALIAS next; + uint32_t spaceCount; + XrSpace* spaces; + uint32_t userCount; + XrSpaceUserFB* users; +} XrSpaceShareInfoFB; + +typedef struct XrEventDataSpaceShareCompleteFB { + XrStructureType type; + const void* XR_MAY_ALIAS next; + XrAsyncRequestIdFB requestId; + XrResult result; +} XrEventDataSpaceShareCompleteFB; + +typedef XrResult (XRAPI_PTR *PFN_xrShareSpacesFB)(XrSession session, const XrSpaceShareInfoFB* info, XrAsyncRequestIdFB* requestId); + +#ifndef XR_NO_PROTOTYPES +#ifdef XR_EXTENSION_PROTOTYPES +XRAPI_ATTR XrResult XRAPI_CALL xrShareSpacesFB( + XrSession session, + const XrSpaceShareInfoFB* info, + XrAsyncRequestIdFB* requestId); +#endif /* XR_EXTENSION_PROTOTYPES */ +#endif /* !XR_NO_PROTOTYPES */ + + +#define XR_FB_space_warp 1 +#define XR_FB_space_warp_SPEC_VERSION 2 +#define XR_FB_SPACE_WARP_EXTENSION_NAME "XR_FB_space_warp" +typedef XrFlags64 XrCompositionLayerSpaceWarpInfoFlagsFB; + +// Flag bits for XrCompositionLayerSpaceWarpInfoFlagsFB +static const XrCompositionLayerSpaceWarpInfoFlagsFB XR_COMPOSITION_LAYER_SPACE_WARP_INFO_FRAME_SKIP_BIT_FB = 0x00000001; + +// XrCompositionLayerSpaceWarpInfoFB extends XrCompositionLayerProjectionView +typedef struct XrCompositionLayerSpaceWarpInfoFB { + XrStructureType type; + const void* XR_MAY_ALIAS next; + XrCompositionLayerSpaceWarpInfoFlagsFB layerFlags; + XrSwapchainSubImage motionVectorSubImage; + XrPosef appSpaceDeltaPose; + XrSwapchainSubImage depthSubImage; + float minDepth; + float maxDepth; + float nearZ; + float farZ; +} XrCompositionLayerSpaceWarpInfoFB; + +// XrSystemSpaceWarpPropertiesFB extends XrSystemProperties +typedef struct XrSystemSpaceWarpPropertiesFB { + XrStructureType type; + void* XR_MAY_ALIAS next; + uint32_t recommendedMotionVectorImageRectWidth; + uint32_t recommendedMotionVectorImageRectHeight; +} XrSystemSpaceWarpPropertiesFB; + + + +#define XR_FB_haptic_amplitude_envelope 1 + +#define XR_MAX_HAPTIC_AMPLITUDE_ENVELOPE_SAMPLES_FB 4000u + +#define XR_FB_haptic_amplitude_envelope_SPEC_VERSION 1 +#define XR_FB_HAPTIC_AMPLITUDE_ENVELOPE_EXTENSION_NAME "XR_FB_haptic_amplitude_envelope" +typedef struct XrHapticAmplitudeEnvelopeVibrationFB { + XrStructureType type; + const void* XR_MAY_ALIAS next; + XrDuration duration; + uint32_t amplitudeCount; + const float* amplitudes; +} XrHapticAmplitudeEnvelopeVibrationFB; + + + +#define XR_FB_scene 1 +#define XR_FB_scene_SPEC_VERSION 3 +#define XR_FB_SCENE_EXTENSION_NAME "XR_FB_scene" +typedef XrFlags64 XrSemanticLabelsSupportFlagsFB; + +// Flag bits for XrSemanticLabelsSupportFlagsFB +static const XrSemanticLabelsSupportFlagsFB XR_SEMANTIC_LABELS_SUPPORT_MULTIPLE_SEMANTIC_LABELS_BIT_FB = 0x00000001; +static const XrSemanticLabelsSupportFlagsFB XR_SEMANTIC_LABELS_SUPPORT_ACCEPT_DESK_TO_TABLE_MIGRATION_BIT_FB = 0x00000002; + +typedef struct XrExtent3DfFB { + float width; + float height; + float depth; +} XrExtent3DfFB; + +typedef struct XrOffset3DfFB { + float x; + float y; + float z; +} XrOffset3DfFB; + +typedef struct XrRect3DfFB { + XrOffset3DfFB offset; + XrExtent3DfFB extent; +} XrRect3DfFB; + +typedef struct XrSemanticLabelsFB { + XrStructureType type; + const void* XR_MAY_ALIAS next; + uint32_t bufferCapacityInput; + uint32_t bufferCountOutput; + char* buffer; +} XrSemanticLabelsFB; + +typedef struct XrRoomLayoutFB { + XrStructureType type; + const void* XR_MAY_ALIAS next; + XrUuidEXT floorUuid; + XrUuidEXT ceilingUuid; + uint32_t wallUuidCapacityInput; + uint32_t wallUuidCountOutput; + XrUuidEXT* wallUuids; +} XrRoomLayoutFB; + +typedef struct XrBoundary2DFB { + XrStructureType type; + const void* XR_MAY_ALIAS next; + uint32_t vertexCapacityInput; + uint32_t vertexCountOutput; + XrVector2f* vertices; +} XrBoundary2DFB; + +typedef struct XrSemanticLabelsSupportInfoFB { + XrStructureType type; + const void* XR_MAY_ALIAS next; + XrSemanticLabelsSupportFlagsFB flags; + const char* recognizedLabels; +} XrSemanticLabelsSupportInfoFB; + +typedef XrResult (XRAPI_PTR *PFN_xrGetSpaceBoundingBox2DFB)(XrSession session, XrSpace space, XrRect2Df* boundingBox2DOutput); +typedef XrResult (XRAPI_PTR *PFN_xrGetSpaceBoundingBox3DFB)(XrSession session, XrSpace space, XrRect3DfFB* boundingBox3DOutput); +typedef XrResult (XRAPI_PTR *PFN_xrGetSpaceSemanticLabelsFB)(XrSession session, XrSpace space, XrSemanticLabelsFB* semanticLabelsOutput); +typedef XrResult (XRAPI_PTR *PFN_xrGetSpaceBoundary2DFB)(XrSession session, XrSpace space, XrBoundary2DFB* boundary2DOutput); +typedef XrResult (XRAPI_PTR *PFN_xrGetSpaceRoomLayoutFB)(XrSession session, XrSpace space, XrRoomLayoutFB* roomLayoutOutput); + +#ifndef XR_NO_PROTOTYPES +#ifdef XR_EXTENSION_PROTOTYPES +XRAPI_ATTR XrResult XRAPI_CALL xrGetSpaceBoundingBox2DFB( + XrSession session, + XrSpace space, + XrRect2Df* boundingBox2DOutput); + +XRAPI_ATTR XrResult XRAPI_CALL xrGetSpaceBoundingBox3DFB( + XrSession session, + XrSpace space, + XrRect3DfFB* boundingBox3DOutput); + +XRAPI_ATTR XrResult XRAPI_CALL xrGetSpaceSemanticLabelsFB( + XrSession session, + XrSpace space, + XrSemanticLabelsFB* semanticLabelsOutput); + +XRAPI_ATTR XrResult XRAPI_CALL xrGetSpaceBoundary2DFB( + XrSession session, + XrSpace space, + XrBoundary2DFB* boundary2DOutput); + +XRAPI_ATTR XrResult XRAPI_CALL xrGetSpaceRoomLayoutFB( + XrSession session, + XrSpace space, + XrRoomLayoutFB* roomLayoutOutput); +#endif /* XR_EXTENSION_PROTOTYPES */ +#endif /* !XR_NO_PROTOTYPES */ + + +#define XR_EXT_palm_pose 1 +#define XR_EXT_palm_pose_SPEC_VERSION 2 +#define XR_EXT_PALM_POSE_EXTENSION_NAME "XR_EXT_palm_pose" + + +#define XR_ALMALENCE_digital_lens_control 1 +#define XR_ALMALENCE_digital_lens_control_SPEC_VERSION 1 +#define XR_ALMALENCE_DIGITAL_LENS_CONTROL_EXTENSION_NAME "XR_ALMALENCE_digital_lens_control" +typedef XrFlags64 XrDigitalLensControlFlagsALMALENCE; + +// Flag bits for XrDigitalLensControlFlagsALMALENCE +static const XrDigitalLensControlFlagsALMALENCE XR_DIGITAL_LENS_CONTROL_PROCESSING_DISABLE_BIT_ALMALENCE = 0x00000001; + +typedef struct XrDigitalLensControlALMALENCE { + XrStructureType type; + const void* XR_MAY_ALIAS next; + XrDigitalLensControlFlagsALMALENCE flags; +} XrDigitalLensControlALMALENCE; + +typedef XrResult (XRAPI_PTR *PFN_xrSetDigitalLensControlALMALENCE)(XrSession session, const XrDigitalLensControlALMALENCE* digitalLensControl); + +#ifndef XR_NO_PROTOTYPES +#ifdef XR_EXTENSION_PROTOTYPES +XRAPI_ATTR XrResult XRAPI_CALL xrSetDigitalLensControlALMALENCE( + XrSession session, + const XrDigitalLensControlALMALENCE* digitalLensControl); +#endif /* XR_EXTENSION_PROTOTYPES */ +#endif /* !XR_NO_PROTOTYPES */ + + +#define XR_FB_scene_capture 1 +#define XR_FB_scene_capture_SPEC_VERSION 1 +#define XR_FB_SCENE_CAPTURE_EXTENSION_NAME "XR_FB_scene_capture" +typedef struct XrEventDataSceneCaptureCompleteFB { + XrStructureType type; + const void* XR_MAY_ALIAS next; + XrAsyncRequestIdFB requestId; + XrResult result; +} XrEventDataSceneCaptureCompleteFB; + +typedef struct XrSceneCaptureRequestInfoFB { + XrStructureType type; + const void* XR_MAY_ALIAS next; + uint32_t requestByteCount; + const char* request; +} XrSceneCaptureRequestInfoFB; + +typedef XrResult (XRAPI_PTR *PFN_xrRequestSceneCaptureFB)(XrSession session, const XrSceneCaptureRequestInfoFB* info, XrAsyncRequestIdFB* requestId); + +#ifndef XR_NO_PROTOTYPES +#ifdef XR_EXTENSION_PROTOTYPES +XRAPI_ATTR XrResult XRAPI_CALL xrRequestSceneCaptureFB( + XrSession session, + const XrSceneCaptureRequestInfoFB* info, + XrAsyncRequestIdFB* requestId); +#endif /* XR_EXTENSION_PROTOTYPES */ +#endif /* !XR_NO_PROTOTYPES */ + + +#define XR_FB_spatial_entity_container 1 +#define XR_FB_spatial_entity_container_SPEC_VERSION 2 +#define XR_FB_SPATIAL_ENTITY_CONTAINER_EXTENSION_NAME "XR_FB_spatial_entity_container" +typedef struct XrSpaceContainerFB { + XrStructureType type; + const void* XR_MAY_ALIAS next; + uint32_t uuidCapacityInput; + uint32_t uuidCountOutput; + XrUuidEXT* uuids; +} XrSpaceContainerFB; + +typedef XrResult (XRAPI_PTR *PFN_xrGetSpaceContainerFB)(XrSession session, XrSpace space, XrSpaceContainerFB* spaceContainerOutput); + +#ifndef XR_NO_PROTOTYPES +#ifdef XR_EXTENSION_PROTOTYPES +XRAPI_ATTR XrResult XRAPI_CALL xrGetSpaceContainerFB( + XrSession session, + XrSpace space, + XrSpaceContainerFB* spaceContainerOutput); +#endif /* XR_EXTENSION_PROTOTYPES */ +#endif /* !XR_NO_PROTOTYPES */ + + +#define XR_META_foveation_eye_tracked 1 +#define XR_FOVEATION_CENTER_SIZE_META 2 +#define XR_META_foveation_eye_tracked_SPEC_VERSION 1 +#define XR_META_FOVEATION_EYE_TRACKED_EXTENSION_NAME "XR_META_foveation_eye_tracked" +typedef XrFlags64 XrFoveationEyeTrackedProfileCreateFlagsMETA; + +// Flag bits for XrFoveationEyeTrackedProfileCreateFlagsMETA + +typedef XrFlags64 XrFoveationEyeTrackedStateFlagsMETA; + +// Flag bits for XrFoveationEyeTrackedStateFlagsMETA +static const XrFoveationEyeTrackedStateFlagsMETA XR_FOVEATION_EYE_TRACKED_STATE_VALID_BIT_META = 0x00000001; + +// XrFoveationEyeTrackedProfileCreateInfoMETA extends XrFoveationLevelProfileCreateInfoFB +typedef struct XrFoveationEyeTrackedProfileCreateInfoMETA { + XrStructureType type; + const void* XR_MAY_ALIAS next; + XrFoveationEyeTrackedProfileCreateFlagsMETA flags; +} XrFoveationEyeTrackedProfileCreateInfoMETA; + +typedef struct XrFoveationEyeTrackedStateMETA { + XrStructureType type; + void* XR_MAY_ALIAS next; + XrVector2f foveationCenter[XR_FOVEATION_CENTER_SIZE_META]; + XrFoveationEyeTrackedStateFlagsMETA flags; +} XrFoveationEyeTrackedStateMETA; + +// XrSystemFoveationEyeTrackedPropertiesMETA extends XrSystemProperties +typedef struct XrSystemFoveationEyeTrackedPropertiesMETA { + XrStructureType type; + void* XR_MAY_ALIAS next; + XrBool32 supportsFoveationEyeTracked; +} XrSystemFoveationEyeTrackedPropertiesMETA; + +typedef XrResult (XRAPI_PTR *PFN_xrGetFoveationEyeTrackedStateMETA)(XrSession session, XrFoveationEyeTrackedStateMETA* foveationState); + +#ifndef XR_NO_PROTOTYPES +#ifdef XR_EXTENSION_PROTOTYPES +XRAPI_ATTR XrResult XRAPI_CALL xrGetFoveationEyeTrackedStateMETA( + XrSession session, + XrFoveationEyeTrackedStateMETA* foveationState); +#endif /* XR_EXTENSION_PROTOTYPES */ +#endif /* !XR_NO_PROTOTYPES */ + + +#define XR_FB_face_tracking 1 + +#define XR_FACE_EXPRESSSION_SET_DEFAULT_FB XR_FACE_EXPRESSION_SET_DEFAULT_FB + +XR_DEFINE_HANDLE(XrFaceTrackerFB) +#define XR_FB_face_tracking_SPEC_VERSION 1 +#define XR_FB_FACE_TRACKING_EXTENSION_NAME "XR_FB_face_tracking" + +typedef enum XrFaceExpressionFB { + XR_FACE_EXPRESSION_BROW_LOWERER_L_FB = 0, + XR_FACE_EXPRESSION_BROW_LOWERER_R_FB = 1, + XR_FACE_EXPRESSION_CHEEK_PUFF_L_FB = 2, + XR_FACE_EXPRESSION_CHEEK_PUFF_R_FB = 3, + XR_FACE_EXPRESSION_CHEEK_RAISER_L_FB = 4, + XR_FACE_EXPRESSION_CHEEK_RAISER_R_FB = 5, + XR_FACE_EXPRESSION_CHEEK_SUCK_L_FB = 6, + XR_FACE_EXPRESSION_CHEEK_SUCK_R_FB = 7, + XR_FACE_EXPRESSION_CHIN_RAISER_B_FB = 8, + XR_FACE_EXPRESSION_CHIN_RAISER_T_FB = 9, + XR_FACE_EXPRESSION_DIMPLER_L_FB = 10, + XR_FACE_EXPRESSION_DIMPLER_R_FB = 11, + XR_FACE_EXPRESSION_EYES_CLOSED_L_FB = 12, + XR_FACE_EXPRESSION_EYES_CLOSED_R_FB = 13, + XR_FACE_EXPRESSION_EYES_LOOK_DOWN_L_FB = 14, + XR_FACE_EXPRESSION_EYES_LOOK_DOWN_R_FB = 15, + XR_FACE_EXPRESSION_EYES_LOOK_LEFT_L_FB = 16, + XR_FACE_EXPRESSION_EYES_LOOK_LEFT_R_FB = 17, + XR_FACE_EXPRESSION_EYES_LOOK_RIGHT_L_FB = 18, + XR_FACE_EXPRESSION_EYES_LOOK_RIGHT_R_FB = 19, + XR_FACE_EXPRESSION_EYES_LOOK_UP_L_FB = 20, + XR_FACE_EXPRESSION_EYES_LOOK_UP_R_FB = 21, + XR_FACE_EXPRESSION_INNER_BROW_RAISER_L_FB = 22, + XR_FACE_EXPRESSION_INNER_BROW_RAISER_R_FB = 23, + XR_FACE_EXPRESSION_JAW_DROP_FB = 24, + XR_FACE_EXPRESSION_JAW_SIDEWAYS_LEFT_FB = 25, + XR_FACE_EXPRESSION_JAW_SIDEWAYS_RIGHT_FB = 26, + XR_FACE_EXPRESSION_JAW_THRUST_FB = 27, + XR_FACE_EXPRESSION_LID_TIGHTENER_L_FB = 28, + XR_FACE_EXPRESSION_LID_TIGHTENER_R_FB = 29, + XR_FACE_EXPRESSION_LIP_CORNER_DEPRESSOR_L_FB = 30, + XR_FACE_EXPRESSION_LIP_CORNER_DEPRESSOR_R_FB = 31, + XR_FACE_EXPRESSION_LIP_CORNER_PULLER_L_FB = 32, + XR_FACE_EXPRESSION_LIP_CORNER_PULLER_R_FB = 33, + XR_FACE_EXPRESSION_LIP_FUNNELER_LB_FB = 34, + XR_FACE_EXPRESSION_LIP_FUNNELER_LT_FB = 35, + XR_FACE_EXPRESSION_LIP_FUNNELER_RB_FB = 36, + XR_FACE_EXPRESSION_LIP_FUNNELER_RT_FB = 37, + XR_FACE_EXPRESSION_LIP_PRESSOR_L_FB = 38, + XR_FACE_EXPRESSION_LIP_PRESSOR_R_FB = 39, + XR_FACE_EXPRESSION_LIP_PUCKER_L_FB = 40, + XR_FACE_EXPRESSION_LIP_PUCKER_R_FB = 41, + XR_FACE_EXPRESSION_LIP_STRETCHER_L_FB = 42, + XR_FACE_EXPRESSION_LIP_STRETCHER_R_FB = 43, + XR_FACE_EXPRESSION_LIP_SUCK_LB_FB = 44, + XR_FACE_EXPRESSION_LIP_SUCK_LT_FB = 45, + XR_FACE_EXPRESSION_LIP_SUCK_RB_FB = 46, + XR_FACE_EXPRESSION_LIP_SUCK_RT_FB = 47, + XR_FACE_EXPRESSION_LIP_TIGHTENER_L_FB = 48, + XR_FACE_EXPRESSION_LIP_TIGHTENER_R_FB = 49, + XR_FACE_EXPRESSION_LIPS_TOWARD_FB = 50, + XR_FACE_EXPRESSION_LOWER_LIP_DEPRESSOR_L_FB = 51, + XR_FACE_EXPRESSION_LOWER_LIP_DEPRESSOR_R_FB = 52, + XR_FACE_EXPRESSION_MOUTH_LEFT_FB = 53, + XR_FACE_EXPRESSION_MOUTH_RIGHT_FB = 54, + XR_FACE_EXPRESSION_NOSE_WRINKLER_L_FB = 55, + XR_FACE_EXPRESSION_NOSE_WRINKLER_R_FB = 56, + XR_FACE_EXPRESSION_OUTER_BROW_RAISER_L_FB = 57, + XR_FACE_EXPRESSION_OUTER_BROW_RAISER_R_FB = 58, + XR_FACE_EXPRESSION_UPPER_LID_RAISER_L_FB = 59, + XR_FACE_EXPRESSION_UPPER_LID_RAISER_R_FB = 60, + XR_FACE_EXPRESSION_UPPER_LIP_RAISER_L_FB = 61, + XR_FACE_EXPRESSION_UPPER_LIP_RAISER_R_FB = 62, + XR_FACE_EXPRESSION_COUNT_FB = 63, + XR_FACE_EXPRESSION_MAX_ENUM_FB = 0x7FFFFFFF +} XrFaceExpressionFB; + +typedef enum XrFaceExpressionSetFB { + XR_FACE_EXPRESSION_SET_DEFAULT_FB = 0, + XR_FACE_EXPRESSION_SET_MAX_ENUM_FB = 0x7FFFFFFF +} XrFaceExpressionSetFB; + +typedef enum XrFaceConfidenceFB { + XR_FACE_CONFIDENCE_LOWER_FACE_FB = 0, + XR_FACE_CONFIDENCE_UPPER_FACE_FB = 1, + XR_FACE_CONFIDENCE_COUNT_FB = 2, + XR_FACE_CONFIDENCE_MAX_ENUM_FB = 0x7FFFFFFF +} XrFaceConfidenceFB; +// XrSystemFaceTrackingPropertiesFB extends XrSystemProperties +typedef struct XrSystemFaceTrackingPropertiesFB { + XrStructureType type; + void* XR_MAY_ALIAS next; + XrBool32 supportsFaceTracking; +} XrSystemFaceTrackingPropertiesFB; + +typedef struct XrFaceTrackerCreateInfoFB { + XrStructureType type; + const void* XR_MAY_ALIAS next; + XrFaceExpressionSetFB faceExpressionSet; +} XrFaceTrackerCreateInfoFB; + +typedef struct XrFaceExpressionInfoFB { + XrStructureType type; + const void* XR_MAY_ALIAS next; + XrTime time; +} XrFaceExpressionInfoFB; + +typedef struct XrFaceExpressionStatusFB { + XrBool32 isValid; + XrBool32 isEyeFollowingBlendshapesValid; +} XrFaceExpressionStatusFB; + +typedef struct XrFaceExpressionWeightsFB { + XrStructureType type; + void* XR_MAY_ALIAS next; + uint32_t weightCount; + float* weights; + uint32_t confidenceCount; + float* confidences; + XrFaceExpressionStatusFB status; + XrTime time; +} XrFaceExpressionWeightsFB; + +typedef XrResult (XRAPI_PTR *PFN_xrCreateFaceTrackerFB)(XrSession session, const XrFaceTrackerCreateInfoFB* createInfo, XrFaceTrackerFB* faceTracker); +typedef XrResult (XRAPI_PTR *PFN_xrDestroyFaceTrackerFB)(XrFaceTrackerFB faceTracker); +typedef XrResult (XRAPI_PTR *PFN_xrGetFaceExpressionWeightsFB)(XrFaceTrackerFB faceTracker, const XrFaceExpressionInfoFB* expressionInfo, XrFaceExpressionWeightsFB* expressionWeights); + +#ifndef XR_NO_PROTOTYPES +#ifdef XR_EXTENSION_PROTOTYPES +XRAPI_ATTR XrResult XRAPI_CALL xrCreateFaceTrackerFB( + XrSession session, + const XrFaceTrackerCreateInfoFB* createInfo, + XrFaceTrackerFB* faceTracker); + +XRAPI_ATTR XrResult XRAPI_CALL xrDestroyFaceTrackerFB( + XrFaceTrackerFB faceTracker); + +XRAPI_ATTR XrResult XRAPI_CALL xrGetFaceExpressionWeightsFB( + XrFaceTrackerFB faceTracker, + const XrFaceExpressionInfoFB* expressionInfo, + XrFaceExpressionWeightsFB* expressionWeights); +#endif /* XR_EXTENSION_PROTOTYPES */ +#endif /* !XR_NO_PROTOTYPES */ + + +#define XR_FB_eye_tracking_social 1 +XR_DEFINE_HANDLE(XrEyeTrackerFB) +#define XR_FB_eye_tracking_social_SPEC_VERSION 1 +#define XR_FB_EYE_TRACKING_SOCIAL_EXTENSION_NAME "XR_FB_eye_tracking_social" + +typedef enum XrEyePositionFB { + XR_EYE_POSITION_LEFT_FB = 0, + XR_EYE_POSITION_RIGHT_FB = 1, + XR_EYE_POSITION_COUNT_FB = 2, + XR_EYE_POSITION_MAX_ENUM_FB = 0x7FFFFFFF +} XrEyePositionFB; +typedef struct XrEyeGazeFB { + XrBool32 isValid; + XrPosef gazePose; + float gazeConfidence; +} XrEyeGazeFB; + +typedef struct XrEyeTrackerCreateInfoFB { + XrStructureType type; + const void* XR_MAY_ALIAS next; +} XrEyeTrackerCreateInfoFB; + +typedef struct XrEyeGazesInfoFB { + XrStructureType type; + const void* XR_MAY_ALIAS next; + XrSpace baseSpace; + XrTime time; +} XrEyeGazesInfoFB; + +// XrSystemEyeTrackingPropertiesFB extends XrSystemProperties +typedef struct XrSystemEyeTrackingPropertiesFB { + XrStructureType type; + void* XR_MAY_ALIAS next; + XrBool32 supportsEyeTracking; +} XrSystemEyeTrackingPropertiesFB; + +typedef struct XrEyeGazesFB { + XrStructureType type; + void* XR_MAY_ALIAS next; + XrEyeGazeFB gaze[XR_EYE_POSITION_COUNT_FB]; + XrTime time; +} XrEyeGazesFB; + +typedef XrResult (XRAPI_PTR *PFN_xrCreateEyeTrackerFB)(XrSession session, const XrEyeTrackerCreateInfoFB* createInfo, XrEyeTrackerFB* eyeTracker); +typedef XrResult (XRAPI_PTR *PFN_xrDestroyEyeTrackerFB)(XrEyeTrackerFB eyeTracker); +typedef XrResult (XRAPI_PTR *PFN_xrGetEyeGazesFB)(XrEyeTrackerFB eyeTracker, const XrEyeGazesInfoFB* gazeInfo, XrEyeGazesFB* eyeGazes); + +#ifndef XR_NO_PROTOTYPES +#ifdef XR_EXTENSION_PROTOTYPES +XRAPI_ATTR XrResult XRAPI_CALL xrCreateEyeTrackerFB( + XrSession session, + const XrEyeTrackerCreateInfoFB* createInfo, + XrEyeTrackerFB* eyeTracker); + +XRAPI_ATTR XrResult XRAPI_CALL xrDestroyEyeTrackerFB( + XrEyeTrackerFB eyeTracker); + +XRAPI_ATTR XrResult XRAPI_CALL xrGetEyeGazesFB( + XrEyeTrackerFB eyeTracker, + const XrEyeGazesInfoFB* gazeInfo, + XrEyeGazesFB* eyeGazes); +#endif /* XR_EXTENSION_PROTOTYPES */ +#endif /* !XR_NO_PROTOTYPES */ + + +#define XR_FB_passthrough_keyboard_hands 1 +#define XR_FB_passthrough_keyboard_hands_SPEC_VERSION 2 +#define XR_FB_PASSTHROUGH_KEYBOARD_HANDS_EXTENSION_NAME "XR_FB_passthrough_keyboard_hands" +typedef struct XrPassthroughKeyboardHandsIntensityFB { + XrStructureType type; + const void* XR_MAY_ALIAS next; + float leftHandIntensity; + float rightHandIntensity; +} XrPassthroughKeyboardHandsIntensityFB; + +typedef XrResult (XRAPI_PTR *PFN_xrPassthroughLayerSetKeyboardHandsIntensityFB)(XrPassthroughLayerFB layer, const XrPassthroughKeyboardHandsIntensityFB* intensity); + +#ifndef XR_NO_PROTOTYPES +#ifdef XR_EXTENSION_PROTOTYPES +XRAPI_ATTR XrResult XRAPI_CALL xrPassthroughLayerSetKeyboardHandsIntensityFB( + XrPassthroughLayerFB layer, + const XrPassthroughKeyboardHandsIntensityFB* intensity); +#endif /* XR_EXTENSION_PROTOTYPES */ +#endif /* !XR_NO_PROTOTYPES */ + + +#define XR_FB_composition_layer_settings 1 +#define XR_FB_composition_layer_settings_SPEC_VERSION 1 +#define XR_FB_COMPOSITION_LAYER_SETTINGS_EXTENSION_NAME "XR_FB_composition_layer_settings" +typedef XrFlags64 XrCompositionLayerSettingsFlagsFB; + +// Flag bits for XrCompositionLayerSettingsFlagsFB +static const XrCompositionLayerSettingsFlagsFB XR_COMPOSITION_LAYER_SETTINGS_NORMAL_SUPER_SAMPLING_BIT_FB = 0x00000001; +static const XrCompositionLayerSettingsFlagsFB XR_COMPOSITION_LAYER_SETTINGS_QUALITY_SUPER_SAMPLING_BIT_FB = 0x00000002; +static const XrCompositionLayerSettingsFlagsFB XR_COMPOSITION_LAYER_SETTINGS_NORMAL_SHARPENING_BIT_FB = 0x00000004; +static const XrCompositionLayerSettingsFlagsFB XR_COMPOSITION_LAYER_SETTINGS_QUALITY_SHARPENING_BIT_FB = 0x00000008; + +// XrCompositionLayerSettingsFB extends XrCompositionLayerBaseHeader +typedef struct XrCompositionLayerSettingsFB { + XrStructureType type; + const void* XR_MAY_ALIAS next; + XrCompositionLayerSettingsFlagsFB layerFlags; +} XrCompositionLayerSettingsFB; + + + +#define XR_FB_touch_controller_proximity 1 +#define XR_FB_touch_controller_proximity_SPEC_VERSION 1 +#define XR_FB_TOUCH_CONTROLLER_PROXIMITY_EXTENSION_NAME "XR_FB_touch_controller_proximity" + + +#define XR_FB_haptic_pcm 1 + +#define XR_MAX_HAPTIC_PCM_BUFFER_SIZE_FB 4000 + +#define XR_FB_haptic_pcm_SPEC_VERSION 1 +#define XR_FB_HAPTIC_PCM_EXTENSION_NAME "XR_FB_haptic_pcm" +typedef struct XrHapticPcmVibrationFB { + XrStructureType type; + const void* XR_MAY_ALIAS next; + uint32_t bufferSize; + const float* buffer; + float sampleRate; + XrBool32 append; + uint32_t* samplesConsumed; +} XrHapticPcmVibrationFB; + +typedef struct XrDevicePcmSampleRateStateFB { + XrStructureType type; + void* XR_MAY_ALIAS next; + float sampleRate; +} XrDevicePcmSampleRateStateFB; + +typedef XrDevicePcmSampleRateStateFB XrDevicePcmSampleRateGetInfoFB; + +typedef XrResult (XRAPI_PTR *PFN_xrGetDeviceSampleRateFB)(XrSession session, const XrHapticActionInfo* hapticActionInfo, XrDevicePcmSampleRateGetInfoFB* deviceSampleRate); + +#ifndef XR_NO_PROTOTYPES +#ifdef XR_EXTENSION_PROTOTYPES +XRAPI_ATTR XrResult XRAPI_CALL xrGetDeviceSampleRateFB( + XrSession session, + const XrHapticActionInfo* hapticActionInfo, + XrDevicePcmSampleRateGetInfoFB* deviceSampleRate); +#endif /* XR_EXTENSION_PROTOTYPES */ +#endif /* !XR_NO_PROTOTYPES */ + + +#define XR_FB_composition_layer_depth_test 1 +#define XR_FB_composition_layer_depth_test_SPEC_VERSION 1 +#define XR_FB_COMPOSITION_LAYER_DEPTH_TEST_EXTENSION_NAME "XR_FB_composition_layer_depth_test" + +typedef enum XrCompareOpFB { + XR_COMPARE_OP_NEVER_FB = 0, + XR_COMPARE_OP_LESS_FB = 1, + XR_COMPARE_OP_EQUAL_FB = 2, + XR_COMPARE_OP_LESS_OR_EQUAL_FB = 3, + XR_COMPARE_OP_GREATER_FB = 4, + XR_COMPARE_OP_NOT_EQUAL_FB = 5, + XR_COMPARE_OP_GREATER_OR_EQUAL_FB = 6, + XR_COMPARE_OP_ALWAYS_FB = 7, + XR_COMPARE_OP_MAX_ENUM_FB = 0x7FFFFFFF +} XrCompareOpFB; +// XrCompositionLayerDepthTestFB extends XrCompositionLayerBaseHeader +typedef struct XrCompositionLayerDepthTestFB { + XrStructureType type; + const void* XR_MAY_ALIAS next; + XrBool32 depthMask; + XrCompareOpFB compareOp; +} XrCompositionLayerDepthTestFB; + + + +#define XR_META_local_dimming 1 +#define XR_META_local_dimming_SPEC_VERSION 1 +#define XR_META_LOCAL_DIMMING_EXTENSION_NAME "XR_META_local_dimming" + +typedef enum XrLocalDimmingModeMETA { + XR_LOCAL_DIMMING_MODE_OFF_META = 0, + XR_LOCAL_DIMMING_MODE_ON_META = 1, + XR_LOCAL_DIMMING_MODE_MAX_ENUM_META = 0x7FFFFFFF +} XrLocalDimmingModeMETA; +// XrLocalDimmingFrameEndInfoMETA extends XrFrameEndInfo +typedef struct XrLocalDimmingFrameEndInfoMETA { + XrStructureType type; + const void* XR_MAY_ALIAS next; + XrLocalDimmingModeMETA localDimmingMode; +} XrLocalDimmingFrameEndInfoMETA; + + + +#define XR_META_virtual_keyboard 1 +XR_DEFINE_HANDLE(XrVirtualKeyboardMETA) +#define XR_MAX_VIRTUAL_KEYBOARD_COMMIT_TEXT_SIZE_META 3992 +#define XR_META_virtual_keyboard_SPEC_VERSION 1 +#define XR_META_VIRTUAL_KEYBOARD_EXTENSION_NAME "XR_META_virtual_keyboard" + +typedef enum XrVirtualKeyboardLocationTypeMETA { + XR_VIRTUAL_KEYBOARD_LOCATION_TYPE_CUSTOM_META = 0, + XR_VIRTUAL_KEYBOARD_LOCATION_TYPE_FAR_META = 1, + XR_VIRTUAL_KEYBOARD_LOCATION_TYPE_DIRECT_META = 2, + XR_VIRTUAL_KEYBOARD_LOCATION_TYPE_MAX_ENUM_META = 0x7FFFFFFF +} XrVirtualKeyboardLocationTypeMETA; + +typedef enum XrVirtualKeyboardInputSourceMETA { + XR_VIRTUAL_KEYBOARD_INPUT_SOURCE_CONTROLLER_RAY_LEFT_META = 1, + XR_VIRTUAL_KEYBOARD_INPUT_SOURCE_CONTROLLER_RAY_RIGHT_META = 2, + XR_VIRTUAL_KEYBOARD_INPUT_SOURCE_HAND_RAY_LEFT_META = 3, + XR_VIRTUAL_KEYBOARD_INPUT_SOURCE_HAND_RAY_RIGHT_META = 4, + XR_VIRTUAL_KEYBOARD_INPUT_SOURCE_CONTROLLER_DIRECT_LEFT_META = 5, + XR_VIRTUAL_KEYBOARD_INPUT_SOURCE_CONTROLLER_DIRECT_RIGHT_META = 6, + XR_VIRTUAL_KEYBOARD_INPUT_SOURCE_HAND_DIRECT_INDEX_TIP_LEFT_META = 7, + XR_VIRTUAL_KEYBOARD_INPUT_SOURCE_HAND_DIRECT_INDEX_TIP_RIGHT_META = 8, + XR_VIRTUAL_KEYBOARD_INPUT_SOURCE_MAX_ENUM_META = 0x7FFFFFFF +} XrVirtualKeyboardInputSourceMETA; +typedef XrFlags64 XrVirtualKeyboardInputStateFlagsMETA; + +// Flag bits for XrVirtualKeyboardInputStateFlagsMETA +static const XrVirtualKeyboardInputStateFlagsMETA XR_VIRTUAL_KEYBOARD_INPUT_STATE_PRESSED_BIT_META = 0x00000001; + +// XrSystemVirtualKeyboardPropertiesMETA extends XrSystemProperties +typedef struct XrSystemVirtualKeyboardPropertiesMETA { + XrStructureType type; + void* XR_MAY_ALIAS next; + XrBool32 supportsVirtualKeyboard; +} XrSystemVirtualKeyboardPropertiesMETA; + +typedef struct XrVirtualKeyboardCreateInfoMETA { + XrStructureType type; + const void* XR_MAY_ALIAS next; +} XrVirtualKeyboardCreateInfoMETA; + +typedef struct XrVirtualKeyboardSpaceCreateInfoMETA { + XrStructureType type; + const void* XR_MAY_ALIAS next; + XrVirtualKeyboardLocationTypeMETA locationType; + XrSpace space; + XrPosef poseInSpace; +} XrVirtualKeyboardSpaceCreateInfoMETA; + +typedef struct XrVirtualKeyboardLocationInfoMETA { + XrStructureType type; + const void* XR_MAY_ALIAS next; + XrVirtualKeyboardLocationTypeMETA locationType; + XrSpace space; + XrPosef poseInSpace; + float scale; +} XrVirtualKeyboardLocationInfoMETA; + +typedef struct XrVirtualKeyboardModelVisibilitySetInfoMETA { + XrStructureType type; + const void* XR_MAY_ALIAS next; + XrBool32 visible; +} XrVirtualKeyboardModelVisibilitySetInfoMETA; + +typedef struct XrVirtualKeyboardAnimationStateMETA { + XrStructureType type; + void* XR_MAY_ALIAS next; + int32_t animationIndex; + float fraction; +} XrVirtualKeyboardAnimationStateMETA; + +typedef struct XrVirtualKeyboardModelAnimationStatesMETA { + XrStructureType type; + void* XR_MAY_ALIAS next; + uint32_t stateCapacityInput; + uint32_t stateCountOutput; + XrVirtualKeyboardAnimationStateMETA* states; +} XrVirtualKeyboardModelAnimationStatesMETA; + +typedef struct XrVirtualKeyboardTextureDataMETA { + XrStructureType type; + void* XR_MAY_ALIAS next; + uint32_t textureWidth; + uint32_t textureHeight; + uint32_t bufferCapacityInput; + uint32_t bufferCountOutput; + uint8_t* buffer; +} XrVirtualKeyboardTextureDataMETA; + +typedef struct XrVirtualKeyboardInputInfoMETA { + XrStructureType type; + const void* XR_MAY_ALIAS next; + XrVirtualKeyboardInputSourceMETA inputSource; + XrSpace inputSpace; + XrPosef inputPoseInSpace; + XrVirtualKeyboardInputStateFlagsMETA inputState; +} XrVirtualKeyboardInputInfoMETA; + +typedef struct XrVirtualKeyboardTextContextChangeInfoMETA { + XrStructureType type; + const void* XR_MAY_ALIAS next; + const char* textContext; +} XrVirtualKeyboardTextContextChangeInfoMETA; + +typedef struct XrEventDataVirtualKeyboardCommitTextMETA { + XrStructureType type; + const void* XR_MAY_ALIAS next; + XrVirtualKeyboardMETA keyboard; + char text[XR_MAX_VIRTUAL_KEYBOARD_COMMIT_TEXT_SIZE_META]; +} XrEventDataVirtualKeyboardCommitTextMETA; + +typedef struct XrEventDataVirtualKeyboardBackspaceMETA { + XrStructureType type; + const void* XR_MAY_ALIAS next; + XrVirtualKeyboardMETA keyboard; +} XrEventDataVirtualKeyboardBackspaceMETA; + +typedef struct XrEventDataVirtualKeyboardEnterMETA { + XrStructureType type; + const void* XR_MAY_ALIAS next; + XrVirtualKeyboardMETA keyboard; +} XrEventDataVirtualKeyboardEnterMETA; + +typedef struct XrEventDataVirtualKeyboardShownMETA { + XrStructureType type; + const void* XR_MAY_ALIAS next; + XrVirtualKeyboardMETA keyboard; +} XrEventDataVirtualKeyboardShownMETA; + +typedef struct XrEventDataVirtualKeyboardHiddenMETA { + XrStructureType type; + const void* XR_MAY_ALIAS next; + XrVirtualKeyboardMETA keyboard; +} XrEventDataVirtualKeyboardHiddenMETA; + +typedef XrResult (XRAPI_PTR *PFN_xrCreateVirtualKeyboardMETA)(XrSession session, const XrVirtualKeyboardCreateInfoMETA* createInfo, XrVirtualKeyboardMETA* keyboard); +typedef XrResult (XRAPI_PTR *PFN_xrDestroyVirtualKeyboardMETA)(XrVirtualKeyboardMETA keyboard); +typedef XrResult (XRAPI_PTR *PFN_xrCreateVirtualKeyboardSpaceMETA)(XrSession session, XrVirtualKeyboardMETA keyboard, const XrVirtualKeyboardSpaceCreateInfoMETA* createInfo, XrSpace* keyboardSpace); +typedef XrResult (XRAPI_PTR *PFN_xrSuggestVirtualKeyboardLocationMETA)(XrVirtualKeyboardMETA keyboard, const XrVirtualKeyboardLocationInfoMETA* locationInfo); +typedef XrResult (XRAPI_PTR *PFN_xrGetVirtualKeyboardScaleMETA)(XrVirtualKeyboardMETA keyboard, float* scale); +typedef XrResult (XRAPI_PTR *PFN_xrSetVirtualKeyboardModelVisibilityMETA)(XrVirtualKeyboardMETA keyboard, const XrVirtualKeyboardModelVisibilitySetInfoMETA* modelVisibility); +typedef XrResult (XRAPI_PTR *PFN_xrGetVirtualKeyboardModelAnimationStatesMETA)(XrVirtualKeyboardMETA keyboard, XrVirtualKeyboardModelAnimationStatesMETA* animationStates); +typedef XrResult (XRAPI_PTR *PFN_xrGetVirtualKeyboardDirtyTexturesMETA)(XrVirtualKeyboardMETA keyboard, uint32_t textureIdCapacityInput, uint32_t* textureIdCountOutput, uint64_t* textureIds); +typedef XrResult (XRAPI_PTR *PFN_xrGetVirtualKeyboardTextureDataMETA)(XrVirtualKeyboardMETA keyboard, uint64_t textureId, XrVirtualKeyboardTextureDataMETA* textureData); +typedef XrResult (XRAPI_PTR *PFN_xrSendVirtualKeyboardInputMETA)(XrVirtualKeyboardMETA keyboard, const XrVirtualKeyboardInputInfoMETA* info, XrPosef* interactorRootPose); +typedef XrResult (XRAPI_PTR *PFN_xrChangeVirtualKeyboardTextContextMETA)(XrVirtualKeyboardMETA keyboard, const XrVirtualKeyboardTextContextChangeInfoMETA* changeInfo); + +#ifndef XR_NO_PROTOTYPES +#ifdef XR_EXTENSION_PROTOTYPES +XRAPI_ATTR XrResult XRAPI_CALL xrCreateVirtualKeyboardMETA( + XrSession session, + const XrVirtualKeyboardCreateInfoMETA* createInfo, + XrVirtualKeyboardMETA* keyboard); + +XRAPI_ATTR XrResult XRAPI_CALL xrDestroyVirtualKeyboardMETA( + XrVirtualKeyboardMETA keyboard); + +XRAPI_ATTR XrResult XRAPI_CALL xrCreateVirtualKeyboardSpaceMETA( + XrSession session, + XrVirtualKeyboardMETA keyboard, + const XrVirtualKeyboardSpaceCreateInfoMETA* createInfo, + XrSpace* keyboardSpace); + +XRAPI_ATTR XrResult XRAPI_CALL xrSuggestVirtualKeyboardLocationMETA( + XrVirtualKeyboardMETA keyboard, + const XrVirtualKeyboardLocationInfoMETA* locationInfo); + +XRAPI_ATTR XrResult XRAPI_CALL xrGetVirtualKeyboardScaleMETA( + XrVirtualKeyboardMETA keyboard, + float* scale); + +XRAPI_ATTR XrResult XRAPI_CALL xrSetVirtualKeyboardModelVisibilityMETA( + XrVirtualKeyboardMETA keyboard, + const XrVirtualKeyboardModelVisibilitySetInfoMETA* modelVisibility); + +XRAPI_ATTR XrResult XRAPI_CALL xrGetVirtualKeyboardModelAnimationStatesMETA( + XrVirtualKeyboardMETA keyboard, + XrVirtualKeyboardModelAnimationStatesMETA* animationStates); + +XRAPI_ATTR XrResult XRAPI_CALL xrGetVirtualKeyboardDirtyTexturesMETA( + XrVirtualKeyboardMETA keyboard, + uint32_t textureIdCapacityInput, + uint32_t* textureIdCountOutput, + uint64_t* textureIds); + +XRAPI_ATTR XrResult XRAPI_CALL xrGetVirtualKeyboardTextureDataMETA( + XrVirtualKeyboardMETA keyboard, + uint64_t textureId, + XrVirtualKeyboardTextureDataMETA* textureData); + +XRAPI_ATTR XrResult XRAPI_CALL xrSendVirtualKeyboardInputMETA( + XrVirtualKeyboardMETA keyboard, + const XrVirtualKeyboardInputInfoMETA* info, + XrPosef* interactorRootPose); + +XRAPI_ATTR XrResult XRAPI_CALL xrChangeVirtualKeyboardTextContextMETA( + XrVirtualKeyboardMETA keyboard, + const XrVirtualKeyboardTextContextChangeInfoMETA* changeInfo); +#endif /* XR_EXTENSION_PROTOTYPES */ +#endif /* !XR_NO_PROTOTYPES */ + + +#define XR_OCULUS_external_camera 1 +#define XR_MAX_EXTERNAL_CAMERA_NAME_SIZE_OCULUS 32 +#define XR_OCULUS_external_camera_SPEC_VERSION 1 +#define XR_OCULUS_EXTERNAL_CAMERA_EXTENSION_NAME "XR_OCULUS_external_camera" + +typedef enum XrExternalCameraAttachedToDeviceOCULUS { + XR_EXTERNAL_CAMERA_ATTACHED_TO_DEVICE_NONE_OCULUS = 0, + XR_EXTERNAL_CAMERA_ATTACHED_TO_DEVICE_HMD_OCULUS = 1, + XR_EXTERNAL_CAMERA_ATTACHED_TO_DEVICE_LTOUCH_OCULUS = 2, + XR_EXTERNAL_CAMERA_ATTACHED_TO_DEVICE_RTOUCH_OCULUS = 3, + XR_EXTERNAL_CAMERA_ATTACHED_TO_DEVICE_MAX_ENUM_OCULUS = 0x7FFFFFFF +} XrExternalCameraAttachedToDeviceOCULUS; +typedef XrFlags64 XrExternalCameraStatusFlagsOCULUS; + +// Flag bits for XrExternalCameraStatusFlagsOCULUS +static const XrExternalCameraStatusFlagsOCULUS XR_EXTERNAL_CAMERA_STATUS_CONNECTED_BIT_OCULUS = 0x00000001; +static const XrExternalCameraStatusFlagsOCULUS XR_EXTERNAL_CAMERA_STATUS_CALIBRATING_BIT_OCULUS = 0x00000002; +static const XrExternalCameraStatusFlagsOCULUS XR_EXTERNAL_CAMERA_STATUS_CALIBRATION_FAILED_BIT_OCULUS = 0x00000004; +static const XrExternalCameraStatusFlagsOCULUS XR_EXTERNAL_CAMERA_STATUS_CALIBRATED_BIT_OCULUS = 0x00000008; +static const XrExternalCameraStatusFlagsOCULUS XR_EXTERNAL_CAMERA_STATUS_CAPTURING_BIT_OCULUS = 0x00000010; + +typedef struct XrExternalCameraIntrinsicsOCULUS { + XrTime lastChangeTime; + XrFovf fov; + float virtualNearPlaneDistance; + float virtualFarPlaneDistance; + XrExtent2Di imageSensorPixelResolution; +} XrExternalCameraIntrinsicsOCULUS; + +typedef struct XrExternalCameraExtrinsicsOCULUS { + XrTime lastChangeTime; + XrExternalCameraStatusFlagsOCULUS cameraStatusFlags; + XrExternalCameraAttachedToDeviceOCULUS attachedToDevice; + XrPosef relativePose; +} XrExternalCameraExtrinsicsOCULUS; + +typedef struct XrExternalCameraOCULUS { + XrStructureType type; + const void* XR_MAY_ALIAS next; + char name[XR_MAX_EXTERNAL_CAMERA_NAME_SIZE_OCULUS]; + XrExternalCameraIntrinsicsOCULUS intrinsics; + XrExternalCameraExtrinsicsOCULUS extrinsics; +} XrExternalCameraOCULUS; + +typedef XrResult (XRAPI_PTR *PFN_xrEnumerateExternalCamerasOCULUS)(XrSession session, uint32_t cameraCapacityInput, uint32_t* cameraCountOutput, XrExternalCameraOCULUS* cameras); + +#ifndef XR_NO_PROTOTYPES +#ifdef XR_EXTENSION_PROTOTYPES +XRAPI_ATTR XrResult XRAPI_CALL xrEnumerateExternalCamerasOCULUS( + XrSession session, + uint32_t cameraCapacityInput, + uint32_t* cameraCountOutput, + XrExternalCameraOCULUS* cameras); +#endif /* XR_EXTENSION_PROTOTYPES */ +#endif /* !XR_NO_PROTOTYPES */ + + +#define XR_META_performance_metrics 1 +#define XR_META_performance_metrics_SPEC_VERSION 2 +#define XR_META_PERFORMANCE_METRICS_EXTENSION_NAME "XR_META_performance_metrics" + +typedef enum XrPerformanceMetricsCounterUnitMETA { + XR_PERFORMANCE_METRICS_COUNTER_UNIT_GENERIC_META = 0, + XR_PERFORMANCE_METRICS_COUNTER_UNIT_PERCENTAGE_META = 1, + XR_PERFORMANCE_METRICS_COUNTER_UNIT_MILLISECONDS_META = 2, + XR_PERFORMANCE_METRICS_COUNTER_UNIT_BYTES_META = 3, + XR_PERFORMANCE_METRICS_COUNTER_UNIT_HERTZ_META = 4, + XR_PERFORMANCE_METRICS_COUNTER_UNIT_MAX_ENUM_META = 0x7FFFFFFF +} XrPerformanceMetricsCounterUnitMETA; +typedef XrFlags64 XrPerformanceMetricsCounterFlagsMETA; + +// Flag bits for XrPerformanceMetricsCounterFlagsMETA +static const XrPerformanceMetricsCounterFlagsMETA XR_PERFORMANCE_METRICS_COUNTER_ANY_VALUE_VALID_BIT_META = 0x00000001; +static const XrPerformanceMetricsCounterFlagsMETA XR_PERFORMANCE_METRICS_COUNTER_UINT_VALUE_VALID_BIT_META = 0x00000002; +static const XrPerformanceMetricsCounterFlagsMETA XR_PERFORMANCE_METRICS_COUNTER_FLOAT_VALUE_VALID_BIT_META = 0x00000004; + +typedef struct XrPerformanceMetricsStateMETA { + XrStructureType type; + const void* XR_MAY_ALIAS next; + XrBool32 enabled; +} XrPerformanceMetricsStateMETA; + +typedef struct XrPerformanceMetricsCounterMETA { + XrStructureType type; + const void* XR_MAY_ALIAS next; + XrPerformanceMetricsCounterFlagsMETA counterFlags; + XrPerformanceMetricsCounterUnitMETA counterUnit; + uint32_t uintValue; + float floatValue; +} XrPerformanceMetricsCounterMETA; + +typedef XrResult (XRAPI_PTR *PFN_xrEnumeratePerformanceMetricsCounterPathsMETA)(XrInstance instance, uint32_t counterPathCapacityInput, uint32_t* counterPathCountOutput, XrPath* counterPaths); +typedef XrResult (XRAPI_PTR *PFN_xrSetPerformanceMetricsStateMETA)(XrSession session, const XrPerformanceMetricsStateMETA* state); +typedef XrResult (XRAPI_PTR *PFN_xrGetPerformanceMetricsStateMETA)(XrSession session, XrPerformanceMetricsStateMETA* state); +typedef XrResult (XRAPI_PTR *PFN_xrQueryPerformanceMetricsCounterMETA)(XrSession session, XrPath counterPath, XrPerformanceMetricsCounterMETA* counter); + +#ifndef XR_NO_PROTOTYPES +#ifdef XR_EXTENSION_PROTOTYPES +XRAPI_ATTR XrResult XRAPI_CALL xrEnumeratePerformanceMetricsCounterPathsMETA( + XrInstance instance, + uint32_t counterPathCapacityInput, + uint32_t* counterPathCountOutput, + XrPath* counterPaths); + +XRAPI_ATTR XrResult XRAPI_CALL xrSetPerformanceMetricsStateMETA( + XrSession session, + const XrPerformanceMetricsStateMETA* state); + +XRAPI_ATTR XrResult XRAPI_CALL xrGetPerformanceMetricsStateMETA( + XrSession session, + XrPerformanceMetricsStateMETA* state); + +XRAPI_ATTR XrResult XRAPI_CALL xrQueryPerformanceMetricsCounterMETA( + XrSession session, + XrPath counterPath, + XrPerformanceMetricsCounterMETA* counter); +#endif /* XR_EXTENSION_PROTOTYPES */ +#endif /* !XR_NO_PROTOTYPES */ + + +#define XR_FB_spatial_entity_storage_batch 1 +#define XR_FB_spatial_entity_storage_batch_SPEC_VERSION 1 +#define XR_FB_SPATIAL_ENTITY_STORAGE_BATCH_EXTENSION_NAME "XR_FB_spatial_entity_storage_batch" +typedef struct XrSpaceListSaveInfoFB { + XrStructureType type; + const void* XR_MAY_ALIAS next; + uint32_t spaceCount; + XrSpace* spaces; + XrSpaceStorageLocationFB location; +} XrSpaceListSaveInfoFB; + +typedef struct XrEventDataSpaceListSaveCompleteFB { + XrStructureType type; + const void* XR_MAY_ALIAS next; + XrAsyncRequestIdFB requestId; + XrResult result; +} XrEventDataSpaceListSaveCompleteFB; + +typedef XrResult (XRAPI_PTR *PFN_xrSaveSpaceListFB)(XrSession session, const XrSpaceListSaveInfoFB* info, XrAsyncRequestIdFB* requestId); + +#ifndef XR_NO_PROTOTYPES +#ifdef XR_EXTENSION_PROTOTYPES +XRAPI_ATTR XrResult XRAPI_CALL xrSaveSpaceListFB( + XrSession session, + const XrSpaceListSaveInfoFB* info, + XrAsyncRequestIdFB* requestId); +#endif /* XR_EXTENSION_PROTOTYPES */ +#endif /* !XR_NO_PROTOTYPES */ + + +#define XR_FB_spatial_entity_user 1 +typedef uint64_t XrSpaceUserIdFB; +#define XR_FB_spatial_entity_user_SPEC_VERSION 1 +#define XR_FB_SPATIAL_ENTITY_USER_EXTENSION_NAME "XR_FB_spatial_entity_user" +typedef struct XrSpaceUserCreateInfoFB { + XrStructureType type; + const void* XR_MAY_ALIAS next; + XrSpaceUserIdFB userId; +} XrSpaceUserCreateInfoFB; + +typedef XrResult (XRAPI_PTR *PFN_xrCreateSpaceUserFB)(XrSession session, const XrSpaceUserCreateInfoFB* info, XrSpaceUserFB* user); +typedef XrResult (XRAPI_PTR *PFN_xrGetSpaceUserIdFB)(XrSpaceUserFB user, XrSpaceUserIdFB* userId); +typedef XrResult (XRAPI_PTR *PFN_xrDestroySpaceUserFB)(XrSpaceUserFB user); + +#ifndef XR_NO_PROTOTYPES +#ifdef XR_EXTENSION_PROTOTYPES +XRAPI_ATTR XrResult XRAPI_CALL xrCreateSpaceUserFB( + XrSession session, + const XrSpaceUserCreateInfoFB* info, + XrSpaceUserFB* user); + +XRAPI_ATTR XrResult XRAPI_CALL xrGetSpaceUserIdFB( + XrSpaceUserFB user, + XrSpaceUserIdFB* userId); + +XRAPI_ATTR XrResult XRAPI_CALL xrDestroySpaceUserFB( + XrSpaceUserFB user); +#endif /* XR_EXTENSION_PROTOTYPES */ +#endif /* !XR_NO_PROTOTYPES */ + + +#define XR_META_headset_id 1 +#define XR_META_headset_id_SPEC_VERSION 1 +#define XR_META_HEADSET_ID_EXTENSION_NAME "XR_META_headset_id" +// XrSystemHeadsetIdPropertiesMETA extends XrSystemProperties +typedef struct XrSystemHeadsetIdPropertiesMETA { + XrStructureType type; + void* XR_MAY_ALIAS next; + XrUuidEXT id; +} XrSystemHeadsetIdPropertiesMETA; + + + +#define XR_META_passthrough_color_lut 1 +XR_DEFINE_HANDLE(XrPassthroughColorLutMETA) +#define XR_META_passthrough_color_lut_SPEC_VERSION 1 +#define XR_META_PASSTHROUGH_COLOR_LUT_EXTENSION_NAME "XR_META_passthrough_color_lut" + +typedef enum XrPassthroughColorLutChannelsMETA { + XR_PASSTHROUGH_COLOR_LUT_CHANNELS_RGB_META = 1, + XR_PASSTHROUGH_COLOR_LUT_CHANNELS_RGBA_META = 2, + XR_PASSTHROUGH_COLOR_LUT_CHANNELS_MAX_ENUM_META = 0x7FFFFFFF +} XrPassthroughColorLutChannelsMETA; +typedef struct XrPassthroughColorLutDataMETA { + uint32_t bufferSize; + const uint8_t* buffer; +} XrPassthroughColorLutDataMETA; + +typedef struct XrPassthroughColorLutCreateInfoMETA { + XrStructureType type; + const void* XR_MAY_ALIAS next; + XrPassthroughColorLutChannelsMETA channels; + uint32_t resolution; + XrPassthroughColorLutDataMETA data; +} XrPassthroughColorLutCreateInfoMETA; + +typedef struct XrPassthroughColorLutUpdateInfoMETA { + XrStructureType type; + const void* XR_MAY_ALIAS next; + XrPassthroughColorLutDataMETA data; +} XrPassthroughColorLutUpdateInfoMETA; + +// XrPassthroughColorMapLutMETA extends XrPassthroughStyleFB +typedef struct XrPassthroughColorMapLutMETA { + XrStructureType type; + const void* XR_MAY_ALIAS next; + XrPassthroughColorLutMETA colorLut; + float weight; +} XrPassthroughColorMapLutMETA; + +// XrPassthroughColorMapInterpolatedLutMETA extends XrPassthroughStyleFB +typedef struct XrPassthroughColorMapInterpolatedLutMETA { + XrStructureType type; + const void* XR_MAY_ALIAS next; + XrPassthroughColorLutMETA sourceColorLut; + XrPassthroughColorLutMETA targetColorLut; + float weight; +} XrPassthroughColorMapInterpolatedLutMETA; + +// XrSystemPassthroughColorLutPropertiesMETA extends XrSystemProperties +typedef struct XrSystemPassthroughColorLutPropertiesMETA { + XrStructureType type; + const void* XR_MAY_ALIAS next; + uint32_t maxColorLutResolution; +} XrSystemPassthroughColorLutPropertiesMETA; + +typedef XrResult (XRAPI_PTR *PFN_xrCreatePassthroughColorLutMETA)(XrPassthroughFB passthrough, const XrPassthroughColorLutCreateInfoMETA* createInfo, XrPassthroughColorLutMETA* colorLut); +typedef XrResult (XRAPI_PTR *PFN_xrDestroyPassthroughColorLutMETA)(XrPassthroughColorLutMETA colorLut); +typedef XrResult (XRAPI_PTR *PFN_xrUpdatePassthroughColorLutMETA)(XrPassthroughColorLutMETA colorLut, const XrPassthroughColorLutUpdateInfoMETA* updateInfo); + +#ifndef XR_NO_PROTOTYPES +#ifdef XR_EXTENSION_PROTOTYPES +XRAPI_ATTR XrResult XRAPI_CALL xrCreatePassthroughColorLutMETA( + XrPassthroughFB passthrough, + const XrPassthroughColorLutCreateInfoMETA* createInfo, + XrPassthroughColorLutMETA* colorLut); + +XRAPI_ATTR XrResult XRAPI_CALL xrDestroyPassthroughColorLutMETA( + XrPassthroughColorLutMETA colorLut); + +XRAPI_ATTR XrResult XRAPI_CALL xrUpdatePassthroughColorLutMETA( + XrPassthroughColorLutMETA colorLut, + const XrPassthroughColorLutUpdateInfoMETA* updateInfo); +#endif /* XR_EXTENSION_PROTOTYPES */ +#endif /* !XR_NO_PROTOTYPES */ + + +#define XR_EXT_uuid 1 +#define XR_EXT_uuid_SPEC_VERSION 1 +#define XR_EXT_UUID_EXTENSION_NAME "XR_EXT_uuid" + + +#define XR_EXT_hand_interaction 1 +#define XR_EXT_hand_interaction_SPEC_VERSION 1 +#define XR_EXT_HAND_INTERACTION_EXTENSION_NAME "XR_EXT_hand_interaction" + + +#define XR_QCOM_tracking_optimization_settings 1 +#define XR_QCOM_tracking_optimization_settings_SPEC_VERSION 1 +#define XR_QCOM_TRACKING_OPTIMIZATION_SETTINGS_EXTENSION_NAME "XR_QCOM_tracking_optimization_settings" + +typedef enum XrTrackingOptimizationSettingsDomainQCOM { + XR_TRACKING_OPTIMIZATION_SETTINGS_DOMAIN_ALL_QCOM = 1, + XR_TRACKING_OPTIMIZATION_SETTINGS_DOMAIN_MAX_ENUM_QCOM = 0x7FFFFFFF +} XrTrackingOptimizationSettingsDomainQCOM; + +typedef enum XrTrackingOptimizationSettingsHintQCOM { + XR_TRACKING_OPTIMIZATION_SETTINGS_HINT_NONE_QCOM = 0, + XR_TRACKING_OPTIMIZATION_SETTINGS_HINT_LONG_RANGE_PRIORIZATION_QCOM = 1, + XR_TRACKING_OPTIMIZATION_SETTINGS_HINT_CLOSE_RANGE_PRIORIZATION_QCOM = 2, + XR_TRACKING_OPTIMIZATION_SETTINGS_HINT_LOW_POWER_PRIORIZATION_QCOM = 3, + XR_TRACKING_OPTIMIZATION_SETTINGS_HINT_HIGH_POWER_PRIORIZATION_QCOM = 4, + XR_TRACKING_OPTIMIZATION_SETTINGS_HINT_MAX_ENUM_QCOM = 0x7FFFFFFF +} XrTrackingOptimizationSettingsHintQCOM; +typedef XrResult (XRAPI_PTR *PFN_xrSetTrackingOptimizationSettingsHintQCOM)(XrSession session, XrTrackingOptimizationSettingsDomainQCOM domain, XrTrackingOptimizationSettingsHintQCOM hint); + +#ifndef XR_NO_PROTOTYPES +#ifdef XR_EXTENSION_PROTOTYPES +XRAPI_ATTR XrResult XRAPI_CALL xrSetTrackingOptimizationSettingsHintQCOM( + XrSession session, + XrTrackingOptimizationSettingsDomainQCOM domain, + XrTrackingOptimizationSettingsHintQCOM hint); +#endif /* XR_EXTENSION_PROTOTYPES */ +#endif /* !XR_NO_PROTOTYPES */ + + +#define XR_HTC_passthrough 1 +XR_DEFINE_HANDLE(XrPassthroughHTC) +#define XR_HTC_passthrough_SPEC_VERSION 1 +#define XR_HTC_PASSTHROUGH_EXTENSION_NAME "XR_HTC_passthrough" + +typedef enum XrPassthroughFormHTC { + XR_PASSTHROUGH_FORM_PLANAR_HTC = 0, + XR_PASSTHROUGH_FORM_PROJECTED_HTC = 1, + XR_PASSTHROUGH_FORM_MAX_ENUM_HTC = 0x7FFFFFFF +} XrPassthroughFormHTC; +typedef struct XrPassthroughCreateInfoHTC { + XrStructureType type; + const void* XR_MAY_ALIAS next; + XrPassthroughFormHTC form; +} XrPassthroughCreateInfoHTC; + +typedef struct XrPassthroughColorHTC { + XrStructureType type; + const void* XR_MAY_ALIAS next; + float alpha; +} XrPassthroughColorHTC; + +// XrPassthroughMeshTransformInfoHTC extends XrCompositionLayerPassthroughHTC +typedef struct XrPassthroughMeshTransformInfoHTC { + XrStructureType type; + const void* XR_MAY_ALIAS next; + uint32_t vertexCount; + const XrVector3f* vertices; + uint32_t indexCount; + const uint32_t* indices; + XrSpace baseSpace; + XrTime time; + XrPosef pose; + XrVector3f scale; +} XrPassthroughMeshTransformInfoHTC; + +typedef struct XrCompositionLayerPassthroughHTC { + XrStructureType type; + const void* XR_MAY_ALIAS next; + XrCompositionLayerFlags layerFlags; + XrSpace space; + XrPassthroughHTC passthrough; + XrPassthroughColorHTC color; +} XrCompositionLayerPassthroughHTC; + +typedef XrResult (XRAPI_PTR *PFN_xrCreatePassthroughHTC)(XrSession session, const XrPassthroughCreateInfoHTC* createInfo, XrPassthroughHTC* passthrough); +typedef XrResult (XRAPI_PTR *PFN_xrDestroyPassthroughHTC)(XrPassthroughHTC passthrough); + +#ifndef XR_NO_PROTOTYPES +#ifdef XR_EXTENSION_PROTOTYPES +XRAPI_ATTR XrResult XRAPI_CALL xrCreatePassthroughHTC( + XrSession session, + const XrPassthroughCreateInfoHTC* createInfo, + XrPassthroughHTC* passthrough); + +XRAPI_ATTR XrResult XRAPI_CALL xrDestroyPassthroughHTC( + XrPassthroughHTC passthrough); +#endif /* XR_EXTENSION_PROTOTYPES */ +#endif /* !XR_NO_PROTOTYPES */ + + +#define XR_HTC_foveation 1 +#define XR_HTC_foveation_SPEC_VERSION 1 +#define XR_HTC_FOVEATION_EXTENSION_NAME "XR_HTC_foveation" + +typedef enum XrFoveationModeHTC { + XR_FOVEATION_MODE_DISABLE_HTC = 0, + XR_FOVEATION_MODE_FIXED_HTC = 1, + XR_FOVEATION_MODE_DYNAMIC_HTC = 2, + XR_FOVEATION_MODE_CUSTOM_HTC = 3, + XR_FOVEATION_MODE_MAX_ENUM_HTC = 0x7FFFFFFF +} XrFoveationModeHTC; + +typedef enum XrFoveationLevelHTC { + XR_FOVEATION_LEVEL_NONE_HTC = 0, + XR_FOVEATION_LEVEL_LOW_HTC = 1, + XR_FOVEATION_LEVEL_MEDIUM_HTC = 2, + XR_FOVEATION_LEVEL_HIGH_HTC = 3, + XR_FOVEATION_LEVEL_MAX_ENUM_HTC = 0x7FFFFFFF +} XrFoveationLevelHTC; +typedef XrFlags64 XrFoveationDynamicFlagsHTC; + +// Flag bits for XrFoveationDynamicFlagsHTC +static const XrFoveationDynamicFlagsHTC XR_FOVEATION_DYNAMIC_LEVEL_ENABLED_BIT_HTC = 0x00000001; +static const XrFoveationDynamicFlagsHTC XR_FOVEATION_DYNAMIC_CLEAR_FOV_ENABLED_BIT_HTC = 0x00000002; +static const XrFoveationDynamicFlagsHTC XR_FOVEATION_DYNAMIC_FOCAL_CENTER_OFFSET_ENABLED_BIT_HTC = 0x00000004; + +typedef struct XrFoveationApplyInfoHTC { + XrStructureType type; + const void* XR_MAY_ALIAS next; + XrFoveationModeHTC mode; + uint32_t subImageCount; + XrSwapchainSubImage* subImages; +} XrFoveationApplyInfoHTC; + +typedef struct XrFoveationConfigurationHTC { + XrFoveationLevelHTC level; + float clearFovDegree; + XrVector2f focalCenterOffset; +} XrFoveationConfigurationHTC; + +// XrFoveationDynamicModeInfoHTC extends XrFoveationApplyInfoHTC +typedef struct XrFoveationDynamicModeInfoHTC { + XrStructureType type; + const void* XR_MAY_ALIAS next; + XrFoveationDynamicFlagsHTC dynamicFlags; +} XrFoveationDynamicModeInfoHTC; + +// XrFoveationCustomModeInfoHTC extends XrFoveationApplyInfoHTC +typedef struct XrFoveationCustomModeInfoHTC { + XrStructureType type; + const void* XR_MAY_ALIAS next; + uint32_t configCount; + const XrFoveationConfigurationHTC* configs; +} XrFoveationCustomModeInfoHTC; + +typedef XrResult (XRAPI_PTR *PFN_xrApplyFoveationHTC)(XrSession session, const XrFoveationApplyInfoHTC* applyInfo); + +#ifndef XR_NO_PROTOTYPES +#ifdef XR_EXTENSION_PROTOTYPES +XRAPI_ATTR XrResult XRAPI_CALL xrApplyFoveationHTC( + XrSession session, + const XrFoveationApplyInfoHTC* applyInfo); +#endif /* XR_EXTENSION_PROTOTYPES */ +#endif /* !XR_NO_PROTOTYPES */ + + +#define XR_EXT_active_action_set_priority 1 +#define XR_EXT_active_action_set_priority_SPEC_VERSION 1 +#define XR_EXT_ACTIVE_ACTION_SET_PRIORITY_EXTENSION_NAME "XR_EXT_active_action_set_priority" +typedef struct XrActiveActionSetPriorityEXT { + XrActionSet actionSet; + uint32_t priorityOverride; +} XrActiveActionSetPriorityEXT; + +// XrActiveActionSetPrioritiesEXT extends XrActionsSyncInfo +typedef struct XrActiveActionSetPrioritiesEXT { + XrStructureType type; + const void* XR_MAY_ALIAS next; + uint32_t actionSetPriorityCount; + const XrActiveActionSetPriorityEXT* actionSetPriorities; +} XrActiveActionSetPrioritiesEXT; + + + +#define XR_MNDX_force_feedback_curl 1 +#define XR_MNDX_force_feedback_curl_SPEC_VERSION 1 +#define XR_MNDX_FORCE_FEEDBACK_CURL_EXTENSION_NAME "XR_MNDX_force_feedback_curl" + +typedef enum XrForceFeedbackCurlLocationMNDX { + XR_FORCE_FEEDBACK_CURL_LOCATION_THUMB_CURL_MNDX = 0, + XR_FORCE_FEEDBACK_CURL_LOCATION_INDEX_CURL_MNDX = 1, + XR_FORCE_FEEDBACK_CURL_LOCATION_MIDDLE_CURL_MNDX = 2, + XR_FORCE_FEEDBACK_CURL_LOCATION_RING_CURL_MNDX = 3, + XR_FORCE_FEEDBACK_CURL_LOCATION_LITTLE_CURL_MNDX = 4, + XR_FORCE_FEEDBACK_CURL_LOCATION_MAX_ENUM_MNDX = 0x7FFFFFFF +} XrForceFeedbackCurlLocationMNDX; +// XrSystemForceFeedbackCurlPropertiesMNDX extends XrSystemProperties +typedef struct XrSystemForceFeedbackCurlPropertiesMNDX { + XrStructureType type; + void* XR_MAY_ALIAS next; + XrBool32 supportsForceFeedbackCurl; +} XrSystemForceFeedbackCurlPropertiesMNDX; + +typedef struct XrForceFeedbackCurlApplyLocationMNDX { + XrForceFeedbackCurlLocationMNDX location; + float value; +} XrForceFeedbackCurlApplyLocationMNDX; + +typedef struct XrForceFeedbackCurlApplyLocationsMNDX { + XrStructureType type; + const void* XR_MAY_ALIAS next; + uint32_t locationCount; + XrForceFeedbackCurlApplyLocationMNDX* locations; +} XrForceFeedbackCurlApplyLocationsMNDX; + +typedef XrResult (XRAPI_PTR *PFN_xrApplyForceFeedbackCurlMNDX)(XrHandTrackerEXT handTracker, const XrForceFeedbackCurlApplyLocationsMNDX* locations); + +#ifndef XR_NO_PROTOTYPES +#ifdef XR_EXTENSION_PROTOTYPES +XRAPI_ATTR XrResult XRAPI_CALL xrApplyForceFeedbackCurlMNDX( + XrHandTrackerEXT handTracker, + const XrForceFeedbackCurlApplyLocationsMNDX* locations); +#endif /* XR_EXTENSION_PROTOTYPES */ +#endif /* !XR_NO_PROTOTYPES */ + + +#define XR_BD_controller_interaction 1 +#define XR_BD_controller_interaction_SPEC_VERSION 1 +#define XR_BD_CONTROLLER_INTERACTION_EXTENSION_NAME "XR_BD_controller_interaction" + + +#define XR_EXT_local_floor 1 +#define XR_EXT_local_floor_SPEC_VERSION 1 +#define XR_EXT_LOCAL_FLOOR_EXTENSION_NAME "XR_EXT_local_floor" + + +#define XR_EXT_hand_tracking_data_source 1 +#define XR_EXT_hand_tracking_data_source_SPEC_VERSION 1 +#define XR_EXT_HAND_TRACKING_DATA_SOURCE_EXTENSION_NAME "XR_EXT_hand_tracking_data_source" + +typedef enum XrHandTrackingDataSourceEXT { + XR_HAND_TRACKING_DATA_SOURCE_UNOBSTRUCTED_EXT = 1, + XR_HAND_TRACKING_DATA_SOURCE_CONTROLLER_EXT = 2, + XR_HAND_TRACKING_DATA_SOURCE_MAX_ENUM_EXT = 0x7FFFFFFF +} XrHandTrackingDataSourceEXT; +// XrHandTrackingDataSourceInfoEXT extends XrHandTrackerCreateInfoEXT +typedef struct XrHandTrackingDataSourceInfoEXT { + XrStructureType type; + const void* XR_MAY_ALIAS next; + uint32_t requestedDataSourceCount; + XrHandTrackingDataSourceEXT* requestedDataSources; +} XrHandTrackingDataSourceInfoEXT; + +// XrHandTrackingDataSourceStateEXT extends XrHandJointLocationsEXT +typedef struct XrHandTrackingDataSourceStateEXT { + XrStructureType type; + void* XR_MAY_ALIAS next; + XrBool32 isActive; + XrHandTrackingDataSourceEXT dataSource; +} XrHandTrackingDataSourceStateEXT; + + + +#define XR_EXT_plane_detection 1 +XR_DEFINE_HANDLE(XrPlaneDetectorEXT) +#define XR_EXT_plane_detection_SPEC_VERSION 1 +#define XR_EXT_PLANE_DETECTION_EXTENSION_NAME "XR_EXT_plane_detection" + +typedef enum XrPlaneDetectorOrientationEXT { + XR_PLANE_DETECTOR_ORIENTATION_HORIZONTAL_UPWARD_EXT = 0, + XR_PLANE_DETECTOR_ORIENTATION_HORIZONTAL_DOWNWARD_EXT = 1, + XR_PLANE_DETECTOR_ORIENTATION_VERTICAL_EXT = 2, + XR_PLANE_DETECTOR_ORIENTATION_ARBITRARY_EXT = 3, + XR_PLANE_DETECTOR_ORIENTATION_MAX_ENUM_EXT = 0x7FFFFFFF +} XrPlaneDetectorOrientationEXT; + +typedef enum XrPlaneDetectorSemanticTypeEXT { + XR_PLANE_DETECTOR_SEMANTIC_TYPE_UNDEFINED_EXT = 0, + XR_PLANE_DETECTOR_SEMANTIC_TYPE_CEILING_EXT = 1, + XR_PLANE_DETECTOR_SEMANTIC_TYPE_FLOOR_EXT = 2, + XR_PLANE_DETECTOR_SEMANTIC_TYPE_WALL_EXT = 3, + XR_PLANE_DETECTOR_SEMANTIC_TYPE_PLATFORM_EXT = 4, + XR_PLANE_DETECTOR_SEMANTIC_TYPE_MAX_ENUM_EXT = 0x7FFFFFFF +} XrPlaneDetectorSemanticTypeEXT; + +typedef enum XrPlaneDetectionStateEXT { + XR_PLANE_DETECTION_STATE_NONE_EXT = 0, + XR_PLANE_DETECTION_STATE_PENDING_EXT = 1, + XR_PLANE_DETECTION_STATE_DONE_EXT = 2, + XR_PLANE_DETECTION_STATE_ERROR_EXT = 3, + XR_PLANE_DETECTION_STATE_FATAL_EXT = 4, + XR_PLANE_DETECTION_STATE_MAX_ENUM_EXT = 0x7FFFFFFF +} XrPlaneDetectionStateEXT; +typedef XrFlags64 XrPlaneDetectionCapabilityFlagsEXT; + +// Flag bits for XrPlaneDetectionCapabilityFlagsEXT +static const XrPlaneDetectionCapabilityFlagsEXT XR_PLANE_DETECTION_CAPABILITY_PLANE_DETECTION_BIT_EXT = 0x00000001; +static const XrPlaneDetectionCapabilityFlagsEXT XR_PLANE_DETECTION_CAPABILITY_PLANE_HOLES_BIT_EXT = 0x00000002; +static const XrPlaneDetectionCapabilityFlagsEXT XR_PLANE_DETECTION_CAPABILITY_SEMANTIC_CEILING_BIT_EXT = 0x00000004; +static const XrPlaneDetectionCapabilityFlagsEXT XR_PLANE_DETECTION_CAPABILITY_SEMANTIC_FLOOR_BIT_EXT = 0x00000008; +static const XrPlaneDetectionCapabilityFlagsEXT XR_PLANE_DETECTION_CAPABILITY_SEMANTIC_WALL_BIT_EXT = 0x00000010; +static const XrPlaneDetectionCapabilityFlagsEXT XR_PLANE_DETECTION_CAPABILITY_SEMANTIC_PLATFORM_BIT_EXT = 0x00000020; +static const XrPlaneDetectionCapabilityFlagsEXT XR_PLANE_DETECTION_CAPABILITY_ORIENTATION_BIT_EXT = 0x00000040; + +typedef XrFlags64 XrPlaneDetectorFlagsEXT; + +// Flag bits for XrPlaneDetectorFlagsEXT +static const XrPlaneDetectorFlagsEXT XR_PLANE_DETECTOR_ENABLE_CONTOUR_BIT_EXT = 0x00000001; + +// XrSystemPlaneDetectionPropertiesEXT extends XrSystemProperties +typedef struct XrSystemPlaneDetectionPropertiesEXT { + XrStructureType type; + void* XR_MAY_ALIAS next; + XrPlaneDetectionCapabilityFlagsEXT supportedFeatures; +} XrSystemPlaneDetectionPropertiesEXT; + +typedef struct XrPlaneDetectorCreateInfoEXT { + XrStructureType type; + const void* XR_MAY_ALIAS next; + XrPlaneDetectorFlagsEXT flags; +} XrPlaneDetectorCreateInfoEXT; + +typedef struct XrExtent3DfEXT { + float width; + float height; + float depth; +} XrExtent3DfEXT; + +typedef struct XrPlaneDetectorBeginInfoEXT { + XrStructureType type; + const void* XR_MAY_ALIAS next; + XrSpace baseSpace; + XrTime time; + uint32_t orientationCount; + const XrPlaneDetectorOrientationEXT* orientations; + uint32_t semanticTypeCount; + const XrPlaneDetectorSemanticTypeEXT* semanticTypes; + uint32_t maxPlanes; + float minArea; + XrPosef boundingBoxPose; + XrExtent3DfEXT boundingBoxExtent; +} XrPlaneDetectorBeginInfoEXT; + +typedef struct XrPlaneDetectorGetInfoEXT { + XrStructureType type; + const void* XR_MAY_ALIAS next; + XrSpace baseSpace; + XrTime time; +} XrPlaneDetectorGetInfoEXT; + +typedef struct XrPlaneDetectorLocationEXT { + XrStructureType type; + void* XR_MAY_ALIAS next; + uint64_t planeId; + XrSpaceLocationFlags locationFlags; + XrPosef pose; + XrExtent2Df extents; + XrPlaneDetectorOrientationEXT orientation; + XrPlaneDetectorSemanticTypeEXT semanticType; + uint32_t polygonBufferCount; +} XrPlaneDetectorLocationEXT; + +typedef struct XrPlaneDetectorLocationsEXT { + XrStructureType type; + void* XR_MAY_ALIAS next; + uint32_t planeLocationCapacityInput; + uint32_t planeLocationCountOutput; + XrPlaneDetectorLocationEXT* planeLocations; +} XrPlaneDetectorLocationsEXT; + +typedef struct XrPlaneDetectorPolygonBufferEXT { + XrStructureType type; + void* XR_MAY_ALIAS next; + uint32_t vertexCapacityInput; + uint32_t vertexCountOutput; + XrVector2f* vertices; +} XrPlaneDetectorPolygonBufferEXT; + +typedef XrResult (XRAPI_PTR *PFN_xrCreatePlaneDetectorEXT)(XrSession session, const XrPlaneDetectorCreateInfoEXT* createInfo, XrPlaneDetectorEXT* planeDetector); +typedef XrResult (XRAPI_PTR *PFN_xrDestroyPlaneDetectorEXT)(XrPlaneDetectorEXT planeDetector); +typedef XrResult (XRAPI_PTR *PFN_xrBeginPlaneDetectionEXT)(XrPlaneDetectorEXT planeDetector, const XrPlaneDetectorBeginInfoEXT* beginInfo); +typedef XrResult (XRAPI_PTR *PFN_xrGetPlaneDetectionStateEXT)(XrPlaneDetectorEXT planeDetector, XrPlaneDetectionStateEXT* state); +typedef XrResult (XRAPI_PTR *PFN_xrGetPlaneDetectionsEXT)(XrPlaneDetectorEXT planeDetector, const XrPlaneDetectorGetInfoEXT* info, XrPlaneDetectorLocationsEXT* locations); +typedef XrResult (XRAPI_PTR *PFN_xrGetPlanePolygonBufferEXT)(XrPlaneDetectorEXT planeDetector, uint64_t planeId, uint32_t polygonBufferIndex, XrPlaneDetectorPolygonBufferEXT* polygonBuffer); + +#ifndef XR_NO_PROTOTYPES +#ifdef XR_EXTENSION_PROTOTYPES +XRAPI_ATTR XrResult XRAPI_CALL xrCreatePlaneDetectorEXT( + XrSession session, + const XrPlaneDetectorCreateInfoEXT* createInfo, + XrPlaneDetectorEXT* planeDetector); + +XRAPI_ATTR XrResult XRAPI_CALL xrDestroyPlaneDetectorEXT( + XrPlaneDetectorEXT planeDetector); + +XRAPI_ATTR XrResult XRAPI_CALL xrBeginPlaneDetectionEXT( + XrPlaneDetectorEXT planeDetector, + const XrPlaneDetectorBeginInfoEXT* beginInfo); + +XRAPI_ATTR XrResult XRAPI_CALL xrGetPlaneDetectionStateEXT( + XrPlaneDetectorEXT planeDetector, + XrPlaneDetectionStateEXT* state); + +XRAPI_ATTR XrResult XRAPI_CALL xrGetPlaneDetectionsEXT( + XrPlaneDetectorEXT planeDetector, + const XrPlaneDetectorGetInfoEXT* info, + XrPlaneDetectorLocationsEXT* locations); + +XRAPI_ATTR XrResult XRAPI_CALL xrGetPlanePolygonBufferEXT( + XrPlaneDetectorEXT planeDetector, + uint64_t planeId, + uint32_t polygonBufferIndex, + XrPlaneDetectorPolygonBufferEXT* polygonBuffer); +#endif /* XR_EXTENSION_PROTOTYPES */ +#endif /* !XR_NO_PROTOTYPES */ + + +#define XR_OPPO_controller_interaction 1 +#define XR_OPPO_controller_interaction_SPEC_VERSION 1 +#define XR_OPPO_CONTROLLER_INTERACTION_EXTENSION_NAME "XR_OPPO_controller_interaction" + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/third_party/openxr/openxr_loader_negotiation.h b/third_party/openxr/openxr_loader_negotiation.h new file mode 100644 index 0000000..020c345 --- /dev/null +++ b/third_party/openxr/openxr_loader_negotiation.h @@ -0,0 +1,114 @@ +// Copyright (c) 2017-2023, The Khronos Group Inc. +// Copyright (c) 2017 Valve Corporation +// Copyright (c) 2017 LunarG, Inc. +// +// SPDX-License-Identifier: Apache-2.0 OR MIT +// +// Initial Author: Mark Young +// + +#pragma once + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +// Forward declare. +typedef struct XrApiLayerCreateInfo XrApiLayerCreateInfo; + +// Function pointer prototype for the xrCreateApiLayerInstance function used in place of xrCreateInstance. +// This function allows us to pass special API layer information to each layer during the process of creating an Instance. +typedef XrResult(XRAPI_PTR *PFN_xrCreateApiLayerInstance)(const XrInstanceCreateInfo *info, + const XrApiLayerCreateInfo *apiLayerInfo, XrInstance *instance); + +// Loader/API Layer Interface versions +// 1 - First version, introduces negotiation structure and functions +#define XR_CURRENT_LOADER_API_LAYER_VERSION 1 + +// Loader/Runtime Interface versions +// 1 - First version, introduces negotiation structure and functions +#define XR_CURRENT_LOADER_RUNTIME_VERSION 1 + +// Version negotiation values +typedef enum XrLoaderInterfaceStructs { + XR_LOADER_INTERFACE_STRUCT_UNINTIALIZED = 0, + XR_LOADER_INTERFACE_STRUCT_LOADER_INFO, + XR_LOADER_INTERFACE_STRUCT_API_LAYER_REQUEST, + XR_LOADER_INTERFACE_STRUCT_RUNTIME_REQUEST, + XR_LOADER_INTERFACE_STRUCT_API_LAYER_CREATE_INFO, + XR_LOADER_INTERFACE_STRUCT_API_LAYER_NEXT_INFO, +} XrLoaderInterfaceStructs; + +#define XR_LOADER_INFO_STRUCT_VERSION 1 +typedef struct XrNegotiateLoaderInfo { + XrLoaderInterfaceStructs structType; // XR_LOADER_INTERFACE_STRUCT_LOADER_INFO + uint32_t structVersion; // XR_LOADER_INFO_STRUCT_VERSION + size_t structSize; // sizeof(XrNegotiateLoaderInfo) + uint32_t minInterfaceVersion; + uint32_t maxInterfaceVersion; + XrVersion minApiVersion; + XrVersion maxApiVersion; +} XrNegotiateLoaderInfo; + +#define XR_API_LAYER_INFO_STRUCT_VERSION 1 +typedef struct XrNegotiateApiLayerRequest { + XrLoaderInterfaceStructs structType; // XR_LOADER_INTERFACE_STRUCT_API_LAYER_REQUEST + uint32_t structVersion; // XR_API_LAYER_INFO_STRUCT_VERSION + size_t structSize; // sizeof(XrNegotiateApiLayerRequest) + uint32_t layerInterfaceVersion; // CURRENT_LOADER_API_LAYER_VERSION + XrVersion layerApiVersion; + PFN_xrGetInstanceProcAddr getInstanceProcAddr; + PFN_xrCreateApiLayerInstance createApiLayerInstance; +} XrNegotiateApiLayerRequest; + +#define XR_RUNTIME_INFO_STRUCT_VERSION 1 +typedef struct XrNegotiateRuntimeRequest { + XrLoaderInterfaceStructs structType; // XR_LOADER_INTERFACE_STRUCT_RUNTIME_REQUEST + uint32_t structVersion; // XR_RUNTIME_INFO_STRUCT_VERSION + size_t structSize; // sizeof(XrNegotiateRuntimeRequest) + uint32_t runtimeInterfaceVersion; // CURRENT_LOADER_RUNTIME_VERSION + XrVersion runtimeApiVersion; + PFN_xrGetInstanceProcAddr getInstanceProcAddr; +} XrNegotiateRuntimeRequest; + +// Function used to negotiate an interface betewen the loader and an API layer. Each library exposing one or +// more API layers needs to expose at least this function. +typedef XrResult(XRAPI_PTR *PFN_xrNegotiateLoaderApiLayerInterface)(const XrNegotiateLoaderInfo *loaderInfo, + const char *apiLayerName, + XrNegotiateApiLayerRequest *apiLayerRequest); + +// Function used to negotiate an interface betewen the loader and a runtime. Each runtime should expose +// at least this function. +typedef XrResult(XRAPI_PTR *PFN_xrNegotiateLoaderRuntimeInterface)(const XrNegotiateLoaderInfo *loaderInfo, + XrNegotiateRuntimeRequest *runtimeRequest); + +// Forward declare. +typedef struct XrApiLayerNextInfo XrApiLayerNextInfo; + +#define XR_API_LAYER_NEXT_INFO_STRUCT_VERSION 1 +struct XrApiLayerNextInfo { + XrLoaderInterfaceStructs structType; // XR_LOADER_INTERFACE_STRUCT_API_LAYER_NEXT_INFO + uint32_t structVersion; // XR_API_LAYER_NEXT_INFO_STRUCT_VERSION + size_t structSize; // sizeof(XrApiLayerNextInfo) + char layerName[XR_MAX_API_LAYER_NAME_SIZE]; // Name of API layer which should receive this info + PFN_xrGetInstanceProcAddr nextGetInstanceProcAddr; // Pointer to next API layer's xrGetInstanceProcAddr + PFN_xrCreateApiLayerInstance nextCreateApiLayerInstance; // Pointer to next API layer's xrCreateApiLayerInstance + XrApiLayerNextInfo *next; // Pointer to the next API layer info in the sequence +}; + +#define XR_API_LAYER_MAX_SETTINGS_PATH_SIZE 512 +#define XR_API_LAYER_CREATE_INFO_STRUCT_VERSION 1 +typedef struct XrApiLayerCreateInfo { + XrLoaderInterfaceStructs structType; // XR_LOADER_INTERFACE_STRUCT_API_LAYER_CREATE_INFO + uint32_t structVersion; // XR_API_LAYER_CREATE_INFO_STRUCT_VERSION + size_t structSize; // sizeof(XrApiLayerCreateInfo) + void *loaderInstance; // Pointer to the LoaderInstance class + char settings_file_location[XR_API_LAYER_MAX_SETTINGS_PATH_SIZE]; // Location to the found settings file (or empty '\0') + XrApiLayerNextInfo *nextInfo; // Pointer to the next API layer's Info +} XrApiLayerCreateInfo; + +#ifdef __cplusplus +} // extern "C" +#endif diff --git a/third_party/openxr/openxr_platform.h b/third_party/openxr/openxr_platform.h new file mode 100644 index 0000000..b0a5328 --- /dev/null +++ b/third_party/openxr/openxr_platform.h @@ -0,0 +1,714 @@ +#ifndef OPENXR_PLATFORM_H_ +#define OPENXR_PLATFORM_H_ 1 + +/* +** Copyright 2017-2023 The Khronos Group Inc. +** +** SPDX-License-Identifier: Apache-2.0 OR MIT +*/ + +/* +** This header is generated from the Khronos OpenXR XML API Registry. +** +*/ + +#include "openxr.h" + +#ifdef __cplusplus +extern "C" { +#endif + + +#ifdef XR_USE_PLATFORM_ANDROID + +#define XR_KHR_android_thread_settings 1 +#define XR_KHR_android_thread_settings_SPEC_VERSION 5 +#define XR_KHR_ANDROID_THREAD_SETTINGS_EXTENSION_NAME "XR_KHR_android_thread_settings" + +typedef enum XrAndroidThreadTypeKHR { + XR_ANDROID_THREAD_TYPE_APPLICATION_MAIN_KHR = 1, + XR_ANDROID_THREAD_TYPE_APPLICATION_WORKER_KHR = 2, + XR_ANDROID_THREAD_TYPE_RENDERER_MAIN_KHR = 3, + XR_ANDROID_THREAD_TYPE_RENDERER_WORKER_KHR = 4, + XR_ANDROID_THREAD_TYPE_MAX_ENUM_KHR = 0x7FFFFFFF +} XrAndroidThreadTypeKHR; +typedef XrResult (XRAPI_PTR *PFN_xrSetAndroidApplicationThreadKHR)(XrSession session, XrAndroidThreadTypeKHR threadType, uint32_t threadId); + +#ifndef XR_NO_PROTOTYPES +#ifdef XR_EXTENSION_PROTOTYPES +XRAPI_ATTR XrResult XRAPI_CALL xrSetAndroidApplicationThreadKHR( + XrSession session, + XrAndroidThreadTypeKHR threadType, + uint32_t threadId); +#endif /* XR_EXTENSION_PROTOTYPES */ +#endif /* !XR_NO_PROTOTYPES */ +#endif /* XR_USE_PLATFORM_ANDROID */ + +#ifdef XR_USE_PLATFORM_ANDROID + +#define XR_KHR_android_surface_swapchain 1 +#define XR_KHR_android_surface_swapchain_SPEC_VERSION 4 +#define XR_KHR_ANDROID_SURFACE_SWAPCHAIN_EXTENSION_NAME "XR_KHR_android_surface_swapchain" +typedef XrResult (XRAPI_PTR *PFN_xrCreateSwapchainAndroidSurfaceKHR)(XrSession session, const XrSwapchainCreateInfo* info, XrSwapchain* swapchain, jobject* surface); + +#ifndef XR_NO_PROTOTYPES +#ifdef XR_EXTENSION_PROTOTYPES +XRAPI_ATTR XrResult XRAPI_CALL xrCreateSwapchainAndroidSurfaceKHR( + XrSession session, + const XrSwapchainCreateInfo* info, + XrSwapchain* swapchain, + jobject* surface); +#endif /* XR_EXTENSION_PROTOTYPES */ +#endif /* !XR_NO_PROTOTYPES */ +#endif /* XR_USE_PLATFORM_ANDROID */ + +#ifdef XR_USE_PLATFORM_ANDROID + +#define XR_KHR_android_create_instance 1 +#define XR_KHR_android_create_instance_SPEC_VERSION 3 +#define XR_KHR_ANDROID_CREATE_INSTANCE_EXTENSION_NAME "XR_KHR_android_create_instance" +// XrInstanceCreateInfoAndroidKHR extends XrInstanceCreateInfo +typedef struct XrInstanceCreateInfoAndroidKHR { + XrStructureType type; + const void* XR_MAY_ALIAS next; + void* XR_MAY_ALIAS applicationVM; + void* XR_MAY_ALIAS applicationActivity; +} XrInstanceCreateInfoAndroidKHR; + +#endif /* XR_USE_PLATFORM_ANDROID */ + +#ifdef XR_USE_GRAPHICS_API_VULKAN + +#define XR_KHR_vulkan_swapchain_format_list 1 +#define XR_KHR_vulkan_swapchain_format_list_SPEC_VERSION 4 +#define XR_KHR_VULKAN_SWAPCHAIN_FORMAT_LIST_EXTENSION_NAME "XR_KHR_vulkan_swapchain_format_list" +typedef struct XrVulkanSwapchainFormatListCreateInfoKHR { + XrStructureType type; + const void* XR_MAY_ALIAS next; + uint32_t viewFormatCount; + const VkFormat* viewFormats; +} XrVulkanSwapchainFormatListCreateInfoKHR; + +#endif /* XR_USE_GRAPHICS_API_VULKAN */ + +#ifdef XR_USE_GRAPHICS_API_OPENGL + +#define XR_KHR_opengl_enable 1 +#define XR_KHR_opengl_enable_SPEC_VERSION 10 +#define XR_KHR_OPENGL_ENABLE_EXTENSION_NAME "XR_KHR_opengl_enable" +#ifdef XR_USE_PLATFORM_WIN32 +// XrGraphicsBindingOpenGLWin32KHR extends XrSessionCreateInfo +typedef struct XrGraphicsBindingOpenGLWin32KHR { + XrStructureType type; + const void* XR_MAY_ALIAS next; + HDC hDC; + HGLRC hGLRC; +} XrGraphicsBindingOpenGLWin32KHR; +#endif // XR_USE_PLATFORM_WIN32 + +#ifdef XR_USE_PLATFORM_XLIB +// XrGraphicsBindingOpenGLXlibKHR extends XrSessionCreateInfo +typedef struct XrGraphicsBindingOpenGLXlibKHR { + XrStructureType type; + const void* XR_MAY_ALIAS next; + Display* xDisplay; + uint32_t visualid; + GLXFBConfig glxFBConfig; + GLXDrawable glxDrawable; + GLXContext glxContext; +} XrGraphicsBindingOpenGLXlibKHR; +#endif // XR_USE_PLATFORM_XLIB + +#ifdef XR_USE_PLATFORM_XCB +// XrGraphicsBindingOpenGLXcbKHR extends XrSessionCreateInfo +typedef struct XrGraphicsBindingOpenGLXcbKHR { + XrStructureType type; + const void* XR_MAY_ALIAS next; + xcb_connection_t* connection; + uint32_t screenNumber; + xcb_glx_fbconfig_t fbconfigid; + xcb_visualid_t visualid; + xcb_glx_drawable_t glxDrawable; + xcb_glx_context_t glxContext; +} XrGraphicsBindingOpenGLXcbKHR; +#endif // XR_USE_PLATFORM_XCB + +#ifdef XR_USE_PLATFORM_WAYLAND +// XrGraphicsBindingOpenGLWaylandKHR extends XrSessionCreateInfo +typedef struct XrGraphicsBindingOpenGLWaylandKHR { + XrStructureType type; + const void* XR_MAY_ALIAS next; + struct wl_display* display; +} XrGraphicsBindingOpenGLWaylandKHR; +#endif // XR_USE_PLATFORM_WAYLAND + +typedef struct XrSwapchainImageOpenGLKHR { + XrStructureType type; + void* XR_MAY_ALIAS next; + uint32_t image; +} XrSwapchainImageOpenGLKHR; + +typedef struct XrGraphicsRequirementsOpenGLKHR { + XrStructureType type; + void* XR_MAY_ALIAS next; + XrVersion minApiVersionSupported; + XrVersion maxApiVersionSupported; +} XrGraphicsRequirementsOpenGLKHR; + +typedef XrResult (XRAPI_PTR *PFN_xrGetOpenGLGraphicsRequirementsKHR)(XrInstance instance, XrSystemId systemId, XrGraphicsRequirementsOpenGLKHR* graphicsRequirements); + +#ifndef XR_NO_PROTOTYPES +#ifdef XR_EXTENSION_PROTOTYPES +XRAPI_ATTR XrResult XRAPI_CALL xrGetOpenGLGraphicsRequirementsKHR( + XrInstance instance, + XrSystemId systemId, + XrGraphicsRequirementsOpenGLKHR* graphicsRequirements); +#endif /* XR_EXTENSION_PROTOTYPES */ +#endif /* !XR_NO_PROTOTYPES */ +#endif /* XR_USE_GRAPHICS_API_OPENGL */ + +#ifdef XR_USE_GRAPHICS_API_OPENGL_ES + +#define XR_KHR_opengl_es_enable 1 +#define XR_KHR_opengl_es_enable_SPEC_VERSION 8 +#define XR_KHR_OPENGL_ES_ENABLE_EXTENSION_NAME "XR_KHR_opengl_es_enable" +#ifdef XR_USE_PLATFORM_ANDROID +// XrGraphicsBindingOpenGLESAndroidKHR extends XrSessionCreateInfo +typedef struct XrGraphicsBindingOpenGLESAndroidKHR { + XrStructureType type; + const void* XR_MAY_ALIAS next; + EGLDisplay display; + EGLConfig config; + EGLContext context; +} XrGraphicsBindingOpenGLESAndroidKHR; +#endif // XR_USE_PLATFORM_ANDROID + +typedef struct XrSwapchainImageOpenGLESKHR { + XrStructureType type; + void* XR_MAY_ALIAS next; + uint32_t image; +} XrSwapchainImageOpenGLESKHR; + +typedef struct XrGraphicsRequirementsOpenGLESKHR { + XrStructureType type; + void* XR_MAY_ALIAS next; + XrVersion minApiVersionSupported; + XrVersion maxApiVersionSupported; +} XrGraphicsRequirementsOpenGLESKHR; + +typedef XrResult (XRAPI_PTR *PFN_xrGetOpenGLESGraphicsRequirementsKHR)(XrInstance instance, XrSystemId systemId, XrGraphicsRequirementsOpenGLESKHR* graphicsRequirements); + +#ifndef XR_NO_PROTOTYPES +#ifdef XR_EXTENSION_PROTOTYPES +XRAPI_ATTR XrResult XRAPI_CALL xrGetOpenGLESGraphicsRequirementsKHR( + XrInstance instance, + XrSystemId systemId, + XrGraphicsRequirementsOpenGLESKHR* graphicsRequirements); +#endif /* XR_EXTENSION_PROTOTYPES */ +#endif /* !XR_NO_PROTOTYPES */ +#endif /* XR_USE_GRAPHICS_API_OPENGL_ES */ + +#ifdef XR_USE_GRAPHICS_API_VULKAN + +#define XR_KHR_vulkan_enable 1 +#define XR_KHR_vulkan_enable_SPEC_VERSION 8 +#define XR_KHR_VULKAN_ENABLE_EXTENSION_NAME "XR_KHR_vulkan_enable" +// XrGraphicsBindingVulkanKHR extends XrSessionCreateInfo +typedef struct XrGraphicsBindingVulkanKHR { + XrStructureType type; + const void* XR_MAY_ALIAS next; + VkInstance instance; + VkPhysicalDevice physicalDevice; + VkDevice device; + uint32_t queueFamilyIndex; + uint32_t queueIndex; +} XrGraphicsBindingVulkanKHR; + +typedef struct XrSwapchainImageVulkanKHR { + XrStructureType type; + void* XR_MAY_ALIAS next; + VkImage image; +} XrSwapchainImageVulkanKHR; + +typedef struct XrGraphicsRequirementsVulkanKHR { + XrStructureType type; + void* XR_MAY_ALIAS next; + XrVersion minApiVersionSupported; + XrVersion maxApiVersionSupported; +} XrGraphicsRequirementsVulkanKHR; + +typedef XrResult (XRAPI_PTR *PFN_xrGetVulkanInstanceExtensionsKHR)(XrInstance instance, XrSystemId systemId, uint32_t bufferCapacityInput, uint32_t* bufferCountOutput, char* buffer); +typedef XrResult (XRAPI_PTR *PFN_xrGetVulkanDeviceExtensionsKHR)(XrInstance instance, XrSystemId systemId, uint32_t bufferCapacityInput, uint32_t* bufferCountOutput, char* buffer); +typedef XrResult (XRAPI_PTR *PFN_xrGetVulkanGraphicsDeviceKHR)(XrInstance instance, XrSystemId systemId, VkInstance vkInstance, VkPhysicalDevice* vkPhysicalDevice); +typedef XrResult (XRAPI_PTR *PFN_xrGetVulkanGraphicsRequirementsKHR)(XrInstance instance, XrSystemId systemId, XrGraphicsRequirementsVulkanKHR* graphicsRequirements); + +#ifndef XR_NO_PROTOTYPES +#ifdef XR_EXTENSION_PROTOTYPES +XRAPI_ATTR XrResult XRAPI_CALL xrGetVulkanInstanceExtensionsKHR( + XrInstance instance, + XrSystemId systemId, + uint32_t bufferCapacityInput, + uint32_t* bufferCountOutput, + char* buffer); + +XRAPI_ATTR XrResult XRAPI_CALL xrGetVulkanDeviceExtensionsKHR( + XrInstance instance, + XrSystemId systemId, + uint32_t bufferCapacityInput, + uint32_t* bufferCountOutput, + char* buffer); + +XRAPI_ATTR XrResult XRAPI_CALL xrGetVulkanGraphicsDeviceKHR( + XrInstance instance, + XrSystemId systemId, + VkInstance vkInstance, + VkPhysicalDevice* vkPhysicalDevice); + +XRAPI_ATTR XrResult XRAPI_CALL xrGetVulkanGraphicsRequirementsKHR( + XrInstance instance, + XrSystemId systemId, + XrGraphicsRequirementsVulkanKHR* graphicsRequirements); +#endif /* XR_EXTENSION_PROTOTYPES */ +#endif /* !XR_NO_PROTOTYPES */ +#endif /* XR_USE_GRAPHICS_API_VULKAN */ + +#ifdef XR_USE_GRAPHICS_API_D3D11 + +#define XR_KHR_D3D11_enable 1 +#define XR_KHR_D3D11_enable_SPEC_VERSION 9 +#define XR_KHR_D3D11_ENABLE_EXTENSION_NAME "XR_KHR_D3D11_enable" +// XrGraphicsBindingD3D11KHR extends XrSessionCreateInfo +typedef struct XrGraphicsBindingD3D11KHR { + XrStructureType type; + const void* XR_MAY_ALIAS next; + ID3D11Device* device; +} XrGraphicsBindingD3D11KHR; + +typedef struct XrSwapchainImageD3D11KHR { + XrStructureType type; + void* XR_MAY_ALIAS next; + ID3D11Texture2D* texture; +} XrSwapchainImageD3D11KHR; + +typedef struct XrGraphicsRequirementsD3D11KHR { + XrStructureType type; + void* XR_MAY_ALIAS next; + LUID adapterLuid; + D3D_FEATURE_LEVEL minFeatureLevel; +} XrGraphicsRequirementsD3D11KHR; + +typedef XrResult (XRAPI_PTR *PFN_xrGetD3D11GraphicsRequirementsKHR)(XrInstance instance, XrSystemId systemId, XrGraphicsRequirementsD3D11KHR* graphicsRequirements); + +#ifndef XR_NO_PROTOTYPES +#ifdef XR_EXTENSION_PROTOTYPES +XRAPI_ATTR XrResult XRAPI_CALL xrGetD3D11GraphicsRequirementsKHR( + XrInstance instance, + XrSystemId systemId, + XrGraphicsRequirementsD3D11KHR* graphicsRequirements); +#endif /* XR_EXTENSION_PROTOTYPES */ +#endif /* !XR_NO_PROTOTYPES */ +#endif /* XR_USE_GRAPHICS_API_D3D11 */ + +#ifdef XR_USE_GRAPHICS_API_D3D12 + +#define XR_KHR_D3D12_enable 1 +#define XR_KHR_D3D12_enable_SPEC_VERSION 9 +#define XR_KHR_D3D12_ENABLE_EXTENSION_NAME "XR_KHR_D3D12_enable" +// XrGraphicsBindingD3D12KHR extends XrSessionCreateInfo +typedef struct XrGraphicsBindingD3D12KHR { + XrStructureType type; + const void* XR_MAY_ALIAS next; + ID3D12Device* device; + ID3D12CommandQueue* queue; +} XrGraphicsBindingD3D12KHR; + +typedef struct XrSwapchainImageD3D12KHR { + XrStructureType type; + void* XR_MAY_ALIAS next; + ID3D12Resource* texture; +} XrSwapchainImageD3D12KHR; + +typedef struct XrGraphicsRequirementsD3D12KHR { + XrStructureType type; + void* XR_MAY_ALIAS next; + LUID adapterLuid; + D3D_FEATURE_LEVEL minFeatureLevel; +} XrGraphicsRequirementsD3D12KHR; + +typedef XrResult (XRAPI_PTR *PFN_xrGetD3D12GraphicsRequirementsKHR)(XrInstance instance, XrSystemId systemId, XrGraphicsRequirementsD3D12KHR* graphicsRequirements); + +#ifndef XR_NO_PROTOTYPES +#ifdef XR_EXTENSION_PROTOTYPES +XRAPI_ATTR XrResult XRAPI_CALL xrGetD3D12GraphicsRequirementsKHR( + XrInstance instance, + XrSystemId systemId, + XrGraphicsRequirementsD3D12KHR* graphicsRequirements); +#endif /* XR_EXTENSION_PROTOTYPES */ +#endif /* !XR_NO_PROTOTYPES */ +#endif /* XR_USE_GRAPHICS_API_D3D12 */ + +#ifdef XR_USE_PLATFORM_WIN32 + +#define XR_KHR_win32_convert_performance_counter_time 1 +#define XR_KHR_win32_convert_performance_counter_time_SPEC_VERSION 1 +#define XR_KHR_WIN32_CONVERT_PERFORMANCE_COUNTER_TIME_EXTENSION_NAME "XR_KHR_win32_convert_performance_counter_time" +typedef XrResult (XRAPI_PTR *PFN_xrConvertWin32PerformanceCounterToTimeKHR)(XrInstance instance, const LARGE_INTEGER* performanceCounter, XrTime* time); +typedef XrResult (XRAPI_PTR *PFN_xrConvertTimeToWin32PerformanceCounterKHR)(XrInstance instance, XrTime time, LARGE_INTEGER* performanceCounter); + +#ifndef XR_NO_PROTOTYPES +#ifdef XR_EXTENSION_PROTOTYPES +XRAPI_ATTR XrResult XRAPI_CALL xrConvertWin32PerformanceCounterToTimeKHR( + XrInstance instance, + const LARGE_INTEGER* performanceCounter, + XrTime* time); + +XRAPI_ATTR XrResult XRAPI_CALL xrConvertTimeToWin32PerformanceCounterKHR( + XrInstance instance, + XrTime time, + LARGE_INTEGER* performanceCounter); +#endif /* XR_EXTENSION_PROTOTYPES */ +#endif /* !XR_NO_PROTOTYPES */ +#endif /* XR_USE_PLATFORM_WIN32 */ + +#ifdef XR_USE_TIMESPEC + +#define XR_KHR_convert_timespec_time 1 +#define XR_KHR_convert_timespec_time_SPEC_VERSION 1 +#define XR_KHR_CONVERT_TIMESPEC_TIME_EXTENSION_NAME "XR_KHR_convert_timespec_time" +typedef XrResult (XRAPI_PTR *PFN_xrConvertTimespecTimeToTimeKHR)(XrInstance instance, const struct timespec* timespecTime, XrTime* time); +typedef XrResult (XRAPI_PTR *PFN_xrConvertTimeToTimespecTimeKHR)(XrInstance instance, XrTime time, struct timespec* timespecTime); + +#ifndef XR_NO_PROTOTYPES +#ifdef XR_EXTENSION_PROTOTYPES +XRAPI_ATTR XrResult XRAPI_CALL xrConvertTimespecTimeToTimeKHR( + XrInstance instance, + const struct timespec* timespecTime, + XrTime* time); + +XRAPI_ATTR XrResult XRAPI_CALL xrConvertTimeToTimespecTimeKHR( + XrInstance instance, + XrTime time, + struct timespec* timespecTime); +#endif /* XR_EXTENSION_PROTOTYPES */ +#endif /* !XR_NO_PROTOTYPES */ +#endif /* XR_USE_TIMESPEC */ + +#ifdef XR_USE_PLATFORM_ANDROID + +#define XR_KHR_loader_init_android 1 +#define XR_KHR_loader_init_android_SPEC_VERSION 1 +#define XR_KHR_LOADER_INIT_ANDROID_EXTENSION_NAME "XR_KHR_loader_init_android" +typedef struct XrLoaderInitInfoAndroidKHR { + XrStructureType type; + const void* XR_MAY_ALIAS next; + void* XR_MAY_ALIAS applicationVM; + void* XR_MAY_ALIAS applicationContext; +} XrLoaderInitInfoAndroidKHR; + +#endif /* XR_USE_PLATFORM_ANDROID */ + +#ifdef XR_USE_GRAPHICS_API_VULKAN + +#define XR_KHR_vulkan_enable2 1 +#define XR_KHR_vulkan_enable2_SPEC_VERSION 2 +#define XR_KHR_VULKAN_ENABLE2_EXTENSION_NAME "XR_KHR_vulkan_enable2" +typedef XrFlags64 XrVulkanInstanceCreateFlagsKHR; + +// Flag bits for XrVulkanInstanceCreateFlagsKHR + +typedef XrFlags64 XrVulkanDeviceCreateFlagsKHR; + +// Flag bits for XrVulkanDeviceCreateFlagsKHR + +typedef struct XrVulkanInstanceCreateInfoKHR { + XrStructureType type; + const void* XR_MAY_ALIAS next; + XrSystemId systemId; + XrVulkanInstanceCreateFlagsKHR createFlags; + PFN_vkGetInstanceProcAddr pfnGetInstanceProcAddr; + const VkInstanceCreateInfo* vulkanCreateInfo; + const VkAllocationCallbacks* vulkanAllocator; +} XrVulkanInstanceCreateInfoKHR; + +typedef struct XrVulkanDeviceCreateInfoKHR { + XrStructureType type; + const void* XR_MAY_ALIAS next; + XrSystemId systemId; + XrVulkanDeviceCreateFlagsKHR createFlags; + PFN_vkGetInstanceProcAddr pfnGetInstanceProcAddr; + VkPhysicalDevice vulkanPhysicalDevice; + const VkDeviceCreateInfo* vulkanCreateInfo; + const VkAllocationCallbacks* vulkanAllocator; +} XrVulkanDeviceCreateInfoKHR; + +typedef XrGraphicsBindingVulkanKHR XrGraphicsBindingVulkan2KHR; + +typedef struct XrVulkanGraphicsDeviceGetInfoKHR { + XrStructureType type; + const void* XR_MAY_ALIAS next; + XrSystemId systemId; + VkInstance vulkanInstance; +} XrVulkanGraphicsDeviceGetInfoKHR; + +typedef XrSwapchainImageVulkanKHR XrSwapchainImageVulkan2KHR; + +typedef XrGraphicsRequirementsVulkanKHR XrGraphicsRequirementsVulkan2KHR; + +typedef XrResult (XRAPI_PTR *PFN_xrCreateVulkanInstanceKHR)(XrInstance instance, const XrVulkanInstanceCreateInfoKHR* createInfo, VkInstance* vulkanInstance, VkResult* vulkanResult); +typedef XrResult (XRAPI_PTR *PFN_xrCreateVulkanDeviceKHR)(XrInstance instance, const XrVulkanDeviceCreateInfoKHR* createInfo, VkDevice* vulkanDevice, VkResult* vulkanResult); +typedef XrResult (XRAPI_PTR *PFN_xrGetVulkanGraphicsDevice2KHR)(XrInstance instance, const XrVulkanGraphicsDeviceGetInfoKHR* getInfo, VkPhysicalDevice* vulkanPhysicalDevice); +typedef XrResult (XRAPI_PTR *PFN_xrGetVulkanGraphicsRequirements2KHR)(XrInstance instance, XrSystemId systemId, XrGraphicsRequirementsVulkanKHR* graphicsRequirements); + +#ifndef XR_NO_PROTOTYPES +#ifdef XR_EXTENSION_PROTOTYPES +XRAPI_ATTR XrResult XRAPI_CALL xrCreateVulkanInstanceKHR( + XrInstance instance, + const XrVulkanInstanceCreateInfoKHR* createInfo, + VkInstance* vulkanInstance, + VkResult* vulkanResult); + +XRAPI_ATTR XrResult XRAPI_CALL xrCreateVulkanDeviceKHR( + XrInstance instance, + const XrVulkanDeviceCreateInfoKHR* createInfo, + VkDevice* vulkanDevice, + VkResult* vulkanResult); + +XRAPI_ATTR XrResult XRAPI_CALL xrGetVulkanGraphicsDevice2KHR( + XrInstance instance, + const XrVulkanGraphicsDeviceGetInfoKHR* getInfo, + VkPhysicalDevice* vulkanPhysicalDevice); + +XRAPI_ATTR XrResult XRAPI_CALL xrGetVulkanGraphicsRequirements2KHR( + XrInstance instance, + XrSystemId systemId, + XrGraphicsRequirementsVulkanKHR* graphicsRequirements); +#endif /* XR_EXTENSION_PROTOTYPES */ +#endif /* !XR_NO_PROTOTYPES */ +#endif /* XR_USE_GRAPHICS_API_VULKAN */ + +#ifdef XR_USE_PLATFORM_EGL + +#define XR_MNDX_egl_enable 1 +#define XR_MNDX_egl_enable_SPEC_VERSION 1 +#define XR_MNDX_EGL_ENABLE_EXTENSION_NAME "XR_MNDX_egl_enable" +// XrGraphicsBindingEGLMNDX extends XrSessionCreateInfo +typedef struct XrGraphicsBindingEGLMNDX { + XrStructureType type; + const void* XR_MAY_ALIAS next; + PFNEGLGETPROCADDRESSPROC getProcAddress; + EGLDisplay display; + EGLConfig config; + EGLContext context; +} XrGraphicsBindingEGLMNDX; + +#endif /* XR_USE_PLATFORM_EGL */ + +#ifdef XR_USE_PLATFORM_WIN32 + +#define XR_MSFT_perception_anchor_interop 1 +#define XR_MSFT_perception_anchor_interop_SPEC_VERSION 1 +#define XR_MSFT_PERCEPTION_ANCHOR_INTEROP_EXTENSION_NAME "XR_MSFT_perception_anchor_interop" +typedef XrResult (XRAPI_PTR *PFN_xrCreateSpatialAnchorFromPerceptionAnchorMSFT)(XrSession session, IUnknown* perceptionAnchor, XrSpatialAnchorMSFT* anchor); +typedef XrResult (XRAPI_PTR *PFN_xrTryGetPerceptionAnchorFromSpatialAnchorMSFT)(XrSession session, XrSpatialAnchorMSFT anchor, IUnknown** perceptionAnchor); + +#ifndef XR_NO_PROTOTYPES +#ifdef XR_EXTENSION_PROTOTYPES +XRAPI_ATTR XrResult XRAPI_CALL xrCreateSpatialAnchorFromPerceptionAnchorMSFT( + XrSession session, + IUnknown* perceptionAnchor, + XrSpatialAnchorMSFT* anchor); + +XRAPI_ATTR XrResult XRAPI_CALL xrTryGetPerceptionAnchorFromSpatialAnchorMSFT( + XrSession session, + XrSpatialAnchorMSFT anchor, + IUnknown** perceptionAnchor); +#endif /* XR_EXTENSION_PROTOTYPES */ +#endif /* !XR_NO_PROTOTYPES */ +#endif /* XR_USE_PLATFORM_WIN32 */ + +#ifdef XR_USE_PLATFORM_WIN32 + +#define XR_MSFT_holographic_window_attachment 1 +#define XR_MSFT_holographic_window_attachment_SPEC_VERSION 1 +#define XR_MSFT_HOLOGRAPHIC_WINDOW_ATTACHMENT_EXTENSION_NAME "XR_MSFT_holographic_window_attachment" +#ifdef XR_USE_PLATFORM_WIN32 +// XrHolographicWindowAttachmentMSFT extends XrSessionCreateInfo +typedef struct XrHolographicWindowAttachmentMSFT { + XrStructureType type; + const void* XR_MAY_ALIAS next; + IUnknown* holographicSpace; + IUnknown* coreWindow; +} XrHolographicWindowAttachmentMSFT; +#endif // XR_USE_PLATFORM_WIN32 + +#endif /* XR_USE_PLATFORM_WIN32 */ + +#ifdef XR_USE_PLATFORM_ANDROID + +#define XR_FB_android_surface_swapchain_create 1 +#define XR_FB_android_surface_swapchain_create_SPEC_VERSION 1 +#define XR_FB_ANDROID_SURFACE_SWAPCHAIN_CREATE_EXTENSION_NAME "XR_FB_android_surface_swapchain_create" +typedef XrFlags64 XrAndroidSurfaceSwapchainFlagsFB; + +// Flag bits for XrAndroidSurfaceSwapchainFlagsFB +static const XrAndroidSurfaceSwapchainFlagsFB XR_ANDROID_SURFACE_SWAPCHAIN_SYNCHRONOUS_BIT_FB = 0x00000001; +static const XrAndroidSurfaceSwapchainFlagsFB XR_ANDROID_SURFACE_SWAPCHAIN_USE_TIMESTAMPS_BIT_FB = 0x00000002; + +#ifdef XR_USE_PLATFORM_ANDROID +// XrAndroidSurfaceSwapchainCreateInfoFB extends XrSwapchainCreateInfo +typedef struct XrAndroidSurfaceSwapchainCreateInfoFB { + XrStructureType type; + const void* XR_MAY_ALIAS next; + XrAndroidSurfaceSwapchainFlagsFB createFlags; +} XrAndroidSurfaceSwapchainCreateInfoFB; +#endif // XR_USE_PLATFORM_ANDROID + +#endif /* XR_USE_PLATFORM_ANDROID */ + +#ifdef XR_USE_PLATFORM_ML + +#define XR_ML_compat 1 +#define XR_ML_compat_SPEC_VERSION 1 +#define XR_ML_COMPAT_EXTENSION_NAME "XR_ML_compat" +typedef struct XrCoordinateSpaceCreateInfoML { + XrStructureType type; + const void* XR_MAY_ALIAS next; + MLCoordinateFrameUID cfuid; + XrPosef poseInCoordinateSpace; +} XrCoordinateSpaceCreateInfoML; + +typedef XrResult (XRAPI_PTR *PFN_xrCreateSpaceFromCoordinateFrameUIDML)(XrSession session, const XrCoordinateSpaceCreateInfoML *createInfo, XrSpace* space); + +#ifndef XR_NO_PROTOTYPES +#ifdef XR_EXTENSION_PROTOTYPES +XRAPI_ATTR XrResult XRAPI_CALL xrCreateSpaceFromCoordinateFrameUIDML( + XrSession session, + const XrCoordinateSpaceCreateInfoML * createInfo, + XrSpace* space); +#endif /* XR_EXTENSION_PROTOTYPES */ +#endif /* !XR_NO_PROTOTYPES */ +#endif /* XR_USE_PLATFORM_ML */ + +#ifdef XR_USE_PLATFORM_WIN32 + +#define XR_OCULUS_audio_device_guid 1 +#define XR_OCULUS_audio_device_guid_SPEC_VERSION 1 +#define XR_OCULUS_AUDIO_DEVICE_GUID_EXTENSION_NAME "XR_OCULUS_audio_device_guid" +#define XR_MAX_AUDIO_DEVICE_STR_SIZE_OCULUS 128 +typedef XrResult (XRAPI_PTR *PFN_xrGetAudioOutputDeviceGuidOculus)(XrInstance instance, wchar_t buffer[XR_MAX_AUDIO_DEVICE_STR_SIZE_OCULUS]); +typedef XrResult (XRAPI_PTR *PFN_xrGetAudioInputDeviceGuidOculus)(XrInstance instance, wchar_t buffer[XR_MAX_AUDIO_DEVICE_STR_SIZE_OCULUS]); + +#ifndef XR_NO_PROTOTYPES +#ifdef XR_EXTENSION_PROTOTYPES +XRAPI_ATTR XrResult XRAPI_CALL xrGetAudioOutputDeviceGuidOculus( + XrInstance instance, + wchar_t buffer[XR_MAX_AUDIO_DEVICE_STR_SIZE_OCULUS]); + +XRAPI_ATTR XrResult XRAPI_CALL xrGetAudioInputDeviceGuidOculus( + XrInstance instance, + wchar_t buffer[XR_MAX_AUDIO_DEVICE_STR_SIZE_OCULUS]); +#endif /* XR_EXTENSION_PROTOTYPES */ +#endif /* !XR_NO_PROTOTYPES */ +#endif /* XR_USE_PLATFORM_WIN32 */ + +#ifdef XR_USE_GRAPHICS_API_VULKAN + +#define XR_FB_foveation_vulkan 1 +#define XR_FB_foveation_vulkan_SPEC_VERSION 1 +#define XR_FB_FOVEATION_VULKAN_EXTENSION_NAME "XR_FB_foveation_vulkan" +// XrSwapchainImageFoveationVulkanFB extends XrSwapchainImageVulkanKHR +typedef struct XrSwapchainImageFoveationVulkanFB { + XrStructureType type; + void* XR_MAY_ALIAS next; + VkImage image; + uint32_t width; + uint32_t height; +} XrSwapchainImageFoveationVulkanFB; + +#endif /* XR_USE_GRAPHICS_API_VULKAN */ + +#ifdef XR_USE_PLATFORM_ANDROID + +#define XR_FB_swapchain_update_state_android_surface 1 +#define XR_FB_swapchain_update_state_android_surface_SPEC_VERSION 1 +#define XR_FB_SWAPCHAIN_UPDATE_STATE_ANDROID_SURFACE_EXTENSION_NAME "XR_FB_swapchain_update_state_android_surface" +#ifdef XR_USE_PLATFORM_ANDROID +typedef struct XrSwapchainStateAndroidSurfaceDimensionsFB { + XrStructureType type; + void* XR_MAY_ALIAS next; + uint32_t width; + uint32_t height; +} XrSwapchainStateAndroidSurfaceDimensionsFB; +#endif // XR_USE_PLATFORM_ANDROID + +#endif /* XR_USE_PLATFORM_ANDROID */ + +#ifdef XR_USE_GRAPHICS_API_OPENGL_ES + +#define XR_FB_swapchain_update_state_opengl_es 1 +#define XR_FB_swapchain_update_state_opengl_es_SPEC_VERSION 1 +#define XR_FB_SWAPCHAIN_UPDATE_STATE_OPENGL_ES_EXTENSION_NAME "XR_FB_swapchain_update_state_opengl_es" +#ifdef XR_USE_GRAPHICS_API_OPENGL_ES +typedef struct XrSwapchainStateSamplerOpenGLESFB { + XrStructureType type; + void* XR_MAY_ALIAS next; + EGLenum minFilter; + EGLenum magFilter; + EGLenum wrapModeS; + EGLenum wrapModeT; + EGLenum swizzleRed; + EGLenum swizzleGreen; + EGLenum swizzleBlue; + EGLenum swizzleAlpha; + float maxAnisotropy; + XrColor4f borderColor; +} XrSwapchainStateSamplerOpenGLESFB; +#endif // XR_USE_GRAPHICS_API_OPENGL_ES + +#endif /* XR_USE_GRAPHICS_API_OPENGL_ES */ + +#ifdef XR_USE_GRAPHICS_API_VULKAN + +#define XR_FB_swapchain_update_state_vulkan 1 +#define XR_FB_swapchain_update_state_vulkan_SPEC_VERSION 1 +#define XR_FB_SWAPCHAIN_UPDATE_STATE_VULKAN_EXTENSION_NAME "XR_FB_swapchain_update_state_vulkan" +#ifdef XR_USE_GRAPHICS_API_VULKAN +typedef struct XrSwapchainStateSamplerVulkanFB { + XrStructureType type; + void* XR_MAY_ALIAS next; + VkFilter minFilter; + VkFilter magFilter; + VkSamplerMipmapMode mipmapMode; + VkSamplerAddressMode wrapModeS; + VkSamplerAddressMode wrapModeT; + VkComponentSwizzle swizzleRed; + VkComponentSwizzle swizzleGreen; + VkComponentSwizzle swizzleBlue; + VkComponentSwizzle swizzleAlpha; + float maxAnisotropy; + XrColor4f borderColor; +} XrSwapchainStateSamplerVulkanFB; +#endif // XR_USE_GRAPHICS_API_VULKAN + +#endif /* XR_USE_GRAPHICS_API_VULKAN */ + +#ifdef XR_USE_GRAPHICS_API_VULKAN + +#define XR_META_vulkan_swapchain_create_info 1 +#define XR_META_vulkan_swapchain_create_info_SPEC_VERSION 1 +#define XR_META_VULKAN_SWAPCHAIN_CREATE_INFO_EXTENSION_NAME "XR_META_vulkan_swapchain_create_info" +// XrVulkanSwapchainCreateInfoMETA extends XrSwapchainCreateInfo +typedef struct XrVulkanSwapchainCreateInfoMETA { + XrStructureType type; + const void* XR_MAY_ALIAS next; + VkImageCreateFlags additionalCreateFlags; + VkImageUsageFlags additionalUsageFlags; +} XrVulkanSwapchainCreateInfoMETA; + +#endif /* XR_USE_GRAPHICS_API_VULKAN */ + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/third_party/openxr/openxr_platform_defines.h b/third_party/openxr/openxr_platform_defines.h new file mode 100644 index 0000000..820b7b3 --- /dev/null +++ b/third_party/openxr/openxr_platform_defines.h @@ -0,0 +1,114 @@ +/* +** Copyright (c) 2017-2023, The Khronos Group Inc. +** +** SPDX-License-Identifier: Apache-2.0 OR MIT +*/ + +#ifndef OPENXR_PLATFORM_DEFINES_H_ +#define OPENXR_PLATFORM_DEFINES_H_ 1 + +#ifdef __cplusplus +extern "C" { +#endif + +/* Platform-specific calling convention macros. + * + * Platforms should define these so that OpenXR clients call OpenXR functions + * with the same calling conventions that the OpenXR implementation expects. + * + * XRAPI_ATTR - Placed before the return type in function declarations. + * Useful for C++11 and GCC/Clang-style function attribute syntax. + * XRAPI_CALL - Placed after the return type in function declarations. + * Useful for MSVC-style calling convention syntax. + * XRAPI_PTR - Placed between the '(' and '*' in function pointer types. + * + * Function declaration: XRAPI_ATTR void XRAPI_CALL xrFunction(void); + * Function pointer type: typedef void (XRAPI_PTR *PFN_xrFunction)(void); + */ +#if defined(_WIN32) +#define XRAPI_ATTR +// On Windows, functions use the stdcall convention +#define XRAPI_CALL __stdcall +#define XRAPI_PTR XRAPI_CALL +#elif defined(__ANDROID__) && defined(__ARM_ARCH) && __ARM_ARCH < 7 +#error "API not supported for the 'armeabi' NDK ABI" +#elif defined(__ANDROID__) && defined(__ARM_ARCH) && __ARM_ARCH >= 7 && defined(__ARM_32BIT_STATE) +// On Android 32-bit ARM targets, functions use the "hardfloat" +// calling convention, i.e. float parameters are passed in registers. This +// is true even if the rest of the application passes floats on the stack, +// as it does by default when compiling for the armeabi-v7a NDK ABI. +#define XRAPI_ATTR __attribute__((pcs("aapcs-vfp"))) +#define XRAPI_CALL +#define XRAPI_PTR XRAPI_ATTR +#else +// On other platforms, use the default calling convention +#define XRAPI_ATTR +#define XRAPI_CALL +#define XRAPI_PTR +#endif + +#include + +#if !defined(XR_NO_STDINT_H) +#if defined(_MSC_VER) && (_MSC_VER < 1600) +typedef signed __int8 int8_t; +typedef unsigned __int8 uint8_t; +typedef signed __int16 int16_t; +typedef unsigned __int16 uint16_t; +typedef signed __int32 int32_t; +typedef unsigned __int32 uint32_t; +typedef signed __int64 int64_t; +typedef unsigned __int64 uint64_t; +#else +#include +#endif +#endif // !defined( XR_NO_STDINT_H ) + +// XR_PTR_SIZE (in bytes) +#if (defined(__LP64__) || defined(_WIN64) || (defined(__x86_64__) && !defined(__ILP32__) ) || defined(_M_X64) || defined(__ia64) || defined(_M_IA64) || defined(__aarch64__) || defined(__powerpc64__)) +#define XR_PTR_SIZE 8 +#else +#define XR_PTR_SIZE 4 +#endif + +// Needed so we can use clang __has_feature portably. +#if !defined(XR_COMPILER_HAS_FEATURE) +#if defined(__clang__) +#define XR_COMPILER_HAS_FEATURE(x) __has_feature(x) +#else +#define XR_COMPILER_HAS_FEATURE(x) 0 +#endif +#endif + +// Identifies if the current compiler has C++11 support enabled. +// Does not by itself identify if any given C++11 feature is present. +#if !defined(XR_CPP11_ENABLED) && defined(__cplusplus) +#if defined(__GNUC__) && defined(__GXX_EXPERIMENTAL_CXX0X__) +#define XR_CPP11_ENABLED 1 +#elif defined(_MSC_VER) && (_MSC_VER >= 1600) +#define XR_CPP11_ENABLED 1 +#elif (__cplusplus >= 201103L) // 201103 is the first C++11 version. +#define XR_CPP11_ENABLED 1 +#endif +#endif + +// Identifies if the current compiler supports C++11 nullptr. +#if !defined(XR_CPP_NULLPTR_SUPPORTED) +#if defined(XR_CPP11_ENABLED) && \ + ((defined(__clang__) && XR_COMPILER_HAS_FEATURE(cxx_nullptr)) || \ + (defined(__GNUC__) && (((__GNUC__ * 1000) + __GNUC_MINOR__) >= 4006)) || \ + (defined(_MSC_VER) && (_MSC_VER >= 1600)) || \ + (defined(__EDG_VERSION__) && (__EDG_VERSION__ >= 403))) +#define XR_CPP_NULLPTR_SUPPORTED 1 +#endif +#endif + +#if !defined(XR_CPP_NULLPTR_SUPPORTED) +#define XR_CPP_NULLPTR_SUPPORTED 0 +#endif // !defined(XR_CPP_NULLPTR_SUPPORTED) + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/tools/configurator/ConfiguratorMain.cpp b/tools/configurator/ConfiguratorMain.cpp new file mode 100644 index 0000000..1241e7b --- /dev/null +++ b/tools/configurator/ConfiguratorMain.cpp @@ -0,0 +1,254 @@ +// OpenXR Simulator configurator. +// +// A small GLFW + Dear ImGui tool that edits the runtime's JSON config file. The runtime DLL reads +// the same file (resolved via XRSIM_CONFIG, else /openxr_simulator_config.json). + +#define GLFW_INCLUDE_NONE +#ifdef _WIN32 +# ifndef WIN32_LEAN_AND_MEAN +# define WIN32_LEAN_AND_MEAN +# endif +# include +#endif +#include + +#include + +#include "imgui.h" +#include "imgui_impl_glfw.h" +#include "imgui_impl_opengl3.h" + +#include "Config.h" +#include "HeadsetPresets.h" + +#include +#include + +namespace +{ + int PresentModeIndex( xrsim::PresentMode mode ) + { + switch ( mode ) + { + case xrsim::PresentMode::Mailbox: return 0; + case xrsim::PresentMode::Immediate: return 1; + case xrsim::PresentMode::Fifo: return 2; + } + return 0; + } + + int DisplayModeIndex( xrsim::DisplayMode mode ) + { + switch ( mode ) + { + case xrsim::DisplayMode::SideBySide: return 0; + case xrsim::DisplayMode::SingleEyeLeft: return 1; + case xrsim::DisplayMode::SingleEyeRight: return 2; + } + return 0; + } +} // namespace + +int main( int, char ** ) +{ + if ( glfwInit() != GLFW_TRUE ) + { + return 1; + } + + const char * glslVersion = "#version 130"; + glfwWindowHint( GLFW_CONTEXT_VERSION_MAJOR, 3 ); + glfwWindowHint( GLFW_CONTEXT_VERSION_MINOR, 0 ); + + GLFWwindow * window = + glfwCreateWindow( 920, 720, "OpenXR Simulator Configurator", nullptr, nullptr ); + if ( window == nullptr ) + { + glfwTerminate(); + return 1; + } + glfwMakeContextCurrent( window ); + glfwSwapInterval( 1 ); + + IMGUI_CHECKVERSION(); + ImGui::CreateContext(); + ImGui::StyleColorsDark(); + ImGui_ImplGlfw_InitForOpenGL( window, true ); + ImGui_ImplOpenGL3_Init( glslVersion ); + + std::string configPath = xrsim::SimulatorConfig::ResolvePath(); + xrsim::SimulatorConfig config = xrsim::SimulatorConfig::LoadFrom( configPath ); + std::string status; + + while ( glfwWindowShouldClose( window ) == 0 ) + { + glfwPollEvents(); + + ImGui_ImplOpenGL3_NewFrame(); + ImGui_ImplGlfw_NewFrame(); + ImGui::NewFrame(); + + const ImGuiViewport * viewport = ImGui::GetMainViewport(); + ImGui::SetNextWindowPos( viewport->WorkPos ); + ImGui::SetNextWindowSize( viewport->WorkSize ); + ImGui::Begin( + "OpenXR Simulator Config", nullptr, + ImGuiWindowFlags_NoDecoration | ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoResize + ); + + ImGui::TextWrapped( + "These settings are read by openxr_simulator.dll at runtime startup. Restart the " + "application after saving." + ); + ImGui::Separator(); + + static char pathBuffer[1024] = {}; + if ( pathBuffer[0] == '\0' ) + { + std::strncpy( pathBuffer, configPath.c_str(), sizeof( pathBuffer ) - 1 ); + } + if ( ImGui::InputText( "Config path", pathBuffer, sizeof( pathBuffer ) ) ) + { + configPath = pathBuffer; + } + + if ( ImGui::Button( "Reload" ) ) + { + config = xrsim::SimulatorConfig::LoadFrom( configPath ); + status = "Reloaded."; + } + ImGui::SameLine(); + if ( ImGui::Button( "Save" ) ) + { + status = config.Save( configPath ) ? "Saved." : "Failed to save!"; + } + ImGui::SameLine(); + if ( ImGui::Button( "Reset to defaults" ) ) + { + config = xrsim::SimulatorConfig{}; + status = "Reset to defaults (not saved yet)."; + } + if ( !status.empty() ) + { + ImGui::SameLine(); + ImGui::TextColored( ImVec4( 0.5f, 0.9f, 0.5f, 1.0f ), "%s", status.c_str() ); + } + + ImGui::Separator(); + { + constexpr int presetCount = static_cast( xrsim::kHeadsetPresets.size() ); + static const char * presetItems[presetCount + 1] = {}; + if ( presetItems[0] == nullptr ) + { + presetItems[0] = "Custom"; + for ( int i = 0; i < presetCount; ++i ) + { + presetItems[i + 1] = xrsim::kHeadsetPresets[i].name; + } + } + + static int presetIndex = 0; + if ( ImGui::Combo( "Headset preset", &presetIndex, presetItems, presetCount + 1 ) && + presetIndex > 0 ) + { + const xrsim::HeadsetPreset & preset = xrsim::kHeadsetPresets[presetIndex - 1]; + config.systemName = preset.name; + config.eyeWidth = preset.eyeWidth; + config.eyeHeight = preset.eyeHeight; + config.refreshRateHz = preset.refreshRateHz; + config.fovLeftDeg = preset.fovLeftDeg; + config.fovRightDeg = preset.fovRightDeg; + config.fovUpDeg = preset.fovUpDeg; + config.fovDownDeg = preset.fovDownDeg; + config.ipdMeters = preset.ipdMeters; + status = std::string( "Applied preset: " ) + preset.name; + } + } + ImGui::Separator(); + if ( ImGui::CollapsingHeader( "Headset", ImGuiTreeNodeFlags_DefaultOpen ) ) + { + char nameBuffer[256]; + std::strncpy( nameBuffer, config.systemName.c_str(), sizeof( nameBuffer ) - 1 ); + nameBuffer[sizeof( nameBuffer ) - 1] = '\0'; + if ( ImGui::InputText( "System name", nameBuffer, sizeof( nameBuffer ) ) ) + { + config.systemName = nameBuffer; + } + ImGui::InputScalar( "Vendor id", ImGuiDataType_U32, &config.vendorId ); + } + + if ( ImGui::CollapsingHeader( "Display", ImGuiTreeNodeFlags_DefaultOpen ) ) + { + ImGui::InputScalar( "Eye width", ImGuiDataType_U32, &config.eyeWidth ); + ImGui::InputScalar( "Eye height", ImGuiDataType_U32, &config.eyeHeight ); + ImGui::InputScalar( "Refresh rate (Hz)", ImGuiDataType_U32, &config.refreshRateHz ); + ImGui::SliderFloat( "IPD (m)", &config.ipdMeters, 0.04f, 0.09f, "%.3f" ); + ImGui::InputScalar( "Swapchain images", ImGuiDataType_U32, &config.swapchainImageCount ); + } + + if ( ImGui::CollapsingHeader( "Field of view (half-angle degrees)", ImGuiTreeNodeFlags_DefaultOpen ) ) + { + ImGui::SliderFloat( "Left", &config.fovLeftDeg, 20.0f, 80.0f, "%.1f" ); + ImGui::SliderFloat( "Right", &config.fovRightDeg, 20.0f, 80.0f, "%.1f" ); + ImGui::SliderFloat( "Up", &config.fovUpDeg, 20.0f, 80.0f, "%.1f" ); + ImGui::SliderFloat( "Down", &config.fovDownDeg, 20.0f, 80.0f, "%.1f" ); + if ( ImGui::Button( "Symmetric" ) ) + { + config.fovRightDeg = config.fovLeftDeg; + config.fovUpDeg = config.fovLeftDeg; + config.fovDownDeg = config.fovLeftDeg; + } + } + + if ( ImGui::CollapsingHeader( "Compositor window", ImGuiTreeNodeFlags_DefaultOpen ) ) + { + char titleBuffer[256]; + std::strncpy( titleBuffer, config.windowTitle.c_str(), sizeof( titleBuffer ) - 1 ); + titleBuffer[sizeof( titleBuffer ) - 1] = '\0'; + if ( ImGui::InputText( "Window title", titleBuffer, sizeof( titleBuffer ) ) ) + { + config.windowTitle = titleBuffer; + } + ImGui::InputInt( "Window width", &config.windowWidth ); + ImGui::InputInt( "Window height", &config.windowHeight ); + + int presentIndex = PresentModeIndex( config.presentMode ); + const char * presentItems[] = { "Mailbox (uncapped)", "Immediate (uncapped, tearing)", + "FIFO (vsync)" }; + if ( ImGui::Combo( "Present mode", &presentIndex, presentItems, IM_ARRAYSIZE( presentItems ) ) ) + { + config.presentMode = static_cast( presentIndex ); + } + + int displayIndex = DisplayModeIndex( config.displayMode ); + const char * displayItems[] = { "Side by side", "Single eye (left)", "Single eye (right)" }; + if ( ImGui::Combo( "Display mode", &displayIndex, displayItems, IM_ARRAYSIZE( displayItems ) ) ) + { + config.displayMode = static_cast( displayIndex ); + } + } + + ImGui::Separator(); + ImGui::TextDisabled( + "Note: 'Mailbox' avoids capping the application to the monitor refresh rate." + ); + + ImGui::End(); + + ImGui::Render(); + int displayWidth = 0, displayHeight = 0; + glfwGetFramebufferSize( window, &displayWidth, &displayHeight ); + glViewport( 0, 0, displayWidth, displayHeight ); + glClearColor( 0.10f, 0.10f, 0.12f, 1.0f ); + glClear( GL_COLOR_BUFFER_BIT ); + ImGui_ImplOpenGL3_RenderDrawData( ImGui::GetDrawData() ); + glfwSwapBuffers( window ); + } + + ImGui_ImplOpenGL3_Shutdown(); + ImGui_ImplGlfw_Shutdown(); + ImGui::DestroyContext(); + glfwDestroyWindow( window ); + glfwTerminate(); + return 0; +}