diff --git a/COPYRIGHT.txt b/COPYRIGHT.txt
index 368e321a2d..df1ab0c849 100644
--- a/COPYRIGHT.txt
+++ b/COPYRIGHT.txt
@@ -361,12 +361,16 @@ Comment: Multi-channel signed distance field generator
Copyright: 2016, Viktor Chlumsky
License: MIT
-
Files: ./thirdparty/oidn/
Comment: Intel Open Image Denoise
Copyright: 2009-2019, Intel Corporation
License: Apache-2.0
+Files: ./thirdparty/openxr/
+Comment: OpenXR Loader
+Copyright: 2020-2022, The Khronos Group Inc.
+License: Apache-2.0
+
Files: ./thirdparty/pcre2/
Comment: PCRE2
Copyright: 1997-2021, University of Cambridge
diff --git a/SConstruct b/SConstruct
index a27e5490a5..233a79f635 100644
--- a/SConstruct
+++ b/SConstruct
@@ -173,6 +173,7 @@ opts.Add(BoolVariable("minizip", "Enable ZIP archive support using minizip", Tru
opts.Add(BoolVariable("xaudio2", "Enable the XAudio2 audio driver", False))
opts.Add(BoolVariable("vulkan", "Enable the vulkan video driver", True))
opts.Add(BoolVariable("opengl3", "Enable the OpenGL/GLES3 video driver", True))
+opts.Add(BoolVariable("openxr", "Enable the OpenXR driver", True))
opts.Add("custom_modules", "A list of comma-separated directory paths containing custom modules to build.", "")
opts.Add(BoolVariable("custom_modules_recursive", "Detect custom modules recursively for each specified path.", True))
opts.Add(BoolVariable("use_volk", "Use the volk library to load the Vulkan loader dynamically", True))
diff --git a/doc/classes/ProjectSettings.xml b/doc/classes/ProjectSettings.xml
index da35b3260e..a3810bb575 100644
--- a/doc/classes/ProjectSettings.xml
+++ b/doc/classes/ProjectSettings.xml
@@ -1915,8 +1915,23 @@
-
- If [code]true[/code], XR support is enabled in Godot, this ensures required shaders are compiled.
+
+ Action map configuration to load by default.
+
+
+ If [code]true[/code] Godot will setup and initialise OpenXR on startup.
+
+
+ Specify whether OpenXR should be configured for an HMD or a hand held device.
+
+
+ Specify the default reference space.
+
+
+ Specify the view configuration with which to configure OpenXR settting up either Mono or Stereo rendering.
+
+
+ If [code]true[/code], Godot will compile shaders required for XR.
diff --git a/doc/classes/XRController3D.xml b/doc/classes/XRController3D.xml
index a77f8cf9ca..deea888b8f 100644
--- a/doc/classes/XRController3D.xml
+++ b/doc/classes/XRController3D.xml
@@ -41,12 +41,6 @@
-
-
- The degree to which the controller vibrates. Ranges from [code]0.0[/code] to [code]1.0[/code] with precision [code].01[/code]. If changed, updates [member XRPositionalTracker.rumble] accordingly.
- This is a useful property to animate if you want the controller to vibrate for a limited duration.
-
-
diff --git a/doc/classes/XRPositionalTracker.xml b/doc/classes/XRPositionalTracker.xml
index c544ef3cfa..da378759d8 100644
--- a/doc/classes/XRPositionalTracker.xml
+++ b/doc/classes/XRPositionalTracker.xml
@@ -72,9 +72,6 @@
- [code]left_hand[/code] identifies the controller held in the players left hand
- [code]right_hand[/code] identifies the controller held in the players right hand
-
- The degree to which the tracker rumbles. Ranges from [code]0.0[/code] to [code]1.0[/code] with precision [code].01[/code].
-
The type of tracker.
diff --git a/drivers/vulkan/rendering_device_vulkan.cpp b/drivers/vulkan/rendering_device_vulkan.cpp
index ddeac220ec..cda8871f3e 100644
--- a/drivers/vulkan/rendering_device_vulkan.cpp
+++ b/drivers/vulkan/rendering_device_vulkan.cpp
@@ -2118,6 +2118,124 @@ RID RenderingDeviceVulkan::texture_create_shared(const TextureView &p_view, RID
return id;
}
+RID RenderingDeviceVulkan::texture_create_from_extension(TextureType p_type, DataFormat p_format, TextureSamples p_samples, uint64_t p_flags, uint64_t p_image, uint64_t p_width, uint64_t p_height, uint64_t p_depth, uint64_t p_layers) {
+ _THREAD_SAFE_METHOD_
+ // This method creates a texture object using a VkImage created by an extension, module or other external source (OpenXR uses this).
+ VkImage image = (VkImage)p_image;
+
+ Texture texture;
+ texture.image = image;
+ // if we leave texture.allocation as a nullptr, would that be enough to detect we don't "own" the image?
+ // also leave texture.allocation_info alone
+ // we'll set texture.view later on
+ texture.type = p_type;
+ texture.format = p_format;
+ texture.samples = p_samples;
+ texture.width = p_width;
+ texture.height = p_height;
+ texture.depth = p_depth;
+ texture.layers = p_layers;
+ texture.mipmaps = 0; // maybe make this settable too?
+ texture.usage_flags = p_flags;
+ texture.base_mipmap = 0;
+ texture.base_layer = 0;
+ texture.allowed_shared_formats.push_back(RD::DATA_FORMAT_R8G8B8A8_UNORM);
+ texture.allowed_shared_formats.push_back(RD::DATA_FORMAT_R8G8B8A8_SRGB);
+
+ // Do we need to do something with texture.layout ?
+
+ if (texture.usage_flags & TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) {
+ texture.read_aspect_mask = VK_IMAGE_ASPECT_DEPTH_BIT;
+ texture.barrier_aspect_mask = VK_IMAGE_ASPECT_DEPTH_BIT;
+
+ // if (format_has_stencil(p_format.format)) {
+ // texture.barrier_aspect_mask |= VK_IMAGE_ASPECT_STENCIL_BIT;
+ // }
+ } else {
+ texture.read_aspect_mask = VK_IMAGE_ASPECT_COLOR_BIT;
+ texture.barrier_aspect_mask = VK_IMAGE_ASPECT_COLOR_BIT;
+ }
+
+ // Create a view for us to use
+
+ VkImageViewCreateInfo image_view_create_info;
+ image_view_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
+ image_view_create_info.pNext = nullptr;
+ image_view_create_info.flags = 0;
+ image_view_create_info.image = texture.image;
+
+ static const VkImageViewType view_types[TEXTURE_TYPE_MAX] = {
+ VK_IMAGE_VIEW_TYPE_1D,
+ VK_IMAGE_VIEW_TYPE_2D,
+ VK_IMAGE_VIEW_TYPE_3D,
+ VK_IMAGE_VIEW_TYPE_CUBE,
+ VK_IMAGE_VIEW_TYPE_1D_ARRAY,
+ VK_IMAGE_VIEW_TYPE_2D_ARRAY,
+ VK_IMAGE_VIEW_TYPE_CUBE_ARRAY,
+ };
+
+ image_view_create_info.viewType = view_types[texture.type];
+ image_view_create_info.format = vulkan_formats[texture.format];
+
+ static const VkComponentSwizzle component_swizzles[TEXTURE_SWIZZLE_MAX] = {
+ VK_COMPONENT_SWIZZLE_IDENTITY,
+ VK_COMPONENT_SWIZZLE_ZERO,
+ VK_COMPONENT_SWIZZLE_ONE,
+ VK_COMPONENT_SWIZZLE_R,
+ VK_COMPONENT_SWIZZLE_G,
+ VK_COMPONENT_SWIZZLE_B,
+ VK_COMPONENT_SWIZZLE_A
+ };
+
+ // hardcode for now, maybe make this settable from outside..
+ image_view_create_info.components.r = component_swizzles[TEXTURE_SWIZZLE_R];
+ image_view_create_info.components.g = component_swizzles[TEXTURE_SWIZZLE_G];
+ image_view_create_info.components.b = component_swizzles[TEXTURE_SWIZZLE_B];
+ image_view_create_info.components.a = component_swizzles[TEXTURE_SWIZZLE_A];
+
+ image_view_create_info.subresourceRange.baseMipLevel = 0;
+ image_view_create_info.subresourceRange.levelCount = texture.mipmaps;
+ image_view_create_info.subresourceRange.baseArrayLayer = 0;
+ image_view_create_info.subresourceRange.layerCount = texture.layers;
+ if (texture.usage_flags & TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) {
+ image_view_create_info.subresourceRange.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT;
+ } else {
+ image_view_create_info.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
+ }
+
+ VkResult err = vkCreateImageView(device, &image_view_create_info, nullptr, &texture.view);
+
+ if (err) {
+ // vmaDestroyImage(allocator, texture.image, texture.allocation);
+ ERR_FAIL_V_MSG(RID(), "vkCreateImageView failed with error " + itos(err) + ".");
+ }
+
+ //barrier to set layout
+ {
+ VkImageMemoryBarrier image_memory_barrier;
+ image_memory_barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
+ image_memory_barrier.pNext = nullptr;
+ image_memory_barrier.srcAccessMask = 0;
+ image_memory_barrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT;
+ image_memory_barrier.oldLayout = VK_IMAGE_LAYOUT_UNDEFINED;
+ image_memory_barrier.newLayout = texture.layout;
+ image_memory_barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
+ image_memory_barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
+ image_memory_barrier.image = texture.image;
+ image_memory_barrier.subresourceRange.aspectMask = texture.barrier_aspect_mask;
+ image_memory_barrier.subresourceRange.baseMipLevel = 0;
+ image_memory_barrier.subresourceRange.levelCount = texture.mipmaps;
+ image_memory_barrier.subresourceRange.baseArrayLayer = 0;
+ image_memory_barrier.subresourceRange.layerCount = texture.layers;
+
+ vkCmdPipelineBarrier(frames[frame].setup_command_buffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_VERTEX_SHADER_BIT | VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT | VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, 0, 0, nullptr, 0, nullptr, 1, &image_memory_barrier);
+ }
+
+ RID id = texture_owner.make_rid(texture);
+
+ return id;
+}
+
RID RenderingDeviceVulkan::texture_create_shared_from_slice(const TextureView &p_view, RID p_with_texture, uint32_t p_layer, uint32_t p_mipmap, uint32_t p_mipmaps, TextureSliceType p_slice_type) {
_THREAD_SAFE_METHOD_
diff --git a/drivers/vulkan/rendering_device_vulkan.h b/drivers/vulkan/rendering_device_vulkan.h
index 6510893196..3e4327667b 100644
--- a/drivers/vulkan/rendering_device_vulkan.h
+++ b/drivers/vulkan/rendering_device_vulkan.h
@@ -1037,6 +1037,7 @@ class RenderingDeviceVulkan : public RenderingDevice {
public:
virtual RID texture_create(const TextureFormat &p_format, const TextureView &p_view, const Vector> &p_data = Vector>());
virtual RID texture_create_shared(const TextureView &p_view, RID p_with_texture);
+ virtual RID texture_create_from_extension(TextureType p_type, DataFormat p_format, TextureSamples p_samples, uint64_t p_flags, uint64_t p_image, uint64_t p_width, uint64_t p_height, uint64_t p_depth, uint64_t p_layers);
virtual RID texture_create_shared_from_slice(const TextureView &p_view, RID p_with_texture, uint32_t p_layer, uint32_t p_mipmap, uint32_t p_mipmaps = 1, TextureSliceType p_slice_type = TEXTURE_SLICE_2D);
virtual Error texture_update(RID p_texture, uint32_t p_layer, const Vector &p_data, uint32_t p_post_barrier = BARRIER_MASK_ALL);
diff --git a/drivers/vulkan/vulkan_context.cpp b/drivers/vulkan/vulkan_context.cpp
index e4aab8d868..3551b5d6c4 100644
--- a/drivers/vulkan/vulkan_context.cpp
+++ b/drivers/vulkan/vulkan_context.cpp
@@ -46,6 +46,8 @@
#define ARRAY_SIZE(a) (sizeof(a) / sizeof(a[0]))
#define APP_SHORT_NAME "GodotEngine"
+VulkanHooks *VulkanContext::vulkan_hooks = nullptr;
+
VKAPI_ATTR VkBool32 VKAPI_CALL VulkanContext::_debug_messenger_callback(
VkDebugUtilsMessageSeverityFlagBitsEXT messageSeverity,
VkDebugUtilsMessageTypeFlagsEXT messageType,
@@ -695,19 +697,27 @@ Error VulkanContext::_create_instance() {
inst_info.pNext = &dbg_report_callback_create_info;
}
- VkResult err = vkCreateInstance(&inst_info, nullptr, &inst);
- ERR_FAIL_COND_V_MSG(err == VK_ERROR_INCOMPATIBLE_DRIVER, ERR_CANT_CREATE,
- "Cannot find a compatible Vulkan installable client driver (ICD).\n\n"
- "vkCreateInstance Failure");
- ERR_FAIL_COND_V_MSG(err == VK_ERROR_EXTENSION_NOT_PRESENT, ERR_CANT_CREATE,
- "Cannot find a specified extension library.\n"
- "Make sure your layers path is set appropriately.\n"
- "vkCreateInstance Failure");
- ERR_FAIL_COND_V_MSG(err, ERR_CANT_CREATE,
- "vkCreateInstance failed.\n\n"
- "Do you have a compatible Vulkan installable client driver (ICD) installed?\n"
- "Please look at the Getting Started guide for additional information.\n"
- "vkCreateInstance Failure");
+ VkResult err;
+
+ if (vulkan_hooks) {
+ if (!vulkan_hooks->create_vulkan_instance(&inst_info, &inst)) {
+ return ERR_CANT_CREATE;
+ }
+ } else {
+ err = vkCreateInstance(&inst_info, nullptr, &inst);
+ ERR_FAIL_COND_V_MSG(err == VK_ERROR_INCOMPATIBLE_DRIVER, ERR_CANT_CREATE,
+ "Cannot find a compatible Vulkan installable client driver (ICD).\n\n"
+ "vkCreateInstance Failure");
+ ERR_FAIL_COND_V_MSG(err == VK_ERROR_EXTENSION_NOT_PRESENT, ERR_CANT_CREATE,
+ "Cannot find a specified extension library.\n"
+ "Make sure your layers path is set appropriately.\n"
+ "vkCreateInstance Failure");
+ ERR_FAIL_COND_V_MSG(err, ERR_CANT_CREATE,
+ "vkCreateInstance failed.\n\n"
+ "Do you have a compatible Vulkan installable client driver (ICD) installed?\n"
+ "Please look at the Getting Started guide for additional information.\n"
+ "vkCreateInstance Failure");
+ }
inst_initialized = true;
@@ -820,107 +830,122 @@ Error VulkanContext::_create_physical_device(VkSurfaceKHR p_surface) {
{ 0, nullptr },
};
- // TODO: At least on Linux Laptops integrated GPUs fail with Vulkan in many instances.
- // The device should really be a preference, but for now choosing a discrete GPU over the
- // integrated one is better than the default.
-
int32_t device_index = -1;
- int type_selected = -1;
- print_verbose("Vulkan devices:");
- for (uint32_t i = 0; i < gpu_count; ++i) {
- VkPhysicalDeviceProperties props;
- vkGetPhysicalDeviceProperties(physical_devices[i], &props);
-
- bool present_supported = false;
-
- uint32_t device_queue_family_count = 0;
- vkGetPhysicalDeviceQueueFamilyProperties(physical_devices[i], &device_queue_family_count, nullptr);
- VkQueueFamilyProperties *device_queue_props = (VkQueueFamilyProperties *)malloc(device_queue_family_count * sizeof(VkQueueFamilyProperties));
- vkGetPhysicalDeviceQueueFamilyProperties(physical_devices[i], &device_queue_family_count, device_queue_props);
- for (uint32_t j = 0; j < device_queue_family_count; j++) {
- VkBool32 supports;
- vkGetPhysicalDeviceSurfaceSupportKHR(physical_devices[i], j, p_surface, &supports);
- if (supports && ((device_queue_props[j].queueFlags & VK_QUEUE_GRAPHICS_BIT) != 0)) {
- present_supported = true;
- } else {
- continue;
- }
+ if (vulkan_hooks) {
+ if (!vulkan_hooks->get_physical_device(&gpu)) {
+ return ERR_CANT_CREATE;
}
- String name = props.deviceName;
- String vendor = "Unknown";
- String dev_type;
- switch (props.deviceType) {
- case VkPhysicalDeviceType::VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU: {
- dev_type = "Discrete";
- } break;
- case VkPhysicalDeviceType::VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU: {
- dev_type = "Integrated";
- } break;
- case VkPhysicalDeviceType::VK_PHYSICAL_DEVICE_TYPE_VIRTUAL_GPU: {
- dev_type = "Virtual";
- } break;
- case VkPhysicalDeviceType::VK_PHYSICAL_DEVICE_TYPE_CPU: {
- dev_type = "CPU";
- } break;
- default: {
- dev_type = "Other";
- } break;
- }
- uint32_t vendor_idx = 0;
- while (vendor_names[vendor_idx].name != nullptr) {
- if (props.vendorID == vendor_names[vendor_idx].id) {
- vendor = vendor_names[vendor_idx].name;
+
+ // not really needed but nice to print the correct entry
+ for (uint32_t i = 0; i < gpu_count; ++i) {
+ if (physical_devices[i] == gpu) {
+ device_index = i;
break;
}
- vendor_idx++;
}
- free(device_queue_props);
- print_verbose(" #" + itos(i) + ": " + vendor + " " + name + " - " + (present_supported ? "Supported" : "Unsupported") + ", " + dev_type);
+ } else {
+ // TODO: At least on Linux Laptops integrated GPUs fail with Vulkan in many instances.
+ // The device should really be a preference, but for now choosing a discrete GPU over the
+ // integrated one is better than the default.
- if (present_supported) { // Select first supported device of preferred type: Discrete > Integrated > Virtual > CPU > Other.
+ int type_selected = -1;
+ print_verbose("Vulkan devices:");
+ for (uint32_t i = 0; i < gpu_count; ++i) {
+ VkPhysicalDeviceProperties props;
+ vkGetPhysicalDeviceProperties(physical_devices[i], &props);
+
+ bool present_supported = false;
+
+ uint32_t device_queue_family_count = 0;
+ vkGetPhysicalDeviceQueueFamilyProperties(physical_devices[i], &device_queue_family_count, nullptr);
+ VkQueueFamilyProperties *device_queue_props = (VkQueueFamilyProperties *)malloc(device_queue_family_count * sizeof(VkQueueFamilyProperties));
+ vkGetPhysicalDeviceQueueFamilyProperties(physical_devices[i], &device_queue_family_count, device_queue_props);
+ for (uint32_t j = 0; j < device_queue_family_count; j++) {
+ VkBool32 supports;
+ vkGetPhysicalDeviceSurfaceSupportKHR(physical_devices[i], j, p_surface, &supports);
+ if (supports && ((device_queue_props[j].queueFlags & VK_QUEUE_GRAPHICS_BIT) != 0)) {
+ present_supported = true;
+ } else {
+ continue;
+ }
+ }
+ String name = props.deviceName;
+ String vendor = "Unknown";
+ String dev_type;
switch (props.deviceType) {
case VkPhysicalDeviceType::VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU: {
- if (type_selected < 4) {
- type_selected = 4;
- device_index = i;
- }
+ dev_type = "Discrete";
} break;
case VkPhysicalDeviceType::VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU: {
- if (type_selected < 3) {
- type_selected = 3;
- device_index = i;
- }
+ dev_type = "Integrated";
} break;
case VkPhysicalDeviceType::VK_PHYSICAL_DEVICE_TYPE_VIRTUAL_GPU: {
- if (type_selected < 2) {
- type_selected = 2;
- device_index = i;
- }
+ dev_type = "Virtual";
} break;
case VkPhysicalDeviceType::VK_PHYSICAL_DEVICE_TYPE_CPU: {
- if (type_selected < 1) {
- type_selected = 1;
- device_index = i;
- }
+ dev_type = "CPU";
} break;
default: {
- if (type_selected < 0) {
- type_selected = 0;
- device_index = i;
- }
+ dev_type = "Other";
} break;
}
+ uint32_t vendor_idx = 0;
+ while (vendor_names[vendor_idx].name != nullptr) {
+ if (props.vendorID == vendor_names[vendor_idx].id) {
+ vendor = vendor_names[vendor_idx].name;
+ break;
+ }
+ vendor_idx++;
+ }
+ free(device_queue_props);
+ print_verbose(" #" + itos(i) + ": " + vendor + " " + name + " - " + (present_supported ? "Supported" : "Unsupported") + ", " + dev_type);
+
+ if (present_supported) { // Select first supported device of preffered type: Discrete > Integrated > Virtual > CPU > Other.
+ switch (props.deviceType) {
+ case VkPhysicalDeviceType::VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU: {
+ if (type_selected < 4) {
+ type_selected = 4;
+ device_index = i;
+ }
+ } break;
+ case VkPhysicalDeviceType::VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU: {
+ if (type_selected < 3) {
+ type_selected = 3;
+ device_index = i;
+ }
+ } break;
+ case VkPhysicalDeviceType::VK_PHYSICAL_DEVICE_TYPE_VIRTUAL_GPU: {
+ if (type_selected < 2) {
+ type_selected = 2;
+ device_index = i;
+ }
+ } break;
+ case VkPhysicalDeviceType::VK_PHYSICAL_DEVICE_TYPE_CPU: {
+ if (type_selected < 1) {
+ type_selected = 1;
+ device_index = i;
+ }
+ } break;
+ default: {
+ if (type_selected < 0) {
+ type_selected = 0;
+ device_index = i;
+ }
+ } break;
+ }
+ }
}
+
+ int32_t user_device_index = Engine::get_singleton()->get_gpu_index(); // Force user selected GPU.
+ if (user_device_index >= 0 && user_device_index < (int32_t)gpu_count) {
+ device_index = user_device_index;
+ }
+
+ ERR_FAIL_COND_V_MSG(device_index == -1, ERR_CANT_CREATE, "None of Vulkan devices supports both graphics and present queues.");
+
+ gpu = physical_devices[device_index];
}
- int32_t user_device_index = Engine::get_singleton()->get_gpu_index(); // Force user selected GPU.
- if (user_device_index >= 0 && user_device_index < (int32_t)gpu_count) {
- device_index = user_device_index;
- }
-
- ERR_FAIL_COND_V_MSG(device_index == -1, ERR_CANT_CREATE, "None of Vulkan devices supports both graphics and present queues.");
-
- gpu = physical_devices[device_index];
free(physical_devices);
/* Look for device extensions */
@@ -1148,8 +1173,14 @@ Error VulkanContext::_create_device() {
sdevice.queueCreateInfoCount = 2;
}
- err = vkCreateDevice(gpu, &sdevice, nullptr, &device);
- ERR_FAIL_COND_V(err, ERR_CANT_CREATE);
+ if (vulkan_hooks) {
+ if (!vulkan_hooks->create_vulkan_device(&sdevice, &device)) {
+ return ERR_CANT_CREATE;
+ }
+ } else {
+ err = vkCreateDevice(gpu, &sdevice, nullptr, &device);
+ ERR_FAIL_COND_V(err, ERR_CANT_CREATE);
+ }
return OK;
}
diff --git a/drivers/vulkan/vulkan_context.h b/drivers/vulkan/vulkan_context.h
index d4052666e3..8c0111714c 100644
--- a/drivers/vulkan/vulkan_context.h
+++ b/drivers/vulkan/vulkan_context.h
@@ -45,6 +45,8 @@
#include
#endif
+#include "vulkan_hooks.h"
+
class VulkanContext {
public:
struct SubgroupCapabilities {
@@ -86,6 +88,7 @@ private:
FRAME_LAG = 2
};
+ static VulkanHooks *vulkan_hooks;
VkInstance inst = VK_NULL_HANDLE;
VkPhysicalDevice gpu = VK_NULL_HANDLE;
VkPhysicalDeviceProperties gpu_props;
@@ -267,6 +270,8 @@ public:
VkQueue get_graphics_queue() const;
uint32_t get_graphics_queue_family_index() const;
+ static void set_vulkan_hooks(VulkanHooks *p_vulkan_hooks) { vulkan_hooks = p_vulkan_hooks; };
+
void window_resize(DisplayServer::WindowID p_window_id, int p_width, int p_height);
int window_get_width(DisplayServer::WindowID p_window = 0);
int window_get_height(DisplayServer::WindowID p_window = 0);
diff --git a/drivers/vulkan/vulkan_hooks.h b/drivers/vulkan/vulkan_hooks.h
new file mode 100644
index 0000000000..3f244b4d45
--- /dev/null
+++ b/drivers/vulkan/vulkan_hooks.h
@@ -0,0 +1,48 @@
+/*************************************************************************/
+/* vulkan_hooks.h */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+
+#ifndef VULKAN_HOOKS_H
+#define VULKAN_HOOKS_H
+
+#ifdef USE_VOLK
+#include
+#else
+#include
+#endif
+
+class VulkanHooks {
+public:
+ virtual bool create_vulkan_instance(const VkInstanceCreateInfo *p_vulkan_create_info, VkInstance *r_instance) { return false; };
+ virtual bool get_physical_device(VkPhysicalDevice *r_device) { return false; };
+ virtual bool create_vulkan_device(const VkDeviceCreateInfo *p_device_create_info, VkDevice *r_device) { return false; };
+ virtual ~VulkanHooks(){};
+};
+
+#endif
diff --git a/main/main.cpp b/main/main.cpp
index a68792105e..246a26025c 100644
--- a/main/main.cpp
+++ b/main/main.cpp
@@ -1963,6 +1963,10 @@ Error Main::setup2(Thread::ID p_main_tid_override) {
return OK;
}
+String Main::get_rendering_driver_name() {
+ return rendering_driver;
+}
+
// everything the main loop needs to know about frame timings
static MainTimerSync main_timer_sync;
diff --git a/main/main.h b/main/main.h
index cec31545c7..14a8fb4147 100644
--- a/main/main.h
+++ b/main/main.h
@@ -49,6 +49,7 @@ public:
static int test_entrypoint(int argc, char *argv[], bool &tests_need_run);
static Error setup(const char *execpath, int argc, char *argv[], bool p_second_phase = true);
static Error setup2(Thread::ID p_main_tid_override = 0);
+ static String get_rendering_driver_name();
#ifdef TESTS_ENABLED
static Error test_setup();
static void test_cleanup();
diff --git a/modules/openxr/SCsub b/modules/openxr/SCsub
new file mode 100644
index 0000000000..37a8f3909a
--- /dev/null
+++ b/modules/openxr/SCsub
@@ -0,0 +1,87 @@
+#!/usr/bin/env python
+
+Import("env")
+Import("env_modules")
+
+env_openxr = env_modules.Clone()
+
+#################################################
+# Add in our Khronos OpenXR loader
+
+thirdparty_obj = []
+thirdparty_dir = "#thirdparty/openxr"
+
+env_openxr.Prepend(
+ CPPPATH=[
+ thirdparty_dir,
+ thirdparty_dir + "/include",
+ thirdparty_dir + "/src",
+ thirdparty_dir + "/src/common",
+ thirdparty_dir + "/src/external/jsoncpp/include",
+ thirdparty_dir + "/src/loader",
+ ]
+)
+
+# may need to check and set:
+# - XR_USE_TIMESPEC
+
+env_thirdparty = env_openxr.Clone()
+env_thirdparty.disable_warnings()
+env_thirdparty.AppendUnique(CPPDEFINES=["DISABLE_STD_FILESYSTEM"])
+
+if env["platform"] == "android":
+ # may need to set OPENXR_ANDROID_VERSION_SUFFIX
+ env_thirdparty.AppendUnique(CPPDEFINES=["XR_OS_ANDROID", "XR_USE_PLATFORM_ANDROID"])
+
+ # may need to include java parts of the openxr loader
+elif env["platform"] == "linuxbsd":
+ env_thirdparty.AppendUnique(CPPDEFINES=["XR_OS_LINUX", "XR_USE_PLATFORM_XLIB"])
+ # FIXME: Review what needs to be set for Android and macOS.
+ env_thirdparty.AppendUnique(CPPDEFINES=["HAVE_SECURE_GETENV"])
+elif env["platform"] == "windows":
+ env_thirdparty.AppendUnique(CPPDEFINES=["XR_OS_WINDOWS", "NOMINMAX", "XR_USE_PLATFORM_WIN32"])
+
+env_thirdparty.add_source_files(thirdparty_obj, thirdparty_dir + "/src/xr_generated_dispatch_table.c")
+
+# add in common files (hope these don't clash with us)
+env_thirdparty.add_source_files(thirdparty_obj, thirdparty_dir + "/src/common/filesystem_utils.cpp")
+env_thirdparty.add_source_files(thirdparty_obj, thirdparty_dir + "/src/common/object_info.cpp")
+
+# add in external jsoncpp dependency
+env_thirdparty.add_source_files(thirdparty_obj, thirdparty_dir + "/src/external/jsoncpp/src/lib_json/json_reader.cpp")
+env_thirdparty.add_source_files(thirdparty_obj, thirdparty_dir + "/src/external/jsoncpp/src/lib_json/json_value.cpp")
+env_thirdparty.add_source_files(thirdparty_obj, thirdparty_dir + "/src/external/jsoncpp/src/lib_json/json_writer.cpp")
+
+# add in load
+if env["platform"] == "android":
+ env_thirdparty.add_source_files(thirdparty_obj, thirdparty_dir + "/src/loader/android_utilities.cpp")
+
+env_thirdparty.add_source_files(thirdparty_obj, thirdparty_dir + "/src/loader/api_layer_interface.cpp")
+env_thirdparty.add_source_files(thirdparty_obj, thirdparty_dir + "/src/loader/loader_core.cpp")
+env_thirdparty.add_source_files(thirdparty_obj, thirdparty_dir + "/src/loader/loader_instance.cpp")
+env_thirdparty.add_source_files(thirdparty_obj, thirdparty_dir + "/src/loader/loader_logger_recorders.cpp")
+env_thirdparty.add_source_files(thirdparty_obj, thirdparty_dir + "/src/loader/loader_logger.cpp")
+env_thirdparty.add_source_files(thirdparty_obj, thirdparty_dir + "/src/loader/manifest_file.cpp")
+env_thirdparty.add_source_files(thirdparty_obj, thirdparty_dir + "/src/loader/runtime_interface.cpp")
+env_thirdparty.add_source_files(thirdparty_obj, thirdparty_dir + "/src/loader/xr_generated_loader.cpp")
+
+env.modules_sources += thirdparty_obj
+
+#################################################
+# And include our module source
+
+module_obj = []
+
+env_openxr.add_source_files(module_obj, "*.cpp")
+env_openxr.add_source_files(module_obj, "action_map/*.cpp")
+
+# We're a little more targetted with our extensions
+if env["platform"] == "android":
+ env_openxr.add_source_files(module_obj, "extensions/openxr_android_extension.cpp")
+if env["vulkan"]:
+ env_openxr.add_source_files(module_obj, "extensions/openxr_vulkan_extension.cpp")
+
+env.modules_sources += module_obj
+
+# Needed to force rebuilding the module files when the thirdparty library is updated.
+env.Depends(module_obj, thirdparty_obj)
diff --git a/modules/openxr/action_map/openxr_action.cpp b/modules/openxr/action_map/openxr_action.cpp
new file mode 100644
index 0000000000..59ee3f4292
--- /dev/null
+++ b/modules/openxr/action_map/openxr_action.cpp
@@ -0,0 +1,91 @@
+/*************************************************************************/
+/* openxr_action.cpp */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+
+#include "openxr_action.h"
+
+void OpenXRAction::_bind_methods() {
+ ClassDB::bind_method(D_METHOD("set_localized_name", "localized_name"), &OpenXRAction::set_localized_name);
+ ClassDB::bind_method(D_METHOD("get_localized_name"), &OpenXRAction::get_localized_name);
+ ADD_PROPERTY(PropertyInfo(Variant::STRING, "localized_name"), "set_localized_name", "get_localized_name");
+
+ ClassDB::bind_method(D_METHOD("set_action_type", "action_type"), &OpenXRAction::set_action_type);
+ ClassDB::bind_method(D_METHOD("get_action_type"), &OpenXRAction::get_action_type);
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "action_type", PROPERTY_HINT_ENUM, "bool,float,vector2,pose"), "set_action_type", "get_action_type");
+
+ ClassDB::bind_method(D_METHOD("set_toplevel_paths", "toplevel_paths"), &OpenXRAction::set_toplevel_paths);
+ ClassDB::bind_method(D_METHOD("get_toplevel_paths"), &OpenXRAction::get_toplevel_paths);
+ ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "toplevel_paths", PROPERTY_HINT_ARRAY_TYPE, "STRING"), "set_toplevel_paths", "get_toplevel_paths");
+
+ BIND_ENUM_CONSTANT(OPENXR_ACTION_BOOL);
+ BIND_ENUM_CONSTANT(OPENXR_ACTION_FLOAT);
+ BIND_ENUM_CONSTANT(OPENXR_ACTION_VECTOR2);
+ BIND_ENUM_CONSTANT(OPENXR_ACTION_POSE);
+}
+
+Ref OpenXRAction::new_action(const char *p_name, const char *p_localized_name, const ActionType p_action_type, const char *p_toplevel_paths) {
+ // This is a helper function to help build our default action sets
+
+ Ref action;
+ action.instantiate();
+ action->set_name(String(p_name));
+ action->set_localized_name(String(p_localized_name));
+ action->set_action_type(p_action_type);
+ action->parse_toplevel_paths(String(p_toplevel_paths));
+
+ return action;
+}
+
+void OpenXRAction::set_localized_name(const String p_localized_name) {
+ localized_name = p_localized_name;
+}
+
+String OpenXRAction::get_localized_name() const {
+ return localized_name;
+}
+
+void OpenXRAction::set_action_type(const OpenXRAction::ActionType p_action_type) {
+ action_type = p_action_type;
+}
+
+OpenXRAction::ActionType OpenXRAction::get_action_type() const {
+ return action_type;
+}
+
+void OpenXRAction::set_toplevel_paths(const PackedStringArray p_toplevel_paths) {
+ toplevel_paths = p_toplevel_paths;
+}
+
+PackedStringArray OpenXRAction::get_toplevel_paths() const {
+ return toplevel_paths;
+}
+
+void OpenXRAction::parse_toplevel_paths(const String p_toplevel_paths) {
+ toplevel_paths = p_toplevel_paths.split(",", false);
+}
diff --git a/modules/openxr/action_map/openxr_action.h b/modules/openxr/action_map/openxr_action.h
new file mode 100644
index 0000000000..e2cfe79e64
--- /dev/null
+++ b/modules/openxr/action_map/openxr_action.h
@@ -0,0 +1,74 @@
+/*************************************************************************/
+/* openxr_action.h */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+
+#ifndef OPENXR_ACTION_H
+#define OPENXR_ACTION_H
+
+#include "core/io/resource.h"
+
+class OpenXRAction : public Resource {
+ GDCLASS(OpenXRAction, Resource);
+
+public:
+ enum ActionType {
+ OPENXR_ACTION_BOOL,
+ OPENXR_ACTION_FLOAT,
+ OPENXR_ACTION_VECTOR2,
+ OPENXR_ACTION_POSE,
+ OPENXR_ACTION_HAPTIC,
+ };
+
+private:
+ String localized_name;
+ ActionType action_type = OPENXR_ACTION_FLOAT;
+
+ PackedStringArray toplevel_paths;
+
+protected:
+ static void _bind_methods();
+
+public:
+ static Ref new_action(const char *p_name, const char *p_localized_name, const ActionType p_action_type, const char *p_toplevel_paths);
+
+ void set_localized_name(const String p_localized_name);
+ String get_localized_name() const;
+
+ void set_action_type(const ActionType p_action_type);
+ ActionType get_action_type() const;
+
+ void set_toplevel_paths(const PackedStringArray p_toplevel_paths);
+ PackedStringArray get_toplevel_paths() const;
+
+ void parse_toplevel_paths(const String p_toplevel_paths);
+};
+
+VARIANT_ENUM_CAST(OpenXRAction::ActionType);
+
+#endif // !OPENXR_ACTION_H
diff --git a/modules/openxr/action_map/openxr_action_map.cpp b/modules/openxr/action_map/openxr_action_map.cpp
new file mode 100644
index 0000000000..5391f9569a
--- /dev/null
+++ b/modules/openxr/action_map/openxr_action_map.cpp
@@ -0,0 +1,261 @@
+/*************************************************************************/
+/* openxr_action_map.cpp */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+
+#include "openxr_action_map.h"
+
+void OpenXRActionMap::_bind_methods() {
+ ClassDB::bind_method(D_METHOD("set_action_sets", "action_sets"), &OpenXRActionMap::set_action_sets);
+ ClassDB::bind_method(D_METHOD("get_action_sets"), &OpenXRActionMap::get_action_sets);
+ ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "action_sets", PROPERTY_HINT_RESOURCE_TYPE, "OpenXRActionSet", PROPERTY_USAGE_NO_EDITOR), "set_action_sets", "get_action_sets");
+
+ ClassDB::bind_method(D_METHOD("add_action_set", "action_set"), &OpenXRActionMap::add_action_set);
+ ClassDB::bind_method(D_METHOD("remove_action_set", "action_set"), &OpenXRActionMap::remove_action_set);
+
+ ClassDB::bind_method(D_METHOD("set_interaction_profiles", "interaction_profiles"), &OpenXRActionMap::set_interaction_profiles);
+ ClassDB::bind_method(D_METHOD("get_interaction_profiles"), &OpenXRActionMap::get_interaction_profiles);
+ ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "interaction_profiles", PROPERTY_HINT_RESOURCE_TYPE, "OpenXRInteractionProfile", PROPERTY_USAGE_NO_EDITOR), "set_interaction_profiles", "get_interaction_profiles");
+
+ ClassDB::bind_method(D_METHOD("add_interaction_profile", "interaction_profile"), &OpenXRActionMap::add_interaction_profile);
+ ClassDB::bind_method(D_METHOD("remove_interaction_profile", "interaction_profile"), &OpenXRActionMap::remove_interaction_profile);
+
+ ClassDB::bind_method(D_METHOD("create_default_action_sets"), &OpenXRActionMap::create_default_action_sets);
+}
+
+void OpenXRActionMap::set_action_sets(Array p_action_sets) {
+ action_sets = p_action_sets;
+}
+
+Array OpenXRActionMap::get_action_sets() const {
+ return action_sets;
+}
+
+void OpenXRActionMap::add_action_set(Ref p_action_set) {
+ ERR_FAIL_COND(p_action_set.is_null());
+
+ if (action_sets.find(p_action_set) == -1) {
+ action_sets.push_back(p_action_set);
+ }
+}
+
+void OpenXRActionMap::remove_action_set(Ref p_action_set) {
+ int idx = action_sets.find(p_action_set);
+ if (idx != -1) {
+ action_sets.remove_at(idx);
+ }
+}
+
+void OpenXRActionMap::set_interaction_profiles(Array p_interaction_profiles) {
+ interaction_profiles = p_interaction_profiles;
+}
+
+Array OpenXRActionMap::get_interaction_profiles() const {
+ return interaction_profiles;
+}
+
+void OpenXRActionMap::add_interaction_profile(Ref p_interaction_profile) {
+ ERR_FAIL_COND(p_interaction_profile.is_null());
+
+ if (interaction_profiles.find(p_interaction_profile) == -1) {
+ interaction_profiles.push_back(p_interaction_profile);
+ }
+}
+
+void OpenXRActionMap::remove_interaction_profile(Ref p_interaction_profile) {
+ int idx = interaction_profiles.find(p_interaction_profile);
+ if (idx != -1) {
+ interaction_profiles.remove_at(idx);
+ }
+}
+
+void OpenXRActionMap::create_default_action_sets() {
+ // Note, if you make changes here make sure to delete your default_action_map.tres file of it will load an old version.
+
+ // Create our Godot action set
+ Ref action_set = OpenXRActionSet::new_action_set("godot", "Godot action set");
+ add_action_set(action_set);
+
+ // Create our actions
+ Ref trigger = action_set->add_new_action("trigger", "Trigger", OpenXRAction::OPENXR_ACTION_FLOAT, "/user/hand/left,/user/hand/right");
+ Ref trigger_click = action_set->add_new_action("trigger_click", "Trigger click", OpenXRAction::OPENXR_ACTION_BOOL, "/user/hand/left,/user/hand/right");
+ Ref trigger_touch = action_set->add_new_action("trigger_touch", "Trigger touching", OpenXRAction::OPENXR_ACTION_BOOL, "/user/hand/left,/user/hand/right");
+ Ref grip = action_set->add_new_action("grip", "Grip", OpenXRAction::OPENXR_ACTION_FLOAT, "/user/hand/left,/user/hand/right");
+ Ref grip_click = action_set->add_new_action("grip_click", "Grip click", OpenXRAction::OPENXR_ACTION_BOOL, "/user/hand/left,/user/hand/right");
+ Ref grip_touch = action_set->add_new_action("grip_touch", "Grip touching", OpenXRAction::OPENXR_ACTION_BOOL, "/user/hand/left,/user/hand/right");
+ Ref primary = action_set->add_new_action("primary", "Primary joystick/thumbstick/trackpad", OpenXRAction::OPENXR_ACTION_VECTOR2, "/user/hand/left,/user/hand/right");
+ Ref primary_click = action_set->add_new_action("primary_click", "Primary joystick/thumbstick/trackpad click", OpenXRAction::OPENXR_ACTION_BOOL, "/user/hand/left,/user/hand/right");
+ Ref primary_touch = action_set->add_new_action("primary_touch", "Primary joystick/thumbstick/trackpad touching", OpenXRAction::OPENXR_ACTION_BOOL, "/user/hand/left,/user/hand/right");
+ Ref secondary = action_set->add_new_action("secondary", "Secondary joystick/thumbstick/trackpad", OpenXRAction::OPENXR_ACTION_VECTOR2, "/user/hand/left,/user/hand/right");
+ Ref secondary_click = action_set->add_new_action("secondary_click", "Secondary joystick/thumbstick/trackpad click", OpenXRAction::OPENXR_ACTION_BOOL, "/user/hand/left,/user/hand/right");
+ Ref secondary_touch = action_set->add_new_action("secondary_touch", "Secondary joystick/thumbstick/trackpad touching", OpenXRAction::OPENXR_ACTION_BOOL, "/user/hand/left,/user/hand/right");
+ Ref menu_button = action_set->add_new_action("menu_button", "Menu button", OpenXRAction::OPENXR_ACTION_BOOL, "/user/hand/left,/user/hand/right");
+ Ref select_button = action_set->add_new_action("select_button", "Select button", OpenXRAction::OPENXR_ACTION_BOOL, "/user/hand/left,/user/hand/right");
+ Ref ax_button = action_set->add_new_action("ax_button", "A/X button", OpenXRAction::OPENXR_ACTION_BOOL, "/user/hand/left,/user/hand/right");
+ Ref ax_touch = action_set->add_new_action("ax_touch", "A/X touching", OpenXRAction::OPENXR_ACTION_BOOL, "/user/hand/left,/user/hand/right");
+ Ref by_button = action_set->add_new_action("by_button", "B/Y button", OpenXRAction::OPENXR_ACTION_BOOL, "/user/hand/left,/user/hand/right");
+ Ref by_touch = action_set->add_new_action("by_touch", "B/Y touching", OpenXRAction::OPENXR_ACTION_BOOL, "/user/hand/left,/user/hand/right");
+ Ref default_pose = action_set->add_new_action("default_pose", "Default pose", OpenXRAction::OPENXR_ACTION_POSE, "/user/hand/left,/user/hand/right");
+ Ref aim_pose = action_set->add_new_action("aim_pose", "Aim pose", OpenXRAction::OPENXR_ACTION_POSE, "/user/hand/left,/user/hand/right");
+ Ref grip_pose = action_set->add_new_action("grip_pose", "Grip pose", OpenXRAction::OPENXR_ACTION_POSE, "/user/hand/left,/user/hand/right");
+ Ref haptic = action_set->add_new_action("haptic", "Haptic", OpenXRAction::OPENXR_ACTION_HAPTIC, "/user/hand/left,/user/hand/right");
+
+ // Create our interaction profiles
+ Ref profile = OpenXRInteractionProfile::new_profile("/interaction_profiles/khr/simple_controller");
+ profile->add_new_binding(default_pose, "/user/hand/left/input/grip/pose,/user/hand/right/input/grip/pose");
+ profile->add_new_binding(aim_pose, "/user/hand/left/input/aim/pose,/user/hand/right/input/aim/pose");
+ profile->add_new_binding(grip_pose, "/user/hand/left/input/grip/pose,/user/hand/right/input/grip/pose");
+ profile->add_new_binding(menu_button, "/user/hand/left/input/menu/click,/user/hand/right/input/menu/click");
+ profile->add_new_binding(select_button, "/user/hand/left/input/select/click,/user/hand/right/input/select/click");
+ // generic has no support for triggers, grip, A/B buttons, nor joystick/trackpad inputs
+ profile->add_new_binding(haptic, "/user/hand/left/output/haptic,/user/hand/right/output/haptic");
+ add_interaction_profile(profile);
+
+ // Create our Vive controller profile
+ profile = OpenXRInteractionProfile::new_profile("/interaction_profiles/htc/vive_controller");
+ profile->add_new_binding(default_pose, "/user/hand/left/input/grip/pose,/user/hand/right/input/grip/pose");
+ profile->add_new_binding(aim_pose, "/user/hand/left/input/aim/pose,/user/hand/right/input/aim/pose");
+ profile->add_new_binding(grip_pose, "/user/hand/left/input/grip/pose,/user/hand/right/input/grip/pose");
+ profile->add_new_binding(menu_button, "/user/hand/left/input/menu/click,/user/hand/right/input/menu/click");
+ profile->add_new_binding(select_button, "/user/hand/left/input/system/click,/user/hand/right/input/system/click");
+ // wmr controller has no a/b/x/y buttons
+ profile->add_new_binding(trigger, "/user/hand/left/input/trigger/value,/user/hand/right/input/trigger/value");
+ profile->add_new_binding(trigger_click, "/user/hand/left/input/trigger/click,/user/hand/right/input/trigger/click");
+ profile->add_new_binding(grip, "/user/hand/left/input/squeeze/click,/user/hand/right/input/squeeze/click"); // OpenXR will convert bool to float
+ profile->add_new_binding(grip_click, "/user/hand/left/input/squeeze/click,/user/hand/right/input/squeeze/click");
+ // primary on our vive controller is our trackpad
+ profile->add_new_binding(primary, "/user/hand/left/input/trackpad,/user/hand/right/input/trackpad");
+ profile->add_new_binding(primary_click, "/user/hand/left/input/trackpad/click,/user/hand/right/input/trackpad/click");
+ profile->add_new_binding(primary_touch, "/user/hand/left/input/trackpad/touch,/user/hand/right/input/trackpad/touch");
+ // vive controllers have no secondary input
+ profile->add_new_binding(haptic, "/user/hand/left/output/haptic,/user/hand/right/output/haptic");
+ add_interaction_profile(profile);
+
+ // Create our WMR controller profile
+ profile = OpenXRInteractionProfile::new_profile("/interaction_profiles/microsoft/motion_controller");
+ profile->add_new_binding(default_pose, "/user/hand/left/input/grip/pose,/user/hand/right/input/grip/pose");
+ profile->add_new_binding(aim_pose, "/user/hand/left/input/aim/pose,/user/hand/right/input/aim/pose");
+ profile->add_new_binding(grip_pose, "/user/hand/left/input/grip/pose,/user/hand/right/input/grip/pose");
+ // wmr controllers have no select button we can use
+ profile->add_new_binding(menu_button, "/user/hand/left/input/menu/click,/user/hand/right/input/menu/click");
+ // wmr controller has no a/b/x/y buttons
+ profile->add_new_binding(trigger, "/user/hand/left/input/trigger/value,/user/hand/right/input/trigger/value");
+ profile->add_new_binding(trigger_click, "/user/hand/left/input/trigger/value,/user/hand/right/input/trigger/value"); // OpenXR will conver float to bool
+ profile->add_new_binding(grip, "/user/hand/left/input/squeeze/click,/user/hand/right/input/squeeze/click"); // OpenXR will convert bool to float
+ profile->add_new_binding(grip_click, "/user/hand/left/input/squeeze/click,/user/hand/right/input/squeeze/click");
+ // primary on our wmr controller is our thumbstick, no touch
+ profile->add_new_binding(primary, "/user/hand/left/input/thumbstick,/user/hand/right/input/thumbstick");
+ profile->add_new_binding(primary_click, "/user/hand/left/input/thumbstick/click,/user/hand/right/input/thumbstick/click");
+ // secondary on our wmr controller is our trackpad
+ profile->add_new_binding(secondary, "/user/hand/left/input/trackpad,/user/hand/right/input/trackpad");
+ profile->add_new_binding(secondary_click, "/user/hand/left/input/trackpad/click,/user/hand/right/input/trackpad/click");
+ profile->add_new_binding(secondary_touch, "/user/hand/left/input/trackpad/touch,/user/hand/right/input/trackpad/touch");
+ profile->add_new_binding(haptic, "/user/hand/left/output/haptic,/user/hand/right/output/haptic");
+ add_interaction_profile(profile);
+
+ // Create our HP MR controller profile
+ profile = OpenXRInteractionProfile::new_profile("/interaction_profiles/hp/mixed_reality_controller");
+ profile->add_new_binding(default_pose, "/user/hand/left/input/grip/pose,/user/hand/right/input/grip/pose");
+ profile->add_new_binding(aim_pose, "/user/hand/left/input/aim/pose,/user/hand/right/input/aim/pose");
+ profile->add_new_binding(grip_pose, "/user/hand/left/input/grip/pose,/user/hand/right/input/grip/pose");
+ // hpmr controllers have no select button we can use
+ profile->add_new_binding(menu_button, "/user/hand/left/input/menu/click,/user/hand/right/input/menu/click");
+ // hpmr controllers only register click, not touch, on our a/b/x/y buttons
+ profile->add_new_binding(ax_button, "/user/hand/left/input/x/click,/user/hand/right/input/a/click"); // x on left hand, a on right hand
+ profile->add_new_binding(by_button, "/user/hand/left/input/y/click,/user/hand/right/input/b/click"); // y on left hand, b on right hand
+ profile->add_new_binding(trigger, "/user/hand/left/input/trigger/value,/user/hand/right/input/trigger/value");
+ profile->add_new_binding(trigger_click, "/user/hand/left/input/trigger/value,/user/hand/right/input/trigger/value");
+ profile->add_new_binding(grip, "/user/hand/left/input/squeeze/value,/user/hand/right/input/squeeze/value");
+ profile->add_new_binding(grip_click, "/user/hand/left/input/squeeze/value,/user/hand/right/input/squeeze/value");
+ // primary on our hpmr controller is our thumbstick
+ profile->add_new_binding(primary, "/user/hand/left/input/thumbstick,/user/hand/right/input/thumbstick");
+ profile->add_new_binding(primary_click, "/user/hand/left/input/thumbstick/click,/user/hand/right/input/thumbstick/click");
+ // No secondary on our hpmr controller
+ profile->add_new_binding(haptic, "/user/hand/left/output/haptic,/user/hand/right/output/haptic");
+ add_interaction_profile(profile);
+
+ // Create our Meta touch controller profile
+ profile = OpenXRInteractionProfile::new_profile("/interaction_profiles/oculus/touch_controller");
+ profile->add_new_binding(default_pose, "/user/hand/left/input/grip/pose,/user/hand/right/input/grip/pose");
+ profile->add_new_binding(aim_pose, "/user/hand/left/input/aim/pose,/user/hand/right/input/aim/pose");
+ profile->add_new_binding(grip_pose, "/user/hand/left/input/grip/pose,/user/hand/right/input/grip/pose");
+ // touch controllers have no select button we can use
+ profile->add_new_binding(menu_button, "/user/hand/left/input/menu/click,/user/hand/right/input/system/click"); // right hand system click may not be available
+ profile->add_new_binding(ax_button, "/user/hand/left/input/x/click,/user/hand/right/input/a/click"); // x on left hand, a on right hand
+ profile->add_new_binding(ax_touch, "/user/hand/left/input/x/touch,/user/hand/right/input/a/touch");
+ profile->add_new_binding(by_button, "/user/hand/left/input/y/click,/user/hand/right/input/b/click"); // y on left hand, b on right hand
+ profile->add_new_binding(by_touch, "/user/hand/left/input/y/touch,/user/hand/right/input/b/touch");
+ profile->add_new_binding(trigger, "/user/hand/left/input/trigger/value,/user/hand/right/input/trigger/value");
+ profile->add_new_binding(trigger_click, "/user/hand/left/input/trigger/value,/user/hand/right/input/trigger/value"); // should be converted to boolean
+ profile->add_new_binding(trigger_touch, "/user/hand/left/input/trigger/touch,/user/hand/right/input/trigger/touch");
+ profile->add_new_binding(grip, "/user/hand/left/input/squeeze/value,/user/hand/right/input/squeeze/value"); // should be converted to boolean
+ profile->add_new_binding(grip_click, "/user/hand/left/input/squeeze/value,/user/hand/right/input/squeeze/value");
+ // primary on our touch controller is our thumbstick
+ profile->add_new_binding(primary, "/user/hand/left/input/thumbstick,/user/hand/right/input/thumbstick");
+ profile->add_new_binding(primary_click, "/user/hand/left/input/thumbstick/click,/user/hand/right/input/thumbstick/click");
+ profile->add_new_binding(primary_touch, "/user/hand/left/input/thumbstick/touch,/user/hand/right/input/thumbstick/touch");
+ // touch controller has no secondary input
+ profile->add_new_binding(haptic, "/user/hand/left/output/haptic,/user/hand/right/output/haptic");
+ add_interaction_profile(profile);
+
+ // Create our Valve index controller profile
+ profile = OpenXRInteractionProfile::new_profile("/interaction_profiles/valve/index_controller");
+ profile->add_new_binding(default_pose, "/user/hand/left/input/grip/pose,/user/hand/right/input/grip/pose");
+ profile->add_new_binding(aim_pose, "/user/hand/left/input/aim/pose,/user/hand/right/input/aim/pose");
+ profile->add_new_binding(grip_pose, "/user/hand/left/input/grip/pose,/user/hand/right/input/grip/pose");
+ // index controllers have no select button we can use
+ profile->add_new_binding(menu_button, "/user/hand/left/input/system/click,/user/hand/right/input/system/click");
+ profile->add_new_binding(ax_button, "/user/hand/left/input/a/click,/user/hand/right/input/a/click"); // a on both controllers
+ profile->add_new_binding(ax_touch, "/user/hand/left/input/a/touch,/user/hand/right/input/a/touch");
+ profile->add_new_binding(by_button, "/user/hand/left/input/b/click,/user/hand/right/input/b/click"); // b on both controllers
+ profile->add_new_binding(by_touch, "/user/hand/left/input/b/touch,/user/hand/right/input/b/touch");
+ profile->add_new_binding(trigger, "/user/hand/left/input/trigger/value,/user/hand/right/input/trigger/value");
+ profile->add_new_binding(trigger_click, "/user/hand/left/input/trigger/click,/user/hand/right/input/trigger/click");
+ profile->add_new_binding(trigger_touch, "/user/hand/left/input/trigger/touch,/user/hand/right/input/trigger/touch");
+ profile->add_new_binding(grip, "/user/hand/left/input/squeeze/value,/user/hand/right/input/squeeze/value");
+ profile->add_new_binding(grip_click, "/user/hand/left/input/squeeze/value,/user/hand/right/input/squeeze/value"); // this should do a float to bool conversion
+ // primary on our index controller is our thumbstick
+ profile->add_new_binding(primary, "/user/hand/left/input/thumbstick,/user/hand/right/input/thumbstick");
+ profile->add_new_binding(primary_click, "/user/hand/left/input/thumbstick/click,/user/hand/right/input/thumbstick/click");
+ profile->add_new_binding(primary_touch, "/user/hand/left/input/thumbstick/touch,/user/hand/right/input/thumbstick/touch");
+ // secondary on our index controller is our trackpad
+ profile->add_new_binding(secondary, "/user/hand/left/input/trackpad,/user/hand/right/input/trackpad");
+ profile->add_new_binding(secondary_click, "/user/hand/left/input/trackpad/force,/user/hand/right/input/trackpad/force"); // not sure if this will work but doesn't seem to support click...
+ profile->add_new_binding(secondary_touch, "/user/hand/left/input/trackpad/touch,/user/hand/right/input/trackpad/touch");
+ profile->add_new_binding(haptic, "/user/hand/left/output/haptic,/user/hand/right/output/haptic");
+ add_interaction_profile(profile);
+}
+
+void OpenXRActionMap::create_editor_action_sets() {
+ // TODO implement
+}
+
+OpenXRActionMap::~OpenXRActionMap() {
+ action_sets.clear();
+ interaction_profiles.clear();
+}
diff --git a/modules/openxr/action_map/openxr_action_map.h b/modules/openxr/action_map/openxr_action_map.h
new file mode 100644
index 0000000000..866e170468
--- /dev/null
+++ b/modules/openxr/action_map/openxr_action_map.h
@@ -0,0 +1,68 @@
+/*************************************************************************/
+/* openxr_action_map.h */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+
+#ifndef OPENXR_ACTION_SETS_H
+#define OPENXR_ACTION_SETS_H
+
+#include "core/io/resource.h"
+
+#include "openxr_action_set.h"
+#include "openxr_interaction_profile.h"
+
+class OpenXRActionMap : public Resource {
+ GDCLASS(OpenXRActionMap, Resource);
+
+private:
+ Array action_sets;
+ Array interaction_profiles;
+
+protected:
+ static void _bind_methods();
+
+public:
+ void set_action_sets(Array p_action_sets);
+ Array get_action_sets() const;
+
+ void add_action_set(Ref p_action_set);
+ void remove_action_set(Ref p_action_set);
+
+ void set_interaction_profiles(Array p_interaction_profiles);
+ Array get_interaction_profiles() const;
+
+ void add_interaction_profile(Ref p_interaction_profile);
+ void remove_interaction_profile(Ref p_interaction_profile);
+
+ void create_default_action_sets();
+ void create_editor_action_sets();
+
+ ~OpenXRActionMap();
+};
+
+#endif // !OPENXR_ACTION_SETS_H
diff --git a/modules/openxr/action_map/openxr_action_set.cpp b/modules/openxr/action_map/openxr_action_set.cpp
new file mode 100644
index 0000000000..465a709b60
--- /dev/null
+++ b/modules/openxr/action_map/openxr_action_set.cpp
@@ -0,0 +1,111 @@
+/*************************************************************************/
+/* openxr_action_set.cpp */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+
+#include "openxr_action_set.h"
+
+void OpenXRActionSet::_bind_methods() {
+ ClassDB::bind_method(D_METHOD("set_localized_name", "localized_name"), &OpenXRActionSet::set_localized_name);
+ ClassDB::bind_method(D_METHOD("get_localized_name"), &OpenXRActionSet::get_localized_name);
+ ADD_PROPERTY(PropertyInfo(Variant::STRING, "localized_name"), "set_localized_name", "get_localized_name");
+
+ ClassDB::bind_method(D_METHOD("set_priority", "priority"), &OpenXRActionSet::set_priority);
+ ClassDB::bind_method(D_METHOD("get_priority"), &OpenXRActionSet::get_priority);
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "priority"), "set_priority", "get_priority");
+
+ ClassDB::bind_method(D_METHOD("set_actions", "actions"), &OpenXRActionSet::set_actions);
+ ClassDB::bind_method(D_METHOD("get_actions"), &OpenXRActionSet::get_actions);
+ ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "actions", PROPERTY_HINT_RESOURCE_TYPE, "OpenXRAction", PROPERTY_USAGE_NO_EDITOR), "set_actions", "get_actions");
+
+ ClassDB::bind_method(D_METHOD("add_action", "action"), &OpenXRActionSet::add_action);
+ ClassDB::bind_method(D_METHOD("remove_action", "action"), &OpenXRActionSet::remove_action);
+}
+
+Ref OpenXRActionSet::new_action_set(const char *p_name, const char *p_localized_name, const int p_priority) {
+ // This is a helper function to help build our default action sets
+
+ Ref action_set;
+ action_set.instantiate();
+ action_set->set_name(String(p_name));
+ action_set->set_localized_name(p_localized_name);
+ action_set->set_priority(p_priority);
+
+ return action_set;
+}
+
+void OpenXRActionSet::set_localized_name(const String p_localized_name) {
+ localized_name = p_localized_name;
+}
+
+String OpenXRActionSet::get_localized_name() const {
+ return localized_name;
+}
+
+void OpenXRActionSet::set_priority(const int p_priority) {
+ priority = p_priority;
+}
+
+int OpenXRActionSet::get_priority() const {
+ return priority;
+}
+
+void OpenXRActionSet::set_actions(Array p_actions) {
+ actions = p_actions;
+}
+
+Array OpenXRActionSet::get_actions() const {
+ return actions;
+}
+
+void OpenXRActionSet::add_action(Ref p_action) {
+ ERR_FAIL_COND(p_action.is_null());
+
+ if (actions.find(p_action) == -1) {
+ actions.push_back(p_action);
+ }
+}
+
+void OpenXRActionSet::remove_action(Ref p_action) {
+ int idx = actions.find(p_action);
+ if (idx != -1) {
+ actions.remove_at(idx);
+ }
+}
+
+Ref OpenXRActionSet::add_new_action(const char *p_name, const char *p_localized_name, const OpenXRAction::ActionType p_action_type, const char *p_toplevel_paths) {
+ // This is a helper function to help build our default action sets
+
+ Ref new_action = OpenXRAction::new_action(p_name, p_localized_name, p_action_type, p_toplevel_paths);
+ add_action(new_action);
+ return new_action;
+}
+
+OpenXRActionSet::~OpenXRActionSet() {
+ actions.clear();
+}
diff --git a/modules/openxr/action_map/openxr_action_set.h b/modules/openxr/action_map/openxr_action_set.h
new file mode 100644
index 0000000000..012a088b1c
--- /dev/null
+++ b/modules/openxr/action_map/openxr_action_set.h
@@ -0,0 +1,70 @@
+/*************************************************************************/
+/* openxr_action_set.h */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+
+#ifndef OPENXR_ACTION_SET_H
+#define OPENXR_ACTION_SET_H
+
+#include "core/io/resource.h"
+
+#include "openxr_action.h"
+
+class OpenXRActionSet : public Resource {
+ GDCLASS(OpenXRActionSet, Resource);
+
+private:
+ String localized_name;
+ int priority = 0;
+
+ Array actions;
+
+protected:
+ static void _bind_methods();
+
+public:
+ static Ref new_action_set(const char *p_name, const char *p_localized_name, const int p_priority = 0);
+
+ void set_localized_name(const String p_localized_name);
+ String get_localized_name() const;
+
+ void set_priority(const int p_priority);
+ int get_priority() const;
+
+ void set_actions(Array p_actions);
+ Array get_actions() const;
+
+ void add_action(Ref p_action);
+ void remove_action(Ref p_action);
+
+ Ref add_new_action(const char *p_name, const char *p_localized_name, const OpenXRAction::ActionType p_action_type, const char *p_toplevel_paths);
+
+ ~OpenXRActionSet();
+};
+
+#endif // !OPENXR_ACTION_SET_H
diff --git a/modules/openxr/action_map/openxr_interaction_profile.cpp b/modules/openxr/action_map/openxr_interaction_profile.cpp
new file mode 100644
index 0000000000..bc33814f17
--- /dev/null
+++ b/modules/openxr/action_map/openxr_interaction_profile.cpp
@@ -0,0 +1,136 @@
+/*************************************************************************/
+/* openxr_interaction_profile.cpp */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+
+#include "openxr_interaction_profile.h"
+
+void OpenXRIPBinding::_bind_methods() {
+ ClassDB::bind_method(D_METHOD("set_action", "action"), &OpenXRIPBinding::set_action);
+ ClassDB::bind_method(D_METHOD("get_action"), &OpenXRIPBinding::get_action);
+ ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "action", PROPERTY_HINT_RESOURCE_TYPE, "OpenXRAction"), "set_action", "get_action");
+
+ ClassDB::bind_method(D_METHOD("set_paths", "paths"), &OpenXRIPBinding::set_paths);
+ ClassDB::bind_method(D_METHOD("get_paths"), &OpenXRIPBinding::get_paths);
+ ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "paths", PROPERTY_HINT_ARRAY_TYPE, "STRING"), "set_paths", "get_paths");
+}
+
+Ref OpenXRIPBinding::new_binding(const Ref p_action, const char *p_paths) {
+ // This is a helper function to help build our default action sets
+
+ Ref binding;
+ binding.instantiate();
+ binding->set_action(p_action);
+ binding->parse_paths(String(p_paths));
+
+ return binding;
+}
+
+void OpenXRIPBinding::set_action(const Ref p_action) {
+ action = p_action;
+}
+
+Ref OpenXRIPBinding::get_action() const {
+ return action;
+}
+
+void OpenXRIPBinding::set_paths(const PackedStringArray p_paths) {
+ paths = p_paths;
+}
+
+PackedStringArray OpenXRIPBinding::get_paths() const {
+ return paths;
+}
+
+void OpenXRIPBinding::parse_paths(const String p_paths) {
+ paths = p_paths.split(",", false);
+}
+
+OpenXRIPBinding::~OpenXRIPBinding() {
+ action.unref();
+}
+
+void OpenXRInteractionProfile::_bind_methods() {
+ ClassDB::bind_method(D_METHOD("set_interaction_profile_path", "interaction_profile_path"), &OpenXRInteractionProfile::set_interaction_profile_path);
+ ClassDB::bind_method(D_METHOD("get_interaction_profile_path"), &OpenXRInteractionProfile::get_interaction_profile_path);
+ ADD_PROPERTY(PropertyInfo(Variant::STRING, "interaction_profile_path"), "set_interaction_profile_path", "get_interaction_profile_path");
+
+ ClassDB::bind_method(D_METHOD("set_bindings", "bindings"), &OpenXRInteractionProfile::set_bindings);
+ ClassDB::bind_method(D_METHOD("get_bindings"), &OpenXRInteractionProfile::get_bindings);
+ ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "bindings", PROPERTY_HINT_RESOURCE_TYPE, "OpenXRIPBinding", PROPERTY_USAGE_NO_EDITOR), "set_bindings", "get_bindings");
+}
+
+Ref OpenXRInteractionProfile::new_profile(const char *p_input_profile_path) {
+ Ref profile;
+ profile.instantiate();
+ profile->set_interaction_profile_path(String(p_input_profile_path));
+
+ return profile;
+}
+
+void OpenXRInteractionProfile::set_interaction_profile_path(const String p_input_profile_path) {
+ interaction_profile_path = p_input_profile_path;
+}
+
+String OpenXRInteractionProfile::get_interaction_profile_path() const {
+ return interaction_profile_path;
+}
+
+void OpenXRInteractionProfile::set_bindings(Array p_bindings) {
+ bindings = p_bindings;
+}
+
+Array OpenXRInteractionProfile::get_bindings() const {
+ return bindings;
+}
+
+void OpenXRInteractionProfile::add_binding(Ref p_binding) {
+ ERR_FAIL_COND(p_binding.is_null());
+
+ if (bindings.find(p_binding) == -1) {
+ bindings.push_back(p_binding);
+ }
+}
+
+void OpenXRInteractionProfile::remove_binding(Ref p_binding) {
+ int idx = bindings.find(p_binding);
+ if (idx != -1) {
+ bindings.remove_at(idx);
+ }
+}
+
+void OpenXRInteractionProfile::add_new_binding(const Ref p_action, const char *p_paths) {
+ // This is a helper function to help build our default action sets
+
+ Ref binding = OpenXRIPBinding::new_binding(p_action, p_paths);
+ add_binding(binding);
+}
+
+OpenXRInteractionProfile::~OpenXRInteractionProfile() {
+ bindings.clear();
+}
diff --git a/modules/openxr/action_map/openxr_interaction_profile.h b/modules/openxr/action_map/openxr_interaction_profile.h
new file mode 100644
index 0000000000..abbc429e7d
--- /dev/null
+++ b/modules/openxr/action_map/openxr_interaction_profile.h
@@ -0,0 +1,89 @@
+/*************************************************************************/
+/* openxr_interaction_profile.h */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+
+#ifndef OPENXR_INTERACTION_PROFILE_H
+#define OPENXR_INTERACTION_PROFILE_H
+
+#include "core/io/resource.h"
+
+#include "openxr_action.h"
+
+class OpenXRIPBinding : public Resource {
+ GDCLASS(OpenXRIPBinding, Resource);
+
+private:
+ Ref action;
+ PackedStringArray paths;
+
+protected:
+ static void _bind_methods();
+
+public:
+ static Ref new_binding(const Ref p_action, const char *p_paths);
+
+ void set_action(const Ref p_action);
+ Ref get_action() const;
+
+ void set_paths(const PackedStringArray p_paths);
+ PackedStringArray get_paths() const;
+
+ void parse_paths(const String p_paths);
+
+ ~OpenXRIPBinding();
+};
+
+class OpenXRInteractionProfile : public Resource {
+ GDCLASS(OpenXRInteractionProfile, Resource);
+
+private:
+ String interaction_profile_path;
+ Array bindings;
+
+protected:
+ static void _bind_methods();
+
+public:
+ static Ref new_profile(const char *p_input_profile_path);
+
+ void set_interaction_profile_path(const String p_input_profile_path);
+ String get_interaction_profile_path() const;
+
+ void set_bindings(Array p_bindings);
+ Array get_bindings() const;
+
+ void add_binding(Ref p_binding);
+ void remove_binding(Ref p_binding);
+
+ void add_new_binding(const Ref p_action, const char *p_paths);
+
+ ~OpenXRInteractionProfile();
+};
+
+#endif // !OPENXR_INTERACTION_PROFILE_H
diff --git a/modules/openxr/config.py b/modules/openxr/config.py
new file mode 100644
index 0000000000..f91cb1359f
--- /dev/null
+++ b/modules/openxr/config.py
@@ -0,0 +1,27 @@
+def can_build(env, platform):
+ if (
+ platform == "linuxbsd" or platform == "windows"
+ ): # or platform == "android" -- temporarily disabled android support
+ return env["openxr"]
+ else:
+ # not supported on these platforms
+ return False
+
+
+def configure(env):
+ pass
+
+
+def get_doc_classes():
+ return [
+ "OpenXRInterface",
+ "OpenXRAction",
+ "OpenXRActionSet",
+ "OpenXRActionMap",
+ "OpenXRInteractionProfile",
+ "OpenXRIPBinding",
+ ]
+
+
+def get_doc_path():
+ return "doc_classes"
diff --git a/modules/openxr/doc_classes/OpenXRAction.xml b/modules/openxr/doc_classes/OpenXRAction.xml
new file mode 100644
index 0000000000..6ff8c1ad26
--- /dev/null
+++ b/modules/openxr/doc_classes/OpenXRAction.xml
@@ -0,0 +1,38 @@
+
+
+
+ An OpenXR action.
+
+
+ This resource defines an OpenXR action. Actions can be used both for inputs (buttons/joystick/trigger/etc) and outputs (haptics).
+ OpenXR performs automatic conversion between action type and input type whenever possible. An analogue trigger bound to a boolean action will thus return [code]false[/core] if the trigger is depressed and [code]true[/code] if pressed fully.
+ Actions are not directly bound to specific devices, instead OpenXR recognises a limited number of top level paths that identify devices by usage. We can restrict which devices an action can be bound to by these top level paths. For instance an action that should only be used for hand held controllers can have the top level paths "/user/hand/left" and "/user/hand/right" associated with them. See the [url=https://www.khronos.org/registry/OpenXR/specs/1.0/html/xrspec.html#semantic-path-reserved]reserved path section in the OpenXR specification[/url] for more info on the top level paths.
+ Note that the name of the resource is used to register the action with.
+
+
+
+
+
+ The type of action.
+
+
+ The localised description of this action.
+
+
+ A collections of toplevel paths to which this action can be bound.
+
+
+
+
+ This action provides a boolean value.
+
+
+ This action provides a float value between [code]0.0[/code] and [code]1.0[/code] for any analogue input such as triggers.
+
+
+ This action provides a vector2 value and can be bound to embedded trackpads and joysticks
+
+
+
+
+
diff --git a/modules/openxr/doc_classes/OpenXRActionMap.xml b/modules/openxr/doc_classes/OpenXRActionMap.xml
new file mode 100644
index 0000000000..f1def8aad8
--- /dev/null
+++ b/modules/openxr/doc_classes/OpenXRActionMap.xml
@@ -0,0 +1,55 @@
+
+
+
+ Collection of [OpenXRActionSet] and [OpenXRInteractionProfile] resources for the OpenXR module.
+
+
+ OpenXR uses an action system similar to Godots Input map system to bind inputs and outputs on various types of XR controllers to named actions. OpenXR specifies more detail on these inputs and outputs than Godot supports.
+ Another important distinction is that OpenXR offers no control over these bindings. The bindings we register are suggestions, it is up to the XR runtime to offer users the ability to change these bindings. This allows the XR runtime to fill in the gaps if new hardware becomes available.
+ The action map therefor needs to be loaded at startup and can't be changed afterwards. This resource is a container for the entire action map.
+
+
+
+
+
+
+
+
+ Add an action set.
+
+
+
+
+
+
+ Add an interaction profile.
+
+
+
+
+
+ Setup this action set with our default actions.
+
+
+
+
+
+
+ Remove an action set.
+
+
+
+
+
+
+ Remove an interaction profile.
+
+
+
+
+
+
+
+
+
+
diff --git a/modules/openxr/doc_classes/OpenXRActionSet.xml b/modules/openxr/doc_classes/OpenXRActionSet.xml
new file mode 100644
index 0000000000..5a87de463e
--- /dev/null
+++ b/modules/openxr/doc_classes/OpenXRActionSet.xml
@@ -0,0 +1,40 @@
+
+
+
+ Collection of [OpenXRAction] resources that make up an action set.
+
+
+ Action sets in OpenXR define a collection of actions that can be activated in unison. This allows games to easily change between different states that require different inputs or need to reinterpret inputs. For instance we could have an action set that is active when a menu is open, an action set that is active when the player is freely walking around and an action set that is active when the player is controlling a vehicle.
+ Action sets can contain the same actions, or actions with the same name, if such action sets are active at the same time the action set with the highest priority defines which binding is active.
+ Note that the name of the resource is used to identify the action set within OpenXR.
+
+
+
+
+
+
+
+
+ Add an action to this action set.
+
+
+
+
+
+
+ Remove an action from this action set.
+
+
+
+
+
+ Collection of actions for this action set.
+
+
+ The localised name of this action set.
+
+
+ The priority for this action set.
+
+
+
diff --git a/modules/openxr/doc_classes/OpenXRIPBinding.xml b/modules/openxr/doc_classes/OpenXRIPBinding.xml
new file mode 100644
index 0000000000..3fdcde5eb5
--- /dev/null
+++ b/modules/openxr/doc_classes/OpenXRIPBinding.xml
@@ -0,0 +1,19 @@
+
+
+
+ Defines a binding between an [OpenXRAction] and an XR input or output.
+
+
+ This binding resource binds an OpenXR action to inputs or outputs. As most controllers have left hand and right versions that are handled by the same interaction profile we can specify multiple bindings. For instance an action "Fire" could be bound to both "/user/hand/left/input/trigger" and "/user/hand/right/input/trigger".
+
+
+
+
+
+ Action that is bound to these paths.
+
+
+ Paths that define the inputs or outputs bound on the device.
+
+
+
diff --git a/modules/openxr/doc_classes/OpenXRInteractionProfile.xml b/modules/openxr/doc_classes/OpenXRInteractionProfile.xml
new file mode 100644
index 0000000000..a8629caae4
--- /dev/null
+++ b/modules/openxr/doc_classes/OpenXRInteractionProfile.xml
@@ -0,0 +1,20 @@
+
+
+
+ Suggested bindings object for OpenXR.
+
+
+ This object stores suggested bindings for an interaction profile. Interaction profiles define the meta data for a tracked XR device such as an XR controller.
+ For more information see the [url=https://www.khronos.org/registry/OpenXR/specs/1.0/html/xrspec.html#semantic-path-interaction-profiles]interaction profiles info in the OpenXR specification[/url].
+
+
+
+
+
+ Action bindings for this interaction profile.
+
+
+ The interaction profile path identifying the XR device.
+
+
+
diff --git a/modules/openxr/doc_classes/OpenXRInterface.xml b/modules/openxr/doc_classes/OpenXRInterface.xml
new file mode 100644
index 0000000000..1160061e04
--- /dev/null
+++ b/modules/openxr/doc_classes/OpenXRInterface.xml
@@ -0,0 +1,13 @@
+
+
+
+ Our OpenXR interface.
+
+
+ The OpenXR interface allows Godot to interact with OpenXR runtimes and make it possible to create XR experiences and games.
+ Due to the needs of OpenXR this interface works slightly different then other plugin based XR interfaces. It needs to be initialised when Godot starts. You need to enable OpenXR, settings for this can be found in your games project settings under the XR heading. You do need to mark a viewport for use with XR in order for Godot to know which render result should be output to the headset.
+
+
+ $DOCS_URL/tutorials/vr/openxr/index.html
+
+
diff --git a/modules/openxr/extensions/openxr_android_extension.cpp b/modules/openxr/extensions/openxr_android_extension.cpp
new file mode 100644
index 0000000000..3bd4db169c
--- /dev/null
+++ b/modules/openxr/extensions/openxr_android_extension.cpp
@@ -0,0 +1,71 @@
+/*************************************************************************/
+/* openxr_android_extension.cpp */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+
+#include "openxr_android_extension.h"
+
+#include
+#include
+
+OpenXRAndroidExtension *OpenXRAndroidExtension::singleton = nullptr;
+
+OpenXRAndroidExtension *OpenXRAndroidExtension::get_singleton() {
+ return singleton;
+}
+
+OpenXRAndroidExtension::OpenXRAndroidExtension(OpenXRAPI *p_openxr_api) :
+ OpenXRExtensionWrapper(p_openxr_api) {
+ singleton = this;
+
+ request_extensions[XR_KHR_ANDROID_THREAD_SETTINGS_EXTENSION_NAME] = nullptr; // must be available
+
+ // Initialize the loader
+ PFN_xrInitializeLoaderKHR xrInitializeLoaderKHR;
+ result = xrGetInstanceProcAddr(XR_NULL_HANDLE, "xrInitializeLoaderKHR", (PFN_xrVoidFunction *)(&xrInitializeLoaderKHR));
+ ERR_FAIL_COND_MSG(XR_FAILED(result), "Failed to retrieve pointer to xrInitializeLoaderKHR");
+
+ // TODO fix this code, this is still code from GDNative!
+ JNIEnv *env = android_api->godot_android_get_env();
+ JavaVM *vm;
+ env->GetJavaVM(&vm);
+ jobject activity_object = env->NewGlobalRef(android_api->godot_android_get_activity());
+
+ XrLoaderInitInfoAndroidKHR loader_init_info_android = {
+ .type = XR_TYPE_LOADER_INIT_INFO_ANDROID_KHR,
+ .next = nullptr,
+ .applicationVM = vm,
+ .applicationContext = activity_object
+ };
+ xrInitializeLoaderKHR((const XrLoaderInitInfoBaseHeaderKHR *)&loader_init_info_android);
+ ERR_FAIL_COND_MSG(XR_FAILED(result), "Failed to call xrInitializeLoaderKHR");
+}
+
+OpenXRAndroidExtension::~OpenXRAndroidExtension() {
+ singleton = nullptr;
+}
diff --git a/modules/openxr/extensions/openxr_android_extension.h b/modules/openxr/extensions/openxr_android_extension.h
new file mode 100644
index 0000000000..e102197a55
--- /dev/null
+++ b/modules/openxr/extensions/openxr_android_extension.h
@@ -0,0 +1,47 @@
+/*************************************************************************/
+/* openxr_android_extension.h */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+
+#ifndef OPENXR_ANDROID_EXTENSION_H
+#define OPENXR_ANDROID_EXTENSION_H
+
+#include "openxr_extension_wrapper.h"
+
+class OpenXRAndroidExtension : public OpenXRExtensionWrapper {
+public:
+ static OpenXRAndroidExtension *get_singleton();
+
+ OpenXRAndroidExtension(OpenXRAPI *p_openxr_api);
+ virtual ~OpenXRAndroidExtension() override;
+
+private:
+ static OpenXRAndroidExtension *singleton;
+};
+
+#endif // !OPENXR_ANDROID_EXTENSION_H
diff --git a/modules/openxr/extensions/openxr_composition_layer_provider.h b/modules/openxr/extensions/openxr_composition_layer_provider.h
new file mode 100644
index 0000000000..019dffa2a8
--- /dev/null
+++ b/modules/openxr/extensions/openxr_composition_layer_provider.h
@@ -0,0 +1,45 @@
+/*************************************************************************/
+/* openxr_composition_layer_provider.h */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+
+#ifndef OPENXR_COMPOSITION_LAYER_PROVIDER_H
+#define OPENXR_COMPOSITION_LAYER_PROVIDER_H
+
+#include
+
+// Interface for OpenXR extensions that provide a composition layer.
+class OpenXRCompositionLayerProvider {
+public:
+ // TODO changed to normal method definition for now
+ // CI complains until we implement this, haven't ported it yet from plugin
+ // virtual XrCompositionLayerBaseHeader *get_composition_layer() = 0;
+ XrCompositionLayerBaseHeader *get_composition_layer() { return nullptr; };
+};
+
+#endif // OPENXR_COMPOSITION_LAYER_PROVIDER_H
diff --git a/modules/openxr/extensions/openxr_extension_wrapper.h b/modules/openxr/extensions/openxr_extension_wrapper.h
new file mode 100644
index 0000000000..5242ee6063
--- /dev/null
+++ b/modules/openxr/extensions/openxr_extension_wrapper.h
@@ -0,0 +1,106 @@
+/*************************************************************************/
+/* openxr_extension_wrapper.h */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+
+#ifndef OPENXR_EXTENSION_WRAPPER_H
+#define OPENXR_EXTENSION_WRAPPER_H
+
+#include "core/error/error_macros.h"
+#include "core/math/camera_matrix.h"
+#include "core/templates/map.h"
+#include "core/templates/rid.h"
+
+#include "thirdparty/openxr/src/common/xr_linear.h"
+#include
+
+class OpenXRAPI;
+
+class OpenXRExtensionWrapper {
+protected:
+ OpenXRAPI *openxr_api;
+
+ // Store extension we require.
+ // If bool pointer is a nullptr this means this extension is mandatory and initialisation will fail if it is not available
+ // If bool pointer is set, value will be set to true or false depending on whether extension is available
+ Map request_extensions;
+
+public:
+ virtual Map get_request_extensions() {
+ return request_extensions;
+ }
+
+ // These functions allow an extension to add entries to a struct chain.
+ // `p_next_pointer` points to the last struct that was created for this chain
+ // and should be used as the value for the `pNext` pointer in the first struct you add.
+ // You should return the pointer to the last struct you define as your result.
+ // If you are not adding any structs, just return `p_next_pointer`.
+ // See existing extensions for examples of this implementation.
+ virtual void *set_system_properties_and_get_next_pointer(void *p_next_pointer) { return p_next_pointer; }
+ virtual void *set_session_create_and_get_next_pointer(void *p_next_pointer) { return p_next_pointer; }
+ virtual void *set_swapchain_create_info_and_get_next_pointer(void *p_next_pointer) { return p_next_pointer; }
+
+ virtual void on_instance_created(const XrInstance p_instance) {}
+ virtual void on_instance_destroyed() {}
+ virtual void on_session_created(const XrSession p_instance) {}
+ virtual void on_process() {}
+ virtual void on_pre_render() {}
+ virtual void on_session_destroyed() {}
+
+ virtual void on_state_idle() {}
+ virtual void on_state_ready() {}
+ virtual void on_state_synchronized() {}
+ virtual void on_state_visible() {}
+ virtual void on_state_focused() {}
+ virtual void on_state_stopping() {}
+ virtual void on_state_loss_pending() {}
+ virtual void on_state_exiting() {}
+
+ // Returns true if the event was handled, false otherwise.
+ virtual bool on_event_polled(const XrEventDataBuffer &event) {
+ return false;
+ }
+
+ OpenXRExtensionWrapper(OpenXRAPI *p_openxr_api) { openxr_api = p_openxr_api; };
+ virtual ~OpenXRExtensionWrapper() = default;
+};
+
+class OpenXRGraphicsExtensionWrapper : public OpenXRExtensionWrapper {
+public:
+ virtual void get_usable_swapchain_formats(Vector &p_usable_swap_chains) = 0;
+ virtual String get_swapchain_format_name(int64_t p_swapchain_format) const = 0;
+ virtual bool get_swapchain_image_data(XrSwapchain p_swapchain, int64_t p_swapchain_format, uint32_t p_width, uint32_t p_height, uint32_t p_sample_count, uint32_t p_array_size, void **r_swapchain_graphics_data) = 0;
+ virtual void cleanup_swapchain_graphics_data(void **p_swapchain_graphics_data) = 0;
+ virtual bool create_projection_fov(const XrFovf p_fov, double p_z_near, double p_z_far, CameraMatrix &r_camera_matrix) = 0;
+ virtual bool copy_render_target_to_image(RID p_from_render_target, void *p_swapchain_graphics_data, int p_image_index) = 0;
+
+ OpenXRGraphicsExtensionWrapper(OpenXRAPI *p_openxr_api) :
+ OpenXRExtensionWrapper(p_openxr_api){};
+};
+
+#endif // ~OPENXR_EXTENSION_WRAPPER_H
diff --git a/modules/openxr/extensions/openxr_vulkan_extension.cpp b/modules/openxr/extensions/openxr_vulkan_extension.cpp
new file mode 100644
index 0000000000..ba790500f9
--- /dev/null
+++ b/modules/openxr/extensions/openxr_vulkan_extension.cpp
@@ -0,0 +1,695 @@
+/*************************************************************************/
+/* openxr_vulkan_extension.cpp */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+
+#include "core/string/print_string.h"
+
+#include "modules/openxr/extensions/openxr_vulkan_extension.h"
+#include "modules/openxr/openxr_api.h"
+#include "modules/openxr/openxr_util.h"
+#include "servers/rendering/renderer_rd/renderer_storage_rd.h"
+#include "servers/rendering/rendering_server_globals.h"
+#include "servers/rendering_server.h"
+
+// need to include Vulkan so we know of type definitions
+#define XR_USE_GRAPHICS_API_VULKAN
+
+#ifdef WINDOWS_ENABLED
+// Including windows.h here is absolutely evil, we shouldn't be doing this outside of platform
+// however due to the way the openxr headers are put together, we have no choice.
+#include
+#endif
+
+// include platform dependent structs
+#include
+
+PFN_xrGetVulkanGraphicsRequirements2KHR xrGetVulkanGraphicsRequirements2KHR_ptr = nullptr;
+PFN_xrCreateVulkanInstanceKHR xrCreateVulkanInstanceKHR_ptr = nullptr;
+PFN_xrGetVulkanGraphicsDevice2KHR xrGetVulkanGraphicsDevice2KHR_ptr = nullptr;
+PFN_xrCreateVulkanDeviceKHR xrCreateVulkanDeviceKHR_ptr = nullptr;
+
+OpenXRVulkanExtension::OpenXRVulkanExtension(OpenXRAPI *p_openxr_api) :
+ OpenXRGraphicsExtensionWrapper(p_openxr_api) {
+ VulkanContext::set_vulkan_hooks(this);
+
+ request_extensions[XR_KHR_VULKAN_ENABLE2_EXTENSION_NAME] = nullptr; // must be available
+
+ ERR_FAIL_NULL(openxr_api);
+}
+
+OpenXRVulkanExtension::~OpenXRVulkanExtension() {
+ VulkanContext::set_vulkan_hooks(nullptr);
+}
+
+void OpenXRVulkanExtension::on_instance_created(const XrInstance p_instance) {
+ XrResult result;
+
+ ERR_FAIL_NULL(openxr_api);
+
+ // Obtain pointers to functions we're accessing here, they are (not yet) part of core.
+ result = xrGetInstanceProcAddr(p_instance, "xrGetVulkanGraphicsRequirements2KHR", (PFN_xrVoidFunction *)&xrGetVulkanGraphicsRequirements2KHR_ptr);
+ if (XR_FAILED(result)) {
+ print_line("OpenXR: Failed to xrGetVulkanGraphicsRequirements2KHR entry point [", openxr_api->get_error_string(result), "]");
+ }
+
+ result = xrGetInstanceProcAddr(p_instance, "xrCreateVulkanInstanceKHR", (PFN_xrVoidFunction *)&xrCreateVulkanInstanceKHR_ptr);
+ if (XR_FAILED(result)) {
+ print_line("OpenXR: Failed to xrCreateVulkanInstanceKHR entry point [", openxr_api->get_error_string(result), "]");
+ }
+
+ result = xrGetInstanceProcAddr(p_instance, "xrGetVulkanGraphicsDevice2KHR", (PFN_xrVoidFunction *)&xrGetVulkanGraphicsDevice2KHR_ptr);
+ if (XR_FAILED(result)) {
+ print_line("OpenXR: Failed to xrGetVulkanGraphicsDevice2KHR entry point [", openxr_api->get_error_string(result), "]");
+ }
+
+ result = xrGetInstanceProcAddr(p_instance, "xrCreateVulkanDeviceKHR", (PFN_xrVoidFunction *)&xrCreateVulkanDeviceKHR_ptr);
+ if (XR_FAILED(result)) {
+ print_line("OpenXR: Failed to xrCreateVulkanDeviceKHR entry point [", openxr_api->get_error_string(result), "]");
+ }
+}
+
+XrResult OpenXRVulkanExtension::xrGetVulkanGraphicsRequirements2KHR(XrInstance p_instance, XrSystemId p_system_id, XrGraphicsRequirementsVulkanKHR *p_graphics_requirements) {
+ ERR_FAIL_NULL_V(xrGetVulkanGraphicsRequirements2KHR_ptr, XR_ERROR_HANDLE_INVALID);
+
+ return (*xrGetVulkanGraphicsRequirements2KHR_ptr)(p_instance, p_system_id, p_graphics_requirements);
+}
+
+bool OpenXRVulkanExtension::check_graphics_api_support(XrVersion p_desired_version) {
+ ERR_FAIL_NULL_V(openxr_api, false);
+
+ XrGraphicsRequirementsVulkan2KHR vulkan_requirements = {
+ XR_TYPE_GRAPHICS_REQUIREMENTS_VULKAN2_KHR, // type
+ nullptr, // next
+ 0, // minApiVersionSupported
+ 0 // maxApiVersionSupported
+ };
+
+ XrResult result = xrGetVulkanGraphicsRequirements2KHR(openxr_api->get_instance(), openxr_api->get_system_id(), &vulkan_requirements);
+ if (XR_FAILED(result)) {
+ print_line("OpenXR: Failed to get vulkan graphics requirements [", openxr_api->get_error_string(result), "]");
+ return false;
+ }
+
+ // #ifdef DEBUG
+ print_line("OpenXR: XrGraphicsRequirementsVulkan2KHR:");
+ print_line(" - minApiVersionSupported: ", OpenXRUtil::make_xr_version_string(vulkan_requirements.minApiVersionSupported));
+ print_line(" - maxApiVersionSupported: ", OpenXRUtil::make_xr_version_string(vulkan_requirements.maxApiVersionSupported));
+ // #endif
+
+ if (p_desired_version < vulkan_requirements.minApiVersionSupported) {
+ print_line("OpenXR: Requested Vulkan version does not meet the minimum version this runtime supports.");
+ print_line("- desired_version ", OpenXRUtil::make_xr_version_string(p_desired_version));
+ print_line("- minApiVersionSupported ", OpenXRUtil::make_xr_version_string(vulkan_requirements.minApiVersionSupported));
+ print_line("- maxApiVersionSupported ", OpenXRUtil::make_xr_version_string(vulkan_requirements.maxApiVersionSupported));
+ return false;
+ }
+
+ if (p_desired_version > vulkan_requirements.maxApiVersionSupported) {
+ print_line("OpenXR: Requested Vulkan version exceeds the maximum version this runtime has been tested on and is known to support.");
+ print_line("- desired_version ", OpenXRUtil::make_xr_version_string(p_desired_version));
+ print_line("- minApiVersionSupported ", OpenXRUtil::make_xr_version_string(vulkan_requirements.minApiVersionSupported));
+ print_line("- maxApiVersionSupported ", OpenXRUtil::make_xr_version_string(vulkan_requirements.maxApiVersionSupported));
+ }
+
+ return true;
+}
+
+XrResult OpenXRVulkanExtension::xrCreateVulkanInstanceKHR(XrInstance p_instance, const XrVulkanInstanceCreateInfoKHR *p_create_info, VkInstance *r_vulkan_instance, VkResult *r_vulkan_result) {
+ ERR_FAIL_NULL_V(xrCreateVulkanInstanceKHR_ptr, XR_ERROR_HANDLE_INVALID);
+
+ return (*xrCreateVulkanInstanceKHR_ptr)(p_instance, p_create_info, r_vulkan_instance, r_vulkan_result);
+}
+
+bool OpenXRVulkanExtension::create_vulkan_instance(const VkInstanceCreateInfo *p_vulkan_create_info, VkInstance *r_instance) {
+ // get the vulkan version we are creating
+ uint32_t vulkan_version = p_vulkan_create_info->pApplicationInfo->apiVersion;
+ uint32_t major_version = VK_VERSION_MAJOR(vulkan_version);
+ uint32_t minor_version = VK_VERSION_MINOR(vulkan_version);
+ uint32_t patch_version = VK_VERSION_PATCH(vulkan_version);
+ XrVersion desired_version = XR_MAKE_VERSION(major_version, minor_version, patch_version);
+
+ // check if this is supported
+ if (!check_graphics_api_support(desired_version)) {
+ return false;
+ }
+
+ XrVulkanInstanceCreateInfoKHR xr_vulkan_instance_info = {
+ XR_TYPE_VULKAN_INSTANCE_CREATE_INFO_KHR, // type
+ nullptr, // next
+ openxr_api->get_system_id(), // systemId
+ 0, // createFlags
+ vkGetInstanceProcAddr, // pfnGetInstanceProcAddr
+ p_vulkan_create_info, // vulkanCreateInfo
+ nullptr, // vulkanAllocator
+ };
+
+ VkResult vk_result = VK_SUCCESS;
+ XrResult result = xrCreateVulkanInstanceKHR(openxr_api->get_instance(), &xr_vulkan_instance_info, &vulkan_instance, &vk_result);
+ if (XR_FAILED(result)) {
+ print_line("OpenXR: Failed to create vulkan instance [", openxr_api->get_error_string(result), "]");
+ return false;
+ }
+
+ ERR_FAIL_COND_V_MSG(vk_result == VK_ERROR_INCOMPATIBLE_DRIVER, false,
+ "Cannot find a compatible Vulkan installable client driver (ICD).\n\n"
+ "vkCreateInstance Failure");
+ ERR_FAIL_COND_V_MSG(vk_result == VK_ERROR_EXTENSION_NOT_PRESENT, false,
+ "Cannot find a specified extension library.\n"
+ "Make sure your layers path is set appropriately.\n"
+ "vkCreateInstance Failure");
+ ERR_FAIL_COND_V_MSG(vk_result, false,
+ "vkCreateInstance failed.\n\n"
+ "Do you have a compatible Vulkan installable client driver (ICD) installed?\n"
+ "Please look at the Getting Started guide for additional information.\n"
+ "vkCreateInstance Failure");
+
+ *r_instance = vulkan_instance;
+
+ return true;
+}
+
+XrResult OpenXRVulkanExtension::xrGetVulkanGraphicsDevice2KHR(XrInstance p_instance, const XrVulkanGraphicsDeviceGetInfoKHR *p_get_info, VkPhysicalDevice *r_vulkan_physical_device) {
+ ERR_FAIL_NULL_V(xrGetVulkanGraphicsDevice2KHR_ptr, XR_ERROR_HANDLE_INVALID);
+
+ return (*xrGetVulkanGraphicsDevice2KHR_ptr)(p_instance, p_get_info, r_vulkan_physical_device);
+}
+
+bool OpenXRVulkanExtension::get_physical_device(VkPhysicalDevice *r_device) {
+ ERR_FAIL_NULL_V(openxr_api, false);
+
+ XrVulkanGraphicsDeviceGetInfoKHR get_info = {
+ XR_TYPE_VULKAN_GRAPHICS_DEVICE_GET_INFO_KHR, // type
+ nullptr, // next
+ openxr_api->get_system_id(), // systemId
+ vulkan_instance, // vulkanInstance
+ };
+
+ XrResult result = xrGetVulkanGraphicsDevice2KHR(openxr_api->get_instance(), &get_info, &vulkan_physical_device);
+ if (XR_FAILED(result)) {
+ print_line("OpenXR: Failed to obtain vulkan physical device [", openxr_api->get_error_string(result), "]");
+ return false;
+ }
+
+ *r_device = vulkan_physical_device;
+
+ return true;
+}
+
+XrResult OpenXRVulkanExtension::xrCreateVulkanDeviceKHR(XrInstance p_instance, const XrVulkanDeviceCreateInfoKHR *p_create_info, VkDevice *r_device, VkResult *r_result) {
+ ERR_FAIL_NULL_V(xrCreateVulkanDeviceKHR_ptr, XR_ERROR_HANDLE_INVALID);
+
+ return (*xrCreateVulkanDeviceKHR_ptr)(p_instance, p_create_info, r_device, r_result);
+}
+
+bool OpenXRVulkanExtension::create_vulkan_device(const VkDeviceCreateInfo *p_device_create_info, VkDevice *r_device) {
+ ERR_FAIL_NULL_V(openxr_api, false);
+
+ // the first entry in our queue list should be the one we need to remember...
+ vulkan_queue_family_index = p_device_create_info->pQueueCreateInfos[0].queueFamilyIndex;
+ vulkan_queue_index = 0; // ??
+
+ XrVulkanDeviceCreateInfoKHR create_info = {
+ XR_TYPE_VULKAN_DEVICE_CREATE_INFO_KHR, // type
+ nullptr, // next
+ openxr_api->get_system_id(), // systemId
+ 0, // createFlags
+ vkGetInstanceProcAddr, // pfnGetInstanceProcAddr
+ vulkan_physical_device, // vulkanPhysicalDevice
+ p_device_create_info, // vulkanCreateInfo
+ nullptr // vulkanAllocator
+ };
+
+ VkResult vk_result = VK_SUCCESS;
+ XrResult result = xrCreateVulkanDeviceKHR(openxr_api->get_instance(), &create_info, &vulkan_device, &vk_result);
+ if (XR_FAILED(result)) {
+ print_line("OpenXR: Failed to create vulkan device [", openxr_api->get_error_string(result), "]");
+ return false;
+ }
+
+ if (vk_result != VK_SUCCESS) {
+ print_line("OpenXR: Failed to create vulkan device [vulkan error", vk_result, "]");
+ }
+
+ *r_device = vulkan_device;
+
+ return true;
+}
+
+XrGraphicsBindingVulkanKHR OpenXRVulkanExtension::graphics_binding_vulkan;
+
+void *OpenXRVulkanExtension::set_session_create_and_get_next_pointer(void *p_next_pointer) {
+ graphics_binding_vulkan.type = XR_TYPE_GRAPHICS_BINDING_VULKAN_KHR;
+ graphics_binding_vulkan.next = p_next_pointer;
+ graphics_binding_vulkan.instance = vulkan_instance;
+ graphics_binding_vulkan.physicalDevice = vulkan_physical_device;
+ graphics_binding_vulkan.device = vulkan_device;
+ graphics_binding_vulkan.queueFamilyIndex = vulkan_queue_family_index;
+ graphics_binding_vulkan.queueIndex = vulkan_queue_index;
+
+ return &graphics_binding_vulkan;
+}
+
+void OpenXRVulkanExtension::get_usable_swapchain_formats(Vector &p_usable_swap_chains) {
+ // We might want to do more here especially if we keep things in linear color space
+ // Possibly add in R10G10B10A2 as an option if we're using the mobile renderer.
+ p_usable_swap_chains.push_back(VK_FORMAT_R8G8B8A8_SRGB);
+ p_usable_swap_chains.push_back(VK_FORMAT_B8G8R8A8_SRGB);
+ p_usable_swap_chains.push_back(VK_FORMAT_R8G8B8A8_UINT);
+ p_usable_swap_chains.push_back(VK_FORMAT_B8G8R8A8_UINT);
+}
+
+bool OpenXRVulkanExtension::get_swapchain_image_data(XrSwapchain p_swapchain, int64_t p_swapchain_format, uint32_t p_width, uint32_t p_height, uint32_t p_sample_count, uint32_t p_array_size, void **r_swapchain_graphics_data) {
+ XrSwapchainImageVulkanKHR *images = nullptr;
+
+ RenderingServer *rendering_server = RenderingServer::get_singleton();
+ ERR_FAIL_NULL_V(rendering_server, false);
+ RenderingDevice *rendering_device = rendering_server->get_rendering_device();
+ ERR_FAIL_NULL_V(rendering_device, false);
+
+ uint32_t swapchain_length;
+ XrResult result = xrEnumerateSwapchainImages(p_swapchain, 0, &swapchain_length, nullptr);
+ if (XR_FAILED(result)) {
+ print_line("OpenXR: Failed to get swapchaim image count [", openxr_api->get_error_string(result), "]");
+ return false;
+ }
+
+ images = (XrSwapchainImageVulkanKHR *)memalloc(sizeof(XrSwapchainImageVulkanKHR) * swapchain_length);
+ ERR_FAIL_NULL_V_MSG(images, false, "OpenXR Couldn't allocate memory for swap chain image");
+
+ for (uint64_t i = 0; i < swapchain_length; i++) {
+ images[i].type = XR_TYPE_SWAPCHAIN_IMAGE_VULKAN_KHR;
+ images[i].next = nullptr;
+ images[i].image = nullptr;
+ }
+
+ result = xrEnumerateSwapchainImages(p_swapchain, swapchain_length, &swapchain_length, (XrSwapchainImageBaseHeader *)images);
+ if (XR_FAILED(result)) {
+ print_line("OpenXR: Failed to get swapchaim images [", openxr_api->get_error_string(result), "]");
+ memfree(images);
+ return false;
+ }
+
+ // SwapchainGraphicsData *data = (SwapchainGraphicsData *)memalloc(sizeof(SwapchainGraphicsData));
+ SwapchainGraphicsData *data = memnew(SwapchainGraphicsData);
+ if (data == nullptr) {
+ print_line("OpenXR: Failed to allocate memory for swapchain data");
+ memfree(images);
+ return false;
+ }
+ *r_swapchain_graphics_data = data;
+ data->is_multiview = (p_array_size > 1);
+
+ RenderingDevice::DataFormat format = RenderingDevice::DATA_FORMAT_R8G8B8A8_SRGB; // TODO set this based on p_swapchain_format
+ RenderingDevice::TextureSamples samples = RenderingDevice::TEXTURE_SAMPLES_1; // TODO set this based on p_sample_count
+ uint64_t usage_flags = RenderingDevice::TEXTURE_USAGE_SAMPLING_BIT | RenderingDevice::TEXTURE_USAGE_COLOR_ATTACHMENT_BIT;
+
+ Vector image_rids;
+ Vector framebuffers;
+
+ // create Godot texture objects for each entry in our swapchain
+ for (uint64_t i = 0; i < swapchain_length; i++) {
+ RID image_rid = rendering_device->texture_create_from_extension(
+ p_array_size == 1 ? RenderingDevice::TEXTURE_TYPE_2D : RenderingDevice::TEXTURE_TYPE_2D_ARRAY,
+ format,
+ samples,
+ usage_flags,
+ (uint64_t)images[i].image,
+ p_width,
+ p_height,
+ 1,
+ p_array_size);
+
+ image_rids.push_back(image_rid);
+
+ {
+ Vector fb;
+ fb.push_back(image_rid);
+
+ RID fb_rid = rendering_device->framebuffer_create(fb, RenderingDevice::INVALID_ID, p_array_size);
+ framebuffers.push_back(fb_rid);
+ }
+ }
+
+ data->image_rids = image_rids;
+ data->framebuffers = framebuffers;
+
+ memfree(images);
+
+ return true;
+}
+
+bool OpenXRVulkanExtension::create_projection_fov(const XrFovf p_fov, double p_z_near, double p_z_far, CameraMatrix &r_camera_matrix) {
+ // Even though this is a Vulkan renderer we're using OpenGL coordinate systems
+ XrMatrix4x4f matrix;
+ XrMatrix4x4f_CreateProjectionFov(&matrix, GRAPHICS_OPENGL, p_fov, (float)p_z_near, (float)p_z_far);
+
+ for (int j = 0; j < 4; j++) {
+ for (int i = 0; i < 4; i++) {
+ r_camera_matrix.matrix[j][i] = matrix.m[j * 4 + i];
+ }
+ }
+
+ return true;
+}
+
+bool OpenXRVulkanExtension::copy_render_target_to_image(RID p_from_render_target, void *p_swapchain_graphics_data, int p_image_index) {
+ SwapchainGraphicsData *data = (SwapchainGraphicsData *)p_swapchain_graphics_data;
+ ERR_FAIL_NULL_V(data, false);
+ ERR_FAIL_COND_V(p_from_render_target.is_null(), false);
+ ERR_FAIL_NULL_V(RendererStorageRD::base_singleton, false);
+
+ RID source_image = RendererStorageRD::base_singleton->render_target_get_rd_texture(p_from_render_target);
+ ERR_FAIL_COND_V(source_image.is_null(), false);
+
+ RID depth_image; // TODO implement
+
+ ERR_FAIL_INDEX_V(p_image_index, data->framebuffers.size(), false);
+ RID fb = data->framebuffers[p_image_index];
+ ERR_FAIL_COND_V(fb.is_null(), false);
+
+ // Our vulkan extension can only be used in conjunction with our vulkan renderer.
+ // We need access to the effects object in order to have access to our copy logic.
+ // Breaking all the rules but there is no nice way to do this.
+ EffectsRD *effects = RendererStorageRD::base_singleton->get_effects();
+ ERR_FAIL_NULL_V(effects, false);
+ effects->copy_to_fb_rect(source_image, fb, Rect2i(), false, false, false, false, depth_image, data->is_multiview);
+
+ return true;
+}
+
+void OpenXRVulkanExtension::cleanup_swapchain_graphics_data(void **p_swapchain_graphics_data) {
+ if (*p_swapchain_graphics_data == nullptr) {
+ return;
+ }
+
+ SwapchainGraphicsData *data = (SwapchainGraphicsData *)*p_swapchain_graphics_data;
+
+ RenderingServer *rendering_server = RenderingServer::get_singleton();
+ ERR_FAIL_NULL(rendering_server);
+ RenderingDevice *rendering_device = rendering_server->get_rendering_device();
+ ERR_FAIL_NULL(rendering_device);
+
+ for (int i = 0; i < data->image_rids.size(); i++) {
+ // This should clean up our RIDs and associated texture objects but shouldn't destroy the images, they are owned by our XrSwapchain
+ rendering_device->free(data->image_rids[i]);
+ }
+ data->image_rids.clear();
+
+ for (int i = 0; i < data->framebuffers.size(); i++) {
+ // This should clean up our RIDs and associated texture objects but shouldn't destroy the images, they are owned by our XrSwapchain
+ rendering_device->free(data->framebuffers[i]);
+ }
+ data->framebuffers.clear();
+
+ memdelete(data);
+ *p_swapchain_graphics_data = nullptr;
+}
+
+#define ENUM_TO_STRING_CASE(e) \
+ case e: { \
+ return String(#e); \
+ } break;
+
+String OpenXRVulkanExtension::get_swapchain_format_name(int64_t p_swapchain_format) const {
+ // This really should be in vulkan_context...
+ VkFormat format = VkFormat(p_swapchain_format);
+ switch (format) {
+ ENUM_TO_STRING_CASE(VK_FORMAT_UNDEFINED)
+ ENUM_TO_STRING_CASE(VK_FORMAT_R4G4_UNORM_PACK8)
+ ENUM_TO_STRING_CASE(VK_FORMAT_R4G4B4A4_UNORM_PACK16)
+ ENUM_TO_STRING_CASE(VK_FORMAT_B4G4R4A4_UNORM_PACK16)
+ ENUM_TO_STRING_CASE(VK_FORMAT_R5G6B5_UNORM_PACK16)
+ ENUM_TO_STRING_CASE(VK_FORMAT_B5G6R5_UNORM_PACK16)
+ ENUM_TO_STRING_CASE(VK_FORMAT_R5G5B5A1_UNORM_PACK16)
+ ENUM_TO_STRING_CASE(VK_FORMAT_B5G5R5A1_UNORM_PACK16)
+ ENUM_TO_STRING_CASE(VK_FORMAT_A1R5G5B5_UNORM_PACK16)
+ ENUM_TO_STRING_CASE(VK_FORMAT_R8_UNORM)
+ ENUM_TO_STRING_CASE(VK_FORMAT_R8_SNORM)
+ ENUM_TO_STRING_CASE(VK_FORMAT_R8_USCALED)
+ ENUM_TO_STRING_CASE(VK_FORMAT_R8_SSCALED)
+ ENUM_TO_STRING_CASE(VK_FORMAT_R8_UINT)
+ ENUM_TO_STRING_CASE(VK_FORMAT_R8_SINT)
+ ENUM_TO_STRING_CASE(VK_FORMAT_R8_SRGB)
+ ENUM_TO_STRING_CASE(VK_FORMAT_R8G8_UNORM)
+ ENUM_TO_STRING_CASE(VK_FORMAT_R8G8_SNORM)
+ ENUM_TO_STRING_CASE(VK_FORMAT_R8G8_USCALED)
+ ENUM_TO_STRING_CASE(VK_FORMAT_R8G8_SSCALED)
+ ENUM_TO_STRING_CASE(VK_FORMAT_R8G8_UINT)
+ ENUM_TO_STRING_CASE(VK_FORMAT_R8G8_SINT)
+ ENUM_TO_STRING_CASE(VK_FORMAT_R8G8_SRGB)
+ ENUM_TO_STRING_CASE(VK_FORMAT_R8G8B8_UNORM)
+ ENUM_TO_STRING_CASE(VK_FORMAT_R8G8B8_SNORM)
+ ENUM_TO_STRING_CASE(VK_FORMAT_R8G8B8_USCALED)
+ ENUM_TO_STRING_CASE(VK_FORMAT_R8G8B8_SSCALED)
+ ENUM_TO_STRING_CASE(VK_FORMAT_R8G8B8_UINT)
+ ENUM_TO_STRING_CASE(VK_FORMAT_R8G8B8_SINT)
+ ENUM_TO_STRING_CASE(VK_FORMAT_R8G8B8_SRGB)
+ ENUM_TO_STRING_CASE(VK_FORMAT_B8G8R8_UNORM)
+ ENUM_TO_STRING_CASE(VK_FORMAT_B8G8R8_SNORM)
+ ENUM_TO_STRING_CASE(VK_FORMAT_B8G8R8_USCALED)
+ ENUM_TO_STRING_CASE(VK_FORMAT_B8G8R8_SSCALED)
+ ENUM_TO_STRING_CASE(VK_FORMAT_B8G8R8_UINT)
+ ENUM_TO_STRING_CASE(VK_FORMAT_B8G8R8_SINT)
+ ENUM_TO_STRING_CASE(VK_FORMAT_B8G8R8_SRGB)
+ ENUM_TO_STRING_CASE(VK_FORMAT_R8G8B8A8_UNORM)
+ ENUM_TO_STRING_CASE(VK_FORMAT_R8G8B8A8_SNORM)
+ ENUM_TO_STRING_CASE(VK_FORMAT_R8G8B8A8_USCALED)
+ ENUM_TO_STRING_CASE(VK_FORMAT_R8G8B8A8_SSCALED)
+ ENUM_TO_STRING_CASE(VK_FORMAT_R8G8B8A8_UINT)
+ ENUM_TO_STRING_CASE(VK_FORMAT_R8G8B8A8_SINT)
+ ENUM_TO_STRING_CASE(VK_FORMAT_R8G8B8A8_SRGB)
+ ENUM_TO_STRING_CASE(VK_FORMAT_B8G8R8A8_UNORM)
+ ENUM_TO_STRING_CASE(VK_FORMAT_B8G8R8A8_SNORM)
+ ENUM_TO_STRING_CASE(VK_FORMAT_B8G8R8A8_USCALED)
+ ENUM_TO_STRING_CASE(VK_FORMAT_B8G8R8A8_SSCALED)
+ ENUM_TO_STRING_CASE(VK_FORMAT_B8G8R8A8_UINT)
+ ENUM_TO_STRING_CASE(VK_FORMAT_B8G8R8A8_SINT)
+ ENUM_TO_STRING_CASE(VK_FORMAT_B8G8R8A8_SRGB)
+ ENUM_TO_STRING_CASE(VK_FORMAT_A8B8G8R8_UNORM_PACK32)
+ ENUM_TO_STRING_CASE(VK_FORMAT_A8B8G8R8_SNORM_PACK32)
+ ENUM_TO_STRING_CASE(VK_FORMAT_A8B8G8R8_USCALED_PACK32)
+ ENUM_TO_STRING_CASE(VK_FORMAT_A8B8G8R8_SSCALED_PACK32)
+ ENUM_TO_STRING_CASE(VK_FORMAT_A8B8G8R8_UINT_PACK32)
+ ENUM_TO_STRING_CASE(VK_FORMAT_A8B8G8R8_SINT_PACK32)
+ ENUM_TO_STRING_CASE(VK_FORMAT_A8B8G8R8_SRGB_PACK32)
+ ENUM_TO_STRING_CASE(VK_FORMAT_A2R10G10B10_UNORM_PACK32)
+ ENUM_TO_STRING_CASE(VK_FORMAT_A2R10G10B10_SNORM_PACK32)
+ ENUM_TO_STRING_CASE(VK_FORMAT_A2R10G10B10_USCALED_PACK32)
+ ENUM_TO_STRING_CASE(VK_FORMAT_A2R10G10B10_SSCALED_PACK32)
+ ENUM_TO_STRING_CASE(VK_FORMAT_A2R10G10B10_UINT_PACK32)
+ ENUM_TO_STRING_CASE(VK_FORMAT_A2R10G10B10_SINT_PACK32)
+ ENUM_TO_STRING_CASE(VK_FORMAT_A2B10G10R10_UNORM_PACK32)
+ ENUM_TO_STRING_CASE(VK_FORMAT_A2B10G10R10_SNORM_PACK32)
+ ENUM_TO_STRING_CASE(VK_FORMAT_A2B10G10R10_USCALED_PACK32)
+ ENUM_TO_STRING_CASE(VK_FORMAT_A2B10G10R10_SSCALED_PACK32)
+ ENUM_TO_STRING_CASE(VK_FORMAT_A2B10G10R10_UINT_PACK32)
+ ENUM_TO_STRING_CASE(VK_FORMAT_A2B10G10R10_SINT_PACK32)
+ ENUM_TO_STRING_CASE(VK_FORMAT_R16_UNORM)
+ ENUM_TO_STRING_CASE(VK_FORMAT_R16_SNORM)
+ ENUM_TO_STRING_CASE(VK_FORMAT_R16_USCALED)
+ ENUM_TO_STRING_CASE(VK_FORMAT_R16_SSCALED)
+ ENUM_TO_STRING_CASE(VK_FORMAT_R16_UINT)
+ ENUM_TO_STRING_CASE(VK_FORMAT_R16_SINT)
+ ENUM_TO_STRING_CASE(VK_FORMAT_R16_SFLOAT)
+ ENUM_TO_STRING_CASE(VK_FORMAT_R16G16_UNORM)
+ ENUM_TO_STRING_CASE(VK_FORMAT_R16G16_SNORM)
+ ENUM_TO_STRING_CASE(VK_FORMAT_R16G16_USCALED)
+ ENUM_TO_STRING_CASE(VK_FORMAT_R16G16_SSCALED)
+ ENUM_TO_STRING_CASE(VK_FORMAT_R16G16_UINT)
+ ENUM_TO_STRING_CASE(VK_FORMAT_R16G16_SINT)
+ ENUM_TO_STRING_CASE(VK_FORMAT_R16G16_SFLOAT)
+ ENUM_TO_STRING_CASE(VK_FORMAT_R16G16B16_UNORM)
+ ENUM_TO_STRING_CASE(VK_FORMAT_R16G16B16_SNORM)
+ ENUM_TO_STRING_CASE(VK_FORMAT_R16G16B16_USCALED)
+ ENUM_TO_STRING_CASE(VK_FORMAT_R16G16B16_SSCALED)
+ ENUM_TO_STRING_CASE(VK_FORMAT_R16G16B16_UINT)
+ ENUM_TO_STRING_CASE(VK_FORMAT_R16G16B16_SINT)
+ ENUM_TO_STRING_CASE(VK_FORMAT_R16G16B16_SFLOAT)
+ ENUM_TO_STRING_CASE(VK_FORMAT_R16G16B16A16_UNORM)
+ ENUM_TO_STRING_CASE(VK_FORMAT_R16G16B16A16_SNORM)
+ ENUM_TO_STRING_CASE(VK_FORMAT_R16G16B16A16_USCALED)
+ ENUM_TO_STRING_CASE(VK_FORMAT_R16G16B16A16_SSCALED)
+ ENUM_TO_STRING_CASE(VK_FORMAT_R16G16B16A16_UINT)
+ ENUM_TO_STRING_CASE(VK_FORMAT_R16G16B16A16_SINT)
+ ENUM_TO_STRING_CASE(VK_FORMAT_R16G16B16A16_SFLOAT)
+ ENUM_TO_STRING_CASE(VK_FORMAT_R32_UINT)
+ ENUM_TO_STRING_CASE(VK_FORMAT_R32_SINT)
+ ENUM_TO_STRING_CASE(VK_FORMAT_R32_SFLOAT)
+ ENUM_TO_STRING_CASE(VK_FORMAT_R32G32_UINT)
+ ENUM_TO_STRING_CASE(VK_FORMAT_R32G32_SINT)
+ ENUM_TO_STRING_CASE(VK_FORMAT_R32G32_SFLOAT)
+ ENUM_TO_STRING_CASE(VK_FORMAT_R32G32B32_UINT)
+ ENUM_TO_STRING_CASE(VK_FORMAT_R32G32B32_SINT)
+ ENUM_TO_STRING_CASE(VK_FORMAT_R32G32B32_SFLOAT)
+ ENUM_TO_STRING_CASE(VK_FORMAT_R32G32B32A32_UINT)
+ ENUM_TO_STRING_CASE(VK_FORMAT_R32G32B32A32_SINT)
+ ENUM_TO_STRING_CASE(VK_FORMAT_R32G32B32A32_SFLOAT)
+ ENUM_TO_STRING_CASE(VK_FORMAT_R64_UINT)
+ ENUM_TO_STRING_CASE(VK_FORMAT_R64_SINT)
+ ENUM_TO_STRING_CASE(VK_FORMAT_R64_SFLOAT)
+ ENUM_TO_STRING_CASE(VK_FORMAT_R64G64_UINT)
+ ENUM_TO_STRING_CASE(VK_FORMAT_R64G64_SINT)
+ ENUM_TO_STRING_CASE(VK_FORMAT_R64G64_SFLOAT)
+ ENUM_TO_STRING_CASE(VK_FORMAT_R64G64B64_UINT)
+ ENUM_TO_STRING_CASE(VK_FORMAT_R64G64B64_SINT)
+ ENUM_TO_STRING_CASE(VK_FORMAT_R64G64B64_SFLOAT)
+ ENUM_TO_STRING_CASE(VK_FORMAT_R64G64B64A64_UINT)
+ ENUM_TO_STRING_CASE(VK_FORMAT_R64G64B64A64_SINT)
+ ENUM_TO_STRING_CASE(VK_FORMAT_R64G64B64A64_SFLOAT)
+ ENUM_TO_STRING_CASE(VK_FORMAT_B10G11R11_UFLOAT_PACK32)
+ ENUM_TO_STRING_CASE(VK_FORMAT_E5B9G9R9_UFLOAT_PACK32)
+ ENUM_TO_STRING_CASE(VK_FORMAT_D16_UNORM)
+ ENUM_TO_STRING_CASE(VK_FORMAT_X8_D24_UNORM_PACK32)
+ ENUM_TO_STRING_CASE(VK_FORMAT_D32_SFLOAT)
+ ENUM_TO_STRING_CASE(VK_FORMAT_S8_UINT)
+ ENUM_TO_STRING_CASE(VK_FORMAT_D16_UNORM_S8_UINT)
+ ENUM_TO_STRING_CASE(VK_FORMAT_D24_UNORM_S8_UINT)
+ ENUM_TO_STRING_CASE(VK_FORMAT_D32_SFLOAT_S8_UINT)
+ ENUM_TO_STRING_CASE(VK_FORMAT_BC1_RGB_UNORM_BLOCK)
+ ENUM_TO_STRING_CASE(VK_FORMAT_BC1_RGB_SRGB_BLOCK)
+ ENUM_TO_STRING_CASE(VK_FORMAT_BC1_RGBA_UNORM_BLOCK)
+ ENUM_TO_STRING_CASE(VK_FORMAT_BC1_RGBA_SRGB_BLOCK)
+ ENUM_TO_STRING_CASE(VK_FORMAT_BC2_UNORM_BLOCK)
+ ENUM_TO_STRING_CASE(VK_FORMAT_BC2_SRGB_BLOCK)
+ ENUM_TO_STRING_CASE(VK_FORMAT_BC3_UNORM_BLOCK)
+ ENUM_TO_STRING_CASE(VK_FORMAT_BC3_SRGB_BLOCK)
+ ENUM_TO_STRING_CASE(VK_FORMAT_BC4_UNORM_BLOCK)
+ ENUM_TO_STRING_CASE(VK_FORMAT_BC4_SNORM_BLOCK)
+ ENUM_TO_STRING_CASE(VK_FORMAT_BC5_UNORM_BLOCK)
+ ENUM_TO_STRING_CASE(VK_FORMAT_BC5_SNORM_BLOCK)
+ ENUM_TO_STRING_CASE(VK_FORMAT_BC6H_UFLOAT_BLOCK)
+ ENUM_TO_STRING_CASE(VK_FORMAT_BC6H_SFLOAT_BLOCK)
+ ENUM_TO_STRING_CASE(VK_FORMAT_BC7_UNORM_BLOCK)
+ ENUM_TO_STRING_CASE(VK_FORMAT_BC7_SRGB_BLOCK)
+ ENUM_TO_STRING_CASE(VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK)
+ ENUM_TO_STRING_CASE(VK_FORMAT_ETC2_R8G8B8_SRGB_BLOCK)
+ ENUM_TO_STRING_CASE(VK_FORMAT_ETC2_R8G8B8A1_UNORM_BLOCK)
+ ENUM_TO_STRING_CASE(VK_FORMAT_ETC2_R8G8B8A1_SRGB_BLOCK)
+ ENUM_TO_STRING_CASE(VK_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK)
+ ENUM_TO_STRING_CASE(VK_FORMAT_ETC2_R8G8B8A8_SRGB_BLOCK)
+ ENUM_TO_STRING_CASE(VK_FORMAT_EAC_R11_UNORM_BLOCK)
+ ENUM_TO_STRING_CASE(VK_FORMAT_EAC_R11_SNORM_BLOCK)
+ ENUM_TO_STRING_CASE(VK_FORMAT_EAC_R11G11_UNORM_BLOCK)
+ ENUM_TO_STRING_CASE(VK_FORMAT_EAC_R11G11_SNORM_BLOCK)
+ ENUM_TO_STRING_CASE(VK_FORMAT_ASTC_4x4_UNORM_BLOCK)
+ ENUM_TO_STRING_CASE(VK_FORMAT_ASTC_4x4_SRGB_BLOCK)
+ ENUM_TO_STRING_CASE(VK_FORMAT_ASTC_5x4_UNORM_BLOCK)
+ ENUM_TO_STRING_CASE(VK_FORMAT_ASTC_5x4_SRGB_BLOCK)
+ ENUM_TO_STRING_CASE(VK_FORMAT_ASTC_5x5_UNORM_BLOCK)
+ ENUM_TO_STRING_CASE(VK_FORMAT_ASTC_5x5_SRGB_BLOCK)
+ ENUM_TO_STRING_CASE(VK_FORMAT_ASTC_6x5_UNORM_BLOCK)
+ ENUM_TO_STRING_CASE(VK_FORMAT_ASTC_6x5_SRGB_BLOCK)
+ ENUM_TO_STRING_CASE(VK_FORMAT_ASTC_6x6_UNORM_BLOCK)
+ ENUM_TO_STRING_CASE(VK_FORMAT_ASTC_6x6_SRGB_BLOCK)
+ ENUM_TO_STRING_CASE(VK_FORMAT_ASTC_8x5_UNORM_BLOCK)
+ ENUM_TO_STRING_CASE(VK_FORMAT_ASTC_8x5_SRGB_BLOCK)
+ ENUM_TO_STRING_CASE(VK_FORMAT_ASTC_8x6_UNORM_BLOCK)
+ ENUM_TO_STRING_CASE(VK_FORMAT_ASTC_8x6_SRGB_BLOCK)
+ ENUM_TO_STRING_CASE(VK_FORMAT_ASTC_8x8_UNORM_BLOCK)
+ ENUM_TO_STRING_CASE(VK_FORMAT_ASTC_8x8_SRGB_BLOCK)
+ ENUM_TO_STRING_CASE(VK_FORMAT_ASTC_10x5_UNORM_BLOCK)
+ ENUM_TO_STRING_CASE(VK_FORMAT_ASTC_10x5_SRGB_BLOCK)
+ ENUM_TO_STRING_CASE(VK_FORMAT_ASTC_10x6_UNORM_BLOCK)
+ ENUM_TO_STRING_CASE(VK_FORMAT_ASTC_10x6_SRGB_BLOCK)
+ ENUM_TO_STRING_CASE(VK_FORMAT_ASTC_10x8_UNORM_BLOCK)
+ ENUM_TO_STRING_CASE(VK_FORMAT_ASTC_10x8_SRGB_BLOCK)
+ ENUM_TO_STRING_CASE(VK_FORMAT_ASTC_10x10_UNORM_BLOCK)
+ ENUM_TO_STRING_CASE(VK_FORMAT_ASTC_10x10_SRGB_BLOCK)
+ ENUM_TO_STRING_CASE(VK_FORMAT_ASTC_12x10_UNORM_BLOCK)
+ ENUM_TO_STRING_CASE(VK_FORMAT_ASTC_12x10_SRGB_BLOCK)
+ ENUM_TO_STRING_CASE(VK_FORMAT_ASTC_12x12_UNORM_BLOCK)
+ ENUM_TO_STRING_CASE(VK_FORMAT_ASTC_12x12_SRGB_BLOCK)
+ ENUM_TO_STRING_CASE(VK_FORMAT_G8B8G8R8_422_UNORM)
+ ENUM_TO_STRING_CASE(VK_FORMAT_B8G8R8G8_422_UNORM)
+ ENUM_TO_STRING_CASE(VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM)
+ ENUM_TO_STRING_CASE(VK_FORMAT_G8_B8R8_2PLANE_420_UNORM)
+ ENUM_TO_STRING_CASE(VK_FORMAT_G8_B8_R8_3PLANE_422_UNORM)
+ ENUM_TO_STRING_CASE(VK_FORMAT_G8_B8R8_2PLANE_422_UNORM)
+ ENUM_TO_STRING_CASE(VK_FORMAT_G8_B8_R8_3PLANE_444_UNORM)
+ ENUM_TO_STRING_CASE(VK_FORMAT_R10X6_UNORM_PACK16)
+ ENUM_TO_STRING_CASE(VK_FORMAT_R10X6G10X6_UNORM_2PACK16)
+ ENUM_TO_STRING_CASE(VK_FORMAT_R10X6G10X6B10X6A10X6_UNORM_4PACK16)
+ ENUM_TO_STRING_CASE(VK_FORMAT_G10X6B10X6G10X6R10X6_422_UNORM_4PACK16)
+ ENUM_TO_STRING_CASE(VK_FORMAT_B10X6G10X6R10X6G10X6_422_UNORM_4PACK16)
+ ENUM_TO_STRING_CASE(VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_420_UNORM_3PACK16)
+ ENUM_TO_STRING_CASE(VK_FORMAT_G10X6_B10X6R10X6_2PLANE_420_UNORM_3PACK16)
+ ENUM_TO_STRING_CASE(VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_422_UNORM_3PACK16)
+ ENUM_TO_STRING_CASE(VK_FORMAT_G10X6_B10X6R10X6_2PLANE_422_UNORM_3PACK16)
+ ENUM_TO_STRING_CASE(VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_444_UNORM_3PACK16)
+ ENUM_TO_STRING_CASE(VK_FORMAT_R12X4_UNORM_PACK16)
+ ENUM_TO_STRING_CASE(VK_FORMAT_R12X4G12X4_UNORM_2PACK16)
+ ENUM_TO_STRING_CASE(VK_FORMAT_R12X4G12X4B12X4A12X4_UNORM_4PACK16)
+ ENUM_TO_STRING_CASE(VK_FORMAT_G12X4B12X4G12X4R12X4_422_UNORM_4PACK16)
+ ENUM_TO_STRING_CASE(VK_FORMAT_B12X4G12X4R12X4G12X4_422_UNORM_4PACK16)
+ ENUM_TO_STRING_CASE(VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_420_UNORM_3PACK16)
+ ENUM_TO_STRING_CASE(VK_FORMAT_G12X4_B12X4R12X4_2PLANE_420_UNORM_3PACK16)
+ ENUM_TO_STRING_CASE(VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_422_UNORM_3PACK16)
+ ENUM_TO_STRING_CASE(VK_FORMAT_G12X4_B12X4R12X4_2PLANE_422_UNORM_3PACK16)
+ ENUM_TO_STRING_CASE(VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_444_UNORM_3PACK16)
+ ENUM_TO_STRING_CASE(VK_FORMAT_G16B16G16R16_422_UNORM)
+ ENUM_TO_STRING_CASE(VK_FORMAT_B16G16R16G16_422_UNORM)
+ ENUM_TO_STRING_CASE(VK_FORMAT_G16_B16_R16_3PLANE_420_UNORM)
+ ENUM_TO_STRING_CASE(VK_FORMAT_G16_B16R16_2PLANE_420_UNORM)
+ ENUM_TO_STRING_CASE(VK_FORMAT_G16_B16_R16_3PLANE_422_UNORM)
+ ENUM_TO_STRING_CASE(VK_FORMAT_G16_B16R16_2PLANE_422_UNORM)
+ ENUM_TO_STRING_CASE(VK_FORMAT_G16_B16_R16_3PLANE_444_UNORM)
+ ENUM_TO_STRING_CASE(VK_FORMAT_PVRTC1_2BPP_UNORM_BLOCK_IMG)
+ ENUM_TO_STRING_CASE(VK_FORMAT_PVRTC1_4BPP_UNORM_BLOCK_IMG)
+ ENUM_TO_STRING_CASE(VK_FORMAT_PVRTC2_2BPP_UNORM_BLOCK_IMG)
+ ENUM_TO_STRING_CASE(VK_FORMAT_PVRTC2_4BPP_UNORM_BLOCK_IMG)
+ ENUM_TO_STRING_CASE(VK_FORMAT_PVRTC1_2BPP_SRGB_BLOCK_IMG)
+ ENUM_TO_STRING_CASE(VK_FORMAT_PVRTC1_4BPP_SRGB_BLOCK_IMG)
+ ENUM_TO_STRING_CASE(VK_FORMAT_PVRTC2_2BPP_SRGB_BLOCK_IMG)
+ ENUM_TO_STRING_CASE(VK_FORMAT_PVRTC2_4BPP_SRGB_BLOCK_IMG)
+ ENUM_TO_STRING_CASE(VK_FORMAT_ASTC_4x4_SFLOAT_BLOCK_EXT)
+ ENUM_TO_STRING_CASE(VK_FORMAT_ASTC_5x4_SFLOAT_BLOCK_EXT)
+ ENUM_TO_STRING_CASE(VK_FORMAT_ASTC_5x5_SFLOAT_BLOCK_EXT)
+ ENUM_TO_STRING_CASE(VK_FORMAT_ASTC_6x5_SFLOAT_BLOCK_EXT)
+ ENUM_TO_STRING_CASE(VK_FORMAT_ASTC_6x6_SFLOAT_BLOCK_EXT)
+ ENUM_TO_STRING_CASE(VK_FORMAT_ASTC_8x5_SFLOAT_BLOCK_EXT)
+ ENUM_TO_STRING_CASE(VK_FORMAT_ASTC_8x6_SFLOAT_BLOCK_EXT)
+ ENUM_TO_STRING_CASE(VK_FORMAT_ASTC_8x8_SFLOAT_BLOCK_EXT)
+ ENUM_TO_STRING_CASE(VK_FORMAT_ASTC_10x5_SFLOAT_BLOCK_EXT)
+ ENUM_TO_STRING_CASE(VK_FORMAT_ASTC_10x6_SFLOAT_BLOCK_EXT)
+ ENUM_TO_STRING_CASE(VK_FORMAT_ASTC_10x8_SFLOAT_BLOCK_EXT)
+ ENUM_TO_STRING_CASE(VK_FORMAT_ASTC_10x10_SFLOAT_BLOCK_EXT)
+ ENUM_TO_STRING_CASE(VK_FORMAT_ASTC_12x10_SFLOAT_BLOCK_EXT)
+ ENUM_TO_STRING_CASE(VK_FORMAT_ASTC_12x12_SFLOAT_BLOCK_EXT)
+ ENUM_TO_STRING_CASE(VK_FORMAT_G8_B8R8_2PLANE_444_UNORM_EXT)
+ ENUM_TO_STRING_CASE(VK_FORMAT_G10X6_B10X6R10X6_2PLANE_444_UNORM_3PACK16_EXT)
+ ENUM_TO_STRING_CASE(VK_FORMAT_G12X4_B12X4R12X4_2PLANE_444_UNORM_3PACK16_EXT)
+ ENUM_TO_STRING_CASE(VK_FORMAT_G16_B16R16_2PLANE_444_UNORM_EXT)
+ ENUM_TO_STRING_CASE(VK_FORMAT_A4R4G4B4_UNORM_PACK16_EXT)
+ ENUM_TO_STRING_CASE(VK_FORMAT_A4B4G4R4_UNORM_PACK16_EXT)
+ ENUM_TO_STRING_CASE(VK_FORMAT_MAX_ENUM)
+ default: {
+ return String("Swapchain format ") + String::num_int64(int64_t(p_swapchain_format));
+ } break;
+ }
+}
diff --git a/modules/openxr/extensions/openxr_vulkan_extension.h b/modules/openxr/extensions/openxr_vulkan_extension.h
new file mode 100644
index 0000000000..c04ea2c1dd
--- /dev/null
+++ b/modules/openxr/extensions/openxr_vulkan_extension.h
@@ -0,0 +1,93 @@
+/*************************************************************************/
+/* openxr_vulkan_extension.h */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+
+#ifndef OPENXR_VULKAN_EXTENSION_H
+#define OPENXR_VULKAN_EXTENSION_H
+
+#include "core/templates/vector.h"
+#include "openxr_extension_wrapper.h"
+
+#include "drivers/vulkan/vulkan_context.h"
+
+// Forward declare these so we don't need OpenXR headers where-ever this is included
+// Including OpenXR at this point gives loads and loads of compile issues especially
+// on Windows because windows.h is EVIL and really shouldn't be included outside of platform
+// but we really don't have a choice in the matter
+
+struct XrGraphicsRequirementsVulkanKHR;
+struct XrVulkanInstanceCreateInfoKHR;
+struct XrVulkanGraphicsDeviceGetInfoKHR;
+struct XrVulkanDeviceCreateInfoKHR;
+struct XrGraphicsBindingVulkanKHR;
+
+class OpenXRVulkanExtension : public OpenXRGraphicsExtensionWrapper, VulkanHooks {
+public:
+ OpenXRVulkanExtension(OpenXRAPI *p_openxr_api);
+ virtual ~OpenXRVulkanExtension() override;
+
+ virtual void on_instance_created(const XrInstance p_instance) override;
+ virtual void *set_session_create_and_get_next_pointer(void *p_next_pointer) override;
+
+ virtual bool create_vulkan_instance(const VkInstanceCreateInfo *p_vulkan_create_info, VkInstance *r_instance);
+ virtual bool get_physical_device(VkPhysicalDevice *r_device);
+ virtual bool create_vulkan_device(const VkDeviceCreateInfo *p_device_create_info, VkDevice *r_device);
+
+ virtual void get_usable_swapchain_formats(Vector &p_usable_swap_chains) override;
+ virtual String get_swapchain_format_name(int64_t p_swapchain_format) const override;
+ virtual bool get_swapchain_image_data(XrSwapchain p_swapchain, int64_t p_swapchain_format, uint32_t p_width, uint32_t p_height, uint32_t p_sample_count, uint32_t p_array_size, void **r_swapchain_graphics_data) override;
+ virtual void cleanup_swapchain_graphics_data(void **p_swapchain_graphics_data) override;
+ virtual bool create_projection_fov(const XrFovf p_fov, double p_z_near, double p_z_far, CameraMatrix &r_camera_matrix) override;
+ virtual bool copy_render_target_to_image(RID p_from_render_target, void *p_swapchain_graphics_data, int p_image_index) override;
+
+private:
+ static OpenXRVulkanExtension *singleton;
+ static XrGraphicsBindingVulkanKHR graphics_binding_vulkan; // declaring this as static so we don't need to know its size and we only need it once when creating our session
+
+ struct SwapchainGraphicsData {
+ bool is_multiview;
+ Vector image_rids;
+ Vector framebuffers;
+ };
+
+ bool check_graphics_api_support(XrVersion p_desired_version);
+
+ VkInstance vulkan_instance;
+ VkPhysicalDevice vulkan_physical_device;
+ VkDevice vulkan_device;
+ uint32_t vulkan_queue_family_index;
+ uint32_t vulkan_queue_index;
+
+ XrResult xrGetVulkanGraphicsRequirements2KHR(XrInstance p_instance, XrSystemId p_system_id, XrGraphicsRequirementsVulkanKHR *p_graphics_requirements);
+ XrResult xrCreateVulkanInstanceKHR(XrInstance p_instance, const XrVulkanInstanceCreateInfoKHR *p_create_info, VkInstance *r_vulkan_instance, VkResult *r_vulkan_result);
+ XrResult xrGetVulkanGraphicsDevice2KHR(XrInstance p_instance, const XrVulkanGraphicsDeviceGetInfoKHR *p_get_info, VkPhysicalDevice *r_vulkan_physical_device);
+ XrResult xrCreateVulkanDeviceKHR(XrInstance p_instance, const XrVulkanDeviceCreateInfoKHR *p_create_info, VkDevice *r_device, VkResult *r_result);
+};
+
+#endif // !OPENXR_VULKAN_EXTENSION_H
diff --git a/modules/openxr/openxr_api.cpp b/modules/openxr/openxr_api.cpp
new file mode 100644
index 0000000000..23fd0404d5
--- /dev/null
+++ b/modules/openxr/openxr_api.cpp
@@ -0,0 +1,2171 @@
+/*************************************************************************/
+/* openxr_api.cpp */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+
+#include "openxr_api.h"
+#include "openxr_util.h"
+
+#include "core/config/engine.h"
+#include "core/config/project_settings.h"
+#include "core/os/memory.h"
+#include "core/version.h"
+
+#ifdef TOOLS_ENABLED
+#include "editor/editor_settings.h"
+#endif
+
+#ifdef ANDROID_ENABLED
+#include "extensions/openxr_android_extension.h"
+#endif
+
+#ifdef VULKAN_ENABLED
+#include "extensions/openxr_vulkan_extension.h"
+#endif
+
+OpenXRAPI *OpenXRAPI::singleton = nullptr;
+
+void OpenXRAPI::setup_global_defs() {
+ // As OpenXRAPI is not constructed if OpenXR is not enabled, we register our project and editor settings here
+
+ // Project settings
+ GLOBAL_DEF_BASIC("xr/openxr/enabled", false);
+ GLOBAL_DEF_BASIC("xr/openxr/default_action_map", "res://default_action_map.tres");
+ ProjectSettings::get_singleton()->set_custom_property_info("xr/openxr/default_action_map", PropertyInfo(Variant::STRING, "xr/openxr/default_action_map", PROPERTY_HINT_FILE, "*.tres"));
+
+ GLOBAL_DEF_BASIC("xr/openxr/form_factor", "0");
+ ProjectSettings::get_singleton()->set_custom_property_info("xr/openxr/form_factor", PropertyInfo(Variant::INT, "xr/openxr/form_factor", PROPERTY_HINT_ENUM, "Head mounted,Handheld"));
+
+ GLOBAL_DEF_BASIC("xr/openxr/view_configuration", "1");
+ ProjectSettings::get_singleton()->set_custom_property_info("xr/openxr/view_configuration", PropertyInfo(Variant::INT, "xr/openxr/view_configuration", PROPERTY_HINT_ENUM, "Mono,Stereo")); // "Mono,Stereo,Quad,Observer"
+
+ GLOBAL_DEF_BASIC("xr/openxr/reference_space", "1");
+ ProjectSettings::get_singleton()->set_custom_property_info("xr/openxr/reference_space", PropertyInfo(Variant::INT, "xr/openxr/reference_space", PROPERTY_HINT_ENUM, "Local,Stage"));
+
+#ifdef TOOLS_ENABLED
+ // Disabled for now, using XR inside of the editor we'll be working on during the coming months.
+
+ // editor settings (it seems we're too early in the process when setting up rendering, to access editor settings...)
+ // EDITOR_DEF_RST("xr/openxr/in_editor", false);
+ // GLOBAL_DEF("xr/openxr/in_editor", false);
+#endif
+}
+
+bool OpenXRAPI::openxr_is_enabled() {
+ // @TODO we need an overrule switch so we can force enable openxr, i.e run "godot --openxr_enabled"
+
+ if (Engine::get_singleton()->is_editor_hint()) {
+#ifdef TOOLS_ENABLED
+ // Disabled for now, using XR inside of the editor we'll be working on during the coming months.
+ return false;
+
+ // bool enabled = GLOBAL_GET("xr/openxr/in_editor"); // EDITOR_GET("xr/openxr/in_editor");
+ // return enabled;
+#else
+ // we should never get here, editor hint won't be true if the editor isn't compiled in.
+ return false;
+#endif
+ } else {
+ bool enabled = GLOBAL_GET("xr/openxr/enabled");
+ return enabled;
+ }
+}
+
+OpenXRAPI *OpenXRAPI::get_singleton() {
+ if (singleton != nullptr) {
+ // already constructed, return our singleton
+ return singleton;
+ } else if (openxr_is_enabled()) {
+ // construct our singleton and return it
+ singleton = memnew(OpenXRAPI);
+ return singleton;
+ } else {
+ // not enabled, don't instantiate, return nullptr
+ return nullptr;
+ }
+}
+
+String OpenXRAPI::get_default_action_map_resource_name() {
+ String name = GLOBAL_GET("xr/openxr/default_action_map");
+
+ return name;
+}
+
+String OpenXRAPI::get_error_string(XrResult result) {
+ if (XR_SUCCEEDED(result)) {
+ return String("Succeeded");
+ }
+
+ if (instance == XR_NULL_HANDLE) {
+ Array args;
+ args.push_back(Variant(result));
+ return String("Error code {0}").format(args);
+ }
+
+ char resultString[XR_MAX_RESULT_STRING_SIZE];
+ xrResultToString(instance, result, resultString);
+
+ return String(resultString);
+}
+
+String OpenXRAPI::get_swapchain_format_name(int64_t p_swapchain_format) const {
+ // This is rendering engine dependend...
+ if (graphics_extension) {
+ return graphics_extension->get_swapchain_format_name(p_swapchain_format);
+ }
+
+ return String("Swapchain format ") + String::num_int64(int64_t(p_swapchain_format));
+}
+
+bool OpenXRAPI::load_layer_properties() {
+ // This queries additional layers that are available and can be initialised when we create our OpenXR instance
+ if (layer_properties != nullptr) {
+ // already retrieved this
+ return true;
+ }
+
+ // Note, instance is not yet setup so we can't use get_error_string to retrieve our error
+ XrResult result = xrEnumerateApiLayerProperties(0, &num_layer_properties, nullptr);
+ ERR_FAIL_COND_V_MSG(XR_FAILED(result), false, "OpenXR: Failed to enumerate number of api layer properties");
+
+ layer_properties = (XrApiLayerProperties *)memalloc(sizeof(XrApiLayerProperties) * num_layer_properties);
+ ERR_FAIL_NULL_V(layer_properties, false);
+ for (uint32_t i = 0; i < num_layer_properties; i++) {
+ layer_properties[i].type = XR_TYPE_API_LAYER_PROPERTIES;
+ layer_properties[i].next = nullptr;
+ }
+
+ result = xrEnumerateApiLayerProperties(num_layer_properties, &num_layer_properties, layer_properties);
+ ERR_FAIL_COND_V_MSG(XR_FAILED(result), false, "OpenXR: Failed to enumerate api layer properties");
+
+#ifdef DEBUG
+ for (uint32_t i = 0; i < num_layer_properties; i++) {
+ print_line("OpenXR: Found OpenXR layer ", layer_properties[i].layerName);
+ }
+#endif
+
+ return true;
+}
+
+bool OpenXRAPI::load_supported_extensions() {
+ // This queries supported extensions that are available and can be initialised when we create our OpenXR instance
+
+ if (supported_extensions != nullptr) {
+ // already retrieved this
+ return true;
+ }
+
+ // Note, instance is not yet setup so we can't use get_error_string to retrieve our error
+ XrResult result = xrEnumerateInstanceExtensionProperties(nullptr, 0, &num_supported_extensions, nullptr);
+ ERR_FAIL_COND_V_MSG(XR_FAILED(result), false, "OpenXR: Failed to enumerate number of extension properties");
+
+ supported_extensions = (XrExtensionProperties *)memalloc(sizeof(XrExtensionProperties) * num_supported_extensions);
+ ERR_FAIL_NULL_V(supported_extensions, false);
+
+ // set our types
+ for (uint32_t i = 0; i < num_supported_extensions; i++) {
+ supported_extensions[i].type = XR_TYPE_EXTENSION_PROPERTIES;
+ supported_extensions[i].next = nullptr;
+ }
+ result = xrEnumerateInstanceExtensionProperties(nullptr, num_supported_extensions, &num_supported_extensions, supported_extensions);
+ ERR_FAIL_COND_V_MSG(XR_FAILED(result), false, "OpenXR: Failed to enumerate extension properties");
+
+#ifdef DEBUG
+ for (uint32_t i = 0; i < num_supported_extensions; i++) {
+ print_line("OpenXR: Found OpenXR extension ", supported_extensions[i].extensionName);
+ }
+#endif
+
+ return true;
+}
+
+bool OpenXRAPI::is_extension_supported(const char *p_extension) const {
+ for (uint32_t i = 0; i < num_supported_extensions; i++) {
+ if (strcmp(supported_extensions[i].extensionName, p_extension)) {
+ return true;
+ }
+ }
+
+ return false;
+}
+
+void OpenXRAPI::copy_string_to_char_buffer(const String p_string, char *p_buffer, int p_buffer_len) {
+ CharString char_string = p_string.utf8();
+ int len = char_string.length();
+ if (len < p_buffer_len - 1) {
+ // was having weird CI issues with strcpy so....
+ memcpy(p_buffer, char_string.get_data(), len);
+ p_buffer[len] = '\0';
+ } else {
+ memcpy(p_buffer, char_string.get_data(), p_buffer_len - 1);
+ p_buffer[p_buffer_len - 1] = '\0';
+ }
+}
+
+bool OpenXRAPI::create_instance() {
+ // Create our OpenXR instance, this will query any registered extension wrappers for extensions we need to enable.
+
+ // Append the extensions requested by the registered extension wrappers.
+ Map requested_extensions;
+ for (OpenXRExtensionWrapper *wrapper : registered_extension_wrappers) {
+ Map wrapper_request_extensions = wrapper->get_request_extensions();
+
+ // requested_extensions.insert(wrapper_request_extensions.begin(), wrapper_request_extensions.end());
+ for (auto &requested_extension : wrapper_request_extensions) {
+ requested_extensions[requested_extension.key] = requested_extension.value;
+ }
+ }
+
+ // Check which extensions are supported
+ enabled_extensions.clear();
+ for (auto &requested_extension : requested_extensions) {
+ if (!is_extension_supported(requested_extension.key)) {
+ if (requested_extension.value == nullptr) {
+ // nullptr means this is a manditory extension so we fail
+ ERR_FAIL_V_MSG(false, "OpenXR: OpenXR Runtime does not support OpenGL extension!");
+ } else {
+ // set this extension as not supported
+ *requested_extension.value = false;
+ }
+ } else if (requested_extension.value != nullptr) {
+ // set this extension as supported
+ *requested_extension.value = true;
+
+ // and record that we want to enable it
+ enabled_extensions.push_back(requested_extension.key);
+ } else {
+ // record that we want to enable this
+ enabled_extensions.push_back(requested_extension.key);
+ }
+ }
+
+ // Get our project name
+ String project_name = GLOBAL_GET("application/config/name");
+
+ // Create our OpenXR instance
+ XrApplicationInfo application_info{
+ "", // applicationName, we'll set this down below
+ 1, // applicationVersion, we don't currently have this
+ "Godot Game Engine", // engineName
+ VERSION_MAJOR * 10000 + VERSION_MINOR * 100 + VERSION_PATCH, // engineVersion 4.0 -> 40000, 4.0.1 -> 40001, 4.1 -> 40100, etc.
+ XR_CURRENT_API_VERSION // apiVersion
+ };
+
+ XrInstanceCreateInfo instance_create_info = {
+ XR_TYPE_INSTANCE_CREATE_INFO, // type
+ nullptr, // next
+ 0, // createFlags
+ application_info, // applicationInfo
+ 0, // enabledApiLayerCount, need to find out if we need support for this?
+ nullptr, // enabledApiLayerNames
+ uint32_t(enabled_extensions.size()), // enabledExtensionCount
+ enabled_extensions.ptr() // enabledExtensionNames
+ };
+
+ copy_string_to_char_buffer(project_name, instance_create_info.applicationInfo.applicationName, XR_MAX_APPLICATION_NAME_SIZE);
+
+ XrResult result = xrCreateInstance(&instance_create_info, &instance);
+ ERR_FAIL_COND_V_MSG(XR_FAILED(result), false, "Failed to create XR instance.");
+
+ // from this point on we can use get_error_string to get more info about our errors...
+
+ XrInstanceProperties instanceProps = {
+ XR_TYPE_INSTANCE_PROPERTIES, // type;
+ nullptr, // next
+ 0, // runtimeVersion, from here will be set by our get call
+ "" // runtimeName
+ };
+ result = xrGetInstanceProperties(instance, &instanceProps);
+ if (XR_FAILED(result)) {
+ // not fatal probably
+ print_line("OpenXR: Failed to get XR instance properties [", get_error_string(result), "]");
+ } else {
+ print_line("OpenXR: Running on OpenXR runtime: ", instanceProps.runtimeName, " ", OpenXRUtil::make_xr_version_string(instanceProps.runtimeVersion));
+ }
+
+ for (OpenXRExtensionWrapper *wrapper : registered_extension_wrappers) {
+ wrapper->on_instance_created(instance);
+ }
+
+ return true;
+}
+
+bool OpenXRAPI::get_system_info() {
+ // Retrieve basic OpenXR system info based on the form factor we desire
+
+ // Retrieve the system for our form factor, fails if form factor is not available
+ XrSystemGetInfo system_get_info = {
+ XR_TYPE_SYSTEM_GET_INFO, // type;
+ nullptr, // next
+ form_factor // formFactor
+ };
+
+ XrResult result = xrGetSystem(instance, &system_get_info, &system_id);
+ if (XR_FAILED(result)) {
+ print_line("OpenXR: Failed to get system for our form factor [", get_error_string(result), "]");
+ return false;
+ }
+
+ // obtain info about our system, writing this out completely to make CI on Linux happy..
+ void *next_pointer = nullptr;
+ for (OpenXRExtensionWrapper *wrapper : registered_extension_wrappers) {
+ void *np = wrapper->set_system_properties_and_get_next_pointer(next_pointer);
+ if (np != nullptr) {
+ next_pointer = np;
+ }
+ }
+
+ XrSystemProperties system_properties = {
+ XR_TYPE_SYSTEM_PROPERTIES, // type
+ next_pointer, // next
+ 0, // systemId, from here will be set by our get call
+ 0, // vendorId
+ "", // systemName
+ {
+ 0, // maxSwapchainImageHeight
+ 0, // maxSwapchainImageWidth
+ 0, // maxLayerCount
+ }, // graphicsProperties
+ {
+ false, // orientationTracking
+ false // positionTracking
+ } // trackingProperties
+ };
+
+ result = xrGetSystemProperties(instance, system_id, &system_properties);
+ if (XR_FAILED(result)) {
+ print_line("OpenXR: Failed to get System properties [", get_error_string(result), "]");
+ return false;
+ }
+
+ // remember this state, we'll use it later
+ system_name = String(system_properties.systemName);
+ vendor_id = system_properties.vendorId;
+ graphics_properties = system_properties.graphicsProperties;
+ tracking_properties = system_properties.trackingProperties;
+
+ return true;
+}
+
+bool OpenXRAPI::load_supported_view_configuration_types() {
+ // This queries the supported configuration types, likely there will only be one chosing between Mono (phone AR) and Stereo (HMDs)
+
+ ERR_FAIL_COND_V(instance == XR_NULL_HANDLE, false);
+
+ if (supported_view_configuration_types != nullptr) {
+ // free previous results
+ memfree(supported_view_configuration_types);
+ supported_view_configuration_types = nullptr;
+ }
+
+ XrResult result = xrEnumerateViewConfigurations(instance, system_id, 0, &num_view_configuration_types, nullptr);
+ if (XR_FAILED(result)) {
+ print_line("OpenXR: Failed to get view configuration count [", get_error_string(result), "]");
+ return false;
+ }
+
+ supported_view_configuration_types = (XrViewConfigurationType *)memalloc(sizeof(XrViewConfigurationType) * num_view_configuration_types);
+ ERR_FAIL_NULL_V(supported_view_configuration_types, false);
+
+ result = xrEnumerateViewConfigurations(instance, system_id, num_view_configuration_types, &num_view_configuration_types, supported_view_configuration_types);
+ ERR_FAIL_COND_V_MSG(XR_FAILED(result), false, "OpenXR: Failed to enumerateview configurations");
+
+#ifdef DEBUG
+ for (uint32_t i = 0; i < num_view_configuration_types; i++) {
+ print_line("OpenXR: Found supported view configuration ", OpenXRUtil::get_view_configuration_name(supported_view_configuration_types[i]));
+ }
+#endif
+
+ return true;
+}
+
+bool OpenXRAPI::is_view_configuration_supported(XrViewConfigurationType p_configuration_type) const {
+ ERR_FAIL_NULL_V(supported_view_configuration_types, false);
+
+ for (uint32_t i = 0; i < num_view_configuration_types; i++) {
+ if (supported_view_configuration_types[i] == p_configuration_type) {
+ return true;
+ }
+ }
+
+ return false;
+}
+
+bool OpenXRAPI::load_supported_view_configuration_views(XrViewConfigurationType p_configuration_type) {
+ // This loads our view configuration for each view so for a stereo HMD, we'll get two entries (that are likely identical)
+ // The returned data supplies us with the recommended render target size
+
+ if (!is_view_configuration_supported(p_configuration_type)) {
+ print_line("OpenXR: View configuration ", OpenXRUtil::get_view_configuration_name(view_configuration), " is not supported.");
+ return false;
+ }
+
+ if (view_configuration_views != nullptr) {
+ // free previous results
+ memfree(view_configuration_views);
+ view_configuration_views = nullptr;
+ }
+
+ XrResult result = xrEnumerateViewConfigurationViews(instance, system_id, p_configuration_type, 0, &view_count, nullptr);
+ if (XR_FAILED(result)) {
+ print_line("OpenXR: Failed to get view configuration count [", get_error_string(result), "]");
+ return false;
+ }
+
+ view_configuration_views = (XrViewConfigurationView *)memalloc(sizeof(XrViewConfigurationView) * view_count);
+ ERR_FAIL_NULL_V(view_configuration_views, false);
+
+ for (uint32_t i = 0; i < view_count; i++) {
+ view_configuration_views[i].type = XR_TYPE_VIEW_CONFIGURATION_VIEW;
+ view_configuration_views[i].next = NULL;
+ }
+
+ result = xrEnumerateViewConfigurationViews(instance, system_id, p_configuration_type, view_count, &view_count, view_configuration_views);
+ ERR_FAIL_COND_V_MSG(XR_FAILED(result), false, "OpenXR: Failed to enumerate view configurations");
+
+#ifdef DEBUG
+ for (uint32_t i = 0; i < view_count; i++) {
+ print_line("OpenXR: Found supported view configuration view");
+ print_line(" - width: ", view_configuration_views[i].maxImageRectWidth);
+ print_line(" - height: ", view_configuration_views[i].maxImageRectHeight);
+ print_line(" - sample count: ", view_configuration_views[i].maxSwapchainSampleCount);
+ print_line(" - recommended render width: ", view_configuration_views[i].recommendedImageRectWidth);
+ print_line(" - recommended render height: ", view_configuration_views[i].recommendedImageRectHeight);
+ print_line(" - recommended render sample count: ", view_configuration_views[i].recommendedSwapchainSampleCount);
+ }
+#endif
+
+ return true;
+}
+
+void OpenXRAPI::destroy_instance() {
+ if (view_configuration_views != nullptr) {
+ memfree(view_configuration_views);
+ view_configuration_views = nullptr;
+ }
+
+ if (supported_view_configuration_types != nullptr) {
+ memfree(supported_view_configuration_types);
+ supported_view_configuration_types = nullptr;
+ }
+
+ if (instance != XR_NULL_HANDLE) {
+ for (OpenXRExtensionWrapper *wrapper : registered_extension_wrappers) {
+ wrapper->on_instance_destroyed();
+ }
+
+ xrDestroyInstance(instance);
+ instance = XR_NULL_HANDLE;
+ }
+ enabled_extensions.clear();
+}
+
+bool OpenXRAPI::create_session() {
+ ERR_FAIL_COND_V(instance == XR_NULL_HANDLE, false);
+ ERR_FAIL_COND_V(session != XR_NULL_HANDLE, false);
+
+ void *next_pointer = nullptr;
+ for (OpenXRExtensionWrapper *wrapper : registered_extension_wrappers) {
+ void *np = wrapper->set_session_create_and_get_next_pointer(next_pointer);
+ if (np != nullptr) {
+ next_pointer = np;
+ }
+ }
+
+ XrSessionCreateInfo session_create_info = {
+ XR_TYPE_SESSION_CREATE_INFO, // type
+ next_pointer, // next
+ 0, // createFlags
+ system_id // systemId
+ };
+
+ XrResult result = xrCreateSession(instance, &session_create_info, &session);
+ if (XR_FAILED(result)) {
+ print_line("OpenXR: Failed to create session [", get_error_string(result), "]");
+ return false;
+ }
+
+ for (OpenXRExtensionWrapper *wrapper : registered_extension_wrappers) {
+ wrapper->on_session_created(session);
+ }
+
+ return true;
+}
+
+bool OpenXRAPI::load_supported_reference_spaces() {
+ // loads the supported reference spaces for our OpenXR session
+
+ ERR_FAIL_COND_V(session == XR_NULL_HANDLE, false);
+
+ if (supported_reference_spaces != nullptr) {
+ // free previous results
+ memfree(supported_reference_spaces);
+ supported_reference_spaces = nullptr;
+ }
+
+ XrResult result = xrEnumerateReferenceSpaces(session, 0, &num_reference_spaces, nullptr);
+ if (XR_FAILED(result)) {
+ print_line("OpenXR: Failed to get reference space count [", get_error_string(result), "]");
+ return false;
+ }
+
+ supported_reference_spaces = (XrReferenceSpaceType *)memalloc(sizeof(XrReferenceSpaceType) * num_reference_spaces);
+ ERR_FAIL_NULL_V(supported_reference_spaces, false);
+
+ result = xrEnumerateReferenceSpaces(session, num_reference_spaces, &num_reference_spaces, supported_reference_spaces);
+ ERR_FAIL_COND_V_MSG(XR_FAILED(result), false, "OpenXR: Failed to enumerate reference spaces");
+
+ // #ifdef DEBUG
+ for (uint32_t i = 0; i < num_reference_spaces; i++) {
+ print_line("OpenXR: Found supported reference space ", OpenXRUtil::get_reference_space_name(supported_reference_spaces[i]));
+ }
+ // #endif
+
+ return true;
+}
+
+bool OpenXRAPI::is_reference_space_supported(XrReferenceSpaceType p_reference_space) {
+ ERR_FAIL_NULL_V(supported_reference_spaces, false);
+
+ for (uint32_t i = 0; i < num_reference_spaces; i++) {
+ if (supported_reference_spaces[i] == p_reference_space) {
+ return true;
+ }
+ }
+
+ return false;
+}
+
+bool OpenXRAPI::setup_spaces() {
+ XrResult result;
+
+ XrPosef identityPose = {
+ { 0.0, 0.0, 0.0, 1.0 },
+ { 0.0, 0.0, 0.0 }
+ };
+
+ ERR_FAIL_COND_V(session == XR_NULL_HANDLE, false);
+
+ // create play space
+ {
+ if (!is_reference_space_supported(reference_space)) {
+ print_line("OpenXR: reference space ", OpenXRUtil::get_reference_space_name(reference_space), " is not supported.");
+ return false;
+ }
+
+ XrReferenceSpaceCreateInfo play_space_create_info = {
+ XR_TYPE_REFERENCE_SPACE_CREATE_INFO, // type
+ nullptr, // next
+ reference_space, // referenceSpaceType
+ identityPose // poseInReferenceSpace
+ };
+
+ result = xrCreateReferenceSpace(session, &play_space_create_info, &play_space);
+ if (XR_FAILED(result)) {
+ print_line("OpenXR: Failed to create play space [", get_error_string(result), "]");
+ return false;
+ }
+ }
+
+ // create view space
+ {
+ if (!is_reference_space_supported(XR_REFERENCE_SPACE_TYPE_VIEW)) {
+ print_line("OpenXR: reference space XR_REFERENCE_SPACE_TYPE_VIEW is not supported.");
+ return false;
+ }
+
+ XrReferenceSpaceCreateInfo view_space_create_info = {
+ XR_TYPE_REFERENCE_SPACE_CREATE_INFO, // type
+ nullptr, // next
+ XR_REFERENCE_SPACE_TYPE_VIEW, // referenceSpaceType
+ identityPose // poseInReferenceSpace
+ };
+
+ result = xrCreateReferenceSpace(session, &view_space_create_info, &view_space);
+ if (XR_FAILED(result)) {
+ print_line("OpenXR: Failed to create view space [", get_error_string(result), "]");
+ return false;
+ }
+ }
+
+ return true;
+}
+
+bool OpenXRAPI::load_supported_swapchain_formats() {
+ ERR_FAIL_COND_V(session == XR_NULL_HANDLE, false);
+
+ if (supported_swapchain_formats != nullptr) {
+ // free previous results
+ memfree(supported_swapchain_formats);
+ supported_swapchain_formats = nullptr;
+ }
+
+ XrResult result = xrEnumerateSwapchainFormats(session, 0, &num_swapchain_formats, nullptr);
+ if (XR_FAILED(result)) {
+ print_line("OpenXR: Failed to get swapchain format count [", get_error_string(result), "]");
+ return false;
+ }
+
+ supported_swapchain_formats = (int64_t *)memalloc(sizeof(int64_t) * num_swapchain_formats);
+ ERR_FAIL_NULL_V(supported_swapchain_formats, false);
+
+ result = xrEnumerateSwapchainFormats(session, num_swapchain_formats, &num_swapchain_formats, supported_swapchain_formats);
+ ERR_FAIL_COND_V_MSG(XR_FAILED(result), false, "OpenXR: Failed to enumerate swapchain formats");
+
+ // #ifdef DEBUG
+ for (uint32_t i = 0; i < num_swapchain_formats; i++) {
+ print_line("OpenXR: Found supported swapchain format ", get_swapchain_format_name(supported_swapchain_formats[i]));
+ }
+ // #endif
+
+ return true;
+}
+
+bool OpenXRAPI::is_swapchain_format_supported(int64_t p_swapchain_format) {
+ ERR_FAIL_NULL_V(supported_swapchain_formats, false);
+
+ for (uint32_t i = 0; i < num_swapchain_formats; i++) {
+ if (supported_swapchain_formats[i] == p_swapchain_format) {
+ return true;
+ }
+ }
+
+ return false;
+}
+
+bool OpenXRAPI::create_main_swapchain() {
+ ERR_FAIL_NULL_V(graphics_extension, false);
+ ERR_FAIL_COND_V(session == XR_NULL_HANDLE, false);
+
+ /*
+ TODO: We need to improve on this, for now we're taking our old approach of creating our main swapchains and substituting
+ those for the ones Godot normally creates.
+ This however means we can only use swapchains for our main XR view.
+
+ It would have been nicer if we could override the swapchain creation in Godot with ours but we have a timing issue here.
+ We can't create XR swapchains until after our XR session is fully instantiated, yet Godot creates its swapchain much earlier.
+
+ Also Godot only creates a swapchain for the main output.
+ OpenXR will require us to create swapchains as the render target for additional viewports if we want to use the layer system
+ to optimise text rendering and background rendering as OpenXR may choose to re-use the results for reprojection while we're
+ already rendering the next frame.
+
+ Finally an area we need to expand upon is that Foveated rendering is only enabled for the swap chain we create,
+ as we render 3D content into internal buffers that are copied into the swapchain, we don't get any of the performance gains
+ until such time as we implement VRS.
+ */
+
+ // Build a vector with swapchain formats we want to use, from best fit to worst
+ Vector usable_swapchain_formats;
+ int64_t swapchain_format_to_use = 0;
+
+ graphics_extension->get_usable_swapchain_formats(usable_swapchain_formats);
+
+ // now find out which one is supported
+ for (int i = 0; i < usable_swapchain_formats.size() && swapchain_format_to_use == 0; i++) {
+ if (is_swapchain_format_supported(usable_swapchain_formats[i])) {
+ swapchain_format_to_use = usable_swapchain_formats[i];
+ }
+ }
+
+ if (swapchain_format_to_use == 0) {
+ swapchain_format_to_use = usable_swapchain_formats[0]; // just use the first one and hope for the best...
+ print_line("Couldn't find usable swap chain format, using", get_swapchain_format_name(swapchain_format_to_use), "instead.");
+ } else {
+ print_line("Using swap chain format:", get_swapchain_format_name(swapchain_format_to_use));
+ }
+
+ Size2 recommended_size = get_recommended_target_size();
+
+ if (!create_swapchain(swapchain_format_to_use, recommended_size.width, recommended_size.height, view_configuration_views[0].recommendedSwapchainSampleCount, view_count, swapchain, &swapchain_graphics_data)) {
+ return false;
+ }
+
+ views = (XrView *)memalloc(sizeof(XrView) * view_count);
+ ERR_FAIL_NULL_V_MSG(views, false, "OpenXR Couldn't allocate memory for views");
+
+ projection_views = (XrCompositionLayerProjectionView *)memalloc(sizeof(XrCompositionLayerProjectionView) * view_count);
+ ERR_FAIL_NULL_V_MSG(projection_views, false, "OpenXR Couldn't allocate memory for projection views");
+
+ for (uint32_t i = 0; i < view_count; i++) {
+ views[i].type = XR_TYPE_VIEW;
+ views[i].next = NULL;
+
+ projection_views[i].type = XR_TYPE_COMPOSITION_LAYER_PROJECTION_VIEW;
+ projection_views[i].next = NULL;
+ projection_views[i].subImage.swapchain = swapchain;
+ projection_views[i].subImage.imageArrayIndex = i;
+ projection_views[i].subImage.imageRect.offset.x = 0;
+ projection_views[i].subImage.imageRect.offset.y = 0;
+ projection_views[i].subImage.imageRect.extent.width = recommended_size.width;
+ projection_views[i].subImage.imageRect.extent.height = recommended_size.height;
+ };
+
+ return true;
+};
+
+void OpenXRAPI::destroy_session() {
+ if (running && session != XR_NULL_HANDLE) {
+ xrEndSession(session);
+ }
+
+ if (graphics_extension) {
+ graphics_extension->cleanup_swapchain_graphics_data(&swapchain_graphics_data);
+ }
+
+ if (views != nullptr) {
+ memfree(views);
+ views = nullptr;
+ }
+
+ if (projection_views != nullptr) {
+ memfree(projection_views);
+ projection_views = nullptr;
+ }
+
+ if (swapchain != XR_NULL_HANDLE) {
+ xrDestroySwapchain(swapchain);
+ swapchain = XR_NULL_HANDLE;
+ }
+
+ if (supported_swapchain_formats != nullptr) {
+ memfree(supported_swapchain_formats);
+ supported_swapchain_formats = nullptr;
+ }
+
+ // destroy our spaces
+ if (play_space != XR_NULL_HANDLE) {
+ xrDestroySpace(play_space);
+ play_space = XR_NULL_HANDLE;
+ }
+ if (view_space != XR_NULL_HANDLE) {
+ xrDestroySpace(view_space);
+ view_space = XR_NULL_HANDLE;
+ }
+
+ if (supported_reference_spaces != nullptr) {
+ // free previous results
+ memfree(supported_reference_spaces);
+ supported_reference_spaces = nullptr;
+ }
+
+ if (session != XR_NULL_HANDLE) {
+ for (OpenXRExtensionWrapper *wrapper : registered_extension_wrappers) {
+ wrapper->on_session_destroyed();
+ }
+
+ xrDestroySession(session);
+ session = XR_NULL_HANDLE;
+ }
+}
+
+bool OpenXRAPI::create_swapchain(int64_t p_swapchain_format, uint32_t p_width, uint32_t p_height, uint32_t p_sample_count, uint32_t p_array_size, XrSwapchain &r_swapchain, void **r_swapchain_graphics_data) {
+ ERR_FAIL_COND_V(session == XR_NULL_HANDLE, false);
+ ERR_FAIL_NULL_V(graphics_extension, false);
+
+ XrResult result;
+
+ void *next_pointer = nullptr;
+ for (OpenXRExtensionWrapper *wrapper : registered_extension_wrappers) {
+ void *np = wrapper->set_swapchain_create_info_and_get_next_pointer(next_pointer);
+ if (np != nullptr) {
+ next_pointer = np;
+ }
+ }
+
+ XrSwapchainCreateInfo swapchain_create_info = {
+ XR_TYPE_SWAPCHAIN_CREATE_INFO, // type
+ next_pointer, // next
+ 0, // createFlags
+ XR_SWAPCHAIN_USAGE_SAMPLED_BIT | XR_SWAPCHAIN_USAGE_COLOR_ATTACHMENT_BIT, // usageFlags
+ p_swapchain_format, // format
+ p_sample_count, // sampleCount
+ p_width, // width
+ p_height, // height
+ 1, // faceCount
+ p_array_size, // arraySize
+ 1 // mipCount
+ };
+
+ XrSwapchain new_swapchain;
+ result = xrCreateSwapchain(session, &swapchain_create_info, &new_swapchain);
+ if (XR_FAILED(result)) {
+ print_line("OpenXR: Failed to get swapchain [", get_error_string(result), "]");
+ return false;
+ }
+
+ if (!graphics_extension->get_swapchain_image_data(new_swapchain, p_swapchain_format, p_width, p_height, p_array_size, p_array_size, r_swapchain_graphics_data)) {
+ xrDestroySwapchain(new_swapchain);
+ return false;
+ }
+
+ r_swapchain = new_swapchain;
+
+ return true;
+}
+
+bool OpenXRAPI::on_state_idle() {
+#ifdef DEBUG
+ print_line("On state idle");
+#endif
+
+ for (OpenXRExtensionWrapper *wrapper : registered_extension_wrappers) {
+ wrapper->on_state_idle();
+ }
+
+ return true;
+}
+
+bool OpenXRAPI::on_state_ready() {
+#ifdef DEBUG
+ print_line("On state ready");
+#endif
+
+ // begin session
+ XrSessionBeginInfo session_begin_info = {
+ XR_TYPE_SESSION_BEGIN_INFO, // type
+ nullptr, // next
+ view_configuration // primaryViewConfigurationType
+ };
+
+ XrResult result = xrBeginSession(session, &session_begin_info);
+ if (XR_FAILED(result)) {
+ print_line("OpenXR: Failed to begin session [", get_error_string(result), "]");
+ return false;
+ }
+
+ // This is when we create our swapchain, this can be a "long" time after Godot finishes, we can deal with this for now
+ // but once we want to provide Viewports for additional layers where OpenXR requires us to create further swapchains,
+ // we'll be creating those viewport WAY before we reach this point.
+ // We may need to implement a wait in our init in main.cpp polling our events until the session is ready.
+ // That will be very very ugly
+ // The other possibility is to create a separate OpenXRViewport type specifically for this goal as part of our OpenXR module
+
+ if (!create_main_swapchain()) {
+ return false;
+ }
+
+ // we're running
+ running = true;
+
+ for (OpenXRExtensionWrapper *wrapper : registered_extension_wrappers) {
+ wrapper->on_state_ready();
+ }
+
+ // TODO emit signal
+
+ // TODO Tell android
+
+ return true;
+}
+
+bool OpenXRAPI::on_state_synchronized() {
+#ifdef DEBUG
+ print_line("On state synchronized");
+#endif
+
+ for (OpenXRExtensionWrapper *wrapper : registered_extension_wrappers) {
+ wrapper->on_state_synchronized();
+ }
+
+ return true;
+}
+
+bool OpenXRAPI::on_state_visible() {
+#ifdef DEBUG
+ print_line("On state visible");
+#endif
+
+ for (OpenXRExtensionWrapper *wrapper : registered_extension_wrappers) {
+ wrapper->on_state_visible();
+ }
+
+ // TODO emit signal
+
+ return true;
+}
+
+bool OpenXRAPI::on_state_focused() {
+#ifdef DEBUG
+ print_line("On state focused");
+#endif
+
+ for (OpenXRExtensionWrapper *wrapper : registered_extension_wrappers) {
+ wrapper->on_state_focused();
+ }
+
+ // TODO emit signal
+
+ return true;
+}
+
+bool OpenXRAPI::on_state_stopping() {
+#ifdef DEBUG
+ print_line("On state stopping");
+#endif
+
+ // TODO emit signal
+
+ for (OpenXRExtensionWrapper *wrapper : registered_extension_wrappers) {
+ wrapper->on_state_stopping();
+ }
+
+ if (running) {
+ XrResult result = xrEndSession(session);
+ if (XR_FAILED(result)) {
+ // we only report this..
+ print_line("OpenXR: Failed to end session [", get_error_string(result), "]");
+ }
+
+ running = false;
+ }
+
+ // TODO further cleanup
+
+ return true;
+}
+
+bool OpenXRAPI::on_state_loss_pending() {
+#ifdef DEBUG
+ print_line("On state loss pending");
+#endif
+
+ for (OpenXRExtensionWrapper *wrapper : registered_extension_wrappers) {
+ wrapper->on_state_loss_pending();
+ }
+
+ // TODO need to look into the correct action here, read up on the spec but we may need to signal Godot to exit (if it's not already exiting)
+
+ return true;
+}
+
+bool OpenXRAPI::on_state_exiting() {
+#ifdef DEBUG
+ print_line("On state existing");
+#endif
+
+ for (OpenXRExtensionWrapper *wrapper : registered_extension_wrappers) {
+ wrapper->on_state_exiting();
+ }
+
+ // TODO need to look into the correct action here, read up on the spec but we may need to signal Godot to exit (if it's not already exiting)
+
+ return true;
+}
+
+bool OpenXRAPI::is_initialized() {
+ return (instance != XR_NULL_HANDLE);
+}
+
+bool OpenXRAPI::is_running() {
+ if (instance == XR_NULL_HANDLE) {
+ return false;
+ }
+ if (session == XR_NULL_HANDLE) {
+ return false;
+ }
+
+ return running;
+}
+
+bool OpenXRAPI::initialise(const String &p_rendering_driver) {
+ ERR_FAIL_COND_V_MSG(instance != XR_NULL_HANDLE, false, "OpenXR instance was already created");
+
+ if (p_rendering_driver == "vulkan") {
+#ifdef VULKAN_ENABLED
+ graphics_extension = memnew(OpenXRVulkanExtension(this));
+ register_extension_wrapper(graphics_extension);
+#else
+ // shouldn't be possible...
+ ERR_FAIL_V(false);
+#endif
+ } else if (p_rendering_driver == "opengl3") {
+#ifdef OPENGL3_ENABLED
+ // graphics_extension = memnew(OpenXROpenGLExtension(this));
+ // register_extension_wrapper(graphics_extension);
+ ERR_FAIL_V_MSG(false, "OpenXR: OpenGL is not supported at this time.");
+#else
+ // shouldn't be possible...
+ ERR_FAIL_V(false);
+#endif
+ } else {
+ ERR_FAIL_V_MSG(false, "OpenXR: Unsupported rendering device.");
+ }
+
+ // initialise
+ if (!load_layer_properties()) {
+ destroy_instance();
+ return false;
+ }
+
+ if (!load_supported_extensions()) {
+ destroy_instance();
+ return false;
+ }
+
+ if (!create_instance()) {
+ destroy_instance();
+ return false;
+ }
+
+ if (!get_system_info()) {
+ destroy_instance();
+ return false;
+ }
+
+ if (!load_supported_view_configuration_types()) {
+ destroy_instance();
+ return false;
+ }
+
+ if (!load_supported_view_configuration_views(view_configuration)) {
+ destroy_instance();
+ return false;
+ }
+
+ return true;
+}
+
+bool OpenXRAPI::initialise_session() {
+ if (!create_session()) {
+ destroy_session();
+ return false;
+ }
+
+ if (!load_supported_reference_spaces()) {
+ destroy_session();
+ return false;
+ }
+
+ if (!setup_spaces()) {
+ destroy_session();
+ return false;
+ }
+
+ if (!load_supported_swapchain_formats()) {
+ destroy_session();
+ return false;
+ }
+
+ return true;
+}
+
+void OpenXRAPI::finish() {
+ destroy_session();
+
+ destroy_instance();
+}
+
+void OpenXRAPI::register_extension_wrapper(OpenXRExtensionWrapper *p_extension_wrapper) {
+ registered_extension_wrappers.push_back(p_extension_wrapper);
+}
+
+Size2 OpenXRAPI::get_recommended_target_size() {
+ ERR_FAIL_NULL_V(view_configuration_views, Size2());
+
+ Size2 target_size;
+
+ target_size.width = view_configuration_views[0].recommendedImageRectWidth;
+ target_size.height = view_configuration_views[0].recommendedImageRectHeight;
+
+ return target_size;
+}
+
+XRPose::TrackingConfidence OpenXRAPI::get_head_center(Transform3D &r_transform, Vector3 &r_linear_velocity, Vector3 &r_angular_velocity) {
+ XrResult result;
+
+ ERR_FAIL_COND_V(!running, XRPose::XR_TRACKING_CONFIDENCE_NONE);
+
+ // xrWaitFrame not run yet
+ if (frame_state.predictedDisplayTime == 0) {
+ return XRPose::XR_TRACKING_CONFIDENCE_NONE;
+ }
+
+ // Get timing for the next frame, as that is the current frame we're processing
+ XrTime display_time = get_next_frame_time();
+
+ XrSpaceVelocity velocity = {
+ XR_TYPE_SPACE_VELOCITY, // type
+ nullptr, // next
+ 0, // velocityFlags
+ { 0.0, 0.0, 0.0 }, // linearVelocity
+ { 0.0, 0.0, 0.0 } // angularVelocity
+ };
+
+ XrSpaceLocation location = {
+ XR_TYPE_SPACE_LOCATION, // type
+ &velocity, // next
+ 0, // locationFlags
+ {
+ { 0.0, 0.0, 0.0, 0.0 }, // orientation
+ { 0.0, 0.0, 0.0 } // position
+ } // pose
+ };
+
+ result = xrLocateSpace(view_space, play_space, display_time, &location);
+ if (XR_FAILED(result)) {
+ print_line("OpenXR: Failed to locate view space in play space [", get_error_string(result), "]");
+ return XRPose::XR_TRACKING_CONFIDENCE_NONE;
+ }
+
+ XRPose::TrackingConfidence confidence = transform_from_location(location, r_transform);
+ parse_velocities(velocity, r_linear_velocity, r_angular_velocity);
+
+ if (head_pose_confidence != confidence) {
+ // prevent error spam
+ head_pose_confidence = confidence;
+ if (head_pose_confidence == XRPose::XR_TRACKING_CONFIDENCE_NONE) {
+ print_line("OpenXR head space location not valid (check tracking?)");
+#ifdef DEBUG
+ } else if (head_pose_confidence == XRPose::XR_TRACKING_CONFIDENCE_LOW) {
+ print_line("OpenVR Head pose now tracking with low confidence");
+ } else {
+ print_line("OpenVR Head pose now tracking with high confidence");
+#endif
+ }
+ }
+
+ return confidence;
+}
+
+bool OpenXRAPI::get_view_transform(uint32_t p_view, Transform3D &r_transform) {
+ ERR_FAIL_COND_V(!running, false);
+
+ // xrWaitFrame not run yet
+ if (frame_state.predictedDisplayTime == 0) {
+ return false;
+ }
+
+ // we don't have valid view info
+ if (views == NULL || !view_pose_valid) {
+ return false;
+ }
+
+ // Note, the timing of this is set right before rendering, which is what we need here.
+ r_transform = transform_from_pose(views[p_view].pose);
+
+ return true;
+}
+
+bool OpenXRAPI::get_view_projection(uint32_t p_view, double p_z_near, double p_z_far, CameraMatrix &p_camera_matrix) {
+ ERR_FAIL_COND_V(!running, false);
+ ERR_FAIL_NULL_V(graphics_extension, false);
+
+ // xrWaitFrame not run yet
+ if (frame_state.predictedDisplayTime == 0) {
+ return false;
+ }
+
+ // we don't have valid view info
+ if (views == NULL || !view_pose_valid) {
+ return false;
+ }
+
+ return graphics_extension->create_projection_fov(views[p_view].fov, p_z_near, p_z_far, p_camera_matrix);
+}
+
+bool OpenXRAPI::poll_events() {
+ ERR_FAIL_COND_V(instance == XR_NULL_HANDLE, false);
+
+ XrEventDataBuffer runtimeEvent;
+ runtimeEvent.type = XR_TYPE_EVENT_DATA_BUFFER;
+ runtimeEvent.next = nullptr;
+ // runtimeEvent.varying = ...
+
+ XrResult pollResult = xrPollEvent(instance, &runtimeEvent);
+ while (pollResult == XR_SUCCESS) {
+ bool handled = false;
+ for (OpenXRExtensionWrapper *wrapper : registered_extension_wrappers) {
+ handled |= wrapper->on_event_polled(runtimeEvent);
+ }
+ switch (runtimeEvent.type) {
+ // case XR_TYPE_EVENT_DATA_EVENTS_LOST: {
+ // } break;
+ // case XR_TYPE_EVENT_DATA_VISIBILITY_MASK_CHANGED_KHR: {
+ // } break;
+ // case XR_TYPE_EVENT_DATA_INSTANCE_LOSS_PENDING: {
+ // } break;
+ case XR_TYPE_EVENT_DATA_SESSION_STATE_CHANGED: {
+ XrEventDataSessionStateChanged *event = (XrEventDataSessionStateChanged *)&runtimeEvent;
+
+ session_state = event->state;
+ if (session_state >= XR_SESSION_STATE_MAX_ENUM) {
+ print_line("OpenXR EVENT: session state changed to UNKNOWN -", session_state);
+ } else {
+ print_line("OpenXR EVENT: session state changed to", OpenXRUtil::get_session_state_name(session_state));
+
+ switch (session_state) {
+ case XR_SESSION_STATE_IDLE:
+ on_state_idle();
+ break;
+ case XR_SESSION_STATE_READY:
+ on_state_ready();
+ break;
+ case XR_SESSION_STATE_SYNCHRONIZED:
+ on_state_synchronized();
+ break;
+ case XR_SESSION_STATE_VISIBLE:
+ on_state_visible();
+ break;
+ case XR_SESSION_STATE_FOCUSED:
+ on_state_focused();
+ break;
+ case XR_SESSION_STATE_STOPPING:
+ on_state_stopping();
+ break;
+ case XR_SESSION_STATE_LOSS_PENDING:
+ on_state_loss_pending();
+ break;
+ case XR_SESSION_STATE_EXITING:
+ on_state_exiting();
+ break;
+ default:
+ break;
+ }
+ }
+ } break;
+ // case XR_TYPE_EVENT_DATA_REFERENCE_SPACE_CHANGE_PENDING: {
+ // } break;
+ // case XR_TYPE_EVENT_DATA_INTERACTION_PROFILE_CHANGED: {
+ // } break;
+ default:
+ if (!handled) {
+ print_line("OpenXR Unhandled event type", OpenXRUtil::get_structure_type_name(runtimeEvent.type));
+ }
+ break;
+ }
+
+ runtimeEvent.type = XR_TYPE_EVENT_DATA_BUFFER;
+ pollResult = xrPollEvent(instance, &runtimeEvent);
+ }
+
+ if (pollResult == XR_EVENT_UNAVAILABLE) {
+ // processed all events in the queue
+ return true;
+ } else {
+ ERR_FAIL_V_MSG(false, "OpenXR: Failed to poll events!");
+ }
+}
+
+bool OpenXRAPI::process() {
+ ERR_FAIL_COND_V(instance == XR_NULL_HANDLE, false);
+
+ if (!poll_events()) {
+ return false;
+ }
+
+ if (!running) {
+ return false;
+ }
+
+ for (OpenXRExtensionWrapper *wrapper : registered_extension_wrappers) {
+ wrapper->on_process();
+ }
+
+ return true;
+}
+
+bool OpenXRAPI::acquire_image(XrSwapchain p_swapchain, uint32_t &r_image_index) {
+ ERR_FAIL_COND_V(image_acquired, true); // this was not released when it should be, error out and re-use...
+
+ XrResult result;
+ XrSwapchainImageAcquireInfo swapchain_image_acquire_info = {
+ XR_TYPE_SWAPCHAIN_IMAGE_ACQUIRE_INFO, // type
+ nullptr // next
+ };
+ result = xrAcquireSwapchainImage(p_swapchain, &swapchain_image_acquire_info, &r_image_index);
+ if (XR_FAILED(result)) {
+ print_line("OpenXR: failed to acquire swapchain image [", get_error_string(result), "]");
+ return false;
+ }
+
+ XrSwapchainImageWaitInfo swapchain_image_wait_info = {
+ XR_TYPE_SWAPCHAIN_IMAGE_WAIT_INFO, // type
+ nullptr, // next
+ 17000000 // timeout in nanoseconds
+ };
+
+ result = xrWaitSwapchainImage(p_swapchain, &swapchain_image_wait_info);
+ if (XR_FAILED(result)) {
+ print_line("OpenXR: failed to wait for swapchain image [", get_error_string(result), "]");
+ return false;
+ }
+
+ return true;
+}
+
+bool OpenXRAPI::release_image(XrSwapchain p_swapchain) {
+ XrSwapchainImageReleaseInfo swapchain_image_release_info = {
+ XR_TYPE_SWAPCHAIN_IMAGE_RELEASE_INFO, // type
+ nullptr // next
+ };
+ XrResult result = xrReleaseSwapchainImage(swapchain, &swapchain_image_release_info);
+ if (XR_FAILED(result)) {
+ print_line("OpenXR: failed to release swapchain image! [", get_error_string(result), "]");
+ return false;
+ }
+
+ return true;
+}
+
+void OpenXRAPI::pre_render() {
+ ERR_FAIL_COND(instance == XR_NULL_HANDLE);
+
+ if (!running) {
+ return;
+ }
+
+ // Waitframe does 2 important things in our process:
+ // 1) It provides us with predictive timing, telling us when OpenXR expects to display the frame we're about to commit
+ // 2) It will use the previous timing to pause our thread so that rendering starts as close to displaying as possible
+ // This must thus be called as close to when we start rendering as possible
+ XrFrameWaitInfo frame_wait_info = { XR_TYPE_FRAME_WAIT_INFO, nullptr };
+ XrResult result = xrWaitFrame(session, &frame_wait_info, &frame_state);
+ if (XR_FAILED(result)) {
+ print_line("OpenXR: xrWaitFrame() was not successful [", get_error_string(result), "]");
+ return;
+ }
+
+ for (OpenXRExtensionWrapper *wrapper : registered_extension_wrappers) {
+ wrapper->on_pre_render();
+ }
+
+ // Get our view info for the frame we're about to render, note from the OpenXR manual:
+ // "Repeatedly calling xrLocateViews with the same time may not necessarily return the same result. Instead the prediction gets increasingly accurate as the function is called closer to the given time for which a prediction is made"
+
+ // We're calling this "relatively" early, the positioning we're obtaining here will be used to do our frustum culling,
+ // occlusion culling, etc. There is however a technique that we can investigate in the future where after our entire
+ // Vulkan command buffer is build, but right before vkSubmitQueue is called, we call xrLocateViews one more time and
+ // update the view and projection matrix once more with a slightly more accurate predication and then submit the
+ // command queues.
+
+ // That is not possible yet but worth investigating in the future.
+
+ XrViewLocateInfo view_locate_info = {
+ XR_TYPE_VIEW_LOCATE_INFO, // type
+ nullptr, // next
+ view_configuration, // viewConfigurationType
+ frame_state.predictedDisplayTime, // displayTime
+ play_space // space
+ };
+ XrViewState view_state = {
+ XR_TYPE_VIEW_STATE, // type
+ nullptr, // next
+ 0 // viewStateFlags
+ };
+ uint32_t view_count_output;
+ result = xrLocateViews(session, &view_locate_info, &view_state, view_count, &view_count_output, views);
+ if (XR_FAILED(result)) {
+ print_line("OpenXR: Couldn't locate views [", get_error_string(result), "]");
+ return;
+ }
+
+ bool pose_valid = true;
+ for (uint64_t i = 0; i < view_count_output; i++) {
+ if ((view_state.viewStateFlags & XR_VIEW_STATE_ORIENTATION_VALID_BIT) == 0 ||
+ (view_state.viewStateFlags & XR_VIEW_STATE_POSITION_VALID_BIT) == 0) {
+ pose_valid = false;
+ }
+ }
+ if (view_pose_valid != pose_valid) {
+ view_pose_valid = pose_valid;
+#ifdef DEBUG
+ if (!view_pose_valid) {
+ print_line("OpenXR View pose became invalid");
+ } else {
+ print_line("OpenXR View pose became valid");
+ }
+#endif
+ }
+
+ // let's start our frame..
+ XrFrameBeginInfo frame_begin_info = {
+ XR_TYPE_FRAME_BEGIN_INFO, // type
+ nullptr // next
+ };
+ result = xrBeginFrame(session, &frame_begin_info);
+ if (XR_FAILED(result)) {
+ print_line("OpenXR: failed to being frame [", get_error_string(result), "]");
+ return;
+ }
+}
+
+bool OpenXRAPI::pre_draw_viewport(RID p_render_target) {
+ if (!can_render()) {
+ return false;
+ }
+
+ // TODO: at some point in time we may support multiple viewports in which case we need to handle that...
+
+ return true;
+}
+
+void OpenXRAPI::post_draw_viewport(RID p_render_target) {
+ if (!can_render()) {
+ return;
+ }
+
+ // TODO: at some point in time we may support multiple viewports in which case we need to handle that...
+
+ // TODO: if we can get PR 51179 to work properly we can change away from this approach and move this into get_external_texture or something
+ if (!image_acquired) {
+ if (!acquire_image(swapchain, image_index)) {
+ return;
+ }
+ image_acquired = true;
+
+ // print_line("OpenXR: acquired image " + itos(image_index) + ", copying...");
+
+ // Copy our buffer into our swap chain (remove once PR 51179 is done)
+ graphics_extension->copy_render_target_to_image(p_render_target, swapchain_graphics_data, image_index);
+ }
+};
+
+void OpenXRAPI::end_frame() {
+ XrResult result;
+
+ ERR_FAIL_COND(instance == XR_NULL_HANDLE);
+
+ if (!running) {
+ return;
+ }
+
+ if (frame_state.shouldRender && view_pose_valid && !image_acquired) {
+ print_line("OpenXR: No viewport was marked with use_xr, there is no rendered output!");
+ }
+
+ // must have:
+ // - shouldRender set to true
+ // - a valid view pose for projection_views[eye].pose to submit layer
+ // - an image to render
+ if (!frame_state.shouldRender || !view_pose_valid || !image_acquired) {
+ // submit 0 layers when we shouldn't render
+ XrFrameEndInfo frame_end_info = {
+ XR_TYPE_FRAME_END_INFO, // type
+ nullptr, // next
+ frame_state.predictedDisplayTime, // displayTime
+ XR_ENVIRONMENT_BLEND_MODE_OPAQUE, // environmentBlendMode
+ 0, // layerCount
+ nullptr // layers
+ };
+ result = xrEndFrame(session, &frame_end_info);
+ if (XR_FAILED(result)) {
+ print_line("OpenXR: failed to end frame! [", get_error_string(result), "]");
+ return;
+ }
+
+ // neither eye is rendered
+ return;
+ }
+
+ // release our swapchain image if we acquired it
+ if (image_acquired) {
+ image_acquired = false; // whether we succeed or not, consider this released.
+
+ release_image(swapchain);
+ }
+
+ for (uint32_t eye = 0; eye < view_count; eye++) {
+ projection_views[eye].fov = views[eye].fov;
+ projection_views[eye].pose = views[eye].pose;
+ }
+
+ Vector layers_list;
+
+ // Add composition layers from providers
+ for (OpenXRCompositionLayerProvider *provider : composition_layer_providers) {
+ XrCompositionLayerBaseHeader *layer = provider->get_composition_layer();
+ if (layer) {
+ layers_list.push_back(layer);
+ }
+ }
+
+ XrCompositionLayerProjection projection_layer = {
+ XR_TYPE_COMPOSITION_LAYER_PROJECTION, // type
+ nullptr, // next
+ layers_list.size() > 1 ? XR_COMPOSITION_LAYER_BLEND_TEXTURE_SOURCE_ALPHA_BIT | XR_COMPOSITION_LAYER_CORRECT_CHROMATIC_ABERRATION_BIT : XR_COMPOSITION_LAYER_CORRECT_CHROMATIC_ABERRATION_BIT, // layerFlags
+ play_space, // space
+ view_count, // viewCount
+ projection_views, // views
+ };
+ layers_list.push_back((const XrCompositionLayerBaseHeader *)&projection_layer);
+
+ XrFrameEndInfo frame_end_info = {
+ XR_TYPE_FRAME_END_INFO, // type
+ nullptr, // next
+ frame_state.predictedDisplayTime, // displayTime
+ XR_ENVIRONMENT_BLEND_MODE_OPAQUE, // environmentBlendMode
+ static_cast(layers_list.size()), // layerCount
+ layers_list.ptr() // layers
+ };
+ result = xrEndFrame(session, &frame_end_info);
+ if (XR_FAILED(result)) {
+ print_line("OpenXR: failed to end frame! [", get_error_string(result), "]");
+ return;
+ }
+}
+
+OpenXRAPI::OpenXRAPI() {
+ // OpenXRAPI is only constructed if OpenXR is enabled.
+ // It will be constructed when the rendering device first accesses OpenXR (be it the Vulkan or OpenGL rendering system)
+
+ if (Engine::get_singleton()->is_editor_hint()) {
+ // Enabled OpenXR in the editor? Adjust our settings for the editor
+
+ } else {
+ // Load settings from project settings
+ int ff = GLOBAL_GET("xr/openxr/form_factor");
+ switch (ff) {
+ case 0: {
+ form_factor = XR_FORM_FACTOR_HEAD_MOUNTED_DISPLAY;
+ } break;
+ case 1: {
+ form_factor = XR_FORM_FACTOR_HANDHELD_DISPLAY;
+ } break;
+ default:
+ break;
+ }
+
+ int vc = GLOBAL_GET("xr/openxr/view_configuration");
+ switch (vc) {
+ case 0: {
+ view_configuration = XR_VIEW_CONFIGURATION_TYPE_PRIMARY_MONO;
+ } break;
+ case 1: {
+ view_configuration = XR_VIEW_CONFIGURATION_TYPE_PRIMARY_STEREO;
+ } break;
+ /* we don't support quad and observer configurations (yet)
+ case 2: {
+ view_configuration = XR_VIEW_CONFIGURATION_TYPE_PRIMARY_QUAD_VARJO;
+ } break;
+ case 3: {
+ view_configuration = XR_VIEW_CONFIGURATION_TYPE_SECONDARY_MONO_FIRST_PERSON_OBSERVER_MSFT;
+ } break;
+ */
+ default:
+ break;
+ }
+
+ int rs = GLOBAL_GET("xr/openxr/reference_space");
+ switch (rs) {
+ case 0: {
+ reference_space = XR_REFERENCE_SPACE_TYPE_LOCAL;
+ } break;
+ case 1: {
+ reference_space = XR_REFERENCE_SPACE_TYPE_STAGE;
+ } break;
+ default:
+ break;
+ }
+ }
+
+ // reset a few things that can't be done in our class definition
+ frame_state.predictedDisplayTime = 0;
+ frame_state.predictedDisplayPeriod = 0;
+
+#ifdef ANDROID_ENABLED
+ // our android wrapper will initialise our android loader at this point
+ register_extension_wrapper(memnew(OpenXRAndroidExtension(this)));
+#endif
+}
+
+OpenXRAPI::~OpenXRAPI() {
+ // cleanup our composition layer providers
+ for (OpenXRCompositionLayerProvider *provider : composition_layer_providers) {
+ memdelete(provider);
+ }
+ composition_layer_providers.clear();
+
+ // cleanup our extension wrappers
+ for (OpenXRExtensionWrapper *extension_wrapper : registered_extension_wrappers) {
+ memdelete(extension_wrapper);
+ }
+ registered_extension_wrappers.clear();
+
+ if (supported_extensions != nullptr) {
+ memfree(supported_extensions);
+ supported_extensions = nullptr;
+ }
+
+ if (layer_properties != nullptr) {
+ memfree(layer_properties);
+ layer_properties = nullptr;
+ }
+}
+
+Transform3D OpenXRAPI::transform_from_pose(const XrPosef &p_pose) {
+ Quaternion q(p_pose.orientation.x, p_pose.orientation.y, p_pose.orientation.z, p_pose.orientation.w);
+ Basis basis(q);
+ Vector3 origin(p_pose.position.x, p_pose.position.y, p_pose.position.z);
+
+ return Transform3D(basis, origin);
+}
+
+template
+XRPose::TrackingConfidence _transform_from_location(const T &p_location, Transform3D &r_transform) {
+ Basis basis;
+ Vector3 origin;
+ XRPose::TrackingConfidence confidence = XRPose::XR_TRACKING_CONFIDENCE_NONE;
+ const auto &pose = p_location.pose;
+
+ // Check orientation
+ if (p_location.locationFlags & XR_SPACE_LOCATION_ORIENTATION_VALID_BIT) {
+ Quaternion q(pose.orientation.x, pose.orientation.y, pose.orientation.z, pose.orientation.w);
+ r_transform.basis = Basis(q);
+
+ if (p_location.locationFlags & XR_SPACE_LOCATION_ORIENTATION_TRACKED_BIT) {
+ // Fully valid orientation, so either 3DOF or 6DOF tracking with high confidence so default to HIGH_TRACKING
+ confidence = XRPose::XR_TRACKING_CONFIDENCE_HIGH;
+ } else {
+ // Orientation is being tracked but we're using old/predicted data, so low tracking confidence
+ confidence = XRPose::XR_TRACKING_CONFIDENCE_LOW;
+ }
+ } else {
+ r_transform.basis = Basis();
+ }
+
+ // Check location
+ if (p_location.locationFlags & XR_SPACE_LOCATION_POSITION_VALID_BIT) {
+ r_transform.origin = Vector3(pose.position.x, pose.position.y, pose.position.z);
+
+ if (!(p_location.locationFlags & XR_SPACE_LOCATION_ORIENTATION_TRACKED_BIT)) {
+ // Location is being tracked but we're using old/predicted data, so low tracking confidence
+ confidence = XRPose::XR_TRACKING_CONFIDENCE_LOW;
+ } else if (confidence == XRPose::XR_TRACKING_CONFIDENCE_NONE) {
+ // Position tracking without orientation tracking?
+ confidence = XRPose::XR_TRACKING_CONFIDENCE_HIGH;
+ }
+ } else {
+ // No tracking or 3DOF I guess..
+ r_transform.origin = Vector3();
+ }
+
+ return confidence;
+}
+
+XRPose::TrackingConfidence OpenXRAPI::transform_from_location(const XrSpaceLocation &p_location, Transform3D &r_transform) {
+ return _transform_from_location(p_location, r_transform);
+}
+
+XRPose::TrackingConfidence OpenXRAPI::transform_from_location(const XrHandJointLocationEXT &p_location, Transform3D &r_transform) {
+ return _transform_from_location(p_location, r_transform);
+}
+
+void OpenXRAPI::parse_velocities(const XrSpaceVelocity &p_velocity, Vector3 &r_linear_velocity, Vector3 r_angular_velocity) {
+ if (p_velocity.velocityFlags & XR_SPACE_VELOCITY_LINEAR_VALID_BIT) {
+ XrVector3f linear_velocity = p_velocity.linearVelocity;
+ r_linear_velocity = Vector3(linear_velocity.x, linear_velocity.y, linear_velocity.z);
+ } else {
+ r_linear_velocity = Vector3();
+ }
+ if (p_velocity.velocityFlags & XR_SPACE_VELOCITY_ANGULAR_VALID_BIT) {
+ XrVector3f angular_velocity = p_velocity.angularVelocity;
+ r_angular_velocity = Vector3(angular_velocity.x, angular_velocity.y, angular_velocity.z);
+ } else {
+ r_angular_velocity = Vector3();
+ }
+}
+
+RID OpenXRAPI::path_create(const String p_name) {
+ ERR_FAIL_COND_V(instance == XR_NULL_HANDLE, RID());
+
+ // Encoding our path as a RID is probably overkill but it does future proof this
+ // Note that we only do this for XrPaths that we access from outside of this class!
+
+ Path new_path;
+
+ print_line("Parsing path ", p_name);
+
+ XrResult result = xrStringToPath(instance, p_name.utf8().get_data(), &new_path.path);
+ if (XR_FAILED(result)) {
+ print_line("OpenXR: failed to get path for ", p_name, "! [", get_error_string(result), "]");
+ return RID();
+ }
+
+ return xr_path_owner.make_rid(new_path);
+}
+
+void OpenXRAPI::path_free(RID p_path) {
+ Path *path = xr_path_owner.get_or_null(p_path);
+ ERR_FAIL_NULL(path);
+
+ // there is nothing to free here
+
+ xr_path_owner.free(p_path);
+}
+
+RID OpenXRAPI::action_set_create(const String p_name, const String p_localized_name, const int p_priority) {
+ ERR_FAIL_COND_V(instance == XR_NULL_HANDLE, RID());
+ ActionSet action_set;
+
+ action_set.is_attached = false;
+
+ // create our action set...
+ XrActionSetCreateInfo action_set_info = {
+ XR_TYPE_ACTION_SET_CREATE_INFO, // type
+ nullptr, // next
+ "", // actionSetName
+ "", // localizedActionSetName
+ uint32_t(p_priority) // priority
+ };
+
+ copy_string_to_char_buffer(p_name, action_set_info.actionSetName, XR_MAX_ACTION_SET_NAME_SIZE);
+ copy_string_to_char_buffer(p_localized_name, action_set_info.localizedActionSetName, XR_MAX_LOCALIZED_ACTION_SET_NAME_SIZE);
+
+ print_line("Creating action set ", action_set_info.actionSetName, " - ", action_set_info.localizedActionSetName, " (", itos(action_set_info.priority), ")");
+
+ XrResult result = xrCreateActionSet(instance, &action_set_info, &action_set.handle);
+ if (XR_FAILED(result)) {
+ print_line("OpenXR: failed to create action set ", p_name, "! [", get_error_string(result), "]");
+ return RID();
+ }
+
+ return action_set_owner.make_rid(action_set);
+}
+
+bool OpenXRAPI::action_set_attach(RID p_action_set) {
+ ActionSet *action_set = action_set_owner.get_or_null(p_action_set);
+ ERR_FAIL_NULL_V(action_set, false);
+
+ if (action_set->is_attached) {
+ // already attached
+ return true;
+ }
+
+ ERR_FAIL_COND_V(session == XR_NULL_HANDLE, false);
+
+ // So according to the docs, once we attach our action set to our session it becomes read only..
+ // https://www.khronos.org/registry/OpenXR/specs/1.0/man/html/xrAttachSessionActionSets.html
+ XrSessionActionSetsAttachInfo attach_info = {
+ XR_TYPE_SESSION_ACTION_SETS_ATTACH_INFO, // type
+ nullptr, // next
+ 1, // countActionSets,
+ &action_set->handle // actionSets
+ };
+
+ XrResult result = xrAttachSessionActionSets(session, &attach_info);
+ if (XR_FAILED(result)) {
+ print_line("OpenXR: failed to attach action set! [", get_error_string(result), "]");
+ return false;
+ }
+
+ action_set->is_attached = true;
+
+ return true;
+}
+
+void OpenXRAPI::action_set_free(RID p_action_set) {
+ ActionSet *action_set = action_set_owner.get_or_null(p_action_set);
+ ERR_FAIL_NULL(action_set);
+
+ if (action_set->handle != XR_NULL_HANDLE) {
+ xrDestroyActionSet(action_set->handle);
+ }
+
+ action_set_owner.free(p_action_set);
+}
+
+RID OpenXRAPI::action_create(RID p_action_set, const String p_name, const String p_localized_name, OpenXRAction::ActionType p_action_type, const Vector &p_toplevel_paths) {
+ ERR_FAIL_COND_V(instance == XR_NULL_HANDLE, RID());
+
+ Action action;
+
+ ActionSet *action_set = action_set_owner.get_or_null(p_action_set);
+ ERR_FAIL_NULL_V(action_set, RID());
+ ERR_FAIL_COND_V(action_set->handle == XR_NULL_HANDLE, RID());
+
+ switch (p_action_type) {
+ case OpenXRAction::OPENXR_ACTION_BOOL:
+ action.action_type = XR_ACTION_TYPE_BOOLEAN_INPUT;
+ break;
+ case OpenXRAction::OPENXR_ACTION_FLOAT:
+ action.action_type = XR_ACTION_TYPE_FLOAT_INPUT;
+ break;
+ case OpenXRAction::OPENXR_ACTION_VECTOR2:
+ action.action_type = XR_ACTION_TYPE_VECTOR2F_INPUT;
+ break;
+ case OpenXRAction::OPENXR_ACTION_POSE:
+ action.action_type = XR_ACTION_TYPE_POSE_INPUT;
+ break;
+ case OpenXRAction::OPENXR_ACTION_HAPTIC:
+ action.action_type = XR_ACTION_TYPE_VIBRATION_OUTPUT;
+ break;
+ default:
+ ERR_FAIL_V(RID());
+ break;
+ }
+
+ Vector toplevel_paths;
+ for (int i = 0; i < p_toplevel_paths.size(); i++) {
+ Path *xr_path = xr_path_owner.get_or_null(p_toplevel_paths[i]);
+ if (xr_path != nullptr && xr_path->path != XR_NULL_PATH) {
+ PathWithSpace path_with_space = {
+ xr_path->path, // toplevel_path
+ XR_NULL_HANDLE, // space
+ false // was_location_valid
+ };
+ action.toplevel_paths.push_back(path_with_space);
+
+ toplevel_paths.push_back(xr_path->path);
+ }
+ }
+
+ XrActionCreateInfo action_info = {
+ XR_TYPE_ACTION_CREATE_INFO, // type
+ nullptr, // next
+ "", // actionName
+ action.action_type, // actionType
+ uint32_t(toplevel_paths.size()), // countSubactionPaths
+ toplevel_paths.ptr(), // subactionPaths
+ "" // localizedActionName
+ };
+
+ copy_string_to_char_buffer(p_name, action_info.actionName, XR_MAX_ACTION_NAME_SIZE);
+ copy_string_to_char_buffer(p_localized_name, action_info.localizedActionName, XR_MAX_LOCALIZED_ACTION_NAME_SIZE);
+
+ print_line("Creating action ", action_info.actionName, action_info.localizedActionName, action_info.countSubactionPaths);
+
+ XrResult result = xrCreateAction(action_set->handle, &action_info, &action.handle);
+ if (XR_FAILED(result)) {
+ print_line("OpenXR: failed to create action ", p_name, "! [", get_error_string(result), "]");
+ return RID();
+ }
+
+ return action_owner.make_rid(action);
+}
+
+void OpenXRAPI::action_free(RID p_action) {
+ Action *action = action_owner.get_or_null(p_action);
+ ERR_FAIL_NULL(action);
+
+ if (action->handle != XR_NULL_HANDLE) {
+ xrDestroyAction(action->handle);
+ }
+
+ action_owner.free(p_action);
+}
+
+bool OpenXRAPI::suggest_bindings(const String p_interaction_profile, const Vector p_bindings) {
+ ERR_FAIL_COND_V(instance == XR_NULL_HANDLE, false);
+
+ XrPath interaction_profile;
+ Vector bindings;
+
+ XrResult result = xrStringToPath(instance, p_interaction_profile.utf8().get_data(), &interaction_profile);
+ if (XR_FAILED(result)) {
+ print_line("OpenXR: failed to get path for ", p_interaction_profile, "! [", get_error_string(result), "]");
+ return false;
+ }
+
+ for (int i = 0; i < p_bindings.size(); i++) {
+ XrActionSuggestedBinding binding;
+
+ Action *action = action_owner.get_or_null(p_bindings[i].action);
+ if (action == nullptr || action->handle == XR_NULL_HANDLE) {
+ // just skip it
+ continue;
+ }
+
+ binding.action = action->handle;
+
+ result = xrStringToPath(instance, p_bindings[i].path.utf8().get_data(), &binding.binding);
+ if (XR_FAILED(result)) {
+ print_line("OpenXR: failed to get path for ", p_bindings[i].path, "! [", get_error_string(result), "]");
+ continue;
+ }
+
+ bindings.push_back(binding);
+ }
+
+ const XrInteractionProfileSuggestedBinding suggested_bindings = {
+ XR_TYPE_INTERACTION_PROFILE_SUGGESTED_BINDING, // type
+ nullptr, // next
+ interaction_profile, // interactionProfile
+ uint32_t(bindings.size()), // countSuggestedBindings
+ bindings.ptr() // suggestedBindings
+ };
+
+ result = xrSuggestInteractionProfileBindings(instance, &suggested_bindings);
+ if (XR_FAILED(result)) {
+ print_line("OpenXR: failed to suggest bindings for ", p_interaction_profile, "! [", get_error_string(result), "]");
+ // reporting is enough...
+ }
+
+ return true;
+}
+
+bool OpenXRAPI::sync_action_sets(const Vector p_active_sets) {
+ ERR_FAIL_COND_V(session == XR_NULL_HANDLE, false);
+
+ if (!running) {
+ return false;
+ }
+
+ Vector active_sets;
+ for (int i = 0; i < p_active_sets.size(); i++) {
+ ActionSet *action_set = action_set_owner.get_or_null(p_active_sets[i]);
+ if (action_set && action_set->handle != XR_NULL_HANDLE) {
+ XrActiveActionSet aset;
+ aset.actionSet = action_set->handle;
+ aset.subactionPath = XR_NULL_PATH;
+ active_sets.push_back(aset);
+ }
+ }
+
+ ERR_FAIL_COND_V(active_sets.size() == 0, false);
+
+ XrActionsSyncInfo sync_info = {
+ XR_TYPE_ACTIONS_SYNC_INFO, // type
+ nullptr, // next
+ uint32_t(active_sets.size()), // countActiveActionSets
+ active_sets.ptr() // activeActionSets
+ };
+
+ XrResult result = xrSyncActions(session, &sync_info);
+ if (XR_FAILED(result)) {
+ print_line("OpenXR: failed to sync active action sets! [", get_error_string(result), "]");
+ return false;
+ }
+
+ return true;
+}
+
+bool OpenXRAPI::get_action_bool(RID p_action, RID p_path) {
+ ERR_FAIL_COND_V(session == XR_NULL_HANDLE, false);
+ Action *action = action_owner.get_or_null(p_action);
+ ERR_FAIL_NULL_V(action, false);
+ Path *path = xr_path_owner.get_or_null(p_path);
+ ERR_FAIL_NULL_V(path, false);
+
+ if (!running) {
+ return false;
+ }
+
+ ERR_FAIL_COND_V(action->action_type != XR_ACTION_TYPE_BOOLEAN_INPUT, false);
+
+ XrActionStateGetInfo get_info = {
+ XR_TYPE_ACTION_STATE_GET_INFO, // type
+ nullptr, // next
+ action->handle, // action
+ path->path // subactionPath
+ };
+
+ XrActionStateBoolean result_state;
+ result_state.type = XR_TYPE_ACTION_STATE_BOOLEAN,
+ result_state.next = nullptr;
+ XrResult result = xrGetActionStateBoolean(session, &get_info, &result_state);
+ if (XR_FAILED(result)) {
+ print_line("OpenXR: couldn't get action boolean! [", get_error_string(result), "]");
+ return false;
+ }
+
+ return result_state.isActive && result_state.currentState;
+}
+
+float OpenXRAPI::get_action_float(RID p_action, RID p_path) {
+ ERR_FAIL_COND_V(session == XR_NULL_HANDLE, 0.0);
+ Action *action = action_owner.get_or_null(p_action);
+ ERR_FAIL_NULL_V(action, 0.0);
+ Path *path = xr_path_owner.get_or_null(p_path);
+ ERR_FAIL_NULL_V(path, 0.0);
+
+ if (!running) {
+ return 0.0;
+ }
+
+ ERR_FAIL_COND_V(action->action_type != XR_ACTION_TYPE_FLOAT_INPUT, 0.0);
+
+ XrActionStateGetInfo get_info = {
+ XR_TYPE_ACTION_STATE_GET_INFO, // type
+ nullptr, // next
+ action->handle, // action
+ path->path // subactionPath
+ };
+
+ XrActionStateFloat result_state;
+ result_state.type = XR_TYPE_ACTION_STATE_FLOAT,
+ result_state.next = nullptr;
+ XrResult result = xrGetActionStateFloat(session, &get_info, &result_state);
+ if (XR_FAILED(result)) {
+ print_line("OpenXR: couldn't get action float! [", get_error_string(result), "]");
+ return 0.0;
+ }
+
+ return result_state.isActive ? result_state.currentState : 0.0;
+}
+
+Vector2 OpenXRAPI::get_action_vector2(RID p_action, RID p_path) {
+ ERR_FAIL_COND_V(session == XR_NULL_HANDLE, Vector2());
+ Action *action = action_owner.get_or_null(p_action);
+ ERR_FAIL_NULL_V(action, Vector2());
+ Path *path = xr_path_owner.get_or_null(p_path);
+ ERR_FAIL_NULL_V(path, Vector2());
+
+ if (!running) {
+ return Vector2();
+ }
+
+ ERR_FAIL_COND_V(action->action_type != XR_ACTION_TYPE_VECTOR2F_INPUT, Vector2());
+
+ XrActionStateGetInfo get_info = {
+ XR_TYPE_ACTION_STATE_GET_INFO, // type
+ nullptr, // next
+ action->handle, // action
+ path->path // subactionPath
+ };
+
+ XrActionStateVector2f result_state;
+ result_state.type = XR_TYPE_ACTION_STATE_VECTOR2F,
+ result_state.next = nullptr;
+ XrResult result = xrGetActionStateVector2f(session, &get_info, &result_state);
+ if (XR_FAILED(result)) {
+ print_line("OpenXR: couldn't get action vector2! [", get_error_string(result), "]");
+ return Vector2();
+ }
+
+ return result_state.isActive ? Vector2(result_state.currentState.x, result_state.currentState.y) : Vector2();
+}
+
+XRPose::TrackingConfidence OpenXRAPI::get_action_pose(RID p_action, RID p_path, Transform3D &r_transform, Vector3 &r_linear_velocity, Vector3 &r_angular_velocity) {
+ ERR_FAIL_COND_V(session == XR_NULL_HANDLE, XRPose::XR_TRACKING_CONFIDENCE_NONE);
+ Action *action = action_owner.get_or_null(p_action);
+ ERR_FAIL_NULL_V(action, XRPose::XR_TRACKING_CONFIDENCE_NONE);
+ Path *path = xr_path_owner.get_or_null(p_path);
+ ERR_FAIL_NULL_V(path, XRPose::XR_TRACKING_CONFIDENCE_NONE);
+
+ if (!running) {
+ return XRPose::XR_TRACKING_CONFIDENCE_NONE;
+ }
+
+ ERR_FAIL_COND_V(action->action_type != XR_ACTION_TYPE_POSE_INPUT, XRPose::XR_TRACKING_CONFIDENCE_NONE);
+
+ uint64_t index = 0xFFFFFFFF;
+ uint64_t size = uint64_t(action->toplevel_paths.size());
+ for (uint64_t i = 0; i < size && index == 0xFFFFFFFF; i++) {
+ if (action->toplevel_paths[i].toplevel_path == path->path) {
+ index = i;
+ }
+ }
+
+ if (index == 0xFFFFFFFF) {
+ // couldn't find it?
+ return XRPose::XR_TRACKING_CONFIDENCE_NONE;
+ }
+
+ if (action->toplevel_paths[index].space == XR_NULL_HANDLE) {
+ // if this is a pose we need to define spaces
+
+ XrActionSpaceCreateInfo action_space_info = {
+ XR_TYPE_ACTION_SPACE_CREATE_INFO, // type
+ nullptr, // next
+ action->handle, // action
+ action->toplevel_paths[index].toplevel_path, // subactionPath
+ {
+ { 0.0, 0.0, 0.0, 1.0 }, // orientation
+ { 0.0, 0.0, 0.0 } // position
+ } // poseInActionSpace
+ };
+
+ XrSpace space;
+ XrResult result = xrCreateActionSpace(session, &action_space_info, &space);
+ if (XR_FAILED(result)) {
+ print_line("OpenXR: couldn't create action space! [", get_error_string(result), "]");
+ return XRPose::XR_TRACKING_CONFIDENCE_NONE;
+ }
+
+ action->toplevel_paths.ptrw()[index].space = space;
+ }
+
+ XrTime display_time = get_next_frame_time();
+
+ XrSpaceVelocity velocity = {
+ XR_TYPE_SPACE_VELOCITY, // type
+ nullptr, // next
+ 0, // velocityFlags
+ { 0.0, 0.0, 0.0 }, // linearVelocity
+ { 0.0, 0.0, 0.0 } // angularVelocity
+ };
+
+ XrSpaceLocation location = {
+ XR_TYPE_SPACE_LOCATION, // type
+ &velocity, // next
+ 0, // locationFlags
+ {
+ { 0.0, 0.0, 0.0, 0.0 }, // orientation
+ { 0.0, 0.0, 0.0 } // position
+ } // pose
+ };
+
+ XrResult result = xrLocateSpace(action->toplevel_paths[index].space, play_space, display_time, &location);
+ if (XR_FAILED(result)) {
+ print_line("OpenXR: failed to locate space! [", get_error_string(result), "]");
+ return XRPose::XR_TRACKING_CONFIDENCE_NONE;
+ }
+
+ XRPose::TrackingConfidence confidence = transform_from_location(location, r_transform);
+ parse_velocities(velocity, r_linear_velocity, r_angular_velocity);
+
+ return confidence;
+}
+
+bool OpenXRAPI::trigger_haptic_pulse(RID p_action, RID p_path, float p_frequency, float p_amplitude, XrDuration p_duration_ns) {
+ ERR_FAIL_COND_V(session == XR_NULL_HANDLE, false);
+ Action *action = action_owner.get_or_null(p_action);
+ ERR_FAIL_NULL_V(action, false);
+ Path *path = xr_path_owner.get_or_null(p_path);
+ ERR_FAIL_NULL_V(path, false);
+
+ if (!running) {
+ return false;
+ }
+
+ ERR_FAIL_COND_V(action->action_type != XR_ACTION_TYPE_VIBRATION_OUTPUT, false);
+
+ XrHapticActionInfo action_info = {
+ XR_TYPE_HAPTIC_ACTION_INFO, // type
+ nullptr, // next
+ action->handle, // action
+ path->path // subactionPath
+ };
+
+ XrHapticVibration vibration = {
+ XR_TYPE_HAPTIC_VIBRATION, // type
+ nullptr, // next
+ p_duration_ns, // duration
+ p_frequency, // frequency
+ p_amplitude, // amplitude
+ };
+
+ XrResult result = xrApplyHapticFeedback(session, &action_info, (const XrHapticBaseHeader *)&vibration);
+ if (XR_FAILED(result)) {
+ print_line("OpenXR: failed to apply haptic feedback! [", get_error_string(result), "]");
+ return false;
+ }
+
+ return true;
+}
diff --git a/modules/openxr/openxr_api.h b/modules/openxr/openxr_api.h
new file mode 100644
index 0000000000..33b503543a
--- /dev/null
+++ b/modules/openxr/openxr_api.h
@@ -0,0 +1,261 @@
+/*************************************************************************/
+/* openxr_api.h */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+
+#ifndef OPENXR_DRIVER_H
+#define OPENXR_DRIVER_H
+
+#include "core/error/error_macros.h"
+#include "core/math/camera_matrix.h"
+#include "core/math/transform_3d.h"
+#include "core/math/vector2.h"
+#include "core/os/memory.h"
+#include "core/string/ustring.h"
+#include "core/templates/map.h"
+#include "core/templates/rid_owner.h"
+#include "core/templates/vector.h"
+#include "servers/xr/xr_pose.h"
+
+#include "thirdparty/openxr/src/common/xr_linear.h"
+#include
+
+#include "action_map/openxr_action.h"
+
+#include "extensions/openxr_composition_layer_provider.h"
+#include "extensions/openxr_extension_wrapper.h"
+
+// Note, OpenXR code that we wrote for our plugin makes use of C++20 notation for initialising structs which ensures zeroing out unspecified members.
+// Godot is currently restricted to C++17 which doesn't allow this notation. Make sure critical fields are set.
+
+// forward declarations, we don't want to include these fully
+class OpenXRVulkanExtension;
+
+class OpenXRAPI {
+private:
+ // our singleton
+ static OpenXRAPI *singleton;
+
+ // layers
+ uint32_t num_layer_properties = 0;
+ XrApiLayerProperties *layer_properties = nullptr;
+
+ // extensions
+ uint32_t num_supported_extensions = 0;
+ XrExtensionProperties *supported_extensions = nullptr;
+ Vector registered_extension_wrappers;
+ Vector enabled_extensions;
+
+ // composition layer providers
+ Vector composition_layer_providers;
+
+ // view configuration
+ uint32_t num_view_configuration_types = 0;
+ XrViewConfigurationType *supported_view_configuration_types = nullptr;
+
+ // reference spaces
+ uint32_t num_reference_spaces = 0;
+ XrReferenceSpaceType *supported_reference_spaces = nullptr;
+
+ // swapchains (note these are platform dependent)
+ uint32_t num_swapchain_formats = 0;
+ int64_t *supported_swapchain_formats = nullptr;
+
+ // configuration
+ XrFormFactor form_factor = XR_FORM_FACTOR_HEAD_MOUNTED_DISPLAY;
+ XrViewConfigurationType view_configuration = XR_VIEW_CONFIGURATION_TYPE_PRIMARY_STEREO;
+ XrReferenceSpaceType reference_space = XR_REFERENCE_SPACE_TYPE_STAGE;
+ XrEnvironmentBlendMode environment_blend_mode = XR_ENVIRONMENT_BLEND_MODE_OPAQUE;
+
+ // state
+ XrInstance instance = XR_NULL_HANDLE;
+ XrSystemId system_id;
+ String system_name;
+ uint32_t vendor_id;
+ XrSystemTrackingProperties tracking_properties;
+ XrSession session = XR_NULL_HANDLE;
+ XrSessionState session_state = XR_SESSION_STATE_UNKNOWN;
+ bool running = false;
+ XrFrameState frame_state = { XR_TYPE_FRAME_STATE, NULL, 0, 0, false };
+
+ OpenXRGraphicsExtensionWrapper *graphics_extension = nullptr;
+ XrSystemGraphicsProperties graphics_properties;
+ void *swapchain_graphics_data = nullptr;
+ uint32_t image_index = 0;
+ bool image_acquired = false;
+
+ uint32_t view_count = 0;
+ XrViewConfigurationView *view_configuration_views = nullptr;
+ XrView *views = nullptr;
+ XrCompositionLayerProjectionView *projection_views = nullptr;
+ XrSwapchain swapchain = XR_NULL_HANDLE;
+
+ XrSpace play_space = XR_NULL_HANDLE;
+ XrSpace view_space = XR_NULL_HANDLE;
+ bool view_pose_valid = false;
+ XRPose::TrackingConfidence head_pose_confidence = XRPose::XR_TRACKING_CONFIDENCE_NONE;
+
+ bool load_layer_properties();
+ bool load_supported_extensions();
+ bool is_extension_supported(const char *p_extension) const;
+
+ // instance
+ bool create_instance();
+ bool get_system_info();
+ bool load_supported_view_configuration_types();
+ bool is_view_configuration_supported(XrViewConfigurationType p_configuration_type) const;
+ bool load_supported_view_configuration_views(XrViewConfigurationType p_configuration_type);
+ void destroy_instance();
+
+ // session
+ bool create_session();
+ bool load_supported_reference_spaces();
+ bool is_reference_space_supported(XrReferenceSpaceType p_reference_space);
+ bool setup_spaces();
+ bool load_supported_swapchain_formats();
+ bool is_swapchain_format_supported(int64_t p_swapchain_format);
+ bool create_main_swapchain();
+ void destroy_session();
+
+ // swapchains
+ bool create_swapchain(int64_t p_swapchain_format, uint32_t p_width, uint32_t p_height, uint32_t p_sample_count, uint32_t p_array_size, XrSwapchain &r_swapchain, void **r_swapchain_graphics_data);
+ bool acquire_image(XrSwapchain p_swapchain, uint32_t &r_image_index);
+ bool release_image(XrSwapchain p_swapchain);
+
+ // action map
+ struct Path {
+ XrPath path;
+ };
+ RID_Owner xr_path_owner;
+
+ struct ActionSet {
+ bool is_attached;
+ XrActionSet handle;
+ };
+ RID_Owner action_set_owner;
+
+ struct PathWithSpace {
+ XrPath toplevel_path;
+ XrSpace space;
+ bool was_location_valid;
+ };
+
+ struct Action {
+ XrActionType action_type;
+ Vector toplevel_paths;
+ XrAction handle;
+ };
+ RID_Owner action_owner;
+
+ // state changes
+ bool poll_events();
+ bool on_state_idle();
+ bool on_state_ready();
+ bool on_state_synchronized();
+ bool on_state_visible();
+ bool on_state_focused();
+ bool on_state_stopping();
+ bool on_state_loss_pending();
+ bool on_state_exiting();
+
+ // convencience
+ void copy_string_to_char_buffer(const String p_string, char *p_buffer, int p_buffer_len);
+
+protected:
+ friend class OpenXRVulkanExtension;
+
+ XrInstance get_instance() const { return instance; };
+ XrSystemId get_system_id() const { return system_id; };
+ XrSession get_session() const { return session; };
+
+ // helper method to convert an XrPosef to a Transform3D
+ Transform3D transform_from_pose(const XrPosef &p_pose);
+
+ // helper method to get a valid Transform3D from an openxr space location
+ XRPose::TrackingConfidence transform_from_location(const XrSpaceLocation &p_location, Transform3D &r_transform);
+ XRPose::TrackingConfidence transform_from_location(const XrHandJointLocationEXT &p_location, Transform3D &r_transform);
+ void parse_velocities(const XrSpaceVelocity &p_velocity, Vector3 &r_linear_velocity, Vector3 r_angular_velocity);
+
+public:
+ static void setup_global_defs();
+ static bool openxr_is_enabled();
+ static OpenXRAPI *get_singleton();
+
+ String get_error_string(XrResult result);
+ String get_swapchain_format_name(int64_t p_swapchain_format) const;
+
+ void register_extension_wrapper(OpenXRExtensionWrapper *p_extension_wrapper);
+
+ bool is_initialized();
+ bool is_running();
+ bool initialise(const String &p_rendering_driver);
+ bool initialise_session();
+ void finish();
+
+ XrTime get_next_frame_time() { return frame_state.predictedDisplayTime + frame_state.predictedDisplayPeriod; };
+ bool can_render() { return instance != XR_NULL_HANDLE && session != XR_NULL_HANDLE && running && view_pose_valid && frame_state.shouldRender; };
+
+ Size2 get_recommended_target_size();
+ XRPose::TrackingConfidence get_head_center(Transform3D &r_transform, Vector3 &r_linear_velocity, Vector3 &r_angular_velocity);
+ bool get_view_transform(uint32_t p_view, Transform3D &r_transform);
+ bool get_view_projection(uint32_t p_view, double p_z_near, double p_z_far, CameraMatrix &p_camera_matrix);
+ bool process();
+
+ void pre_render();
+ bool pre_draw_viewport(RID p_render_target);
+ void post_draw_viewport(RID p_render_target);
+ void end_frame();
+
+ // action map
+ String get_default_action_map_resource_name();
+ RID path_create(const String p_name);
+ void path_free(RID p_path);
+ RID action_set_create(const String p_name, const String p_localized_name, const int p_priority);
+ bool action_set_attach(RID p_action_set);
+ void action_set_free(RID p_action_set);
+ RID action_create(RID p_action_set, const String p_name, const String p_localized_name, OpenXRAction::ActionType p_action_type, const Vector &p_toplevel_paths);
+ void action_free(RID p_action);
+
+ struct Binding {
+ RID action;
+ String path;
+ };
+ bool suggest_bindings(const String p_interaction_profile, const Vector p_bindings);
+
+ bool sync_action_sets(const Vector p_active_sets);
+ bool get_action_bool(RID p_action, RID p_path);
+ float get_action_float(RID p_action, RID p_path);
+ Vector2 get_action_vector2(RID p_action, RID p_path);
+ XRPose::TrackingConfidence get_action_pose(RID p_action, RID p_path, Transform3D &r_transform, Vector3 &r_linear_velocity, Vector3 &r_angular_velocity);
+ bool trigger_haptic_pulse(RID p_action, RID p_path, float p_frequency, float p_amplitude, XrDuration p_duration_ns);
+
+ OpenXRAPI();
+ ~OpenXRAPI();
+};
+
+#endif // !OPENXR_DRIVER_H
diff --git a/modules/openxr/openxr_interface.cpp b/modules/openxr/openxr_interface.cpp
new file mode 100644
index 0000000000..394f634687
--- /dev/null
+++ b/modules/openxr/openxr_interface.cpp
@@ -0,0 +1,663 @@
+/*************************************************************************/
+/* openxr_interface.cpp */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+
+#include "openxr_interface.h"
+
+#include "core/io/resource_loader.h"
+#include "core/io/resource_saver.h"
+#include "servers/rendering/rendering_server_globals.h"
+
+void OpenXRInterface::_bind_methods() {
+ // todo
+}
+
+StringName OpenXRInterface::get_name() const {
+ return StringName("OpenXR");
+};
+
+uint32_t OpenXRInterface::get_capabilities() const {
+ return XRInterface::XR_VR + XRInterface::XR_STEREO;
+};
+
+XRInterface::TrackingStatus OpenXRInterface::get_tracking_status() const {
+ return tracking_state;
+}
+
+void OpenXRInterface::_load_action_map() {
+ ERR_FAIL_NULL(openxr_api);
+
+ // This may seem a bit duplicitous to a little bit of background info here.
+ // OpenXRActionMap (with all its sub resource classes) is a class that allows us to configure and store an action map in.
+ // This gives the user the ability to edit the action map in a UI and customise the actions.
+ // OpenXR however requires us to submit an action map and it takes over from that point and we can no longer change it.
+ // This system does that push and we store the info needed to then work with this action map going forward.
+
+ // Within our openxr device we maintain a number of classes that wrap the relevant OpenXR objects for this.
+ // Within OpenXRInterface we have a few internal classes that keep track of what we've created.
+ // This allow us to process the relevant actions each frame.
+
+ // just in case clean up
+ free_action_sets();
+ free_trackers();
+
+ Ref action_map;
+ if (Engine::get_singleton()->is_editor_hint()) {
+#ifdef TOOLS_ENABLED
+ action_map.instantiate();
+ action_map->create_editor_action_sets();
+#endif
+ } else {
+ String default_tres_name = openxr_api->get_default_action_map_resource_name();
+
+ // Check if we can load our default
+ if (ResourceLoader::exists(default_tres_name)) {
+ action_map = ResourceLoader::load(default_tres_name);
+ }
+
+ // Check if we need to create default action set
+ if (action_map.is_null()) {
+ action_map.instantiate();
+ action_map->create_default_action_sets();
+#ifdef TOOLS_ENABLED
+ // Save our action sets so our user can
+ action_map->set_path(default_tres_name, true);
+ ResourceSaver::save(default_tres_name, action_map);
+#endif
+ }
+ }
+
+ // process our action map
+ if (action_map.is_valid()) {
+ Map[, RID> action_rids;
+
+ Array action_sets = action_map->get_action_sets();
+ for (int i = 0; i < action_sets.size(); i++) {
+ // Create our action set
+ Ref xr_action_set = action_sets[i];
+ ActionSet *action_set = create_action_set(xr_action_set->get_name(), xr_action_set->get_localized_name(), xr_action_set->get_priority());
+ if (!action_set) {
+ continue;
+ }
+
+ // Now create our actions for these
+ Array actions = xr_action_set->get_actions();
+ for (int j = 0; j < actions.size(); j++) {
+ Ref xr_action = actions[j];
+
+ PackedStringArray toplevel_paths = xr_action->get_toplevel_paths();
+ Vector toplevel_rids;
+ Vector trackers;
+
+ for (int k = 0; k < toplevel_paths.size(); k++) {
+ Tracker *tracker = get_tracker(toplevel_paths[k]);
+ if (tracker) {
+ toplevel_rids.push_back(tracker->path_rid);
+ trackers.push_back(tracker);
+ }
+ }
+
+ Action *action = create_action(action_set, xr_action->get_name(), xr_action->get_localized_name(), xr_action->get_action_type(), toplevel_rids);
+ if (action) {
+ // we link our actions back to our trackers so we know which actions to check when we're processing our trackers
+ for (int t = 0; t < trackers.size(); t++) {
+ link_action_to_tracker(trackers[t], action);
+ }
+
+ // add this to our map for creating our interaction profiles
+ action_rids[xr_action] = action->action_rid;
+ }
+ }
+ }
+
+ // now do our suggestions
+ Array interaction_profiles = action_map->get_interaction_profiles();
+ for (int i = 0; i < interaction_profiles.size(); i++) {
+ Vector bindings;
+ Ref xr_interaction_profile = interaction_profiles[i];
+
+ Array xr_bindings = xr_interaction_profile->get_bindings();
+ for (int j = 0; j < xr_bindings.size(); j++) {
+ Ref xr_binding = xr_bindings[j];
+ Ref xr_action = xr_binding->get_action();
+ OpenXRAPI::Binding binding;
+
+ if (action_rids.has(xr_action)) {
+ binding.action = action_rids[xr_action];
+ } else {
+ print_line("Action ", xr_action->get_name(), " isn't part of an action set!");
+ continue;
+ }
+
+ PackedStringArray xr_paths = xr_binding->get_paths();
+ for (int k = 0; k < xr_paths.size(); k++) {
+ binding.path = xr_paths[k];
+ bindings.push_back(binding);
+ }
+ }
+
+ openxr_api->suggest_bindings(xr_interaction_profile->get_interaction_profile_path(), bindings);
+ }
+ }
+}
+
+OpenXRInterface::ActionSet *OpenXRInterface::create_action_set(const String &p_action_set_name, const String &p_localized_name, const int p_priority) {
+ ERR_FAIL_NULL_V(openxr_api, nullptr);
+
+ // find if it already exists
+ for (int i = 0; i < action_sets.size(); i++) {
+ if (action_sets[i]->action_set_name == p_action_set_name) {
+ // already exists in this set
+ return nullptr;
+ }
+ }
+
+ ActionSet *action_set = memnew(ActionSet);
+ action_set->action_set_name = p_action_set_name;
+ action_set->is_active = true;
+ action_set->action_set_rid = openxr_api->action_set_create(p_action_set_name, p_localized_name, p_priority);
+ action_sets.push_back(action_set);
+
+ return action_set;
+}
+
+void OpenXRInterface::free_action_sets() {
+ ERR_FAIL_NULL(openxr_api);
+
+ for (int i = 0; i < action_sets.size(); i++) {
+ ActionSet *action_set = action_sets[i];
+
+ openxr_api->path_free(action_set->action_set_rid);
+ free_actions(action_set);
+
+ memfree(action_set);
+ }
+ action_sets.clear();
+}
+
+OpenXRInterface::Action *OpenXRInterface::create_action(ActionSet *p_action_set, const String &p_action_name, const String &p_localized_name, OpenXRAction::ActionType p_action_type, const Vector p_toplevel_paths) {
+ ERR_FAIL_NULL_V(openxr_api, nullptr);
+
+ for (int i = 0; i < p_action_set->actions.size(); i++) {
+ if (p_action_set->actions[i]->action_name == p_action_name) {
+ // already exists in this set
+ return nullptr;
+ }
+ }
+
+ Action *action = memnew(Action);
+ action->action_name = p_action_name;
+ action->action_type = p_action_type;
+ action->action_rid = openxr_api->action_create(p_action_set->action_set_rid, p_action_name, p_localized_name, p_action_type, p_toplevel_paths);
+ p_action_set->actions.push_back(action);
+
+ return action;
+}
+
+OpenXRInterface::Action *OpenXRInterface::find_action(const String &p_action_name) {
+ // We just find the first action by this name
+
+ for (int i = 0; i < action_sets.size(); i++) {
+ for (int j = 0; j < action_sets[i]->actions.size(); j++) {
+ if (action_sets[i]->actions[j]->action_name == p_action_name) {
+ return action_sets[i]->actions[j];
+ }
+ }
+ }
+
+ // not found
+ return nullptr;
+}
+
+void OpenXRInterface::free_actions(ActionSet *p_action_set) {
+ ERR_FAIL_NULL(openxr_api);
+
+ for (int i = 0; i < p_action_set->actions.size(); i++) {
+ Action *action = p_action_set->actions[i];
+
+ openxr_api->action_free(action->action_rid);
+
+ memdelete(action);
+ }
+ p_action_set->actions.clear();
+}
+
+OpenXRInterface::Tracker *OpenXRInterface::get_tracker(const String &p_path_name) {
+ XRServer *xr_server = XRServer::get_singleton();
+ ERR_FAIL_NULL_V(xr_server, nullptr);
+ ERR_FAIL_NULL_V(openxr_api, nullptr);
+
+ Tracker *tracker = nullptr;
+ for (int i = 0; i < trackers.size(); i++) {
+ tracker = trackers[i];
+ if (tracker->path_name == p_path_name) {
+ return tracker;
+ }
+ }
+
+ // create our positional tracker
+ Ref positional_tracker;
+ positional_tracker.instantiate();
+
+ // We have standardised some names to make things nicer to the user so lets recognise the toplevel paths related to these.
+ if (p_path_name == "/user/hand/left") {
+ positional_tracker->set_tracker_type(XRServer::TRACKER_CONTROLLER);
+ positional_tracker->set_tracker_name("left_hand");
+ positional_tracker->set_tracker_desc("Left hand controller");
+ positional_tracker->set_tracker_hand(XRPositionalTracker::TRACKER_HAND_LEFT);
+ } else if (p_path_name == "/user/hand/right") {
+ positional_tracker->set_tracker_type(XRServer::TRACKER_CONTROLLER);
+ positional_tracker->set_tracker_name("right_hand");
+ positional_tracker->set_tracker_desc("Right hand controller");
+ positional_tracker->set_tracker_hand(XRPositionalTracker::TRACKER_HAND_RIGHT);
+ } else {
+ positional_tracker->set_tracker_type(XRServer::TRACKER_CONTROLLER);
+ positional_tracker->set_tracker_name(p_path_name);
+ positional_tracker->set_tracker_desc(p_path_name);
+ }
+ xr_server->add_tracker(positional_tracker);
+
+ // create a new entry
+ tracker = memnew(Tracker);
+ tracker->path_name = p_path_name;
+ tracker->path_rid = openxr_api->path_create(p_path_name);
+ tracker->positional_tracker = positional_tracker;
+ trackers.push_back(tracker);
+
+ return tracker;
+}
+
+OpenXRInterface::Tracker *OpenXRInterface::find_tracker(const String &p_positional_tracker_name) {
+ for (int i = 0; i < trackers.size(); i++) {
+ Tracker *tracker = trackers[i];
+ if (tracker->positional_tracker.is_valid() && tracker->positional_tracker->get_tracker_name() == p_positional_tracker_name) {
+ return tracker;
+ }
+ }
+
+ return nullptr;
+}
+
+void OpenXRInterface::link_action_to_tracker(Tracker *p_tracker, Action *p_action) {
+ if (p_tracker->actions.find(p_action) == -1) {
+ p_tracker->actions.push_back(p_action);
+ }
+}
+
+void OpenXRInterface::handle_tracker(Tracker *p_tracker) {
+ ERR_FAIL_NULL(openxr_api);
+ ERR_FAIL_COND(p_tracker->positional_tracker.is_null());
+
+ // handle all the actions
+ for (int i = 0; i < p_tracker->actions.size(); i++) {
+ Action *action = p_tracker->actions[i];
+ switch (action->action_type) {
+ case OpenXRAction::OPENXR_ACTION_BOOL: {
+ bool pressed = openxr_api->get_action_bool(action->action_rid, p_tracker->path_rid);
+ p_tracker->positional_tracker->set_input(action->action_name, Variant(pressed));
+ } break;
+ case OpenXRAction::OPENXR_ACTION_FLOAT: {
+ real_t value = openxr_api->get_action_float(action->action_rid, p_tracker->path_rid);
+ p_tracker->positional_tracker->set_input(action->action_name, Variant(value));
+ } break;
+ case OpenXRAction::OPENXR_ACTION_VECTOR2: {
+ Vector2 value = openxr_api->get_action_vector2(action->action_rid, p_tracker->path_rid);
+ p_tracker->positional_tracker->set_input(action->action_name, Variant(value));
+ } break;
+ case OpenXRAction::OPENXR_ACTION_POSE: {
+ Transform3D transform;
+ Vector3 linear, angular;
+ XRPose::TrackingConfidence confidence = openxr_api->get_action_pose(action->action_rid, p_tracker->path_rid, transform, linear, angular);
+ if (confidence != XRPose::XR_TRACKING_CONFIDENCE_NONE) {
+ String name;
+ // We can't have dual action names in OpenXR hence we added _pose, but default, aim and grip and default pose action names in Godot so rename them on the tracker.
+ // NOTE need to decide on whether we should keep the naming convention or rename it on Godots side
+ if (action->action_name == "default_pose") {
+ name = "default";
+ } else if (action->action_name == "aim_pose") {
+ name = "aim";
+ } else if (action->action_name == "grip_pose") {
+ name = "grip";
+ } else {
+ name = action->action_name;
+ }
+ p_tracker->positional_tracker->set_pose(name, transform, linear, angular, confidence);
+ }
+ } break;
+ default: {
+ // not yet supported
+ } break;
+ }
+ }
+}
+
+void OpenXRInterface::trigger_haptic_pulse(const String &p_action_name, const StringName &p_tracker_name, double p_frequency, double p_amplitude, double p_duration_sec, double p_delay_sec) {
+ ERR_FAIL_NULL(openxr_api);
+ Action *action = find_action(p_action_name);
+ ERR_FAIL_NULL(action);
+ Tracker *tracker = find_tracker(p_tracker_name);
+ ERR_FAIL_NULL(tracker);
+
+ // TODO OpenXR does not support delay, so we may need to add support for that somehow...
+
+ XrDuration duration = XrDuration(p_duration_sec * 1000000000.0); // seconds -> nanoseconds
+
+ openxr_api->trigger_haptic_pulse(action->action_rid, tracker->path_rid, p_frequency, p_amplitude, duration);
+}
+
+void OpenXRInterface::free_trackers() {
+ XRServer *xr_server = XRServer::get_singleton();
+ ERR_FAIL_NULL(xr_server);
+ ERR_FAIL_NULL(openxr_api);
+
+ for (int i = 0; i < trackers.size(); i++) {
+ Tracker *tracker = trackers[i];
+
+ openxr_api->path_free(tracker->path_rid);
+ xr_server->remove_tracker(tracker->positional_tracker);
+ tracker->positional_tracker.unref();
+
+ memdelete(tracker);
+ }
+ trackers.clear();
+}
+
+bool OpenXRInterface::initialise_on_startup() const {
+ if (openxr_api == nullptr) {
+ return false;
+ } else if (!openxr_api->is_initialized()) {
+ return false;
+ } else {
+ return true;
+ }
+}
+
+bool OpenXRInterface::is_initialized() const {
+ return initialized;
+};
+
+bool OpenXRInterface::initialize() {
+ XRServer *xr_server = XRServer::get_singleton();
+ ERR_FAIL_NULL_V(xr_server, false);
+
+ if (openxr_api == nullptr) {
+ return false;
+ } else if (!openxr_api->is_initialized()) {
+ return false;
+ } else if (initialized) {
+ return true;
+ }
+
+ // load up our action sets before setting up our session, note that our profiles are suggestions, OpenXR takes ownership of (re)binding
+ _load_action_map();
+
+ if (!openxr_api->initialise_session()) {
+ return false;
+ }
+
+ // we must create a tracker for our head
+ head.instantiate();
+ head->set_tracker_type(XRServer::TRACKER_HEAD);
+ head->set_tracker_name("head");
+ head->set_tracker_desc("Players head");
+ xr_server->add_tracker(head);
+
+ // attach action sets
+ for (int i = 0; i < action_sets.size(); i++) {
+ openxr_api->action_set_attach(action_sets[i]->action_set_rid);
+ }
+
+ // make this our primary interface
+ xr_server->set_primary_interface(this);
+
+ initialized = true;
+
+ return initialized;
+}
+
+void OpenXRInterface::uninitialize() {
+ // Our OpenXR driver will clean itself up properly when Godot exits, so we just do some basic stuff here
+
+ // end the session if we need to?
+
+ // cleanup stuff
+ free_action_sets();
+ free_trackers();
+
+ XRServer *xr_server = XRServer::get_singleton();
+ if (xr_server) {
+ if (head.is_valid()) {
+ xr_server->remove_tracker(head);
+
+ head.unref();
+ }
+ }
+
+ initialized = false;
+}
+
+bool OpenXRInterface::supports_play_area_mode(XRInterface::PlayAreaMode p_mode) {
+ return false;
+}
+
+XRInterface::PlayAreaMode OpenXRInterface::get_play_area_mode() const {
+ return XRInterface::XR_PLAY_AREA_UNKNOWN;
+}
+
+bool OpenXRInterface::set_play_area_mode(XRInterface::PlayAreaMode p_mode) {
+ return false;
+}
+
+Size2 OpenXRInterface::get_render_target_size() {
+ if (openxr_api == nullptr) {
+ return Size2();
+ } else {
+ return openxr_api->get_recommended_target_size();
+ }
+}
+
+uint32_t OpenXRInterface::get_view_count() {
+ // TODO set this based on our configuration
+ return 2;
+}
+
+void OpenXRInterface::_set_default_pos(Transform3D &p_transform, double p_world_scale, uint64_t p_eye) {
+ p_transform = Transform3D();
+
+ // if we're not tracking, don't put our head on the floor...
+ p_transform.origin.y = 1.5 * p_world_scale;
+
+ // overkill but..
+ if (p_eye == 1) {
+ p_transform.origin.x = 0.03 * p_world_scale;
+ } else if (p_eye == 2) {
+ p_transform.origin.x = -0.03 * p_world_scale;
+ }
+}
+
+Transform3D OpenXRInterface::get_camera_transform() {
+ XRServer *xr_server = XRServer::get_singleton();
+ ERR_FAIL_NULL_V(xr_server, Transform3D());
+
+ Transform3D hmd_transform;
+ double world_scale = xr_server->get_world_scale();
+
+ // head_transform should be updated in process
+
+ hmd_transform.basis = head_transform.basis;
+ hmd_transform.origin = head_transform.origin * world_scale;
+
+ return hmd_transform;
+}
+
+Transform3D OpenXRInterface::get_transform_for_view(uint32_t p_view, const Transform3D &p_cam_transform) {
+ XRServer *xr_server = XRServer::get_singleton();
+ ERR_FAIL_NULL_V(xr_server, Transform3D());
+
+ Transform3D t;
+ if (openxr_api && openxr_api->get_view_transform(p_view, t)) {
+ // update our cached value if we have a valid transform
+ transform_for_view[p_view] = t;
+ } else {
+ // reuse cached value
+ t = transform_for_view[p_view];
+ }
+
+ // Apply our world scale
+ double world_scale = xr_server->get_world_scale();
+ t.origin *= world_scale;
+
+ return p_cam_transform * xr_server->get_reference_frame() * t;
+}
+
+CameraMatrix OpenXRInterface::get_projection_for_view(uint32_t p_view, double p_aspect, double p_z_near, double p_z_far) {
+ CameraMatrix cm;
+
+ if (openxr_api) {
+ if (openxr_api->get_view_projection(p_view, p_z_near, p_z_far, cm)) {
+ return cm;
+ }
+ }
+
+ // Failed to get from our OpenXR device? Default to some sort of sensible camera matrix..
+ cm.set_for_hmd(p_view + 1, 1.0, 6.0, 14.5, 4.0, 1.5, p_z_near, p_z_far);
+
+ return cm;
+}
+
+void OpenXRInterface::process() {
+ if (openxr_api) {
+ // do our normal process
+ if (openxr_api->process()) {
+ Transform3D t;
+ Vector3 linear_velocity;
+ Vector3 angular_velocity;
+ XRPose::TrackingConfidence confidence = openxr_api->get_head_center(t, linear_velocity, angular_velocity);
+ if (confidence != XRPose::XR_TRACKING_CONFIDENCE_NONE) {
+ // Only update our transform if we have one to update it with
+ // note that poses are stored without world scale and reference frame applied!
+ head_transform = t;
+ head_linear_velocity = linear_velocity;
+ head_angular_velocity = angular_velocity;
+ }
+ }
+
+ // handle our action sets....
+ Vector active_sets;
+ for (int i = 0; i < action_sets.size(); i++) {
+ if (action_sets[i]->is_active) {
+ active_sets.push_back(action_sets[i]->action_set_rid);
+ }
+ }
+
+ if (openxr_api->sync_action_sets(active_sets)) {
+ for (int i = 0; i < trackers.size(); i++) {
+ handle_tracker(trackers[i]);
+ }
+ }
+ }
+
+ if (head.is_valid()) {
+ // TODO figure out how to get our velocities
+
+ head->set_pose("default", head_transform, head_linear_velocity, head_angular_velocity);
+
+ // TODO set confidence on pose once we support tracking this..
+ }
+}
+
+void OpenXRInterface::pre_render() {
+ if (openxr_api) {
+ openxr_api->pre_render();
+ }
+}
+
+bool OpenXRInterface::pre_draw_viewport(RID p_render_target) {
+ if (openxr_api) {
+ return openxr_api->pre_draw_viewport(p_render_target);
+ } else {
+ // don't render
+ return false;
+ }
+}
+
+Vector OpenXRInterface::post_draw_viewport(RID p_render_target, const Rect2 &p_screen_rect) {
+ Vector blit_to_screen;
+
+ // If separate HMD we should output one eye to screen
+ if (p_screen_rect != Rect2()) {
+ BlitToScreen blit;
+
+ blit.render_target = p_render_target;
+ blit.multi_view.use_layer = true;
+ blit.multi_view.layer = 0;
+ blit.lens_distortion.apply = false;
+
+ Size2 render_size = get_render_target_size();
+ Rect2 dst_rect = p_screen_rect;
+ float new_height = dst_rect.size.x * (render_size.y / render_size.x);
+ if (new_height > dst_rect.size.y) {
+ dst_rect.position.y = (0.5 * dst_rect.size.y) - (0.5 * new_height);
+ dst_rect.size.y = new_height;
+ } else {
+ float new_width = dst_rect.size.y * (render_size.x / render_size.y);
+
+ dst_rect.position.x = (0.5 * dst_rect.size.x) - (0.5 * new_width);
+ dst_rect.size.x = new_width;
+ }
+
+ blit.dst_rect = dst_rect;
+ blit_to_screen.push_back(blit);
+ }
+
+ if (openxr_api) {
+ openxr_api->post_draw_viewport(p_render_target);
+ }
+
+ return blit_to_screen;
+}
+
+void OpenXRInterface::end_frame() {
+ if (openxr_api) {
+ openxr_api->end_frame();
+ }
+}
+
+OpenXRInterface::OpenXRInterface() {
+ openxr_api = OpenXRAPI::get_singleton();
+
+ // while we don't have head tracking, don't put the headset on the floor...
+ _set_default_pos(head_transform, 1.0, 0);
+ _set_default_pos(transform_for_view[0], 1.0, 1);
+ _set_default_pos(transform_for_view[1], 1.0, 2);
+}
+
+OpenXRInterface::~OpenXRInterface() {
+ openxr_api = nullptr;
+}
diff --git a/modules/openxr/openxr_interface.h b/modules/openxr/openxr_interface.h
new file mode 100644
index 0000000000..ede7d481d2
--- /dev/null
+++ b/modules/openxr/openxr_interface.h
@@ -0,0 +1,129 @@
+/*************************************************************************/
+/* openxr_interface.h */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+
+#ifndef OPENXR_INTERFACE_H
+#define OPENXR_INTERFACE_H
+
+#include "servers/xr/xr_interface.h"
+#include "servers/xr/xr_positional_tracker.h"
+
+#include "action_map/openxr_action_map.h"
+#include "openxr_api.h"
+
+class OpenXRInterface : public XRInterface {
+ GDCLASS(OpenXRInterface, XRInterface);
+
+private:
+ OpenXRAPI *openxr_api = nullptr;
+ bool initialized = false;
+ XRInterface::TrackingStatus tracking_state;
+
+ // At a minimum we need a tracker for our head
+ Ref head;
+ Transform3D head_transform;
+ Vector3 head_linear_velocity;
+ Vector3 head_angular_velocity;
+ Transform3D transform_for_view[2]; // We currently assume 2, but could be 4 for VARJO which we do not support yet
+
+ void _load_action_map();
+
+ struct Action {
+ String action_name;
+ OpenXRAction::ActionType action_type;
+ RID action_rid;
+ };
+ struct ActionSet {
+ String action_set_name;
+ bool is_active;
+ RID action_set_rid;
+ Vector actions;
+ };
+ struct Tracker {
+ String path_name;
+ RID path_rid;
+ Ref positional_tracker;
+ Vector actions;
+ };
+
+ Vector action_sets;
+ Vector trackers;
+
+ ActionSet *create_action_set(const String &p_action_set_name, const String &p_localized_name, const int p_priority);
+ void free_action_sets();
+
+ Action *create_action(ActionSet *p_action_set, const String &p_action_name, const String &p_localized_name, OpenXRAction::ActionType p_action_type, const Vector p_toplevel_paths);
+ Action *find_action(const String &p_action_name);
+ void free_actions(ActionSet *p_action_set);
+
+ Tracker *get_tracker(const String &p_path_name);
+ Tracker *find_tracker(const String &p_positional_tracker_name);
+ void link_action_to_tracker(Tracker *p_tracker, Action *p_action);
+ void handle_tracker(Tracker *p_tracker);
+ void free_trackers();
+
+ void _set_default_pos(Transform3D &p_transform, double p_world_scale, uint64_t p_eye);
+
+protected:
+ static void _bind_methods();
+
+public:
+ virtual StringName get_name() const override;
+ virtual uint32_t get_capabilities() const override;
+
+ virtual TrackingStatus get_tracking_status() const override;
+
+ bool initialise_on_startup() const;
+ virtual bool is_initialized() const override;
+ virtual bool initialize() override;
+ virtual void uninitialize() override;
+
+ virtual void trigger_haptic_pulse(const String &p_action_name, const StringName &p_tracker_name, double p_frequency, double p_amplitude, double p_duration_sec, double p_delay_sec = 0) override;
+
+ virtual bool supports_play_area_mode(XRInterface::PlayAreaMode p_mode) override;
+ virtual XRInterface::PlayAreaMode get_play_area_mode() const override;
+ virtual bool set_play_area_mode(XRInterface::PlayAreaMode p_mode) override;
+
+ virtual Size2 get_render_target_size() override;
+ virtual uint32_t get_view_count() override;
+ virtual Transform3D get_camera_transform() override;
+ virtual Transform3D get_transform_for_view(uint32_t p_view, const Transform3D &p_cam_transform) override;
+ virtual CameraMatrix get_projection_for_view(uint32_t p_view, double p_aspect, double p_z_near, double p_z_far) override;
+
+ virtual void process() override;
+ virtual void pre_render() override;
+ bool pre_draw_viewport(RID p_render_target) override;
+ virtual Vector post_draw_viewport(RID p_render_target, const Rect2 &p_screen_rect) override;
+ virtual void end_frame() override;
+
+ OpenXRInterface();
+ ~OpenXRInterface();
+};
+
+#endif // !OPENXR_INTERFACE_H
diff --git a/modules/openxr/openxr_util.cpp b/modules/openxr/openxr_util.cpp
new file mode 100644
index 0000000000..e515336daa
--- /dev/null
+++ b/modules/openxr/openxr_util.cpp
@@ -0,0 +1,291 @@
+/*************************************************************************/
+/* openxr_util.cpp */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+
+#include "openxr_util.h"
+
+#define ENUM_TO_STRING_CASE(e) \
+ case e: { \
+ return String(#e); \
+ } break;
+
+// TODO see if we can generate this code further using the xml file with meta data supplied by OpenXR
+
+String OpenXRUtil::get_view_configuration_name(XrViewConfigurationType p_view_configuration) {
+ switch (p_view_configuration) {
+ ENUM_TO_STRING_CASE(XR_VIEW_CONFIGURATION_TYPE_PRIMARY_MONO)
+ ENUM_TO_STRING_CASE(XR_VIEW_CONFIGURATION_TYPE_PRIMARY_STEREO)
+ ENUM_TO_STRING_CASE(XR_VIEW_CONFIGURATION_TYPE_PRIMARY_QUAD_VARJO)
+ ENUM_TO_STRING_CASE(XR_VIEW_CONFIGURATION_TYPE_SECONDARY_MONO_FIRST_PERSON_OBSERVER_MSFT)
+ ENUM_TO_STRING_CASE(XR_VIEW_CONFIGURATION_TYPE_MAX_ENUM)
+ default: {
+ return String("View Configuration ") + String::num_int64(int64_t(p_view_configuration));
+ } break;
+ }
+}
+
+String OpenXRUtil::get_reference_space_name(XrReferenceSpaceType p_reference_space) {
+ switch (p_reference_space) {
+ ENUM_TO_STRING_CASE(XR_REFERENCE_SPACE_TYPE_VIEW)
+ ENUM_TO_STRING_CASE(XR_REFERENCE_SPACE_TYPE_LOCAL)
+ ENUM_TO_STRING_CASE(XR_REFERENCE_SPACE_TYPE_STAGE)
+ ENUM_TO_STRING_CASE(XR_REFERENCE_SPACE_TYPE_UNBOUNDED_MSFT)
+ ENUM_TO_STRING_CASE(XR_REFERENCE_SPACE_TYPE_COMBINED_EYE_VARJO)
+ ENUM_TO_STRING_CASE(XR_REFERENCE_SPACE_TYPE_MAX_ENUM)
+ default: {
+ return String("Reference space ") + String::num_int64(int64_t(p_reference_space));
+ } break;
+ }
+}
+
+String OpenXRUtil::get_structure_type_name(XrStructureType p_structure_type) {
+ switch (p_structure_type) {
+ ENUM_TO_STRING_CASE(XR_TYPE_UNKNOWN)
+ ENUM_TO_STRING_CASE(XR_TYPE_API_LAYER_PROPERTIES)
+ ENUM_TO_STRING_CASE(XR_TYPE_EXTENSION_PROPERTIES)
+ ENUM_TO_STRING_CASE(XR_TYPE_INSTANCE_CREATE_INFO)
+ ENUM_TO_STRING_CASE(XR_TYPE_SYSTEM_GET_INFO)
+ ENUM_TO_STRING_CASE(XR_TYPE_SYSTEM_PROPERTIES)
+ ENUM_TO_STRING_CASE(XR_TYPE_VIEW_LOCATE_INFO)
+ ENUM_TO_STRING_CASE(XR_TYPE_VIEW)
+ ENUM_TO_STRING_CASE(XR_TYPE_SESSION_CREATE_INFO)
+ ENUM_TO_STRING_CASE(XR_TYPE_SWAPCHAIN_CREATE_INFO)
+ ENUM_TO_STRING_CASE(XR_TYPE_SESSION_BEGIN_INFO)
+ ENUM_TO_STRING_CASE(XR_TYPE_VIEW_STATE)
+ ENUM_TO_STRING_CASE(XR_TYPE_FRAME_END_INFO)
+ ENUM_TO_STRING_CASE(XR_TYPE_HAPTIC_VIBRATION)
+ ENUM_TO_STRING_CASE(XR_TYPE_EVENT_DATA_BUFFER)
+ ENUM_TO_STRING_CASE(XR_TYPE_EVENT_DATA_INSTANCE_LOSS_PENDING)
+ ENUM_TO_STRING_CASE(XR_TYPE_EVENT_DATA_SESSION_STATE_CHANGED)
+ ENUM_TO_STRING_CASE(XR_TYPE_ACTION_STATE_BOOLEAN)
+ ENUM_TO_STRING_CASE(XR_TYPE_ACTION_STATE_FLOAT)
+ ENUM_TO_STRING_CASE(XR_TYPE_ACTION_STATE_VECTOR2F)
+ ENUM_TO_STRING_CASE(XR_TYPE_ACTION_STATE_POSE)
+ ENUM_TO_STRING_CASE(XR_TYPE_ACTION_SET_CREATE_INFO)
+ ENUM_TO_STRING_CASE(XR_TYPE_ACTION_CREATE_INFO)
+ ENUM_TO_STRING_CASE(XR_TYPE_INSTANCE_PROPERTIES)
+ ENUM_TO_STRING_CASE(XR_TYPE_FRAME_WAIT_INFO)
+ ENUM_TO_STRING_CASE(XR_TYPE_COMPOSITION_LAYER_PROJECTION)
+ ENUM_TO_STRING_CASE(XR_TYPE_COMPOSITION_LAYER_QUAD)
+ ENUM_TO_STRING_CASE(XR_TYPE_REFERENCE_SPACE_CREATE_INFO)
+ ENUM_TO_STRING_CASE(XR_TYPE_ACTION_SPACE_CREATE_INFO)
+ ENUM_TO_STRING_CASE(XR_TYPE_EVENT_DATA_REFERENCE_SPACE_CHANGE_PENDING)
+ ENUM_TO_STRING_CASE(XR_TYPE_VIEW_CONFIGURATION_VIEW)
+ ENUM_TO_STRING_CASE(XR_TYPE_SPACE_LOCATION)
+ ENUM_TO_STRING_CASE(XR_TYPE_SPACE_VELOCITY)
+ ENUM_TO_STRING_CASE(XR_TYPE_FRAME_STATE)
+ ENUM_TO_STRING_CASE(XR_TYPE_VIEW_CONFIGURATION_PROPERTIES)
+ ENUM_TO_STRING_CASE(XR_TYPE_FRAME_BEGIN_INFO)
+ ENUM_TO_STRING_CASE(XR_TYPE_COMPOSITION_LAYER_PROJECTION_VIEW)
+ ENUM_TO_STRING_CASE(XR_TYPE_EVENT_DATA_EVENTS_LOST)
+ ENUM_TO_STRING_CASE(XR_TYPE_INTERACTION_PROFILE_SUGGESTED_BINDING)
+ ENUM_TO_STRING_CASE(XR_TYPE_EVENT_DATA_INTERACTION_PROFILE_CHANGED)
+ ENUM_TO_STRING_CASE(XR_TYPE_INTERACTION_PROFILE_STATE)
+ ENUM_TO_STRING_CASE(XR_TYPE_SWAPCHAIN_IMAGE_ACQUIRE_INFO)
+ ENUM_TO_STRING_CASE(XR_TYPE_SWAPCHAIN_IMAGE_WAIT_INFO)
+ ENUM_TO_STRING_CASE(XR_TYPE_SWAPCHAIN_IMAGE_RELEASE_INFO)
+ ENUM_TO_STRING_CASE(XR_TYPE_ACTION_STATE_GET_INFO)
+ ENUM_TO_STRING_CASE(XR_TYPE_HAPTIC_ACTION_INFO)
+ ENUM_TO_STRING_CASE(XR_TYPE_SESSION_ACTION_SETS_ATTACH_INFO)
+ ENUM_TO_STRING_CASE(XR_TYPE_ACTIONS_SYNC_INFO)
+ ENUM_TO_STRING_CASE(XR_TYPE_BOUND_SOURCES_FOR_ACTION_ENUMERATE_INFO)
+ ENUM_TO_STRING_CASE(XR_TYPE_INPUT_SOURCE_LOCALIZED_NAME_GET_INFO)
+ ENUM_TO_STRING_CASE(XR_TYPE_COMPOSITION_LAYER_CUBE_KHR)
+ ENUM_TO_STRING_CASE(XR_TYPE_INSTANCE_CREATE_INFO_ANDROID_KHR)
+ ENUM_TO_STRING_CASE(XR_TYPE_COMPOSITION_LAYER_DEPTH_INFO_KHR)
+ ENUM_TO_STRING_CASE(XR_TYPE_VULKAN_SWAPCHAIN_FORMAT_LIST_CREATE_INFO_KHR)
+ ENUM_TO_STRING_CASE(XR_TYPE_EVENT_DATA_PERF_SETTINGS_EXT)
+ ENUM_TO_STRING_CASE(XR_TYPE_COMPOSITION_LAYER_CYLINDER_KHR)
+ ENUM_TO_STRING_CASE(XR_TYPE_COMPOSITION_LAYER_EQUIRECT_KHR)
+ ENUM_TO_STRING_CASE(XR_TYPE_DEBUG_UTILS_OBJECT_NAME_INFO_EXT)
+ ENUM_TO_STRING_CASE(XR_TYPE_DEBUG_UTILS_MESSENGER_CALLBACK_DATA_EXT)
+ ENUM_TO_STRING_CASE(XR_TYPE_DEBUG_UTILS_MESSENGER_CREATE_INFO_EXT)
+ ENUM_TO_STRING_CASE(XR_TYPE_DEBUG_UTILS_LABEL_EXT)
+ ENUM_TO_STRING_CASE(XR_TYPE_GRAPHICS_BINDING_OPENGL_WIN32_KHR)
+ ENUM_TO_STRING_CASE(XR_TYPE_GRAPHICS_BINDING_OPENGL_XLIB_KHR)
+ ENUM_TO_STRING_CASE(XR_TYPE_GRAPHICS_BINDING_OPENGL_XCB_KHR)
+ ENUM_TO_STRING_CASE(XR_TYPE_GRAPHICS_BINDING_OPENGL_WAYLAND_KHR)
+ ENUM_TO_STRING_CASE(XR_TYPE_SWAPCHAIN_IMAGE_OPENGL_KHR)
+ ENUM_TO_STRING_CASE(XR_TYPE_GRAPHICS_REQUIREMENTS_OPENGL_KHR)
+ ENUM_TO_STRING_CASE(XR_TYPE_GRAPHICS_BINDING_OPENGL_ES_ANDROID_KHR)
+ ENUM_TO_STRING_CASE(XR_TYPE_SWAPCHAIN_IMAGE_OPENGL_ES_KHR)
+ ENUM_TO_STRING_CASE(XR_TYPE_GRAPHICS_REQUIREMENTS_OPENGL_ES_KHR)
+ ENUM_TO_STRING_CASE(XR_TYPE_GRAPHICS_BINDING_VULKAN_KHR)
+ ENUM_TO_STRING_CASE(XR_TYPE_SWAPCHAIN_IMAGE_VULKAN_KHR)
+ ENUM_TO_STRING_CASE(XR_TYPE_GRAPHICS_REQUIREMENTS_VULKAN_KHR)
+ ENUM_TO_STRING_CASE(XR_TYPE_GRAPHICS_BINDING_D3D11_KHR)
+ ENUM_TO_STRING_CASE(XR_TYPE_SWAPCHAIN_IMAGE_D3D11_KHR)
+ ENUM_TO_STRING_CASE(XR_TYPE_GRAPHICS_REQUIREMENTS_D3D11_KHR)
+ ENUM_TO_STRING_CASE(XR_TYPE_GRAPHICS_BINDING_D3D12_KHR)
+ ENUM_TO_STRING_CASE(XR_TYPE_SWAPCHAIN_IMAGE_D3D12_KHR)
+ ENUM_TO_STRING_CASE(XR_TYPE_GRAPHICS_REQUIREMENTS_D3D12_KHR)
+ ENUM_TO_STRING_CASE(XR_TYPE_SYSTEM_EYE_GAZE_INTERACTION_PROPERTIES_EXT)
+ ENUM_TO_STRING_CASE(XR_TYPE_EYE_GAZE_SAMPLE_TIME_EXT)
+ ENUM_TO_STRING_CASE(XR_TYPE_VISIBILITY_MASK_KHR)
+ ENUM_TO_STRING_CASE(XR_TYPE_EVENT_DATA_VISIBILITY_MASK_CHANGED_KHR)
+ ENUM_TO_STRING_CASE(XR_TYPE_SESSION_CREATE_INFO_OVERLAY_EXTX)
+ ENUM_TO_STRING_CASE(XR_TYPE_EVENT_DATA_MAIN_SESSION_VISIBILITY_CHANGED_EXTX)
+ ENUM_TO_STRING_CASE(XR_TYPE_COMPOSITION_LAYER_COLOR_SCALE_BIAS_KHR)
+ ENUM_TO_STRING_CASE(XR_TYPE_SPATIAL_ANCHOR_CREATE_INFO_MSFT)
+ ENUM_TO_STRING_CASE(XR_TYPE_SPATIAL_ANCHOR_SPACE_CREATE_INFO_MSFT)
+ ENUM_TO_STRING_CASE(XR_TYPE_COMPOSITION_LAYER_IMAGE_LAYOUT_FB)
+ ENUM_TO_STRING_CASE(XR_TYPE_COMPOSITION_LAYER_ALPHA_BLEND_FB)
+ ENUM_TO_STRING_CASE(XR_TYPE_VIEW_CONFIGURATION_DEPTH_RANGE_EXT)
+ ENUM_TO_STRING_CASE(XR_TYPE_GRAPHICS_BINDING_EGL_MNDX)
+ ENUM_TO_STRING_CASE(XR_TYPE_SPATIAL_GRAPH_NODE_SPACE_CREATE_INFO_MSFT)
+ ENUM_TO_STRING_CASE(XR_TYPE_SYSTEM_HAND_TRACKING_PROPERTIES_EXT)
+ ENUM_TO_STRING_CASE(XR_TYPE_HAND_TRACKER_CREATE_INFO_EXT)
+ ENUM_TO_STRING_CASE(XR_TYPE_HAND_JOINTS_LOCATE_INFO_EXT)
+ ENUM_TO_STRING_CASE(XR_TYPE_HAND_JOINT_LOCATIONS_EXT)
+ ENUM_TO_STRING_CASE(XR_TYPE_HAND_JOINT_VELOCITIES_EXT)
+ ENUM_TO_STRING_CASE(XR_TYPE_SYSTEM_HAND_TRACKING_MESH_PROPERTIES_MSFT)
+ ENUM_TO_STRING_CASE(XR_TYPE_HAND_MESH_SPACE_CREATE_INFO_MSFT)
+ ENUM_TO_STRING_CASE(XR_TYPE_HAND_MESH_UPDATE_INFO_MSFT)
+ ENUM_TO_STRING_CASE(XR_TYPE_HAND_MESH_MSFT)
+ ENUM_TO_STRING_CASE(XR_TYPE_HAND_POSE_TYPE_INFO_MSFT)
+ ENUM_TO_STRING_CASE(XR_TYPE_SECONDARY_VIEW_CONFIGURATION_SESSION_BEGIN_INFO_MSFT)
+ ENUM_TO_STRING_CASE(XR_TYPE_SECONDARY_VIEW_CONFIGURATION_STATE_MSFT)
+ ENUM_TO_STRING_CASE(XR_TYPE_SECONDARY_VIEW_CONFIGURATION_FRAME_STATE_MSFT)
+ ENUM_TO_STRING_CASE(XR_TYPE_SECONDARY_VIEW_CONFIGURATION_FRAME_END_INFO_MSFT)
+ ENUM_TO_STRING_CASE(XR_TYPE_SECONDARY_VIEW_CONFIGURATION_LAYER_INFO_MSFT)
+ ENUM_TO_STRING_CASE(XR_TYPE_SECONDARY_VIEW_CONFIGURATION_SWAPCHAIN_CREATE_INFO_MSFT)
+ ENUM_TO_STRING_CASE(XR_TYPE_CONTROLLER_MODEL_KEY_STATE_MSFT)
+ ENUM_TO_STRING_CASE(XR_TYPE_CONTROLLER_MODEL_NODE_PROPERTIES_MSFT)
+ ENUM_TO_STRING_CASE(XR_TYPE_CONTROLLER_MODEL_PROPERTIES_MSFT)
+ ENUM_TO_STRING_CASE(XR_TYPE_CONTROLLER_MODEL_NODE_STATE_MSFT)
+ ENUM_TO_STRING_CASE(XR_TYPE_CONTROLLER_MODEL_STATE_MSFT)
+ ENUM_TO_STRING_CASE(XR_TYPE_VIEW_CONFIGURATION_VIEW_FOV_EPIC)
+ ENUM_TO_STRING_CASE(XR_TYPE_HOLOGRAPHIC_WINDOW_ATTACHMENT_MSFT)
+ ENUM_TO_STRING_CASE(XR_TYPE_COMPOSITION_LAYER_REPROJECTION_INFO_MSFT)
+ ENUM_TO_STRING_CASE(XR_TYPE_COMPOSITION_LAYER_REPROJECTION_PLANE_OVERRIDE_MSFT)
+ ENUM_TO_STRING_CASE(XR_TYPE_ANDROID_SURFACE_SWAPCHAIN_CREATE_INFO_FB)
+ ENUM_TO_STRING_CASE(XR_TYPE_COMPOSITION_LAYER_SECURE_CONTENT_FB)
+ ENUM_TO_STRING_CASE(XR_TYPE_INTERACTION_PROFILE_ANALOG_THRESHOLD_VALVE)
+ ENUM_TO_STRING_CASE(XR_TYPE_HAND_JOINTS_MOTION_RANGE_INFO_EXT)
+ ENUM_TO_STRING_CASE(XR_TYPE_LOADER_INIT_INFO_ANDROID_KHR)
+ ENUM_TO_STRING_CASE(XR_TYPE_VULKAN_INSTANCE_CREATE_INFO_KHR)
+ ENUM_TO_STRING_CASE(XR_TYPE_VULKAN_DEVICE_CREATE_INFO_KHR)
+ ENUM_TO_STRING_CASE(XR_TYPE_VULKAN_GRAPHICS_DEVICE_GET_INFO_KHR)
+ ENUM_TO_STRING_CASE(XR_TYPE_COMPOSITION_LAYER_EQUIRECT2_KHR)
+ ENUM_TO_STRING_CASE(XR_TYPE_SCENE_OBSERVER_CREATE_INFO_MSFT)
+ ENUM_TO_STRING_CASE(XR_TYPE_SCENE_CREATE_INFO_MSFT)
+ ENUM_TO_STRING_CASE(XR_TYPE_NEW_SCENE_COMPUTE_INFO_MSFT)
+ ENUM_TO_STRING_CASE(XR_TYPE_VISUAL_MESH_COMPUTE_LOD_INFO_MSFT)
+ ENUM_TO_STRING_CASE(XR_TYPE_SCENE_COMPONENTS_MSFT)
+ ENUM_TO_STRING_CASE(XR_TYPE_SCENE_COMPONENTS_GET_INFO_MSFT)
+ ENUM_TO_STRING_CASE(XR_TYPE_SCENE_COMPONENT_LOCATIONS_MSFT)
+ ENUM_TO_STRING_CASE(XR_TYPE_SCENE_COMPONENTS_LOCATE_INFO_MSFT)
+ ENUM_TO_STRING_CASE(XR_TYPE_SCENE_OBJECTS_MSFT)
+ ENUM_TO_STRING_CASE(XR_TYPE_SCENE_COMPONENT_PARENT_FILTER_INFO_MSFT)
+ ENUM_TO_STRING_CASE(XR_TYPE_SCENE_OBJECT_TYPES_FILTER_INFO_MSFT)
+ ENUM_TO_STRING_CASE(XR_TYPE_SCENE_PLANES_MSFT)
+ ENUM_TO_STRING_CASE(XR_TYPE_SCENE_PLANE_ALIGNMENT_FILTER_INFO_MSFT)
+ ENUM_TO_STRING_CASE(XR_TYPE_SCENE_MESHES_MSFT)
+ ENUM_TO_STRING_CASE(XR_TYPE_SCENE_MESH_BUFFERS_GET_INFO_MSFT)
+ ENUM_TO_STRING_CASE(XR_TYPE_SCENE_MESH_BUFFERS_MSFT)
+ ENUM_TO_STRING_CASE(XR_TYPE_SCENE_MESH_VERTEX_BUFFER_MSFT)
+ ENUM_TO_STRING_CASE(XR_TYPE_SCENE_MESH_INDICES_UINT32_MSFT)
+ ENUM_TO_STRING_CASE(XR_TYPE_SCENE_MESH_INDICES_UINT16_MSFT)
+ ENUM_TO_STRING_CASE(XR_TYPE_SERIALIZED_SCENE_FRAGMENT_DATA_GET_INFO_MSFT)
+ ENUM_TO_STRING_CASE(XR_TYPE_SCENE_DESERIALIZE_INFO_MSFT)
+ ENUM_TO_STRING_CASE(XR_TYPE_EVENT_DATA_DISPLAY_REFRESH_RATE_CHANGED_FB)
+ ENUM_TO_STRING_CASE(XR_TYPE_VIVE_TRACKER_PATHS_HTCX)
+ ENUM_TO_STRING_CASE(XR_TYPE_EVENT_DATA_VIVE_TRACKER_CONNECTED_HTCX)
+ ENUM_TO_STRING_CASE(XR_TYPE_SYSTEM_COLOR_SPACE_PROPERTIES_FB)
+ ENUM_TO_STRING_CASE(XR_TYPE_HAND_TRACKING_MESH_FB)
+ ENUM_TO_STRING_CASE(XR_TYPE_HAND_TRACKING_SCALE_FB)
+ ENUM_TO_STRING_CASE(XR_TYPE_HAND_TRACKING_AIM_STATE_FB)
+ ENUM_TO_STRING_CASE(XR_TYPE_HAND_TRACKING_CAPSULES_STATE_FB)
+ ENUM_TO_STRING_CASE(XR_TYPE_FOVEATION_PROFILE_CREATE_INFO_FB)
+ ENUM_TO_STRING_CASE(XR_TYPE_SWAPCHAIN_CREATE_INFO_FOVEATION_FB)
+ ENUM_TO_STRING_CASE(XR_TYPE_SWAPCHAIN_STATE_FOVEATION_FB)
+ ENUM_TO_STRING_CASE(XR_TYPE_FOVEATION_LEVEL_PROFILE_CREATE_INFO_FB)
+ ENUM_TO_STRING_CASE(XR_TYPE_TRIANGLE_MESH_CREATE_INFO_FB)
+ ENUM_TO_STRING_CASE(XR_TYPE_SYSTEM_PASSTHROUGH_PROPERTIES_FB)
+ ENUM_TO_STRING_CASE(XR_TYPE_PASSTHROUGH_CREATE_INFO_FB)
+ ENUM_TO_STRING_CASE(XR_TYPE_PASSTHROUGH_LAYER_CREATE_INFO_FB)
+ ENUM_TO_STRING_CASE(XR_TYPE_COMPOSITION_LAYER_PASSTHROUGH_FB)
+ ENUM_TO_STRING_CASE(XR_TYPE_GEOMETRY_INSTANCE_CREATE_INFO_FB)
+ ENUM_TO_STRING_CASE(XR_TYPE_GEOMETRY_INSTANCE_TRANSFORM_FB)
+ ENUM_TO_STRING_CASE(XR_TYPE_PASSTHROUGH_STYLE_FB)
+ ENUM_TO_STRING_CASE(XR_TYPE_PASSTHROUGH_COLOR_MAP_MONO_TO_RGBA_FB)
+ ENUM_TO_STRING_CASE(XR_TYPE_PASSTHROUGH_COLOR_MAP_MONO_TO_MONO_FB)
+ ENUM_TO_STRING_CASE(XR_TYPE_EVENT_DATA_PASSTHROUGH_STATE_CHANGED_FB)
+ ENUM_TO_STRING_CASE(XR_TYPE_BINDING_MODIFICATIONS_KHR)
+ ENUM_TO_STRING_CASE(XR_TYPE_VIEW_LOCATE_FOVEATED_RENDERING_VARJO)
+ ENUM_TO_STRING_CASE(XR_TYPE_FOVEATED_VIEW_CONFIGURATION_VIEW_VARJO)
+ ENUM_TO_STRING_CASE(XR_TYPE_SYSTEM_FOVEATED_RENDERING_PROPERTIES_VARJO)
+ ENUM_TO_STRING_CASE(XR_TYPE_COMPOSITION_LAYER_DEPTH_TEST_VARJO)
+ ENUM_TO_STRING_CASE(XR_TYPE_SYSTEM_MARKER_TRACKING_PROPERTIES_VARJO)
+ ENUM_TO_STRING_CASE(XR_TYPE_EVENT_DATA_MARKER_TRACKING_UPDATE_VARJO)
+ ENUM_TO_STRING_CASE(XR_TYPE_MARKER_SPACE_CREATE_INFO_VARJO)
+ ENUM_TO_STRING_CASE(XR_TYPE_SPATIAL_ANCHOR_PERSISTENCE_INFO_MSFT)
+ ENUM_TO_STRING_CASE(XR_TYPE_SPATIAL_ANCHOR_FROM_PERSISTED_ANCHOR_CREATE_INFO_MSFT)
+ ENUM_TO_STRING_CASE(XR_TYPE_SWAPCHAIN_IMAGE_FOVEATION_VULKAN_FB)
+ ENUM_TO_STRING_CASE(XR_TYPE_SWAPCHAIN_STATE_ANDROID_SURFACE_DIMENSIONS_FB)
+ ENUM_TO_STRING_CASE(XR_TYPE_SWAPCHAIN_STATE_SAMPLER_OPENGL_ES_FB)
+ ENUM_TO_STRING_CASE(XR_TYPE_SWAPCHAIN_STATE_SAMPLER_VULKAN_FB)
+ ENUM_TO_STRING_CASE(XR_TYPE_COMPOSITION_LAYER_SPACE_WARP_INFO_FB)
+ ENUM_TO_STRING_CASE(XR_TYPE_SYSTEM_SPACE_WARP_PROPERTIES_FB)
+ ENUM_TO_STRING_CASE(XR_STRUCTURE_TYPE_MAX_ENUM)
+ default: {
+ return String("Structure type ") + String::num_int64(int64_t(p_structure_type));
+ } break;
+ }
+}
+
+String OpenXRUtil::get_session_state_name(XrSessionState p_session_state) {
+ switch (p_session_state) {
+ ENUM_TO_STRING_CASE(XR_SESSION_STATE_UNKNOWN)
+ ENUM_TO_STRING_CASE(XR_SESSION_STATE_IDLE)
+ ENUM_TO_STRING_CASE(XR_SESSION_STATE_READY)
+ ENUM_TO_STRING_CASE(XR_SESSION_STATE_SYNCHRONIZED)
+ ENUM_TO_STRING_CASE(XR_SESSION_STATE_VISIBLE)
+ ENUM_TO_STRING_CASE(XR_SESSION_STATE_FOCUSED)
+ ENUM_TO_STRING_CASE(XR_SESSION_STATE_STOPPING)
+ ENUM_TO_STRING_CASE(XR_SESSION_STATE_LOSS_PENDING)
+ ENUM_TO_STRING_CASE(XR_SESSION_STATE_EXITING)
+ ENUM_TO_STRING_CASE(XR_SESSION_STATE_MAX_ENUM)
+ default: {
+ return String("Session state ") + String::num_int64(int64_t(p_session_state));
+ } break;
+ }
+}
+
+String OpenXRUtil::make_xr_version_string(XrVersion p_version) {
+ String version;
+
+ version += String::num_int64(XR_VERSION_MAJOR(p_version));
+ version += String(".");
+ version += String::num_int64(XR_VERSION_MINOR(p_version));
+ version += String(".");
+ version += String::num_int64(XR_VERSION_PATCH(p_version));
+
+ return version;
+}
diff --git a/modules/openxr/openxr_util.h b/modules/openxr/openxr_util.h
new file mode 100644
index 0000000000..1261268376
--- /dev/null
+++ b/modules/openxr/openxr_util.h
@@ -0,0 +1,46 @@
+/*************************************************************************/
+/* openxr_util.h */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+
+#ifndef OPENXR_UTIL_H
+#define OPENXR_UTIL_H
+
+#include "core/string/ustring.h"
+#include
+
+class OpenXRUtil {
+public:
+ static String get_view_configuration_name(XrViewConfigurationType p_view_configuration);
+ static String get_reference_space_name(XrReferenceSpaceType p_reference_space);
+ static String get_structure_type_name(XrStructureType p_structure_type);
+ static String get_session_state_name(XrSessionState p_session_state);
+ static String make_xr_version_string(XrVersion p_version);
+};
+
+#endif // !OPENXR_UTIL_H
diff --git a/modules/openxr/register_types.cpp b/modules/openxr/register_types.cpp
new file mode 100644
index 0000000000..86ff368619
--- /dev/null
+++ b/modules/openxr/register_types.cpp
@@ -0,0 +1,91 @@
+/*************************************************************************/
+/* register_types.cpp */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+
+#include "register_types.h"
+#include "main/main.h"
+
+#include "openxr_interface.h"
+
+#include "action_map/openxr_action.h"
+#include "action_map/openxr_action_map.h"
+#include "action_map/openxr_action_set.h"
+#include "action_map/openxr_interaction_profile.h"
+
+OpenXRAPI *openxr_api = nullptr;
+Ref openxr_interface;
+
+void preregister_openxr_types() {
+ // For now we create our openxr device here. If we merge it with openxr_interface we'll create that here soon.
+
+ OpenXRAPI::setup_global_defs();
+ openxr_api = OpenXRAPI::get_singleton();
+ if (openxr_api) {
+ if (!openxr_api->initialise(Main::get_rendering_driver_name())) {
+ return;
+ }
+ }
+}
+
+void register_openxr_types() {
+ GDREGISTER_CLASS(OpenXRInterface);
+
+ GDREGISTER_CLASS(OpenXRAction);
+ GDREGISTER_CLASS(OpenXRActionSet);
+ GDREGISTER_CLASS(OpenXRActionMap);
+ GDREGISTER_CLASS(OpenXRIPBinding);
+ GDREGISTER_CLASS(OpenXRInteractionProfile);
+
+ XRServer *xr_server = XRServer::get_singleton();
+ if (xr_server) {
+ openxr_interface.instantiate();
+ xr_server->add_interface(openxr_interface);
+
+ if (openxr_interface->initialise_on_startup()) {
+ openxr_interface->initialize();
+ }
+ }
+}
+
+void unregister_openxr_types() {
+ if (openxr_interface.is_valid()) {
+ // unregister our interface from the XR server
+ if (XRServer::get_singleton()) {
+ XRServer::get_singleton()->remove_interface(openxr_interface);
+ }
+
+ // and release
+ openxr_interface.unref();
+ }
+
+ if (openxr_api) {
+ openxr_api->finish();
+ memdelete(openxr_api);
+ }
+}
diff --git a/modules/openxr/register_types.h b/modules/openxr/register_types.h
new file mode 100644
index 0000000000..fb42770750
--- /dev/null
+++ b/modules/openxr/register_types.h
@@ -0,0 +1,40 @@
+/*************************************************************************/
+/* register_types.h */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+
+#ifndef OPENXR_REGISTER_TYPES_H
+#define OPENXR_REGISTER_TYPES_H
+
+#define MODULE_OPENXR_HAS_PREREGISTER
+
+void preregister_openxr_types();
+void register_openxr_types();
+void unregister_openxr_types();
+
+#endif // OPENXR_REGISTER_TYPES_H
diff --git a/scene/3d/xr_nodes.cpp b/scene/3d/xr_nodes.cpp
index b18819c920..efae81e048 100644
--- a/scene/3d/xr_nodes.cpp
+++ b/scene/3d/xr_nodes.cpp
@@ -448,11 +448,6 @@ void XRController3D::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_tracker_hand"), &XRController3D::get_tracker_hand);
- ClassDB::bind_method(D_METHOD("get_rumble"), &XRController3D::get_rumble);
- ClassDB::bind_method(D_METHOD("set_rumble", "rumble"), &XRController3D::set_rumble);
- ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "rumble", PROPERTY_HINT_RANGE, "0.0,1.0,0.01"), "set_rumble", "get_rumble");
- ADD_PROPERTY_DEFAULT("rumble", 0.0);
-
ADD_SIGNAL(MethodInfo("button_pressed", PropertyInfo(Variant::STRING, "name")));
ADD_SIGNAL(MethodInfo("button_released", PropertyInfo(Variant::STRING, "name")));
ADD_SIGNAL(MethodInfo("input_value_changed", PropertyInfo(Variant::STRING, "name"), PropertyInfo(Variant::FLOAT, "value")));
@@ -558,20 +553,6 @@ Vector2 XRController3D::get_axis(const StringName &p_name) const {
}
}
-real_t XRController3D::get_rumble() const {
- if (!tracker.is_valid()) {
- return 0.0;
- }
-
- return tracker->get_rumble();
-}
-
-void XRController3D::set_rumble(real_t p_rumble) {
- if (tracker.is_valid()) {
- tracker->set_rumble(p_rumble);
- }
-}
-
XRPositionalTracker::TrackerHand XRController3D::get_tracker_hand() const {
// get our XRServer
if (!tracker.is_valid()) {
@@ -612,7 +593,7 @@ TypedArray XROrigin3D::get_configuration_warnings() const {
}
}
- bool xr_enabled = GLOBAL_GET("rendering/xr/enabled");
+ bool xr_enabled = GLOBAL_GET("xr/shaders/enabled");
if (!xr_enabled) {
warnings.push_back(TTR("XR is not enabled in rendering project settings. Stereoscopic output is not supported unless this is enabled."));
}
diff --git a/scene/3d/xr_nodes.h b/scene/3d/xr_nodes.h
index 5675cbd944..3079e20dc7 100644
--- a/scene/3d/xr_nodes.h
+++ b/scene/3d/xr_nodes.h
@@ -139,9 +139,6 @@ public:
float get_value(const StringName &p_name) const;
Vector2 get_axis(const StringName &p_name) const;
- real_t get_rumble() const;
- void set_rumble(real_t p_rumble);
-
XRPositionalTracker::TrackerHand get_tracker_hand() const;
XRController3D() {}
diff --git a/servers/rendering/renderer_compositor.cpp b/servers/rendering/renderer_compositor.cpp
index 82e8bd6ef9..fa4d9c8b31 100644
--- a/servers/rendering/renderer_compositor.cpp
+++ b/servers/rendering/renderer_compositor.cpp
@@ -45,7 +45,7 @@ bool RendererCompositor::is_xr_enabled() const {
}
RendererCompositor::RendererCompositor() {
- xr_enabled = GLOBAL_GET("rendering/xr/enabled");
+ xr_enabled = GLOBAL_GET("xr/shaders/enabled");
}
RendererCanvasRender *RendererCanvasRender::singleton = nullptr;
diff --git a/servers/rendering/renderer_rd/effects_rd.cpp b/servers/rendering/renderer_rd/effects_rd.cpp
index f16a4b1d19..7883a2d816 100644
--- a/servers/rendering/renderer_rd/effects_rd.cpp
+++ b/servers/rendering/renderer_rd/effects_rd.cpp
@@ -332,7 +332,7 @@ void EffectsRD::copy_to_atlas_fb(RID p_source_rd_texture, RID p_dest_framebuffer
RD::get_singleton()->draw_list_draw(draw_list, true);
}
-void EffectsRD::copy_to_fb_rect(RID p_source_rd_texture, RID p_dest_framebuffer, const Rect2i &p_rect, bool p_flip_y, bool p_force_luminance, bool p_alpha_to_zero, bool p_srgb, RID p_secondary) {
+void EffectsRD::copy_to_fb_rect(RID p_source_rd_texture, RID p_dest_framebuffer, const Rect2i &p_rect, bool p_flip_y, bool p_force_luminance, bool p_alpha_to_zero, bool p_srgb, RID p_secondary, bool p_multiview) {
memset(©_to_fb.push_constant, 0, sizeof(CopyToFbPushConstant));
if (p_flip_y) {
@@ -348,10 +348,18 @@ void EffectsRD::copy_to_fb_rect(RID p_source_rd_texture, RID p_dest_framebuffer,
copy_to_fb.push_constant.srgb = true;
}
+ CopyToFBMode mode;
+ if (p_multiview) {
+ mode = p_secondary.is_valid() ? COPY_TO_FB_MULTIVIEW_WITH_DEPTH : COPY_TO_FB_MULTIVIEW;
+ } else {
+ mode = p_secondary.is_valid() ? COPY_TO_FB_COPY2 : COPY_TO_FB_COPY;
+ }
+
RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(p_dest_framebuffer, RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_DISCARD, Vector(), 1.0, 0, p_rect);
- RD::get_singleton()->draw_list_bind_render_pipeline(draw_list, copy_to_fb.pipelines[p_secondary.is_valid() ? COPY_TO_FB_COPY2 : COPY_TO_FB_COPY].get_render_pipeline(RD::INVALID_ID, RD::get_singleton()->framebuffer_get_format(p_dest_framebuffer)));
+ RD::get_singleton()->draw_list_bind_render_pipeline(draw_list, copy_to_fb.pipelines[mode].get_render_pipeline(RD::INVALID_ID, RD::get_singleton()->framebuffer_get_format(p_dest_framebuffer)));
RD::get_singleton()->draw_list_bind_uniform_set(draw_list, _get_uniform_set_from_texture(p_source_rd_texture), 0);
if (p_secondary.is_valid()) {
+ // TODO may need to do this differently when reading from depth buffer for multiview
RD::get_singleton()->draw_list_bind_uniform_set(draw_list, _get_uniform_set_from_texture(p_secondary), 1);
}
RD::get_singleton()->draw_list_bind_index_array(draw_list, index_array);
@@ -2367,15 +2375,26 @@ EffectsRD::EffectsRD(bool p_prefer_raster_effects) {
copy_modes.push_back("\n");
copy_modes.push_back("\n#define MODE_PANORAMA_TO_DP\n");
copy_modes.push_back("\n#define MODE_TWO_SOURCES\n");
+ copy_modes.push_back("\n#define MULTIVIEW\n");
+ copy_modes.push_back("\n#define MULTIVIEW\n#define MODE_TWO_SOURCES\n");
copy_to_fb.shader.initialize(copy_modes);
+ if (!RendererCompositorRD::singleton->is_xr_enabled()) {
+ copy_to_fb.shader.set_variant_enabled(COPY_TO_FB_MULTIVIEW, false);
+ copy_to_fb.shader.set_variant_enabled(COPY_TO_FB_MULTIVIEW_WITH_DEPTH, false);
+ }
+
copy_to_fb.shader_version = copy_to_fb.shader.version_create();
//use additive
for (int i = 0; i < COPY_TO_FB_MAX; i++) {
- copy_to_fb.pipelines[i].setup(copy_to_fb.shader.version_get_shader(copy_to_fb.shader_version, i), RD::RENDER_PRIMITIVE_TRIANGLES, RD::PipelineRasterizationState(), RD::PipelineMultisampleState(), RD::PipelineDepthStencilState(), RD::PipelineColorBlendState::create_disabled(), 0);
+ if (copy_to_fb.shader.is_variant_enabled(i)) {
+ copy_to_fb.pipelines[i].setup(copy_to_fb.shader.version_get_shader(copy_to_fb.shader_version, i), RD::RENDER_PRIMITIVE_TRIANGLES, RD::PipelineRasterizationState(), RD::PipelineMultisampleState(), RD::PipelineDepthStencilState(), RD::PipelineColorBlendState::create_disabled(), 0);
+ } else {
+ copy_to_fb.pipelines[i].clear();
+ }
}
}
diff --git a/servers/rendering/renderer_rd/effects_rd.h b/servers/rendering/renderer_rd/effects_rd.h
index f5e5b1ace7..eca5e09800 100644
--- a/servers/rendering/renderer_rd/effects_rd.h
+++ b/servers/rendering/renderer_rd/effects_rd.h
@@ -203,6 +203,9 @@ private:
COPY_TO_FB_COPY,
COPY_TO_FB_COPY_PANORAMA_TO_DP,
COPY_TO_FB_COPY2,
+
+ COPY_TO_FB_MULTIVIEW,
+ COPY_TO_FB_MULTIVIEW_WITH_DEPTH,
COPY_TO_FB_MAX,
};
@@ -893,7 +896,7 @@ public:
bool get_prefer_raster_effects();
void fsr_upscale(RID p_source_rd_texture, RID p_secondary_texture, RID p_destination_texture, const Size2i &p_internal_size, const Size2i &p_size, float p_fsr_upscale_sharpness);
- void copy_to_fb_rect(RID p_source_rd_texture, RID p_dest_framebuffer, const Rect2i &p_rect, bool p_flip_y = false, bool p_force_luminance = false, bool p_alpha_to_zero = false, bool p_srgb = false, RID p_secondary = RID());
+ void copy_to_fb_rect(RID p_source_rd_texture, RID p_dest_framebuffer, const Rect2i &p_rect, bool p_flip_y = false, bool p_force_luminance = false, bool p_alpha_to_zero = false, bool p_srgb = false, RID p_secondary = RID(), bool p_multiview = false);
void copy_to_rect(RID p_source_rd_texture, RID p_dest_texture, const Rect2i &p_rect, bool p_flip_y = false, bool p_force_luminance = false, bool p_all_source = false, bool p_8_bit_dst = false, bool p_alpha_to_one = false);
void copy_cubemap_to_panorama(RID p_source_cube, RID p_dest_panorama, const Size2i &p_panorama_size, float p_lod, bool p_is_array);
void copy_depth_to_rect(RID p_source_rd_texture, RID p_dest_framebuffer, const Rect2i &p_rect, bool p_flip_y = false);
diff --git a/servers/rendering/renderer_rd/shaders/copy_to_fb.glsl b/servers/rendering/renderer_rd/shaders/copy_to_fb.glsl
index 2f1f9c4765..9787c9879d 100644
--- a/servers/rendering/renderer_rd/shaders/copy_to_fb.glsl
+++ b/servers/rendering/renderer_rd/shaders/copy_to_fb.glsl
@@ -4,7 +4,20 @@
#VERSION_DEFINES
+#ifdef MULTIVIEW
+#ifdef has_VK_KHR_multiview
+#extension GL_EXT_multiview : enable
+#define ViewIndex gl_ViewIndex
+#else // has_VK_KHR_multiview
+#define ViewIndex 0
+#endif // has_VK_KHR_multiview
+#endif //MULTIVIEW
+
+#ifdef MULTIVIEW
+layout(location = 0) out vec3 uv_interp;
+#else
layout(location = 0) out vec2 uv_interp;
+#endif
layout(push_constant, std430) uniform Params {
vec4 section;
@@ -19,9 +32,11 @@ params;
void main() {
vec2 base_arr[4] = vec2[](vec2(0.0, 0.0), vec2(0.0, 1.0), vec2(1.0, 1.0), vec2(1.0, 0.0));
- uv_interp = base_arr[gl_VertexIndex];
-
- vec2 vpos = uv_interp;
+ uv_interp.xy = base_arr[gl_VertexIndex];
+#ifdef MULTIVIEW
+ uv_interp.z = ViewIndex;
+#endif
+ vec2 vpos = uv_interp.xy;
if (params.use_section) {
vpos = params.section.xy + vpos * params.section.zw;
}
@@ -39,6 +54,15 @@ void main() {
#VERSION_DEFINES
+#ifdef MULTIVIEW
+#ifdef has_VK_KHR_multiview
+#extension GL_EXT_multiview : enable
+#define ViewIndex gl_ViewIndex
+#else // has_VK_KHR_multiview
+#define ViewIndex 0
+#endif // has_VK_KHR_multiview
+#endif //MULTIVIEW
+
layout(push_constant, std430) uniform Params {
vec4 section;
vec2 pixel_size;
@@ -52,12 +76,25 @@ layout(push_constant, std430) uniform Params {
}
params;
+#ifdef MULTIVIEW
+layout(location = 0) in vec3 uv_interp;
+#else
layout(location = 0) in vec2 uv_interp;
+#endif
+#ifdef MULTIVIEW
+layout(set = 0, binding = 0) uniform sampler2DArray source_color;
+#ifdef MODE_TWO_SOURCES
+layout(set = 1, binding = 0) uniform sampler2DArray source_depth;
+layout(location = 1) out float depth;
+#endif /* MODE_TWO_SOURCES */
+#else
layout(set = 0, binding = 0) uniform sampler2D source_color;
#ifdef MODE_TWO_SOURCES
layout(set = 1, binding = 0) uniform sampler2D source_color2;
-#endif
+#endif /* MODE_TWO_SOURCES */
+#endif /* MULTIVIEW */
+
layout(location = 0) out vec4 frag_color;
vec3 linear_to_srgb(vec3 color) {
@@ -68,9 +105,14 @@ vec3 linear_to_srgb(vec3 color) {
}
void main() {
+#ifdef MULTIVIEW
+ vec3 uv = uv_interp;
+#else
vec2 uv = uv_interp;
+#endif
#ifdef MODE_PANORAMA_TO_DP
+ // Note, multiview and panorama should not be mixed at this time
//obtain normal from dual paraboloid uv
#define M_PI 3.14159265359
@@ -98,10 +140,20 @@ void main() {
uv = 1.0 - uv;
}
#endif
+
+#ifdef MULTIVIEW
+ vec4 color = textureLod(source_color, uv, 0.0);
+#ifdef MODE_TWO_SOURCES
+ // In multiview our 2nd input will be our depth map
+ depth = textureLod(source_depth, uv, 0.0).r;
+#endif /* MODE_TWO_SOURCES */
+
+#else
vec4 color = textureLod(source_color, uv, 0.0);
#ifdef MODE_TWO_SOURCES
color += textureLod(source_color2, uv, 0.0);
-#endif
+#endif /* MODE_TWO_SOURCES */
+#endif /* MULTIVIEW */
if (params.force_luminance) {
color.rgb = vec3(max(max(color.r, color.g), color.b));
}
diff --git a/servers/rendering/renderer_viewport.cpp b/servers/rendering/renderer_viewport.cpp
index 5a84bace2d..69c017a1c8 100644
--- a/servers/rendering/renderer_viewport.cpp
+++ b/servers/rendering/renderer_viewport.cpp
@@ -548,7 +548,6 @@ void RendererViewport::draw_viewports() {
// get our xr interface in case we need it
Ref xr_interface;
-
XRServer *xr_server = XRServer::get_singleton();
if (xr_server != nullptr) {
// let our XR server know we're about to render our frames so we can get our frame timing
diff --git a/servers/rendering/rendering_device.h b/servers/rendering/rendering_device.h
index 655a32a805..49d89bcadc 100644
--- a/servers/rendering/rendering_device.h
+++ b/servers/rendering/rendering_device.h
@@ -500,6 +500,7 @@ public:
virtual RID texture_create(const TextureFormat &p_format, const TextureView &p_view, const Vector> &p_data = Vector>()) = 0;
virtual RID texture_create_shared(const TextureView &p_view, RID p_with_texture) = 0;
+ virtual RID texture_create_from_extension(TextureType p_type, DataFormat p_format, TextureSamples p_samples, uint64_t p_flags, uint64_t p_image, uint64_t p_width, uint64_t p_height, uint64_t p_depth, uint64_t p_layers) = 0;
enum TextureSliceType {
TEXTURE_SLICE_2D,
diff --git a/servers/rendering_server.cpp b/servers/rendering_server.cpp
index cbe90de2f8..c9ac42863a 100644
--- a/servers/rendering_server.cpp
+++ b/servers/rendering_server.cpp
@@ -2999,7 +2999,7 @@ RenderingServer::RenderingServer() {
GLOBAL_DEF("rendering/limits/cluster_builder/max_clustered_elements", 512);
ProjectSettings::get_singleton()->set_custom_property_info("rendering/limits/cluster_builder/max_clustered_elements", PropertyInfo(Variant::FLOAT, "rendering/limits/cluster_builder/max_clustered_elements", PROPERTY_HINT_RANGE, "32,8192,1"));
- GLOBAL_DEF_RST("rendering/xr/enabled", false);
+ GLOBAL_DEF_RST_BASIC("xr/shaders/enabled", false);
GLOBAL_DEF_RST("rendering/2d/options/use_software_skinning", true);
GLOBAL_DEF_RST("rendering/2d/options/ninepatch_mode", 1);
diff --git a/servers/xr/xr_positional_tracker.cpp b/servers/xr/xr_positional_tracker.cpp
index 7b21eeba04..671eb7a111 100644
--- a/servers/xr/xr_positional_tracker.cpp
+++ b/servers/xr/xr_positional_tracker.cpp
@@ -65,10 +65,6 @@ void XRPositionalTracker::_bind_methods() {
ADD_SIGNAL(MethodInfo("button_released", PropertyInfo(Variant::STRING, "name")));
ADD_SIGNAL(MethodInfo("input_value_changed", PropertyInfo(Variant::STRING, "name"), PropertyInfo(Variant::FLOAT, "value")));
ADD_SIGNAL(MethodInfo("input_axis_changed", PropertyInfo(Variant::STRING, "name"), PropertyInfo(Variant::VECTOR2, "vector")));
-
- ClassDB::bind_method(D_METHOD("get_rumble"), &XRPositionalTracker::get_rumble);
- ClassDB::bind_method(D_METHOD("set_rumble", "rumble"), &XRPositionalTracker::set_rumble);
- ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "rumble"), "set_rumble", "get_rumble");
};
void XRPositionalTracker::set_tracker_type(XRServer::TrackerType p_type) {
@@ -206,21 +202,8 @@ void XRPositionalTracker::set_input(const StringName &p_action_name, const Varia
}
}
-real_t XRPositionalTracker::get_rumble() const {
- return rumble;
-};
-
-void XRPositionalTracker::set_rumble(real_t p_rumble) {
- if (p_rumble > 0.0) {
- rumble = p_rumble;
- } else {
- rumble = 0.0;
- };
-};
-
XRPositionalTracker::XRPositionalTracker() {
type = XRServer::TRACKER_UNKNOWN;
name = "Unknown";
hand = TRACKER_HAND_UNKNOWN;
- rumble = 0.0;
};
diff --git a/servers/xr/xr_positional_tracker.h b/servers/xr/xr_positional_tracker.h
index 2f358cbb21..ccb30bbbe6 100644
--- a/servers/xr/xr_positional_tracker.h
+++ b/servers/xr/xr_positional_tracker.h
@@ -62,10 +62,6 @@ private:
Map> poses;
Map inputs;
- int joy_id; // if we also have a related joystick entity, the id of the joystick
- Ref mesh; // when available, a mesh that can be used to render this tracker
- real_t rumble; // rumble strength, 0.0 is off, 1.0 is maximum, note that we only record here, xr_interface is responsible for execution
-
protected:
static void _bind_methods();
@@ -87,10 +83,6 @@ public:
Variant get_input(const StringName &p_action_name) const;
void set_input(const StringName &p_action_name, const Variant &p_value);
- // TODO replace by new implementation
- real_t get_rumble() const;
- void set_rumble(real_t p_rumble);
-
XRPositionalTracker();
~XRPositionalTracker() {}
};
diff --git a/servers/xr_server.cpp b/servers/xr_server.cpp
index dbfe76a127..e32b41c7ae 100644
--- a/servers/xr_server.cpp
+++ b/servers/xr_server.cpp
@@ -348,9 +348,10 @@ PackedStringArray XRServer::get_suggested_pose_names(const StringName &p_tracker
}
void XRServer::_process() {
- /* called from renderer_viewport.draw_viewports right before we start drawing our viewports */
+ // called from our main game loop before we handle physics and game logic
+ // note that we can have multiple interfaces active if we have interfaces that purely handle tracking
- /* process all active interfaces */
+ // process all active interfaces
for (int i = 0; i < interfaces.size(); i++) {
if (!interfaces[i].is_valid()) {
// ignore, not a valid reference
diff --git a/thirdparty/README.md b/thirdparty/README.md
index 7d2586b4dc..f204367b8b 100644
--- a/thirdparty/README.md
+++ b/thirdparty/README.md
@@ -474,6 +474,7 @@ Files extracted from the upstream source:
- Files in `core/` folder.
- `LICENSE.txt` and `CHANGELOG.md`
+
## oidn
- Upstream: https://github.com/OpenImageDenoise/oidn
@@ -505,6 +506,30 @@ Patch files are provided in `oidn/patches/`.
- scripts/resource_to_cpp.py (used in modules/denoise/resource_to_cpp.py)
+## openxr
+
+- Upstream: https://github.com/KhronosGroup/OpenXR-SDK
+- Version: 1.0.22 (458984d7f59d1ae6dc1b597d94b02e4f7132eaba, 2022)
+- License: Apache 2.0
+
+Files extracted from upstream source:
+
+- include/
+- src/common/
+- src/loader/
+- src/*.{c,h}
+- src/external/jsoncpp/include/
+- src/external/jsoncpp/src/lib_json/
+- LICENSE and COPYING.adoc
+
+Exclude:
+
+- src/external/android-jni-wrappers and src/external/jnipp (not used yet)
+- All CMake stuff: cmake/, CMakeLists.txt and *.cmake
+- All Gradle stuff: *gradle*, AndroidManifest.xml
+- All following files (and their .license files): *.{def,in,json,map,pom,rc}
+
+
## pcre2
- Upstream: http://www.pcre.org
diff --git a/thirdparty/openxr/COPYING.adoc b/thirdparty/openxr/COPYING.adoc
new file mode 100644
index 0000000000..3a31362acb
--- /dev/null
+++ b/thirdparty/openxr/COPYING.adoc
@@ -0,0 +1,123 @@
+= COPYING.adoc for the Khronos Group OpenXR projects
+
+// Copyright (c) 2020-2022, The Khronos Group Inc.
+//
+// SPDX-License-Identifier: CC-BY-4.0
+
+This document is shared across a number of OpenXR GitHub projects, as the
+set of files in those projects is partially overlapping.
+(There is a single "source of truth" internal Khronos GitLab repo these
+GitHub repositories interact with.)
+
+== Licenses
+
+The OpenXR GitHub projects use several licenses.
+In general, we work to maintain compliance with the
+https://reuse.software/spec/[REUSE 3.0 specification] with clear copyright
+holders and license identifier listed for each file, preferably in each
+file.
+Where this is not possible, or e.g. when we are using files unmodified from
+other open-source projects, license data is listed:
+
+* in an adjacent file of the same name, with the additional extension
+ "`.license`"
+* in the repository-wide "`.reuse/dep5`" copyright description
+ https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/["DEP5"
+ machine-readable copyright data] file.
+
+The https://github.com/fsfe/reuse-tool["`reuse`" command line tool] can be
+used to create a software bill of materials in SPDX format from this data.
+Note that this tool will typically exclude the generated files, so if the
+BOM is important to you, you may consider using the
+https://github.com/KhronosGroup/OpenXR-SDK[OpenXR-SDK] repository that
+contains the API headers and the loader source with all generated files
+pre-generated.
+
+The data in/adjacent to each file is the authoritative license and copyright
+data.
+However, for ease of understanding, the following general practices can be
+observed.
+(If in doubt, or if the following summary conflicts with the per-file data,
+the per-file data remains authoritative.)
+
+* The source files (in asciidoctor and other formats) for the OpenXR
+ Specification, reference pages, and supporting documentation are licensed
+ under the Creative Commons Attribution 4.0 International License (SPDX
+ license identifier "`CC-BY-4.0`").
+* Header files, scripts, programs, XML files, and other tooling used or
+ generated as part of the build process is licensed under the Apache
+ License, Version 2.0.
+* For compatibility with external developers working in GPLed projects who
+ have requested it, the main OpenXR headers, XML registry, and loader
+ source are licensed under a dual license with the SPDX license identifier
+ "`Apache-2.0 OR MIT`" .
+ Relevant files include:
+** "`specification/registry/xr.xml`"
+** "`include/openxr/openxr_platform_defines.h`"
+** The generated OpenXR headers "`openxr.h`", "`openxr_platform.h`", and
+ "`openxr_reflection.h`".
+** Source files in "`src/loader/`", and a few files in "`src/common/`".
+** Generated source files used by the loader (including pre-generated in
+ OpenXR-SDK): "`common_config.h`", "`xr_generated_loader.cpp`", and
+ "`xr_generated_loader.hpp`".
+* There are a few files adopted from other open source projects.
+ Such files continue under their original licenses, and appropriately
+ annotated in accordance with REUSE.
+* Some generated, transient files produced during the course of building the
+ specification, headers, or other targets may not have copyrights.
+ These are typically very short asciidoc fragments describing parts of the
+ OpenXR API, and are incorporated by reference into specification or
+ reference page builds.
+
+Users outside Khronos who create and post OpenXR Specifications, whether
+modified or not, should use the CC-BY-4.0 license on the output documents
+(HTML, PDF, etc.) they generate.
+
+
+== Frequently Asked Questions
+
+Q: Why are the HTML and PDF Specifications posted on Khronos' website under
+a license which is neither CC-BY-4.0 nor Apache 2.0?
+
+A: The Specifications posted by Khronos in the OpenXR Registry are licensed
+under the proprietary Khronos Specification License.
+Only these Specifications are Ratified by the Khronos Board of Promoters,
+and therefore they are the only Specifications covered by the Khronos
+Intellectual Property Rights Policy.
+
+
+Q: Does Khronos allow the creation and distribution of modified versions of
+the OpenXR Specification, such as translations to other languages?
+
+A: Yes.
+Such modified Specifications, since they are not created by Khronos, should
+be placed under the CC-BY-4.0 license.
+If you believe your modifications are of general interest, consider
+contributing them back by making a pull request (PR) on the OpenXR-Docs
+project.
+
+
+Q: Can I contribute changes to the OpenXR Specification?
+
+A: Yes, by opening an Issue or Pull Request (PR) on the
+link:https://github.com/KhronosGroup/OpenXR-Docs/[OpenXR-Docs] GitHub
+project.
+You must execute a click-through Contributor License Agreement, which brings
+your changes under the umbrella of the Khronos IP policy.
+
+
+Q: Can you change the license on your files so they're compatible with my
+license?
+
+A: We are using a dual license license on `xr.xml`, the main API headers,
+and the loader source files, to make them compatible with GPL-2.0- and
+LGPL-2.0/2.1-licensed projects.
+This replaces earlier approaches of an MIT-like license on the XML and
+Apache 2.0 on all headers, and allows use of the SPDX license identifier
+"`Apache-2.0 OR MIT`" to denote the license.
+
+If you *require* this same compatibility for use of other Apache-2.0
+licensed files in our repository, please raise an issue identifying the
+files and we will consider changing those specific files to the dual license
+as well.
+
diff --git a/thirdparty/openxr/LICENSE b/thirdparty/openxr/LICENSE
new file mode 100644
index 0000000000..d645695673
--- /dev/null
+++ b/thirdparty/openxr/LICENSE
@@ -0,0 +1,202 @@
+
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+ APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+ Copyright [yyyy] [name of copyright owner]
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
diff --git a/thirdparty/openxr/include/openxr/openxr.h b/thirdparty/openxr/include/openxr/openxr.h
new file mode 100644
index 0000000000..8798e5a6e0
--- /dev/null
+++ b/thirdparty/openxr/include/openxr/openxr.h
@@ -0,0 +1,3925 @@
+#ifndef OPENXR_H_
+#define OPENXR_H_ 1
+
+/*
+** Copyright (c) 2017-2022, 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, 22)
+
+#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)
+
+#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)
+
+
+#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_MIN_COMPOSITION_LAYERS_SUPPORTED 16
+#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_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_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_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_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_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_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_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_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_SPATIAL_ANCHOR_PERSISTENCE_INFO_MSFT = 1000142000,
+ XR_TYPE_SPATIAL_ANCHOR_FROM_PERSISTED_ANCHOR_CREATE_INFO_MSFT = 1000142001,
+ 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_COMPOSITION_LAYER_SPACE_WARP_INFO_FB = 1000171000,
+ XR_TYPE_SYSTEM_SPACE_WARP_PROPERTIES_FB = 1000171001,
+ XR_TYPE_DIGITAL_LENS_CONTROL_ALMALENCE = 1000196000,
+ XR_TYPE_PASSTHROUGH_KEYBOARD_HANDS_INTENSITY_FB = 1000203002,
+ 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_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_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_HAND_TRACKER_EXT = 1000051000,
+ 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_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 5
+#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 3
+#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 1
+#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
+#define XR_MSFT_spatial_graph_bridge_SPEC_VERSION 1
+#define XR_MSFT_SPATIAL_GRAPH_BRIDGE_EXTENSION_NAME "XR_MSFT_spatial_graph_bridge"
+
+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[16];
+ XrPosef pose;
+} XrSpatialGraphNodeSpaceCreateInfoMSFT;
+
+typedef XrResult (XRAPI_PTR *PFN_xrCreateSpatialGraphNodeSpaceMSFT)(XrSession session, const XrSpatialGraphNodeSpaceCreateInfoMSFT* createInfo, XrSpace* space);
+
+#ifndef XR_NO_PROTOTYPES
+#ifdef XR_EXTENSION_PROTOTYPES
+XRAPI_ATTR XrResult XRAPI_CALL xrCreateSpatialGraphNodeSpaceMSFT(
+ XrSession session,
+ const XrSpatialGraphNodeSpaceCreateInfoMSFT* createInfo,
+ XrSpace* space);
+#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_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_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 1
+#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 1
+#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 1
+#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 1
+#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 1
+#define XR_HTC_VIVE_FOCUS3_CONTROLLER_INTERACTION_EXTENSION_NAME "XR_HTC_vive_focus3_controller_interaction"
+
+
+#define XR_FB_color_space 1
+#define XR_FB_color_space_SPEC_VERSION 2
+#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 1
+#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 XrHandJointsLocateInfoEXT
+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 1
+#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 XrHandJointsLocateInfoEXT
+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_FB_HAND_TRACKING_CAPSULE_POINT_COUNT XR_HAND_TRACKING_CAPSULE_POINT_COUNT_FB
+#define XR_HAND_TRACKING_CAPSULE_COUNT_FB 19
+#define XR_FB_HAND_TRACKING_CAPSULE_COUNT XR_HAND_TRACKING_CAPSULE_COUNT_FB
+#define XR_FB_hand_tracking_capsules_SPEC_VERSION 2
+#define XR_FB_HAND_TRACKING_CAPSULES_EXTENSION_NAME "XR_FB_hand_tracking_capsules"
+typedef struct XrHandCapsuleFB {
+ XrVector3f points[XR_FB_HAND_TRACKING_CAPSULE_POINT_COUNT];
+ float radius;
+ XrHandJointEXT joint;
+} XrHandCapsuleFB;
+
+// XrHandTrackingCapsulesStateFB extends XrHandJointsLocateInfoEXT
+typedef struct XrHandTrackingCapsulesStateFB {
+ XrStructureType type;
+ void* XR_MAY_ALIAS next;
+ XrHandCapsuleFB capsules[XR_FB_HAND_TRACKING_CAPSULE_COUNT];
+} XrHandTrackingCapsulesStateFB;
+
+
+
+#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 1
+#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 1
+#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_MAX_ENUM_FB = 0x7FFFFFFF
+} XrPassthroughLayerPurposeFB;
+typedef XrFlags64 XrPassthroughFlagsFB;
+
+// Flag bits for XrPassthroughFlagsFB
+static const XrPassthroughFlagsFB XR_PASSTHROUGH_IS_RUNNING_AT_CREATION_BIT_FB = 0x00000001;
+
+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;
+
+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;
+
+typedef struct XrPassthroughColorMapMonoToRgbaFB {
+ XrStructureType type;
+ const void* XR_MAY_ALIAS next;
+ XrColor4f textureColorMap[XR_PASSTHROUGH_COLOR_MAP_MONO_SIZE_FB];
+} XrPassthroughColorMapMonoToRgbaFB;
+
+typedef struct XrPassthroughColorMapMonoToMonoFB {
+ XrStructureType type;
+ const void* XR_MAY_ALIAS next;
+ uint8_t textureColorMap[XR_PASSTHROUGH_COLOR_MAP_MONO_SIZE_FB];
+} XrPassthroughColorMapMonoToMonoFB;
+
+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 1
+#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
+
+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;
+
+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 2
+#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_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_FB_space_warp 1
+#define XR_FB_space_warp_SPEC_VERSION 1
+#define XR_FB_SPACE_WARP_EXTENSION_NAME "XR_FB_space_warp"
+typedef XrFlags64 XrCompositionLayerSpaceWarpInfoFlagsFB;
+
+// Flag bits for XrCompositionLayerSpaceWarpInfoFlagsFB
+
+// 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_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_passthrough_keyboard_hands 1
+#define XR_FB_passthrough_keyboard_hands_SPEC_VERSION 1
+#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_EXT_uuid 1
+#define XR_EXT_uuid_SPEC_VERSION 1
+#define XR_EXT_UUID_EXTENSION_NAME "XR_EXT_uuid"
+#define XR_UUID_SIZE_EXT 16
+typedef struct XrUuidEXT {
+ uint8_t data[XR_UUID_SIZE_EXT];
+} XrUuidEXT;
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/thirdparty/openxr/include/openxr/openxr_platform.h b/thirdparty/openxr/include/openxr/openxr_platform.h
new file mode 100644
index 0000000000..eb5e5f8c4b
--- /dev/null
+++ b/thirdparty/openxr/include/openxr/openxr_platform.h
@@ -0,0 +1,675 @@
+#ifndef OPENXR_PLATFORM_H_
+#define OPENXR_PLATFORM_H_ 1
+
+/*
+** Copyright (c) 2017-2022, 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 8
+#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 8
+#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_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 __cplusplus
+}
+#endif
+
+#endif
diff --git a/thirdparty/openxr/include/openxr/openxr_platform_defines.h b/thirdparty/openxr/include/openxr/openxr_platform_defines.h
new file mode 100644
index 0000000000..31fa05a0c8
--- /dev/null
+++ b/thirdparty/openxr/include/openxr/openxr_platform_defines.h
@@ -0,0 +1,110 @@
+/*
+** Copyright (c) 2017-2022, 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
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/thirdparty/openxr/include/openxr/openxr_reflection.h b/thirdparty/openxr/include/openxr/openxr_reflection.h
new file mode 100644
index 0000000000..2bc14be600
--- /dev/null
+++ b/thirdparty/openxr/include/openxr/openxr_reflection.h
@@ -0,0 +1,2746 @@
+#ifndef OPENXR_REFLECTION_H_
+#define OPENXR_REFLECTION_H_ 1
+
+/*
+** Copyright (c) 2017-2022, 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"
+
+/*
+This file contains expansion macros (X Macros) for OpenXR enumerations and structures.
+Example of how to use expansion macros to make an enum-to-string function:
+
+#define XR_ENUM_CASE_STR(name, val) case name: return #name;
+#define XR_ENUM_STR(enumType) \
+ constexpr const char* XrEnumStr(enumType e) { \
+ switch (e) { \
+ XR_LIST_ENUM_##enumType(XR_ENUM_CASE_STR) \
+ default: return "Unknown"; \
+ } \
+ } \
+
+XR_ENUM_STR(XrResult);
+*/
+
+#define XR_LIST_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_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_RESULT_MAX_ENUM, 0x7FFFFFFF)
+
+#define XR_LIST_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_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_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_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_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_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_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_SPATIAL_ANCHOR_PERSISTENCE_INFO_MSFT, 1000142000) \
+ _(XR_TYPE_SPATIAL_ANCHOR_FROM_PERSISTED_ANCHOR_CREATE_INFO_MSFT, 1000142001) \
+ _(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_COMPOSITION_LAYER_SPACE_WARP_INFO_FB, 1000171000) \
+ _(XR_TYPE_SYSTEM_SPACE_WARP_PROPERTIES_FB, 1000171001) \
+ _(XR_TYPE_DIGITAL_LENS_CONTROL_ALMALENCE, 1000196000) \
+ _(XR_TYPE_PASSTHROUGH_KEYBOARD_HANDS_INTENSITY_FB, 1000203002) \
+ _(XR_STRUCTURE_TYPE_MAX_ENUM, 0x7FFFFFFF)
+
+#define XR_LIST_ENUM_XrFormFactor(_) \
+ _(XR_FORM_FACTOR_HEAD_MOUNTED_DISPLAY, 1) \
+ _(XR_FORM_FACTOR_HANDHELD_DISPLAY, 2) \
+ _(XR_FORM_FACTOR_MAX_ENUM, 0x7FFFFFFF)
+
+#define XR_LIST_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)
+
+#define XR_LIST_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)
+
+#define XR_LIST_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_MAX_ENUM, 0x7FFFFFFF)
+
+#define XR_LIST_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)
+
+#define XR_LIST_ENUM_XrEyeVisibility(_) \
+ _(XR_EYE_VISIBILITY_BOTH, 0) \
+ _(XR_EYE_VISIBILITY_LEFT, 1) \
+ _(XR_EYE_VISIBILITY_RIGHT, 2) \
+ _(XR_EYE_VISIBILITY_MAX_ENUM, 0x7FFFFFFF)
+
+#define XR_LIST_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)
+
+#define XR_LIST_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_HAND_TRACKER_EXT, 1000051000) \
+ _(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_MAX_ENUM, 0x7FFFFFFF)
+
+#define XR_LIST_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)
+
+#define XR_LIST_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)
+
+#define XR_LIST_ENUM_XrPerfSettingsDomainEXT(_) \
+ _(XR_PERF_SETTINGS_DOMAIN_CPU_EXT, 1) \
+ _(XR_PERF_SETTINGS_DOMAIN_GPU_EXT, 2) \
+ _(XR_PERF_SETTINGS_DOMAIN_MAX_ENUM_EXT, 0x7FFFFFFF)
+
+#define XR_LIST_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)
+
+#define XR_LIST_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)
+
+#define XR_LIST_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)
+
+#define XR_LIST_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)
+
+#define XR_LIST_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)
+
+#define XR_LIST_ENUM_XrHandEXT(_) \
+ _(XR_HAND_LEFT_EXT, 1) \
+ _(XR_HAND_RIGHT_EXT, 2) \
+ _(XR_HAND_MAX_ENUM_EXT, 0x7FFFFFFF)
+
+#define XR_LIST_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)
+
+#define XR_LIST_ENUM_XrHandJointSetEXT(_) \
+ _(XR_HAND_JOINT_SET_DEFAULT_EXT, 0) \
+ _(XR_HAND_JOINT_SET_MAX_ENUM_EXT, 0x7FFFFFFF)
+
+#define XR_LIST_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)
+
+#define XR_LIST_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)
+
+#define XR_LIST_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)
+
+#define XR_LIST_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)
+
+#define XR_LIST_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)
+
+#define XR_LIST_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)
+
+#define XR_LIST_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)
+
+#define XR_LIST_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)
+
+#define XR_LIST_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)
+
+#define XR_LIST_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)
+
+#define XR_LIST_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)
+
+#define XR_LIST_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)
+
+#define XR_LIST_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)
+
+#define XR_LIST_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)
+
+#define XR_LIST_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)
+
+#define XR_LIST_ENUM_XrFoveationDynamicFB(_) \
+ _(XR_FOVEATION_DYNAMIC_DISABLED_FB, 0) \
+ _(XR_FOVEATION_DYNAMIC_LEVEL_ENABLED_FB, 1) \
+ _(XR_FOVEATION_DYNAMIC_MAX_ENUM_FB, 0x7FFFFFFF)
+
+#define XR_LIST_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)
+
+#define XR_LIST_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_MAX_ENUM_FB, 0x7FFFFFFF)
+
+#define XR_LIST_BITS_XrInstanceCreateFlags(_)
+
+#define XR_LIST_BITS_XrSessionCreateFlags(_)
+
+#define XR_LIST_BITS_XrSpaceVelocityFlags(_) \
+ _(XR_SPACE_VELOCITY_LINEAR_VALID_BIT, 0x00000001) \
+ _(XR_SPACE_VELOCITY_ANGULAR_VALID_BIT, 0x00000002) \
+
+#define XR_LIST_BITS_XrSpaceLocationFlags(_) \
+ _(XR_SPACE_LOCATION_ORIENTATION_VALID_BIT, 0x00000001) \
+ _(XR_SPACE_LOCATION_POSITION_VALID_BIT, 0x00000002) \
+ _(XR_SPACE_LOCATION_ORIENTATION_TRACKED_BIT, 0x00000004) \
+ _(XR_SPACE_LOCATION_POSITION_TRACKED_BIT, 0x00000008) \
+
+#define XR_LIST_BITS_XrSwapchainCreateFlags(_) \
+ _(XR_SWAPCHAIN_CREATE_PROTECTED_CONTENT_BIT, 0x00000001) \
+ _(XR_SWAPCHAIN_CREATE_STATIC_IMAGE_BIT, 0x00000002) \
+
+#define XR_LIST_BITS_XrSwapchainUsageFlags(_) \
+ _(XR_SWAPCHAIN_USAGE_COLOR_ATTACHMENT_BIT, 0x00000001) \
+ _(XR_SWAPCHAIN_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT, 0x00000002) \
+ _(XR_SWAPCHAIN_USAGE_UNORDERED_ACCESS_BIT, 0x00000004) \
+ _(XR_SWAPCHAIN_USAGE_TRANSFER_SRC_BIT, 0x00000008) \
+ _(XR_SWAPCHAIN_USAGE_TRANSFER_DST_BIT, 0x00000010) \
+ _(XR_SWAPCHAIN_USAGE_SAMPLED_BIT, 0x00000020) \
+ _(XR_SWAPCHAIN_USAGE_MUTABLE_FORMAT_BIT, 0x00000040) \
+ _(XR_SWAPCHAIN_USAGE_INPUT_ATTACHMENT_BIT_MND, 0x00000080) \
+ _(XR_SWAPCHAIN_USAGE_INPUT_ATTACHMENT_BIT_KHR, XR_SWAPCHAIN_USAGE_INPUT_ATTACHMENT_BIT_MND) \
+
+#define XR_LIST_BITS_XrCompositionLayerFlags(_) \
+ _(XR_COMPOSITION_LAYER_CORRECT_CHROMATIC_ABERRATION_BIT, 0x00000001) \
+ _(XR_COMPOSITION_LAYER_BLEND_TEXTURE_SOURCE_ALPHA_BIT, 0x00000002) \
+ _(XR_COMPOSITION_LAYER_UNPREMULTIPLIED_ALPHA_BIT, 0x00000004) \
+
+#define XR_LIST_BITS_XrViewStateFlags(_) \
+ _(XR_VIEW_STATE_ORIENTATION_VALID_BIT, 0x00000001) \
+ _(XR_VIEW_STATE_POSITION_VALID_BIT, 0x00000002) \
+ _(XR_VIEW_STATE_ORIENTATION_TRACKED_BIT, 0x00000004) \
+ _(XR_VIEW_STATE_POSITION_TRACKED_BIT, 0x00000008) \
+
+#define XR_LIST_BITS_XrInputSourceLocalizedNameFlags(_) \
+ _(XR_INPUT_SOURCE_LOCALIZED_NAME_USER_PATH_BIT, 0x00000001) \
+ _(XR_INPUT_SOURCE_LOCALIZED_NAME_INTERACTION_PROFILE_BIT, 0x00000002) \
+ _(XR_INPUT_SOURCE_LOCALIZED_NAME_COMPONENT_BIT, 0x00000004) \
+
+#define XR_LIST_BITS_XrVulkanInstanceCreateFlagsKHR(_)
+
+#define XR_LIST_BITS_XrVulkanDeviceCreateFlagsKHR(_)
+
+#define XR_LIST_BITS_XrDebugUtilsMessageSeverityFlagsEXT(_) \
+ _(XR_DEBUG_UTILS_MESSAGE_SEVERITY_VERBOSE_BIT_EXT, 0x00000001) \
+ _(XR_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT, 0x00000010) \
+ _(XR_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT, 0x00000100) \
+ _(XR_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT, 0x00001000) \
+
+#define XR_LIST_BITS_XrDebugUtilsMessageTypeFlagsEXT(_) \
+ _(XR_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT, 0x00000001) \
+ _(XR_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT, 0x00000002) \
+ _(XR_DEBUG_UTILS_MESSAGE_TYPE_PERFORMANCE_BIT_EXT, 0x00000004) \
+ _(XR_DEBUG_UTILS_MESSAGE_TYPE_CONFORMANCE_BIT_EXT, 0x00000008) \
+
+#define XR_LIST_BITS_XrOverlaySessionCreateFlagsEXTX(_)
+
+#define XR_LIST_BITS_XrOverlayMainSessionFlagsEXTX(_) \
+ _(XR_OVERLAY_MAIN_SESSION_ENABLED_COMPOSITION_LAYER_INFO_DEPTH_BIT_EXTX, 0x00000001) \
+
+#define XR_LIST_BITS_XrCompositionLayerImageLayoutFlagsFB(_) \
+ _(XR_COMPOSITION_LAYER_IMAGE_LAYOUT_VERTICAL_FLIP_BIT_FB, 0x00000001) \
+
+#define XR_LIST_BITS_XrAndroidSurfaceSwapchainFlagsFB(_) \
+ _(XR_ANDROID_SURFACE_SWAPCHAIN_SYNCHRONOUS_BIT_FB, 0x00000001) \
+ _(XR_ANDROID_SURFACE_SWAPCHAIN_USE_TIMESTAMPS_BIT_FB, 0x00000002) \
+
+#define XR_LIST_BITS_XrCompositionLayerSecureContentFlagsFB(_) \
+ _(XR_COMPOSITION_LAYER_SECURE_CONTENT_EXCLUDE_LAYER_BIT_FB, 0x00000001) \
+ _(XR_COMPOSITION_LAYER_SECURE_CONTENT_REPLACE_LAYER_BIT_FB, 0x00000002) \
+
+#define XR_LIST_BITS_XrHandTrackingAimFlagsFB(_) \
+ _(XR_HAND_TRACKING_AIM_COMPUTED_BIT_FB, 0x00000001) \
+ _(XR_HAND_TRACKING_AIM_VALID_BIT_FB, 0x00000002) \
+ _(XR_HAND_TRACKING_AIM_INDEX_PINCHING_BIT_FB, 0x00000004) \
+ _(XR_HAND_TRACKING_AIM_MIDDLE_PINCHING_BIT_FB, 0x00000008) \
+ _(XR_HAND_TRACKING_AIM_RING_PINCHING_BIT_FB, 0x00000010) \
+ _(XR_HAND_TRACKING_AIM_LITTLE_PINCHING_BIT_FB, 0x00000020) \
+ _(XR_HAND_TRACKING_AIM_SYSTEM_GESTURE_BIT_FB, 0x00000040) \
+ _(XR_HAND_TRACKING_AIM_DOMINANT_HAND_BIT_FB, 0x00000080) \
+ _(XR_HAND_TRACKING_AIM_MENU_PRESSED_BIT_FB, 0x00000100) \
+
+#define XR_LIST_BITS_XrSwapchainCreateFoveationFlagsFB(_) \
+ _(XR_SWAPCHAIN_CREATE_FOVEATION_SCALED_BIN_BIT_FB, 0x00000001) \
+ _(XR_SWAPCHAIN_CREATE_FOVEATION_FRAGMENT_DENSITY_MAP_BIT_FB, 0x00000002) \
+
+#define XR_LIST_BITS_XrSwapchainStateFoveationFlagsFB(_)
+
+#define XR_LIST_BITS_XrKeyboardTrackingFlagsFB(_) \
+ _(XR_KEYBOARD_TRACKING_EXISTS_BIT_FB, 0x00000001) \
+ _(XR_KEYBOARD_TRACKING_LOCAL_BIT_FB, 0x00000002) \
+ _(XR_KEYBOARD_TRACKING_REMOTE_BIT_FB, 0x00000004) \
+ _(XR_KEYBOARD_TRACKING_CONNECTED_BIT_FB, 0x00000008) \
+
+#define XR_LIST_BITS_XrKeyboardTrackingQueryFlagsFB(_) \
+ _(XR_KEYBOARD_TRACKING_QUERY_LOCAL_BIT_FB, 0x00000002) \
+ _(XR_KEYBOARD_TRACKING_QUERY_REMOTE_BIT_FB, 0x00000004) \
+
+#define XR_LIST_BITS_XrTriangleMeshFlagsFB(_) \
+ _(XR_TRIANGLE_MESH_MUTABLE_BIT_FB, 0x00000001) \
+
+#define XR_LIST_BITS_XrPassthroughFlagsFB(_) \
+ _(XR_PASSTHROUGH_IS_RUNNING_AT_CREATION_BIT_FB, 0x00000001) \
+
+#define XR_LIST_BITS_XrPassthroughStateChangedFlagsFB(_) \
+ _(XR_PASSTHROUGH_STATE_CHANGED_REINIT_REQUIRED_BIT_FB, 0x00000001) \
+ _(XR_PASSTHROUGH_STATE_CHANGED_NON_RECOVERABLE_ERROR_BIT_FB, 0x00000002) \
+ _(XR_PASSTHROUGH_STATE_CHANGED_RECOVERABLE_ERROR_BIT_FB, 0x00000004) \
+ _(XR_PASSTHROUGH_STATE_CHANGED_RESTORED_ERROR_BIT_FB, 0x00000008) \
+
+#define XR_LIST_BITS_XrRenderModelFlagsFB(_)
+
+#define XR_LIST_BITS_XrCompositionLayerSpaceWarpInfoFlagsFB(_)
+
+#define XR_LIST_BITS_XrDigitalLensControlFlagsALMALENCE(_) \
+ _(XR_DIGITAL_LENS_CONTROL_PROCESSING_DISABLE_BIT_ALMALENCE, 0x00000001) \
+
+#define XR_LIST_STRUCT_XrApiLayerProperties(_) \
+ _(type) \
+ _(next) \
+ _(layerName) \
+ _(specVersion) \
+ _(layerVersion) \
+ _(description) \
+
+#define XR_LIST_STRUCT_XrExtensionProperties(_) \
+ _(type) \
+ _(next) \
+ _(extensionName) \
+ _(extensionVersion) \
+
+#define XR_LIST_STRUCT_XrApplicationInfo(_) \
+ _(applicationName) \
+ _(applicationVersion) \
+ _(engineName) \
+ _(engineVersion) \
+ _(apiVersion) \
+
+#define XR_LIST_STRUCT_XrInstanceCreateInfo(_) \
+ _(type) \
+ _(next) \
+ _(createFlags) \
+ _(applicationInfo) \
+ _(enabledApiLayerCount) \
+ _(enabledApiLayerNames) \
+ _(enabledExtensionCount) \
+ _(enabledExtensionNames) \
+
+#define XR_LIST_STRUCT_XrInstanceProperties(_) \
+ _(type) \
+ _(next) \
+ _(runtimeVersion) \
+ _(runtimeName) \
+
+#define XR_LIST_STRUCT_XrEventDataBuffer(_) \
+ _(type) \
+ _(next) \
+ _(varying) \
+
+#define XR_LIST_STRUCT_XrSystemGetInfo(_) \
+ _(type) \
+ _(next) \
+ _(formFactor) \
+
+#define XR_LIST_STRUCT_XrSystemGraphicsProperties(_) \
+ _(maxSwapchainImageHeight) \
+ _(maxSwapchainImageWidth) \
+ _(maxLayerCount) \
+
+#define XR_LIST_STRUCT_XrSystemTrackingProperties(_) \
+ _(orientationTracking) \
+ _(positionTracking) \
+
+#define XR_LIST_STRUCT_XrSystemProperties(_) \
+ _(type) \
+ _(next) \
+ _(systemId) \
+ _(vendorId) \
+ _(systemName) \
+ _(graphicsProperties) \
+ _(trackingProperties) \
+
+#define XR_LIST_STRUCT_XrSessionCreateInfo(_) \
+ _(type) \
+ _(next) \
+ _(createFlags) \
+ _(systemId) \
+
+#define XR_LIST_STRUCT_XrVector3f(_) \
+ _(x) \
+ _(y) \
+ _(z) \
+
+#define XR_LIST_STRUCT_XrSpaceVelocity(_) \
+ _(type) \
+ _(next) \
+ _(velocityFlags) \
+ _(linearVelocity) \
+ _(angularVelocity) \
+
+#define XR_LIST_STRUCT_XrQuaternionf(_) \
+ _(x) \
+ _(y) \
+ _(z) \
+ _(w) \
+
+#define XR_LIST_STRUCT_XrPosef(_) \
+ _(orientation) \
+ _(position) \
+
+#define XR_LIST_STRUCT_XrReferenceSpaceCreateInfo(_) \
+ _(type) \
+ _(next) \
+ _(referenceSpaceType) \
+ _(poseInReferenceSpace) \
+
+#define XR_LIST_STRUCT_XrExtent2Df(_) \
+ _(width) \
+ _(height) \
+
+#define XR_LIST_STRUCT_XrActionSpaceCreateInfo(_) \
+ _(type) \
+ _(next) \
+ _(action) \
+ _(subactionPath) \
+ _(poseInActionSpace) \
+
+#define XR_LIST_STRUCT_XrSpaceLocation(_) \
+ _(type) \
+ _(next) \
+ _(locationFlags) \
+ _(pose) \
+
+#define XR_LIST_STRUCT_XrViewConfigurationProperties(_) \
+ _(type) \
+ _(next) \
+ _(viewConfigurationType) \
+ _(fovMutable) \
+
+#define XR_LIST_STRUCT_XrViewConfigurationView(_) \
+ _(type) \
+ _(next) \
+ _(recommendedImageRectWidth) \
+ _(maxImageRectWidth) \
+ _(recommendedImageRectHeight) \
+ _(maxImageRectHeight) \
+ _(recommendedSwapchainSampleCount) \
+ _(maxSwapchainSampleCount) \
+
+#define XR_LIST_STRUCT_XrSwapchainCreateInfo(_) \
+ _(type) \
+ _(next) \
+ _(createFlags) \
+ _(usageFlags) \
+ _(format) \
+ _(sampleCount) \
+ _(width) \
+ _(height) \
+ _(faceCount) \
+ _(arraySize) \
+ _(mipCount) \
+
+#define XR_LIST_STRUCT_XrSwapchainImageBaseHeader(_) \
+ _(type) \
+ _(next) \
+
+#define XR_LIST_STRUCT_XrSwapchainImageAcquireInfo(_) \
+ _(type) \
+ _(next) \
+
+#define XR_LIST_STRUCT_XrSwapchainImageWaitInfo(_) \
+ _(type) \
+ _(next) \
+ _(timeout) \
+
+#define XR_LIST_STRUCT_XrSwapchainImageReleaseInfo(_) \
+ _(type) \
+ _(next) \
+
+#define XR_LIST_STRUCT_XrSessionBeginInfo(_) \
+ _(type) \
+ _(next) \
+ _(primaryViewConfigurationType) \
+
+#define XR_LIST_STRUCT_XrFrameWaitInfo(_) \
+ _(type) \
+ _(next) \
+
+#define XR_LIST_STRUCT_XrFrameState(_) \
+ _(type) \
+ _(next) \
+ _(predictedDisplayTime) \
+ _(predictedDisplayPeriod) \
+ _(shouldRender) \
+
+#define XR_LIST_STRUCT_XrFrameBeginInfo(_) \
+ _(type) \
+ _(next) \
+
+#define XR_LIST_STRUCT_XrCompositionLayerBaseHeader(_) \
+ _(type) \
+ _(next) \
+ _(layerFlags) \
+ _(space) \
+
+#define XR_LIST_STRUCT_XrFrameEndInfo(_) \
+ _(type) \
+ _(next) \
+ _(displayTime) \
+ _(environmentBlendMode) \
+ _(layerCount) \
+ _(layers) \
+
+#define XR_LIST_STRUCT_XrViewLocateInfo(_) \
+ _(type) \
+ _(next) \
+ _(viewConfigurationType) \
+ _(displayTime) \
+ _(space) \
+
+#define XR_LIST_STRUCT_XrViewState(_) \
+ _(type) \
+ _(next) \
+ _(viewStateFlags) \
+
+#define XR_LIST_STRUCT_XrFovf(_) \
+ _(angleLeft) \
+ _(angleRight) \
+ _(angleUp) \
+ _(angleDown) \
+
+#define XR_LIST_STRUCT_XrView(_) \
+ _(type) \
+ _(next) \
+ _(pose) \
+ _(fov) \
+
+#define XR_LIST_STRUCT_XrActionSetCreateInfo(_) \
+ _(type) \
+ _(next) \
+ _(actionSetName) \
+ _(localizedActionSetName) \
+ _(priority) \
+
+#define XR_LIST_STRUCT_XrActionCreateInfo(_) \
+ _(type) \
+ _(next) \
+ _(actionName) \
+ _(actionType) \
+ _(countSubactionPaths) \
+ _(subactionPaths) \
+ _(localizedActionName) \
+
+#define XR_LIST_STRUCT_XrActionSuggestedBinding(_) \
+ _(action) \
+ _(binding) \
+
+#define XR_LIST_STRUCT_XrInteractionProfileSuggestedBinding(_) \
+ _(type) \
+ _(next) \
+ _(interactionProfile) \
+ _(countSuggestedBindings) \
+ _(suggestedBindings) \
+
+#define XR_LIST_STRUCT_XrSessionActionSetsAttachInfo(_) \
+ _(type) \
+ _(next) \
+ _(countActionSets) \
+ _(actionSets) \
+
+#define XR_LIST_STRUCT_XrInteractionProfileState(_) \
+ _(type) \
+ _(next) \
+ _(interactionProfile) \
+
+#define XR_LIST_STRUCT_XrActionStateGetInfo(_) \
+ _(type) \
+ _(next) \
+ _(action) \
+ _(subactionPath) \
+
+#define XR_LIST_STRUCT_XrActionStateBoolean(_) \
+ _(type) \
+ _(next) \
+ _(currentState) \
+ _(changedSinceLastSync) \
+ _(lastChangeTime) \
+ _(isActive) \
+
+#define XR_LIST_STRUCT_XrActionStateFloat(_) \
+ _(type) \
+ _(next) \
+ _(currentState) \
+ _(changedSinceLastSync) \
+ _(lastChangeTime) \
+ _(isActive) \
+
+#define XR_LIST_STRUCT_XrVector2f(_) \
+ _(x) \
+ _(y) \
+
+#define XR_LIST_STRUCT_XrActionStateVector2f(_) \
+ _(type) \
+ _(next) \
+ _(currentState) \
+ _(changedSinceLastSync) \
+ _(lastChangeTime) \
+ _(isActive) \
+
+#define XR_LIST_STRUCT_XrActionStatePose(_) \
+ _(type) \
+ _(next) \
+ _(isActive) \
+
+#define XR_LIST_STRUCT_XrActiveActionSet(_) \
+ _(actionSet) \
+ _(subactionPath) \
+
+#define XR_LIST_STRUCT_XrActionsSyncInfo(_) \
+ _(type) \
+ _(next) \
+ _(countActiveActionSets) \
+ _(activeActionSets) \
+
+#define XR_LIST_STRUCT_XrBoundSourcesForActionEnumerateInfo(_) \
+ _(type) \
+ _(next) \
+ _(action) \
+
+#define XR_LIST_STRUCT_XrInputSourceLocalizedNameGetInfo(_) \
+ _(type) \
+ _(next) \
+ _(sourcePath) \
+ _(whichComponents) \
+
+#define XR_LIST_STRUCT_XrHapticActionInfo(_) \
+ _(type) \
+ _(next) \
+ _(action) \
+ _(subactionPath) \
+
+#define XR_LIST_STRUCT_XrHapticBaseHeader(_) \
+ _(type) \
+ _(next) \
+
+#define XR_LIST_STRUCT_XrBaseInStructure(_) \
+ _(type) \
+ _(next) \
+
+#define XR_LIST_STRUCT_XrBaseOutStructure(_) \
+ _(type) \
+ _(next) \
+
+#define XR_LIST_STRUCT_XrOffset2Di(_) \
+ _(x) \
+ _(y) \
+
+#define XR_LIST_STRUCT_XrExtent2Di(_) \
+ _(width) \
+ _(height) \
+
+#define XR_LIST_STRUCT_XrRect2Di(_) \
+ _(offset) \
+ _(extent) \
+
+#define XR_LIST_STRUCT_XrSwapchainSubImage(_) \
+ _(swapchain) \
+ _(imageRect) \
+ _(imageArrayIndex) \
+
+#define XR_LIST_STRUCT_XrCompositionLayerProjectionView(_) \
+ _(type) \
+ _(next) \
+ _(pose) \
+ _(fov) \
+ _(subImage) \
+
+#define XR_LIST_STRUCT_XrCompositionLayerProjection(_) \
+ _(type) \
+ _(next) \
+ _(layerFlags) \
+ _(space) \
+ _(viewCount) \
+ _(views) \
+
+#define XR_LIST_STRUCT_XrCompositionLayerQuad(_) \
+ _(type) \
+ _(next) \
+ _(layerFlags) \
+ _(space) \
+ _(eyeVisibility) \
+ _(subImage) \
+ _(pose) \
+ _(size) \
+
+#define XR_LIST_STRUCT_XrEventDataBaseHeader(_) \
+ _(type) \
+ _(next) \
+
+#define XR_LIST_STRUCT_XrEventDataEventsLost(_) \
+ _(type) \
+ _(next) \
+ _(lostEventCount) \
+
+#define XR_LIST_STRUCT_XrEventDataInstanceLossPending(_) \
+ _(type) \
+ _(next) \
+ _(lossTime) \
+
+#define XR_LIST_STRUCT_XrEventDataSessionStateChanged(_) \
+ _(type) \
+ _(next) \
+ _(session) \
+ _(state) \
+ _(time) \
+
+#define XR_LIST_STRUCT_XrEventDataReferenceSpaceChangePending(_) \
+ _(type) \
+ _(next) \
+ _(session) \
+ _(referenceSpaceType) \
+ _(changeTime) \
+ _(poseValid) \
+ _(poseInPreviousSpace) \
+
+#define XR_LIST_STRUCT_XrEventDataInteractionProfileChanged(_) \
+ _(type) \
+ _(next) \
+ _(session) \
+
+#define XR_LIST_STRUCT_XrHapticVibration(_) \
+ _(type) \
+ _(next) \
+ _(duration) \
+ _(frequency) \
+ _(amplitude) \
+
+#define XR_LIST_STRUCT_XrOffset2Df(_) \
+ _(x) \
+ _(y) \
+
+#define XR_LIST_STRUCT_XrRect2Df(_) \
+ _(offset) \
+ _(extent) \
+
+#define XR_LIST_STRUCT_XrVector4f(_) \
+ _(x) \
+ _(y) \
+ _(z) \
+ _(w) \
+
+#define XR_LIST_STRUCT_XrColor4f(_) \
+ _(r) \
+ _(g) \
+ _(b) \
+ _(a) \
+
+#define XR_LIST_STRUCT_XrCompositionLayerCubeKHR(_) \
+ _(type) \
+ _(next) \
+ _(layerFlags) \
+ _(space) \
+ _(eyeVisibility) \
+ _(swapchain) \
+ _(imageArrayIndex) \
+ _(orientation) \
+
+#define XR_LIST_STRUCT_XrInstanceCreateInfoAndroidKHR(_) \
+ _(type) \
+ _(next) \
+ _(applicationVM) \
+ _(applicationActivity) \
+
+#define XR_LIST_STRUCT_XrCompositionLayerDepthInfoKHR(_) \
+ _(type) \
+ _(next) \
+ _(subImage) \
+ _(minDepth) \
+ _(maxDepth) \
+ _(nearZ) \
+ _(farZ) \
+
+#define XR_LIST_STRUCT_XrVulkanSwapchainFormatListCreateInfoKHR(_) \
+ _(type) \
+ _(next) \
+ _(viewFormatCount) \
+ _(viewFormats) \
+
+#define XR_LIST_STRUCT_XrCompositionLayerCylinderKHR(_) \
+ _(type) \
+ _(next) \
+ _(layerFlags) \
+ _(space) \
+ _(eyeVisibility) \
+ _(subImage) \
+ _(pose) \
+ _(radius) \
+ _(centralAngle) \
+ _(aspectRatio) \
+
+#define XR_LIST_STRUCT_XrCompositionLayerEquirectKHR(_) \
+ _(type) \
+ _(next) \
+ _(layerFlags) \
+ _(space) \
+ _(eyeVisibility) \
+ _(subImage) \
+ _(pose) \
+ _(radius) \
+ _(scale) \
+ _(bias) \
+
+#define XR_LIST_STRUCT_XrGraphicsBindingOpenGLWin32KHR(_) \
+ _(type) \
+ _(next) \
+ _(hDC) \
+ _(hGLRC) \
+
+#define XR_LIST_STRUCT_XrGraphicsBindingOpenGLXlibKHR(_) \
+ _(type) \
+ _(next) \
+ _(xDisplay) \
+ _(visualid) \
+ _(glxFBConfig) \
+ _(glxDrawable) \
+ _(glxContext) \
+
+#define XR_LIST_STRUCT_XrGraphicsBindingOpenGLXcbKHR(_) \
+ _(type) \
+ _(next) \
+ _(connection) \
+ _(screenNumber) \
+ _(fbconfigid) \
+ _(visualid) \
+ _(glxDrawable) \
+ _(glxContext) \
+
+#define XR_LIST_STRUCT_XrGraphicsBindingOpenGLWaylandKHR(_) \
+ _(type) \
+ _(next) \
+ _(display) \
+
+#define XR_LIST_STRUCT_XrSwapchainImageOpenGLKHR(_) \
+ _(type) \
+ _(next) \
+ _(image) \
+
+#define XR_LIST_STRUCT_XrGraphicsRequirementsOpenGLKHR(_) \
+ _(type) \
+ _(next) \
+ _(minApiVersionSupported) \
+ _(maxApiVersionSupported) \
+
+#define XR_LIST_STRUCT_XrGraphicsBindingOpenGLESAndroidKHR(_) \
+ _(type) \
+ _(next) \
+ _(display) \
+ _(config) \
+ _(context) \
+
+#define XR_LIST_STRUCT_XrSwapchainImageOpenGLESKHR(_) \
+ _(type) \
+ _(next) \
+ _(image) \
+
+#define XR_LIST_STRUCT_XrGraphicsRequirementsOpenGLESKHR(_) \
+ _(type) \
+ _(next) \
+ _(minApiVersionSupported) \
+ _(maxApiVersionSupported) \
+
+#define XR_LIST_STRUCT_XrGraphicsBindingVulkanKHR(_) \
+ _(type) \
+ _(next) \
+ _(instance) \
+ _(physicalDevice) \
+ _(device) \
+ _(queueFamilyIndex) \
+ _(queueIndex) \
+
+#define XR_LIST_STRUCT_XrSwapchainImageVulkanKHR(_) \
+ _(type) \
+ _(next) \
+ _(image) \
+
+#define XR_LIST_STRUCT_XrGraphicsRequirementsVulkanKHR(_) \
+ _(type) \
+ _(next) \
+ _(minApiVersionSupported) \
+ _(maxApiVersionSupported) \
+
+#define XR_LIST_STRUCT_XrGraphicsBindingD3D11KHR(_) \
+ _(type) \
+ _(next) \
+ _(device) \
+
+#define XR_LIST_STRUCT_XrSwapchainImageD3D11KHR(_) \
+ _(type) \
+ _(next) \
+ _(texture) \
+
+#define XR_LIST_STRUCT_XrGraphicsRequirementsD3D11KHR(_) \
+ _(type) \
+ _(next) \
+ _(adapterLuid) \
+ _(minFeatureLevel) \
+
+#define XR_LIST_STRUCT_XrGraphicsBindingD3D12KHR(_) \
+ _(type) \
+ _(next) \
+ _(device) \
+ _(queue) \
+
+#define XR_LIST_STRUCT_XrSwapchainImageD3D12KHR(_) \
+ _(type) \
+ _(next) \
+ _(texture) \
+
+#define XR_LIST_STRUCT_XrGraphicsRequirementsD3D12KHR(_) \
+ _(type) \
+ _(next) \
+ _(adapterLuid) \
+ _(minFeatureLevel) \
+
+#define XR_LIST_STRUCT_XrVisibilityMaskKHR(_) \
+ _(type) \
+ _(next) \
+ _(vertexCapacityInput) \
+ _(vertexCountOutput) \
+ _(vertices) \
+ _(indexCapacityInput) \
+ _(indexCountOutput) \
+ _(indices) \
+
+#define XR_LIST_STRUCT_XrEventDataVisibilityMaskChangedKHR(_) \
+ _(type) \
+ _(next) \
+ _(session) \
+ _(viewConfigurationType) \
+ _(viewIndex) \
+
+#define XR_LIST_STRUCT_XrCompositionLayerColorScaleBiasKHR(_) \
+ _(type) \
+ _(next) \
+ _(colorScale) \
+ _(colorBias) \
+
+#define XR_LIST_STRUCT_XrLoaderInitInfoBaseHeaderKHR(_) \
+ _(type) \
+ _(next) \
+
+#define XR_LIST_STRUCT_XrLoaderInitInfoAndroidKHR(_) \
+ _(type) \
+ _(next) \
+ _(applicationVM) \
+ _(applicationContext) \
+
+#define XR_LIST_STRUCT_XrVulkanInstanceCreateInfoKHR(_) \
+ _(type) \
+ _(next) \
+ _(systemId) \
+ _(createFlags) \
+ _(pfnGetInstanceProcAddr) \
+ _(vulkanCreateInfo) \
+ _(vulkanAllocator) \
+
+#define XR_LIST_STRUCT_XrVulkanDeviceCreateInfoKHR(_) \
+ _(type) \
+ _(next) \
+ _(systemId) \
+ _(createFlags) \
+ _(pfnGetInstanceProcAddr) \
+ _(vulkanPhysicalDevice) \
+ _(vulkanCreateInfo) \
+ _(vulkanAllocator) \
+
+#define XR_LIST_STRUCT_XrVulkanGraphicsDeviceGetInfoKHR(_) \
+ _(type) \
+ _(next) \
+ _(systemId) \
+ _(vulkanInstance) \
+
+#define XR_LIST_STRUCT_XrCompositionLayerEquirect2KHR(_) \
+ _(type) \
+ _(next) \
+ _(layerFlags) \
+ _(space) \
+ _(eyeVisibility) \
+ _(subImage) \
+ _(pose) \
+ _(radius) \
+ _(centralHorizontalAngle) \
+ _(upperVerticalAngle) \
+ _(lowerVerticalAngle) \
+
+#define XR_LIST_STRUCT_XrBindingModificationBaseHeaderKHR(_) \
+ _(type) \
+ _(next) \
+
+#define XR_LIST_STRUCT_XrBindingModificationsKHR(_) \
+ _(type) \
+ _(next) \
+ _(bindingModificationCount) \
+ _(bindingModifications) \
+
+#define XR_LIST_STRUCT_XrEventDataPerfSettingsEXT(_) \
+ _(type) \
+ _(next) \
+ _(domain) \
+ _(subDomain) \
+ _(fromLevel) \
+ _(toLevel) \
+
+#define XR_LIST_STRUCT_XrDebugUtilsObjectNameInfoEXT(_) \
+ _(type) \
+ _(next) \
+ _(objectType) \
+ _(objectHandle) \
+ _(objectName) \
+
+#define XR_LIST_STRUCT_XrDebugUtilsLabelEXT(_) \
+ _(type) \
+ _(next) \
+ _(labelName) \
+
+#define XR_LIST_STRUCT_XrDebugUtilsMessengerCallbackDataEXT(_) \
+ _(type) \
+ _(next) \
+ _(messageId) \
+ _(functionName) \
+ _(message) \
+ _(objectCount) \
+ _(objects) \
+ _(sessionLabelCount) \
+ _(sessionLabels) \
+
+#define XR_LIST_STRUCT_XrDebugUtilsMessengerCreateInfoEXT(_) \
+ _(type) \
+ _(next) \
+ _(messageSeverities) \
+ _(messageTypes) \
+ _(userCallback) \
+ _(userData) \
+
+#define XR_LIST_STRUCT_XrSystemEyeGazeInteractionPropertiesEXT(_) \
+ _(type) \
+ _(next) \
+ _(supportsEyeGazeInteraction) \
+
+#define XR_LIST_STRUCT_XrEyeGazeSampleTimeEXT(_) \
+ _(type) \
+ _(next) \
+ _(time) \
+
+#define XR_LIST_STRUCT_XrSessionCreateInfoOverlayEXTX(_) \
+ _(type) \
+ _(next) \
+ _(createFlags) \
+ _(sessionLayersPlacement) \
+
+#define XR_LIST_STRUCT_XrEventDataMainSessionVisibilityChangedEXTX(_) \
+ _(type) \
+ _(next) \
+ _(visible) \
+ _(flags) \
+
+#define XR_LIST_STRUCT_XrSpatialAnchorCreateInfoMSFT(_) \
+ _(type) \
+ _(next) \
+ _(space) \
+ _(pose) \
+ _(time) \
+
+#define XR_LIST_STRUCT_XrSpatialAnchorSpaceCreateInfoMSFT(_) \
+ _(type) \
+ _(next) \
+ _(anchor) \
+ _(poseInAnchorSpace) \
+
+#define XR_LIST_STRUCT_XrCompositionLayerImageLayoutFB(_) \
+ _(type) \
+ _(next) \
+ _(flags) \
+
+#define XR_LIST_STRUCT_XrCompositionLayerAlphaBlendFB(_) \
+ _(type) \
+ _(next) \
+ _(srcFactorColor) \
+ _(dstFactorColor) \
+ _(srcFactorAlpha) \
+ _(dstFactorAlpha) \
+
+#define XR_LIST_STRUCT_XrViewConfigurationDepthRangeEXT(_) \
+ _(type) \
+ _(next) \
+ _(recommendedNearZ) \
+ _(minNearZ) \
+ _(recommendedFarZ) \
+ _(maxFarZ) \
+
+#define XR_LIST_STRUCT_XrGraphicsBindingEGLMNDX(_) \
+ _(type) \
+ _(next) \
+ _(getProcAddress) \
+ _(display) \
+ _(config) \
+ _(context) \
+
+#define XR_LIST_STRUCT_XrSpatialGraphNodeSpaceCreateInfoMSFT(_) \
+ _(type) \
+ _(next) \
+ _(nodeType) \
+ _(nodeId) \
+ _(pose) \
+
+#define XR_LIST_STRUCT_XrSystemHandTrackingPropertiesEXT(_) \
+ _(type) \
+ _(next) \
+ _(supportsHandTracking) \
+
+#define XR_LIST_STRUCT_XrHandTrackerCreateInfoEXT(_) \
+ _(type) \
+ _(next) \
+ _(hand) \
+ _(handJointSet) \
+
+#define XR_LIST_STRUCT_XrHandJointsLocateInfoEXT(_) \
+ _(type) \
+ _(next) \
+ _(baseSpace) \
+ _(time) \
+
+#define XR_LIST_STRUCT_XrHandJointLocationEXT(_) \
+ _(locationFlags) \
+ _(pose) \
+ _(radius) \
+
+#define XR_LIST_STRUCT_XrHandJointVelocityEXT(_) \
+ _(velocityFlags) \
+ _(linearVelocity) \
+ _(angularVelocity) \
+
+#define XR_LIST_STRUCT_XrHandJointLocationsEXT(_) \
+ _(type) \
+ _(next) \
+ _(isActive) \
+ _(jointCount) \
+ _(jointLocations) \
+
+#define XR_LIST_STRUCT_XrHandJointVelocitiesEXT(_) \
+ _(type) \
+ _(next) \
+ _(jointCount) \
+ _(jointVelocities) \
+
+#define XR_LIST_STRUCT_XrSystemHandTrackingMeshPropertiesMSFT(_) \
+ _(type) \
+ _(next) \
+ _(supportsHandTrackingMesh) \
+ _(maxHandMeshIndexCount) \
+ _(maxHandMeshVertexCount) \
+
+#define XR_LIST_STRUCT_XrHandMeshSpaceCreateInfoMSFT(_) \
+ _(type) \
+ _(next) \
+ _(handPoseType) \
+ _(poseInHandMeshSpace) \
+
+#define XR_LIST_STRUCT_XrHandMeshUpdateInfoMSFT(_) \
+ _(type) \
+ _(next) \
+ _(time) \
+ _(handPoseType) \
+
+#define XR_LIST_STRUCT_XrHandMeshIndexBufferMSFT(_) \
+ _(indexBufferKey) \
+ _(indexCapacityInput) \
+ _(indexCountOutput) \
+ _(indices) \
+
+#define XR_LIST_STRUCT_XrHandMeshVertexMSFT(_) \
+ _(position) \
+ _(normal) \
+
+#define XR_LIST_STRUCT_XrHandMeshVertexBufferMSFT(_) \
+ _(vertexUpdateTime) \
+ _(vertexCapacityInput) \
+ _(vertexCountOutput) \
+ _(vertices) \
+
+#define XR_LIST_STRUCT_XrHandMeshMSFT(_) \
+ _(type) \
+ _(next) \
+ _(isActive) \
+ _(indexBufferChanged) \
+ _(vertexBufferChanged) \
+ _(indexBuffer) \
+ _(vertexBuffer) \
+
+#define XR_LIST_STRUCT_XrHandPoseTypeInfoMSFT(_) \
+ _(type) \
+ _(next) \
+ _(handPoseType) \
+
+#define XR_LIST_STRUCT_XrSecondaryViewConfigurationSessionBeginInfoMSFT(_) \
+ _(type) \
+ _(next) \
+ _(viewConfigurationCount) \
+ _(enabledViewConfigurationTypes) \
+
+#define XR_LIST_STRUCT_XrSecondaryViewConfigurationStateMSFT(_) \
+ _(type) \
+ _(next) \
+ _(viewConfigurationType) \
+ _(active) \
+
+#define XR_LIST_STRUCT_XrSecondaryViewConfigurationFrameStateMSFT(_) \
+ _(type) \
+ _(next) \
+ _(viewConfigurationCount) \
+ _(viewConfigurationStates) \
+
+#define XR_LIST_STRUCT_XrSecondaryViewConfigurationLayerInfoMSFT(_) \
+ _(type) \
+ _(next) \
+ _(viewConfigurationType) \
+ _(environmentBlendMode) \
+ _(layerCount) \
+ _(layers) \
+
+#define XR_LIST_STRUCT_XrSecondaryViewConfigurationFrameEndInfoMSFT(_) \
+ _(type) \
+ _(next) \
+ _(viewConfigurationCount) \
+ _(viewConfigurationLayersInfo) \
+
+#define XR_LIST_STRUCT_XrSecondaryViewConfigurationSwapchainCreateInfoMSFT(_) \
+ _(type) \
+ _(next) \
+ _(viewConfigurationType) \
+
+#define XR_LIST_STRUCT_XrControllerModelKeyStateMSFT(_) \
+ _(type) \
+ _(next) \
+ _(modelKey) \
+
+#define XR_LIST_STRUCT_XrControllerModelNodePropertiesMSFT(_) \
+ _(type) \
+ _(next) \
+ _(parentNodeName) \
+ _(nodeName) \
+
+#define XR_LIST_STRUCT_XrControllerModelPropertiesMSFT(_) \
+ _(type) \
+ _(next) \
+ _(nodeCapacityInput) \
+ _(nodeCountOutput) \
+ _(nodeProperties) \
+
+#define XR_LIST_STRUCT_XrControllerModelNodeStateMSFT(_) \
+ _(type) \
+ _(next) \
+ _(nodePose) \
+
+#define XR_LIST_STRUCT_XrControllerModelStateMSFT(_) \
+ _(type) \
+ _(next) \
+ _(nodeCapacityInput) \
+ _(nodeCountOutput) \
+ _(nodeStates) \
+
+#define XR_LIST_STRUCT_XrViewConfigurationViewFovEPIC(_) \
+ _(type) \
+ _(next) \
+ _(recommendedFov) \
+ _(maxMutableFov) \
+
+#define XR_LIST_STRUCT_XrHolographicWindowAttachmentMSFT(_) \
+ _(type) \
+ _(next) \
+ _(holographicSpace) \
+ _(coreWindow) \
+
+#define XR_LIST_STRUCT_XrCompositionLayerReprojectionInfoMSFT(_) \
+ _(type) \
+ _(next) \
+ _(reprojectionMode) \
+
+#define XR_LIST_STRUCT_XrCompositionLayerReprojectionPlaneOverrideMSFT(_) \
+ _(type) \
+ _(next) \
+ _(position) \
+ _(normal) \
+ _(velocity) \
+
+#define XR_LIST_STRUCT_XrAndroidSurfaceSwapchainCreateInfoFB(_) \
+ _(type) \
+ _(next) \
+ _(createFlags) \
+
+#define XR_LIST_STRUCT_XrSwapchainStateBaseHeaderFB(_) \
+ _(type) \
+ _(next) \
+
+#define XR_LIST_STRUCT_XrCompositionLayerSecureContentFB(_) \
+ _(type) \
+ _(next) \
+ _(flags) \
+
+#define XR_LIST_STRUCT_XrInteractionProfileAnalogThresholdVALVE(_) \
+ _(type) \
+ _(next) \
+ _(action) \
+ _(binding) \
+ _(onThreshold) \
+ _(offThreshold) \
+ _(onHaptic) \
+ _(offHaptic) \
+
+#define XR_LIST_STRUCT_XrHandJointsMotionRangeInfoEXT(_) \
+ _(type) \
+ _(next) \
+ _(handJointsMotionRange) \
+
+#define XR_LIST_STRUCT_XrUuidMSFT(_) \
+ _(bytes) \
+
+#define XR_LIST_STRUCT_XrSceneObserverCreateInfoMSFT(_) \
+ _(type) \
+ _(next) \
+
+#define XR_LIST_STRUCT_XrSceneCreateInfoMSFT(_) \
+ _(type) \
+ _(next) \
+
+#define XR_LIST_STRUCT_XrSceneSphereBoundMSFT(_) \
+ _(center) \
+ _(radius) \
+
+#define XR_LIST_STRUCT_XrSceneOrientedBoxBoundMSFT(_) \
+ _(pose) \
+ _(extents) \
+
+#define XR_LIST_STRUCT_XrSceneFrustumBoundMSFT(_) \
+ _(pose) \
+ _(fov) \
+ _(farDistance) \
+
+#define XR_LIST_STRUCT_XrSceneBoundsMSFT(_) \
+ _(space) \
+ _(time) \
+ _(sphereCount) \
+ _(spheres) \
+ _(boxCount) \
+ _(boxes) \
+ _(frustumCount) \
+ _(frustums) \
+
+#define XR_LIST_STRUCT_XrNewSceneComputeInfoMSFT(_) \
+ _(type) \
+ _(next) \
+ _(requestedFeatureCount) \
+ _(requestedFeatures) \
+ _(consistency) \
+ _(bounds) \
+
+#define XR_LIST_STRUCT_XrVisualMeshComputeLodInfoMSFT(_) \
+ _(type) \
+ _(next) \
+ _(lod) \
+
+#define XR_LIST_STRUCT_XrSceneComponentMSFT(_) \
+ _(componentType) \
+ _(id) \
+ _(parentId) \
+ _(updateTime) \
+
+#define XR_LIST_STRUCT_XrSceneComponentsMSFT(_) \
+ _(type) \
+ _(next) \
+ _(componentCapacityInput) \
+ _(componentCountOutput) \
+ _(components) \
+
+#define XR_LIST_STRUCT_XrSceneComponentsGetInfoMSFT(_) \
+ _(type) \
+ _(next) \
+ _(componentType) \
+
+#define XR_LIST_STRUCT_XrSceneComponentLocationMSFT(_) \
+ _(flags) \
+ _(pose) \
+
+#define XR_LIST_STRUCT_XrSceneComponentLocationsMSFT(_) \
+ _(type) \
+ _(next) \
+ _(locationCount) \
+ _(locations) \
+
+#define XR_LIST_STRUCT_XrSceneComponentsLocateInfoMSFT(_) \
+ _(type) \
+ _(next) \
+ _(baseSpace) \
+ _(time) \
+ _(componentIdCount) \
+ _(componentIds) \
+
+#define XR_LIST_STRUCT_XrSceneObjectMSFT(_) \
+ _(objectType) \
+
+#define XR_LIST_STRUCT_XrSceneObjectsMSFT(_) \
+ _(type) \
+ _(next) \
+ _(sceneObjectCount) \
+ _(sceneObjects) \
+
+#define XR_LIST_STRUCT_XrSceneComponentParentFilterInfoMSFT(_) \
+ _(type) \
+ _(next) \
+ _(parentId) \
+
+#define XR_LIST_STRUCT_XrSceneObjectTypesFilterInfoMSFT(_) \
+ _(type) \
+ _(next) \
+ _(objectTypeCount) \
+ _(objectTypes) \
+
+#define XR_LIST_STRUCT_XrScenePlaneMSFT(_) \
+ _(alignment) \
+ _(size) \
+ _(meshBufferId) \
+ _(supportsIndicesUint16) \
+
+#define XR_LIST_STRUCT_XrScenePlanesMSFT(_) \
+ _(type) \
+ _(next) \
+ _(scenePlaneCount) \
+ _(scenePlanes) \
+
+#define XR_LIST_STRUCT_XrScenePlaneAlignmentFilterInfoMSFT(_) \
+ _(type) \
+ _(next) \
+ _(alignmentCount) \
+ _(alignments) \
+
+#define XR_LIST_STRUCT_XrSceneMeshMSFT(_) \
+ _(meshBufferId) \
+ _(supportsIndicesUint16) \
+
+#define XR_LIST_STRUCT_XrSceneMeshesMSFT(_) \
+ _(type) \
+ _(next) \
+ _(sceneMeshCount) \
+ _(sceneMeshes) \
+
+#define XR_LIST_STRUCT_XrSceneMeshBuffersGetInfoMSFT(_) \
+ _(type) \
+ _(next) \
+ _(meshBufferId) \
+
+#define XR_LIST_STRUCT_XrSceneMeshBuffersMSFT(_) \
+ _(type) \
+ _(next) \
+
+#define XR_LIST_STRUCT_XrSceneMeshVertexBufferMSFT(_) \
+ _(type) \
+ _(next) \
+ _(vertexCapacityInput) \
+ _(vertexCountOutput) \
+ _(vertices) \
+
+#define XR_LIST_STRUCT_XrSceneMeshIndicesUint32MSFT(_) \
+ _(type) \
+ _(next) \
+ _(indexCapacityInput) \
+ _(indexCountOutput) \
+ _(indices) \
+
+#define XR_LIST_STRUCT_XrSceneMeshIndicesUint16MSFT(_) \
+ _(type) \
+ _(next) \
+ _(indexCapacityInput) \
+ _(indexCountOutput) \
+ _(indices) \
+
+#define XR_LIST_STRUCT_XrSerializedSceneFragmentDataGetInfoMSFT(_) \
+ _(type) \
+ _(next) \
+ _(sceneFragmentId) \
+
+#define XR_LIST_STRUCT_XrDeserializeSceneFragmentMSFT(_) \
+ _(bufferSize) \
+ _(buffer) \
+
+#define XR_LIST_STRUCT_XrSceneDeserializeInfoMSFT(_) \
+ _(type) \
+ _(next) \
+ _(fragmentCount) \
+ _(fragments) \
+
+#define XR_LIST_STRUCT_XrEventDataDisplayRefreshRateChangedFB(_) \
+ _(type) \
+ _(next) \
+ _(fromDisplayRefreshRate) \
+ _(toDisplayRefreshRate) \
+
+#define XR_LIST_STRUCT_XrViveTrackerPathsHTCX(_) \
+ _(type) \
+ _(next) \
+ _(persistentPath) \
+ _(rolePath) \
+
+#define XR_LIST_STRUCT_XrEventDataViveTrackerConnectedHTCX(_) \
+ _(type) \
+ _(next) \
+ _(paths) \
+
+#define XR_LIST_STRUCT_XrSystemFacialTrackingPropertiesHTC(_) \
+ _(type) \
+ _(next) \
+ _(supportEyeFacialTracking) \
+ _(supportLipFacialTracking) \
+
+#define XR_LIST_STRUCT_XrFacialExpressionsHTC(_) \
+ _(type) \
+ _(next) \
+ _(isActive) \
+ _(sampleTime) \
+ _(expressionCount) \
+ _(expressionWeightings) \
+
+#define XR_LIST_STRUCT_XrFacialTrackerCreateInfoHTC(_) \
+ _(type) \
+ _(next) \
+ _(facialTrackingType) \
+
+#define XR_LIST_STRUCT_XrSystemColorSpacePropertiesFB(_) \
+ _(type) \
+ _(next) \
+ _(colorSpace) \
+
+#define XR_LIST_STRUCT_XrVector4sFB(_) \
+ _(x) \
+ _(y) \
+ _(z) \
+ _(w) \
+
+#define XR_LIST_STRUCT_XrHandTrackingMeshFB(_) \
+ _(type) \
+ _(next) \
+ _(jointCapacityInput) \
+ _(jointCountOutput) \
+ _(jointBindPoses) \
+ _(jointRadii) \
+ _(jointParents) \
+ _(vertexCapacityInput) \
+ _(vertexCountOutput) \
+ _(vertexPositions) \
+ _(vertexNormals) \
+ _(vertexUVs) \
+ _(vertexBlendIndices) \
+ _(vertexBlendWeights) \
+ _(indexCapacityInput) \
+ _(indexCountOutput) \
+ _(indices) \
+
+#define XR_LIST_STRUCT_XrHandTrackingScaleFB(_) \
+ _(type) \
+ _(next) \
+ _(sensorOutput) \
+ _(currentOutput) \
+ _(overrideHandScale) \
+ _(overrideValueInput) \
+
+#define XR_LIST_STRUCT_XrHandTrackingAimStateFB(_) \
+ _(type) \
+ _(next) \
+ _(status) \
+ _(aimPose) \
+ _(pinchStrengthIndex) \
+ _(pinchStrengthMiddle) \
+ _(pinchStrengthRing) \
+ _(pinchStrengthLittle) \
+
+#define XR_LIST_STRUCT_XrHandCapsuleFB(_) \
+ _(points) \
+ _(radius) \
+ _(joint) \
+
+#define XR_LIST_STRUCT_XrHandTrackingCapsulesStateFB(_) \
+ _(type) \
+ _(next) \
+ _(capsules) \
+
+#define XR_LIST_STRUCT_XrFoveationProfileCreateInfoFB(_) \
+ _(type) \
+ _(next) \
+
+#define XR_LIST_STRUCT_XrSwapchainCreateInfoFoveationFB(_) \
+ _(type) \
+ _(next) \
+ _(flags) \
+
+#define XR_LIST_STRUCT_XrSwapchainStateFoveationFB(_) \
+ _(type) \
+ _(next) \
+ _(flags) \
+ _(profile) \
+
+#define XR_LIST_STRUCT_XrFoveationLevelProfileCreateInfoFB(_) \
+ _(type) \
+ _(next) \
+ _(level) \
+ _(verticalOffset) \
+ _(dynamic) \
+
+#define XR_LIST_STRUCT_XrSystemKeyboardTrackingPropertiesFB(_) \
+ _(type) \
+ _(next) \
+ _(supportsKeyboardTracking) \
+
+#define XR_LIST_STRUCT_XrKeyboardTrackingDescriptionFB(_) \
+ _(trackedKeyboardId) \
+ _(size) \
+ _(flags) \
+ _(name) \
+
+#define XR_LIST_STRUCT_XrKeyboardSpaceCreateInfoFB(_) \
+ _(type) \
+ _(next) \
+ _(trackedKeyboardId) \
+
+#define XR_LIST_STRUCT_XrKeyboardTrackingQueryFB(_) \
+ _(type) \
+ _(next) \
+ _(flags) \
+
+#define XR_LIST_STRUCT_XrTriangleMeshCreateInfoFB(_) \
+ _(type) \
+ _(next) \
+ _(flags) \
+ _(windingOrder) \
+ _(vertexCount) \
+ _(vertexBuffer) \
+ _(triangleCount) \
+ _(indexBuffer) \
+
+#define XR_LIST_STRUCT_XrSystemPassthroughPropertiesFB(_) \
+ _(type) \
+ _(next) \
+ _(supportsPassthrough) \
+
+#define XR_LIST_STRUCT_XrPassthroughCreateInfoFB(_) \
+ _(type) \
+ _(next) \
+ _(flags) \
+
+#define XR_LIST_STRUCT_XrPassthroughLayerCreateInfoFB(_) \
+ _(type) \
+ _(next) \
+ _(passthrough) \
+ _(flags) \
+ _(purpose) \
+
+#define XR_LIST_STRUCT_XrCompositionLayerPassthroughFB(_) \
+ _(type) \
+ _(next) \
+ _(flags) \
+ _(space) \
+ _(layerHandle) \
+
+#define XR_LIST_STRUCT_XrGeometryInstanceCreateInfoFB(_) \
+ _(type) \
+ _(next) \
+ _(layer) \
+ _(mesh) \
+ _(baseSpace) \
+ _(pose) \
+ _(scale) \
+
+#define XR_LIST_STRUCT_XrGeometryInstanceTransformFB(_) \
+ _(type) \
+ _(next) \
+ _(baseSpace) \
+ _(time) \
+ _(pose) \
+ _(scale) \
+
+#define XR_LIST_STRUCT_XrPassthroughStyleFB(_) \
+ _(type) \
+ _(next) \
+ _(textureOpacityFactor) \
+ _(edgeColor) \
+
+#define XR_LIST_STRUCT_XrPassthroughColorMapMonoToRgbaFB(_) \
+ _(type) \
+ _(next) \
+ _(textureColorMap) \
+
+#define XR_LIST_STRUCT_XrPassthroughColorMapMonoToMonoFB(_) \
+ _(type) \
+ _(next) \
+ _(textureColorMap) \
+
+#define XR_LIST_STRUCT_XrEventDataPassthroughStateChangedFB(_) \
+ _(type) \
+ _(next) \
+ _(flags) \
+
+#define XR_LIST_STRUCT_XrRenderModelPathInfoFB(_) \
+ _(type) \
+ _(next) \
+ _(path) \
+
+#define XR_LIST_STRUCT_XrRenderModelPropertiesFB(_) \
+ _(type) \
+ _(next) \
+ _(vendorId) \
+ _(modelName) \
+ _(modelKey) \
+ _(modelVersion) \
+ _(flags) \
+
+#define XR_LIST_STRUCT_XrRenderModelBufferFB(_) \
+ _(type) \
+ _(next) \
+ _(bufferCapacityInput) \
+ _(bufferCountOutput) \
+ _(buffer) \
+
+#define XR_LIST_STRUCT_XrRenderModelLoadInfoFB(_) \
+ _(type) \
+ _(next) \
+ _(modelKey) \
+
+#define XR_LIST_STRUCT_XrSystemRenderModelPropertiesFB(_) \
+ _(type) \
+ _(next) \
+ _(supportsRenderModelLoading) \
+
+#define XR_LIST_STRUCT_XrViewLocateFoveatedRenderingVARJO(_) \
+ _(type) \
+ _(next) \
+ _(foveatedRenderingActive) \
+
+#define XR_LIST_STRUCT_XrFoveatedViewConfigurationViewVARJO(_) \
+ _(type) \
+ _(next) \
+ _(foveatedRenderingActive) \
+
+#define XR_LIST_STRUCT_XrSystemFoveatedRenderingPropertiesVARJO(_) \
+ _(type) \
+ _(next) \
+ _(supportsFoveatedRendering) \
+
+#define XR_LIST_STRUCT_XrCompositionLayerDepthTestVARJO(_) \
+ _(type) \
+ _(next) \
+ _(depthTestRangeNearZ) \
+ _(depthTestRangeFarZ) \
+
+#define XR_LIST_STRUCT_XrSystemMarkerTrackingPropertiesVARJO(_) \
+ _(type) \
+ _(next) \
+ _(supportsMarkerTracking) \
+
+#define XR_LIST_STRUCT_XrEventDataMarkerTrackingUpdateVARJO(_) \
+ _(type) \
+ _(next) \
+ _(markerId) \
+ _(isActive) \
+ _(isPredicted) \
+ _(time) \
+
+#define XR_LIST_STRUCT_XrMarkerSpaceCreateInfoVARJO(_) \
+ _(type) \
+ _(next) \
+ _(markerId) \
+ _(poseInMarkerSpace) \
+
+#define XR_LIST_STRUCT_XrSpatialAnchorPersistenceNameMSFT(_) \
+ _(name) \
+
+#define XR_LIST_STRUCT_XrSpatialAnchorPersistenceInfoMSFT(_) \
+ _(type) \
+ _(next) \
+ _(spatialAnchorPersistenceName) \
+ _(spatialAnchor) \
+
+#define XR_LIST_STRUCT_XrSpatialAnchorFromPersistedAnchorCreateInfoMSFT(_) \
+ _(type) \
+ _(next) \
+ _(spatialAnchorStore) \
+ _(spatialAnchorPersistenceName) \
+
+#define XR_LIST_STRUCT_XrSwapchainImageFoveationVulkanFB(_) \
+ _(type) \
+ _(next) \
+ _(image) \
+ _(width) \
+ _(height) \
+
+#define XR_LIST_STRUCT_XrSwapchainStateAndroidSurfaceDimensionsFB(_) \
+ _(type) \
+ _(next) \
+ _(width) \
+ _(height) \
+
+#define XR_LIST_STRUCT_XrSwapchainStateSamplerOpenGLESFB(_) \
+ _(type) \
+ _(next) \
+ _(minFilter) \
+ _(magFilter) \
+ _(wrapModeS) \
+ _(wrapModeT) \
+ _(swizzleRed) \
+ _(swizzleGreen) \
+ _(swizzleBlue) \
+ _(swizzleAlpha) \
+ _(maxAnisotropy) \
+ _(borderColor) \
+
+#define XR_LIST_STRUCT_XrSwapchainStateSamplerVulkanFB(_) \
+ _(type) \
+ _(next) \
+ _(minFilter) \
+ _(magFilter) \
+ _(mipmapMode) \
+ _(wrapModeS) \
+ _(wrapModeT) \
+ _(swizzleRed) \
+ _(swizzleGreen) \
+ _(swizzleBlue) \
+ _(swizzleAlpha) \
+ _(maxAnisotropy) \
+ _(borderColor) \
+
+#define XR_LIST_STRUCT_XrCompositionLayerSpaceWarpInfoFB(_) \
+ _(type) \
+ _(next) \
+ _(layerFlags) \
+ _(motionVectorSubImage) \
+ _(appSpaceDeltaPose) \
+ _(depthSubImage) \
+ _(minDepth) \
+ _(maxDepth) \
+ _(nearZ) \
+ _(farZ) \
+
+#define XR_LIST_STRUCT_XrSystemSpaceWarpPropertiesFB(_) \
+ _(type) \
+ _(next) \
+ _(recommendedMotionVectorImageRectWidth) \
+ _(recommendedMotionVectorImageRectHeight) \
+
+#define XR_LIST_STRUCT_XrDigitalLensControlALMALENCE(_) \
+ _(type) \
+ _(next) \
+ _(flags) \
+
+#define XR_LIST_STRUCT_XrPassthroughKeyboardHandsIntensityFB(_) \
+ _(type) \
+ _(next) \
+ _(leftHandIntensity) \
+ _(rightHandIntensity) \
+
+#define XR_LIST_STRUCT_XrUuidEXT(_) \
+ _(data) \
+
+
+
+#define XR_LIST_STRUCTURE_TYPES_CORE(_) \
+ _(XrApiLayerProperties, XR_TYPE_API_LAYER_PROPERTIES) \
+ _(XrExtensionProperties, XR_TYPE_EXTENSION_PROPERTIES) \
+ _(XrInstanceCreateInfo, XR_TYPE_INSTANCE_CREATE_INFO) \
+ _(XrInstanceProperties, XR_TYPE_INSTANCE_PROPERTIES) \
+ _(XrEventDataBuffer, XR_TYPE_EVENT_DATA_BUFFER) \
+ _(XrSystemGetInfo, XR_TYPE_SYSTEM_GET_INFO) \
+ _(XrSystemProperties, XR_TYPE_SYSTEM_PROPERTIES) \
+ _(XrSessionCreateInfo, XR_TYPE_SESSION_CREATE_INFO) \
+ _(XrSpaceVelocity, XR_TYPE_SPACE_VELOCITY) \
+ _(XrReferenceSpaceCreateInfo, XR_TYPE_REFERENCE_SPACE_CREATE_INFO) \
+ _(XrActionSpaceCreateInfo, XR_TYPE_ACTION_SPACE_CREATE_INFO) \
+ _(XrSpaceLocation, XR_TYPE_SPACE_LOCATION) \
+ _(XrViewConfigurationProperties, XR_TYPE_VIEW_CONFIGURATION_PROPERTIES) \
+ _(XrViewConfigurationView, XR_TYPE_VIEW_CONFIGURATION_VIEW) \
+ _(XrSwapchainCreateInfo, XR_TYPE_SWAPCHAIN_CREATE_INFO) \
+ _(XrSwapchainImageAcquireInfo, XR_TYPE_SWAPCHAIN_IMAGE_ACQUIRE_INFO) \
+ _(XrSwapchainImageWaitInfo, XR_TYPE_SWAPCHAIN_IMAGE_WAIT_INFO) \
+ _(XrSwapchainImageReleaseInfo, XR_TYPE_SWAPCHAIN_IMAGE_RELEASE_INFO) \
+ _(XrSessionBeginInfo, XR_TYPE_SESSION_BEGIN_INFO) \
+ _(XrFrameWaitInfo, XR_TYPE_FRAME_WAIT_INFO) \
+ _(XrFrameState, XR_TYPE_FRAME_STATE) \
+ _(XrFrameBeginInfo, XR_TYPE_FRAME_BEGIN_INFO) \
+ _(XrFrameEndInfo, XR_TYPE_FRAME_END_INFO) \
+ _(XrViewLocateInfo, XR_TYPE_VIEW_LOCATE_INFO) \
+ _(XrViewState, XR_TYPE_VIEW_STATE) \
+ _(XrView, XR_TYPE_VIEW) \
+ _(XrActionSetCreateInfo, XR_TYPE_ACTION_SET_CREATE_INFO) \
+ _(XrActionCreateInfo, XR_TYPE_ACTION_CREATE_INFO) \
+ _(XrInteractionProfileSuggestedBinding, XR_TYPE_INTERACTION_PROFILE_SUGGESTED_BINDING) \
+ _(XrSessionActionSetsAttachInfo, XR_TYPE_SESSION_ACTION_SETS_ATTACH_INFO) \
+ _(XrInteractionProfileState, XR_TYPE_INTERACTION_PROFILE_STATE) \
+ _(XrActionStateGetInfo, XR_TYPE_ACTION_STATE_GET_INFO) \
+ _(XrActionStateBoolean, XR_TYPE_ACTION_STATE_BOOLEAN) \
+ _(XrActionStateFloat, XR_TYPE_ACTION_STATE_FLOAT) \
+ _(XrActionStateVector2f, XR_TYPE_ACTION_STATE_VECTOR2F) \
+ _(XrActionStatePose, XR_TYPE_ACTION_STATE_POSE) \
+ _(XrActionsSyncInfo, XR_TYPE_ACTIONS_SYNC_INFO) \
+ _(XrBoundSourcesForActionEnumerateInfo, XR_TYPE_BOUND_SOURCES_FOR_ACTION_ENUMERATE_INFO) \
+ _(XrInputSourceLocalizedNameGetInfo, XR_TYPE_INPUT_SOURCE_LOCALIZED_NAME_GET_INFO) \
+ _(XrHapticActionInfo, XR_TYPE_HAPTIC_ACTION_INFO) \
+ _(XrCompositionLayerProjectionView, XR_TYPE_COMPOSITION_LAYER_PROJECTION_VIEW) \
+ _(XrCompositionLayerProjection, XR_TYPE_COMPOSITION_LAYER_PROJECTION) \
+ _(XrCompositionLayerQuad, XR_TYPE_COMPOSITION_LAYER_QUAD) \
+ _(XrEventDataEventsLost, XR_TYPE_EVENT_DATA_EVENTS_LOST) \
+ _(XrEventDataInstanceLossPending, XR_TYPE_EVENT_DATA_INSTANCE_LOSS_PENDING) \
+ _(XrEventDataSessionStateChanged, XR_TYPE_EVENT_DATA_SESSION_STATE_CHANGED) \
+ _(XrEventDataReferenceSpaceChangePending, XR_TYPE_EVENT_DATA_REFERENCE_SPACE_CHANGE_PENDING) \
+ _(XrEventDataInteractionProfileChanged, XR_TYPE_EVENT_DATA_INTERACTION_PROFILE_CHANGED) \
+ _(XrHapticVibration, XR_TYPE_HAPTIC_VIBRATION) \
+ _(XrCompositionLayerCubeKHR, XR_TYPE_COMPOSITION_LAYER_CUBE_KHR) \
+ _(XrCompositionLayerDepthInfoKHR, XR_TYPE_COMPOSITION_LAYER_DEPTH_INFO_KHR) \
+ _(XrCompositionLayerCylinderKHR, XR_TYPE_COMPOSITION_LAYER_CYLINDER_KHR) \
+ _(XrCompositionLayerEquirectKHR, XR_TYPE_COMPOSITION_LAYER_EQUIRECT_KHR) \
+ _(XrVisibilityMaskKHR, XR_TYPE_VISIBILITY_MASK_KHR) \
+ _(XrEventDataVisibilityMaskChangedKHR, XR_TYPE_EVENT_DATA_VISIBILITY_MASK_CHANGED_KHR) \
+ _(XrCompositionLayerColorScaleBiasKHR, XR_TYPE_COMPOSITION_LAYER_COLOR_SCALE_BIAS_KHR) \
+ _(XrCompositionLayerEquirect2KHR, XR_TYPE_COMPOSITION_LAYER_EQUIRECT2_KHR) \
+ _(XrBindingModificationsKHR, XR_TYPE_BINDING_MODIFICATIONS_KHR) \
+ _(XrEventDataPerfSettingsEXT, XR_TYPE_EVENT_DATA_PERF_SETTINGS_EXT) \
+ _(XrDebugUtilsObjectNameInfoEXT, XR_TYPE_DEBUG_UTILS_OBJECT_NAME_INFO_EXT) \
+ _(XrDebugUtilsLabelEXT, XR_TYPE_DEBUG_UTILS_LABEL_EXT) \
+ _(XrDebugUtilsMessengerCallbackDataEXT, XR_TYPE_DEBUG_UTILS_MESSENGER_CALLBACK_DATA_EXT) \
+ _(XrDebugUtilsMessengerCreateInfoEXT, XR_TYPE_DEBUG_UTILS_MESSENGER_CREATE_INFO_EXT) \
+ _(XrSystemEyeGazeInteractionPropertiesEXT, XR_TYPE_SYSTEM_EYE_GAZE_INTERACTION_PROPERTIES_EXT) \
+ _(XrEyeGazeSampleTimeEXT, XR_TYPE_EYE_GAZE_SAMPLE_TIME_EXT) \
+ _(XrSessionCreateInfoOverlayEXTX, XR_TYPE_SESSION_CREATE_INFO_OVERLAY_EXTX) \
+ _(XrEventDataMainSessionVisibilityChangedEXTX, XR_TYPE_EVENT_DATA_MAIN_SESSION_VISIBILITY_CHANGED_EXTX) \
+ _(XrSpatialAnchorCreateInfoMSFT, XR_TYPE_SPATIAL_ANCHOR_CREATE_INFO_MSFT) \
+ _(XrSpatialAnchorSpaceCreateInfoMSFT, XR_TYPE_SPATIAL_ANCHOR_SPACE_CREATE_INFO_MSFT) \
+ _(XrCompositionLayerImageLayoutFB, XR_TYPE_COMPOSITION_LAYER_IMAGE_LAYOUT_FB) \
+ _(XrCompositionLayerAlphaBlendFB, XR_TYPE_COMPOSITION_LAYER_ALPHA_BLEND_FB) \
+ _(XrViewConfigurationDepthRangeEXT, XR_TYPE_VIEW_CONFIGURATION_DEPTH_RANGE_EXT) \
+ _(XrSpatialGraphNodeSpaceCreateInfoMSFT, XR_TYPE_SPATIAL_GRAPH_NODE_SPACE_CREATE_INFO_MSFT) \
+ _(XrSystemHandTrackingPropertiesEXT, XR_TYPE_SYSTEM_HAND_TRACKING_PROPERTIES_EXT) \
+ _(XrHandTrackerCreateInfoEXT, XR_TYPE_HAND_TRACKER_CREATE_INFO_EXT) \
+ _(XrHandJointsLocateInfoEXT, XR_TYPE_HAND_JOINTS_LOCATE_INFO_EXT) \
+ _(XrHandJointLocationsEXT, XR_TYPE_HAND_JOINT_LOCATIONS_EXT) \
+ _(XrHandJointVelocitiesEXT, XR_TYPE_HAND_JOINT_VELOCITIES_EXT) \
+ _(XrSystemHandTrackingMeshPropertiesMSFT, XR_TYPE_SYSTEM_HAND_TRACKING_MESH_PROPERTIES_MSFT) \
+ _(XrHandMeshSpaceCreateInfoMSFT, XR_TYPE_HAND_MESH_SPACE_CREATE_INFO_MSFT) \
+ _(XrHandMeshUpdateInfoMSFT, XR_TYPE_HAND_MESH_UPDATE_INFO_MSFT) \
+ _(XrHandMeshMSFT, XR_TYPE_HAND_MESH_MSFT) \
+ _(XrHandPoseTypeInfoMSFT, XR_TYPE_HAND_POSE_TYPE_INFO_MSFT) \
+ _(XrSecondaryViewConfigurationSessionBeginInfoMSFT, XR_TYPE_SECONDARY_VIEW_CONFIGURATION_SESSION_BEGIN_INFO_MSFT) \
+ _(XrSecondaryViewConfigurationStateMSFT, XR_TYPE_SECONDARY_VIEW_CONFIGURATION_STATE_MSFT) \
+ _(XrSecondaryViewConfigurationFrameStateMSFT, XR_TYPE_SECONDARY_VIEW_CONFIGURATION_FRAME_STATE_MSFT) \
+ _(XrSecondaryViewConfigurationLayerInfoMSFT, XR_TYPE_SECONDARY_VIEW_CONFIGURATION_LAYER_INFO_MSFT) \
+ _(XrSecondaryViewConfigurationFrameEndInfoMSFT, XR_TYPE_SECONDARY_VIEW_CONFIGURATION_FRAME_END_INFO_MSFT) \
+ _(XrSecondaryViewConfigurationSwapchainCreateInfoMSFT, XR_TYPE_SECONDARY_VIEW_CONFIGURATION_SWAPCHAIN_CREATE_INFO_MSFT) \
+ _(XrControllerModelKeyStateMSFT, XR_TYPE_CONTROLLER_MODEL_KEY_STATE_MSFT) \
+ _(XrControllerModelNodePropertiesMSFT, XR_TYPE_CONTROLLER_MODEL_NODE_PROPERTIES_MSFT) \
+ _(XrControllerModelPropertiesMSFT, XR_TYPE_CONTROLLER_MODEL_PROPERTIES_MSFT) \
+ _(XrControllerModelNodeStateMSFT, XR_TYPE_CONTROLLER_MODEL_NODE_STATE_MSFT) \
+ _(XrControllerModelStateMSFT, XR_TYPE_CONTROLLER_MODEL_STATE_MSFT) \
+ _(XrViewConfigurationViewFovEPIC, XR_TYPE_VIEW_CONFIGURATION_VIEW_FOV_EPIC) \
+ _(XrCompositionLayerReprojectionInfoMSFT, XR_TYPE_COMPOSITION_LAYER_REPROJECTION_INFO_MSFT) \
+ _(XrCompositionLayerReprojectionPlaneOverrideMSFT, XR_TYPE_COMPOSITION_LAYER_REPROJECTION_PLANE_OVERRIDE_MSFT) \
+ _(XrCompositionLayerSecureContentFB, XR_TYPE_COMPOSITION_LAYER_SECURE_CONTENT_FB) \
+ _(XrInteractionProfileAnalogThresholdVALVE, XR_TYPE_INTERACTION_PROFILE_ANALOG_THRESHOLD_VALVE) \
+ _(XrHandJointsMotionRangeInfoEXT, XR_TYPE_HAND_JOINTS_MOTION_RANGE_INFO_EXT) \
+ _(XrSceneObserverCreateInfoMSFT, XR_TYPE_SCENE_OBSERVER_CREATE_INFO_MSFT) \
+ _(XrSceneCreateInfoMSFT, XR_TYPE_SCENE_CREATE_INFO_MSFT) \
+ _(XrNewSceneComputeInfoMSFT, XR_TYPE_NEW_SCENE_COMPUTE_INFO_MSFT) \
+ _(XrVisualMeshComputeLodInfoMSFT, XR_TYPE_VISUAL_MESH_COMPUTE_LOD_INFO_MSFT) \
+ _(XrSceneComponentsMSFT, XR_TYPE_SCENE_COMPONENTS_MSFT) \
+ _(XrSceneComponentsGetInfoMSFT, XR_TYPE_SCENE_COMPONENTS_GET_INFO_MSFT) \
+ _(XrSceneComponentLocationsMSFT, XR_TYPE_SCENE_COMPONENT_LOCATIONS_MSFT) \
+ _(XrSceneComponentsLocateInfoMSFT, XR_TYPE_SCENE_COMPONENTS_LOCATE_INFO_MSFT) \
+ _(XrSceneObjectsMSFT, XR_TYPE_SCENE_OBJECTS_MSFT) \
+ _(XrSceneComponentParentFilterInfoMSFT, XR_TYPE_SCENE_COMPONENT_PARENT_FILTER_INFO_MSFT) \
+ _(XrSceneObjectTypesFilterInfoMSFT, XR_TYPE_SCENE_OBJECT_TYPES_FILTER_INFO_MSFT) \
+ _(XrScenePlanesMSFT, XR_TYPE_SCENE_PLANES_MSFT) \
+ _(XrScenePlaneAlignmentFilterInfoMSFT, XR_TYPE_SCENE_PLANE_ALIGNMENT_FILTER_INFO_MSFT) \
+ _(XrSceneMeshesMSFT, XR_TYPE_SCENE_MESHES_MSFT) \
+ _(XrSceneMeshBuffersGetInfoMSFT, XR_TYPE_SCENE_MESH_BUFFERS_GET_INFO_MSFT) \
+ _(XrSceneMeshBuffersMSFT, XR_TYPE_SCENE_MESH_BUFFERS_MSFT) \
+ _(XrSceneMeshVertexBufferMSFT, XR_TYPE_SCENE_MESH_VERTEX_BUFFER_MSFT) \
+ _(XrSceneMeshIndicesUint32MSFT, XR_TYPE_SCENE_MESH_INDICES_UINT32_MSFT) \
+ _(XrSceneMeshIndicesUint16MSFT, XR_TYPE_SCENE_MESH_INDICES_UINT16_MSFT) \
+ _(XrSerializedSceneFragmentDataGetInfoMSFT, XR_TYPE_SERIALIZED_SCENE_FRAGMENT_DATA_GET_INFO_MSFT) \
+ _(XrSceneDeserializeInfoMSFT, XR_TYPE_SCENE_DESERIALIZE_INFO_MSFT) \
+ _(XrEventDataDisplayRefreshRateChangedFB, XR_TYPE_EVENT_DATA_DISPLAY_REFRESH_RATE_CHANGED_FB) \
+ _(XrViveTrackerPathsHTCX, XR_TYPE_VIVE_TRACKER_PATHS_HTCX) \
+ _(XrEventDataViveTrackerConnectedHTCX, XR_TYPE_EVENT_DATA_VIVE_TRACKER_CONNECTED_HTCX) \
+ _(XrSystemFacialTrackingPropertiesHTC, XR_TYPE_SYSTEM_FACIAL_TRACKING_PROPERTIES_HTC) \
+ _(XrFacialExpressionsHTC, XR_TYPE_FACIAL_EXPRESSIONS_HTC) \
+ _(XrFacialTrackerCreateInfoHTC, XR_TYPE_FACIAL_TRACKER_CREATE_INFO_HTC) \
+ _(XrSystemColorSpacePropertiesFB, XR_TYPE_SYSTEM_COLOR_SPACE_PROPERTIES_FB) \
+ _(XrHandTrackingMeshFB, XR_TYPE_HAND_TRACKING_MESH_FB) \
+ _(XrHandTrackingScaleFB, XR_TYPE_HAND_TRACKING_SCALE_FB) \
+ _(XrHandTrackingAimStateFB, XR_TYPE_HAND_TRACKING_AIM_STATE_FB) \
+ _(XrHandTrackingCapsulesStateFB, XR_TYPE_HAND_TRACKING_CAPSULES_STATE_FB) \
+ _(XrFoveationProfileCreateInfoFB, XR_TYPE_FOVEATION_PROFILE_CREATE_INFO_FB) \
+ _(XrSwapchainCreateInfoFoveationFB, XR_TYPE_SWAPCHAIN_CREATE_INFO_FOVEATION_FB) \
+ _(XrSwapchainStateFoveationFB, XR_TYPE_SWAPCHAIN_STATE_FOVEATION_FB) \
+ _(XrFoveationLevelProfileCreateInfoFB, XR_TYPE_FOVEATION_LEVEL_PROFILE_CREATE_INFO_FB) \
+ _(XrSystemKeyboardTrackingPropertiesFB, XR_TYPE_SYSTEM_KEYBOARD_TRACKING_PROPERTIES_FB) \
+ _(XrKeyboardSpaceCreateInfoFB, XR_TYPE_KEYBOARD_SPACE_CREATE_INFO_FB) \
+ _(XrKeyboardTrackingQueryFB, XR_TYPE_KEYBOARD_TRACKING_QUERY_FB) \
+ _(XrTriangleMeshCreateInfoFB, XR_TYPE_TRIANGLE_MESH_CREATE_INFO_FB) \
+ _(XrSystemPassthroughPropertiesFB, XR_TYPE_SYSTEM_PASSTHROUGH_PROPERTIES_FB) \
+ _(XrPassthroughCreateInfoFB, XR_TYPE_PASSTHROUGH_CREATE_INFO_FB) \
+ _(XrPassthroughLayerCreateInfoFB, XR_TYPE_PASSTHROUGH_LAYER_CREATE_INFO_FB) \
+ _(XrCompositionLayerPassthroughFB, XR_TYPE_COMPOSITION_LAYER_PASSTHROUGH_FB) \
+ _(XrGeometryInstanceCreateInfoFB, XR_TYPE_GEOMETRY_INSTANCE_CREATE_INFO_FB) \
+ _(XrGeometryInstanceTransformFB, XR_TYPE_GEOMETRY_INSTANCE_TRANSFORM_FB) \
+ _(XrPassthroughStyleFB, XR_TYPE_PASSTHROUGH_STYLE_FB) \
+ _(XrPassthroughColorMapMonoToRgbaFB, XR_TYPE_PASSTHROUGH_COLOR_MAP_MONO_TO_RGBA_FB) \
+ _(XrPassthroughColorMapMonoToMonoFB, XR_TYPE_PASSTHROUGH_COLOR_MAP_MONO_TO_MONO_FB) \
+ _(XrEventDataPassthroughStateChangedFB, XR_TYPE_EVENT_DATA_PASSTHROUGH_STATE_CHANGED_FB) \
+ _(XrRenderModelPathInfoFB, XR_TYPE_RENDER_MODEL_PATH_INFO_FB) \
+ _(XrRenderModelPropertiesFB, XR_TYPE_RENDER_MODEL_PROPERTIES_FB) \
+ _(XrRenderModelBufferFB, XR_TYPE_RENDER_MODEL_BUFFER_FB) \
+ _(XrRenderModelLoadInfoFB, XR_TYPE_RENDER_MODEL_LOAD_INFO_FB) \
+ _(XrSystemRenderModelPropertiesFB, XR_TYPE_SYSTEM_RENDER_MODEL_PROPERTIES_FB) \
+ _(XrViewLocateFoveatedRenderingVARJO, XR_TYPE_VIEW_LOCATE_FOVEATED_RENDERING_VARJO) \
+ _(XrFoveatedViewConfigurationViewVARJO, XR_TYPE_FOVEATED_VIEW_CONFIGURATION_VIEW_VARJO) \
+ _(XrSystemFoveatedRenderingPropertiesVARJO, XR_TYPE_SYSTEM_FOVEATED_RENDERING_PROPERTIES_VARJO) \
+ _(XrCompositionLayerDepthTestVARJO, XR_TYPE_COMPOSITION_LAYER_DEPTH_TEST_VARJO) \
+ _(XrSystemMarkerTrackingPropertiesVARJO, XR_TYPE_SYSTEM_MARKER_TRACKING_PROPERTIES_VARJO) \
+ _(XrEventDataMarkerTrackingUpdateVARJO, XR_TYPE_EVENT_DATA_MARKER_TRACKING_UPDATE_VARJO) \
+ _(XrMarkerSpaceCreateInfoVARJO, XR_TYPE_MARKER_SPACE_CREATE_INFO_VARJO) \
+ _(XrSpatialAnchorPersistenceInfoMSFT, XR_TYPE_SPATIAL_ANCHOR_PERSISTENCE_INFO_MSFT) \
+ _(XrSpatialAnchorFromPersistedAnchorCreateInfoMSFT, XR_TYPE_SPATIAL_ANCHOR_FROM_PERSISTED_ANCHOR_CREATE_INFO_MSFT) \
+ _(XrCompositionLayerSpaceWarpInfoFB, XR_TYPE_COMPOSITION_LAYER_SPACE_WARP_INFO_FB) \
+ _(XrSystemSpaceWarpPropertiesFB, XR_TYPE_SYSTEM_SPACE_WARP_PROPERTIES_FB) \
+ _(XrDigitalLensControlALMALENCE, XR_TYPE_DIGITAL_LENS_CONTROL_ALMALENCE) \
+ _(XrPassthroughKeyboardHandsIntensityFB, XR_TYPE_PASSTHROUGH_KEYBOARD_HANDS_INTENSITY_FB) \
+
+
+
+
+#if defined(XR_USE_GRAPHICS_API_D3D11)
+#define XR_LIST_STRUCTURE_TYPES_XR_USE_GRAPHICS_API_D3D11(_) \
+ _(XrGraphicsBindingD3D11KHR, XR_TYPE_GRAPHICS_BINDING_D3D11_KHR) \
+ _(XrSwapchainImageD3D11KHR, XR_TYPE_SWAPCHAIN_IMAGE_D3D11_KHR) \
+ _(XrGraphicsRequirementsD3D11KHR, XR_TYPE_GRAPHICS_REQUIREMENTS_D3D11_KHR) \
+
+
+#else
+#define XR_LIST_STRUCTURE_TYPES_XR_USE_GRAPHICS_API_D3D11(_)
+#endif
+
+#if defined(XR_USE_GRAPHICS_API_D3D12)
+#define XR_LIST_STRUCTURE_TYPES_XR_USE_GRAPHICS_API_D3D12(_) \
+ _(XrGraphicsBindingD3D12KHR, XR_TYPE_GRAPHICS_BINDING_D3D12_KHR) \
+ _(XrSwapchainImageD3D12KHR, XR_TYPE_SWAPCHAIN_IMAGE_D3D12_KHR) \
+ _(XrGraphicsRequirementsD3D12KHR, XR_TYPE_GRAPHICS_REQUIREMENTS_D3D12_KHR) \
+
+
+#else
+#define XR_LIST_STRUCTURE_TYPES_XR_USE_GRAPHICS_API_D3D12(_)
+#endif
+
+#if defined(XR_USE_GRAPHICS_API_OPENGL)
+#define XR_LIST_STRUCTURE_TYPES_XR_USE_GRAPHICS_API_OPENGL(_) \
+ _(XrSwapchainImageOpenGLKHR, XR_TYPE_SWAPCHAIN_IMAGE_OPENGL_KHR) \
+ _(XrGraphicsRequirementsOpenGLKHR, XR_TYPE_GRAPHICS_REQUIREMENTS_OPENGL_KHR) \
+
+
+#else
+#define XR_LIST_STRUCTURE_TYPES_XR_USE_GRAPHICS_API_OPENGL(_)
+#endif
+
+#if defined(XR_USE_GRAPHICS_API_OPENGL) && defined(XR_USE_PLATFORM_WAYLAND)
+#define XR_LIST_STRUCTURE_TYPES_XR_USE_GRAPHICS_API_OPENGL_XR_USE_PLATFORM_WAYLAND(_) \
+ _(XrGraphicsBindingOpenGLWaylandKHR, XR_TYPE_GRAPHICS_BINDING_OPENGL_WAYLAND_KHR) \
+
+
+#else
+#define XR_LIST_STRUCTURE_TYPES_XR_USE_GRAPHICS_API_OPENGL_XR_USE_PLATFORM_WAYLAND(_)
+#endif
+
+#if defined(XR_USE_GRAPHICS_API_OPENGL) && defined(XR_USE_PLATFORM_WIN32)
+#define XR_LIST_STRUCTURE_TYPES_XR_USE_GRAPHICS_API_OPENGL_XR_USE_PLATFORM_WIN32(_) \
+ _(XrGraphicsBindingOpenGLWin32KHR, XR_TYPE_GRAPHICS_BINDING_OPENGL_WIN32_KHR) \
+
+
+#else
+#define XR_LIST_STRUCTURE_TYPES_XR_USE_GRAPHICS_API_OPENGL_XR_USE_PLATFORM_WIN32(_)
+#endif
+
+#if defined(XR_USE_GRAPHICS_API_OPENGL) && defined(XR_USE_PLATFORM_XCB)
+#define XR_LIST_STRUCTURE_TYPES_XR_USE_GRAPHICS_API_OPENGL_XR_USE_PLATFORM_XCB(_) \
+ _(XrGraphicsBindingOpenGLXcbKHR, XR_TYPE_GRAPHICS_BINDING_OPENGL_XCB_KHR) \
+
+
+#else
+#define XR_LIST_STRUCTURE_TYPES_XR_USE_GRAPHICS_API_OPENGL_XR_USE_PLATFORM_XCB(_)
+#endif
+
+#if defined(XR_USE_GRAPHICS_API_OPENGL) && defined(XR_USE_PLATFORM_XLIB)
+#define XR_LIST_STRUCTURE_TYPES_XR_USE_GRAPHICS_API_OPENGL_XR_USE_PLATFORM_XLIB(_) \
+ _(XrGraphicsBindingOpenGLXlibKHR, XR_TYPE_GRAPHICS_BINDING_OPENGL_XLIB_KHR) \
+
+
+#else
+#define XR_LIST_STRUCTURE_TYPES_XR_USE_GRAPHICS_API_OPENGL_XR_USE_PLATFORM_XLIB(_)
+#endif
+
+#if defined(XR_USE_GRAPHICS_API_OPENGL_ES)
+#define XR_LIST_STRUCTURE_TYPES_XR_USE_GRAPHICS_API_OPENGL_ES(_) \
+ _(XrSwapchainImageOpenGLESKHR, XR_TYPE_SWAPCHAIN_IMAGE_OPENGL_ES_KHR) \
+ _(XrGraphicsRequirementsOpenGLESKHR, XR_TYPE_GRAPHICS_REQUIREMENTS_OPENGL_ES_KHR) \
+ _(XrSwapchainStateSamplerOpenGLESFB, XR_TYPE_SWAPCHAIN_STATE_SAMPLER_OPENGL_ES_FB) \
+
+
+#else
+#define XR_LIST_STRUCTURE_TYPES_XR_USE_GRAPHICS_API_OPENGL_ES(_)
+#endif
+
+#if defined(XR_USE_GRAPHICS_API_OPENGL_ES) && defined(XR_USE_PLATFORM_ANDROID)
+#define XR_LIST_STRUCTURE_TYPES_XR_USE_GRAPHICS_API_OPENGL_ES_XR_USE_PLATFORM_ANDROID(_) \
+ _(XrGraphicsBindingOpenGLESAndroidKHR, XR_TYPE_GRAPHICS_BINDING_OPENGL_ES_ANDROID_KHR) \
+
+
+#else
+#define XR_LIST_STRUCTURE_TYPES_XR_USE_GRAPHICS_API_OPENGL_ES_XR_USE_PLATFORM_ANDROID(_)
+#endif
+
+#if defined(XR_USE_GRAPHICS_API_VULKAN)
+#define XR_LIST_STRUCTURE_TYPES_XR_USE_GRAPHICS_API_VULKAN(_) \
+ _(XrVulkanSwapchainFormatListCreateInfoKHR, XR_TYPE_VULKAN_SWAPCHAIN_FORMAT_LIST_CREATE_INFO_KHR) \
+ _(XrGraphicsBindingVulkanKHR, XR_TYPE_GRAPHICS_BINDING_VULKAN_KHR) \
+ _(XrSwapchainImageVulkanKHR, XR_TYPE_SWAPCHAIN_IMAGE_VULKAN_KHR) \
+ _(XrGraphicsRequirementsVulkanKHR, XR_TYPE_GRAPHICS_REQUIREMENTS_VULKAN_KHR) \
+ _(XrVulkanInstanceCreateInfoKHR, XR_TYPE_VULKAN_INSTANCE_CREATE_INFO_KHR) \
+ _(XrVulkanDeviceCreateInfoKHR, XR_TYPE_VULKAN_DEVICE_CREATE_INFO_KHR) \
+ _(XrVulkanGraphicsDeviceGetInfoKHR, XR_TYPE_VULKAN_GRAPHICS_DEVICE_GET_INFO_KHR) \
+ _(XrSwapchainImageFoveationVulkanFB, XR_TYPE_SWAPCHAIN_IMAGE_FOVEATION_VULKAN_FB) \
+ _(XrSwapchainStateSamplerVulkanFB, XR_TYPE_SWAPCHAIN_STATE_SAMPLER_VULKAN_FB) \
+
+
+#else
+#define XR_LIST_STRUCTURE_TYPES_XR_USE_GRAPHICS_API_VULKAN(_)
+#endif
+
+#if defined(XR_USE_PLATFORM_ANDROID)
+#define XR_LIST_STRUCTURE_TYPES_XR_USE_PLATFORM_ANDROID(_) \
+ _(XrInstanceCreateInfoAndroidKHR, XR_TYPE_INSTANCE_CREATE_INFO_ANDROID_KHR) \
+ _(XrLoaderInitInfoAndroidKHR, XR_TYPE_LOADER_INIT_INFO_ANDROID_KHR) \
+ _(XrAndroidSurfaceSwapchainCreateInfoFB, XR_TYPE_ANDROID_SURFACE_SWAPCHAIN_CREATE_INFO_FB) \
+ _(XrSwapchainStateAndroidSurfaceDimensionsFB, XR_TYPE_SWAPCHAIN_STATE_ANDROID_SURFACE_DIMENSIONS_FB) \
+
+
+#else
+#define XR_LIST_STRUCTURE_TYPES_XR_USE_PLATFORM_ANDROID(_)
+#endif
+
+#if defined(XR_USE_PLATFORM_EGL)
+#define XR_LIST_STRUCTURE_TYPES_XR_USE_PLATFORM_EGL(_) \
+ _(XrGraphicsBindingEGLMNDX, XR_TYPE_GRAPHICS_BINDING_EGL_MNDX) \
+
+
+#else
+#define XR_LIST_STRUCTURE_TYPES_XR_USE_PLATFORM_EGL(_)
+#endif
+
+#if defined(XR_USE_PLATFORM_WIN32)
+#define XR_LIST_STRUCTURE_TYPES_XR_USE_PLATFORM_WIN32(_) \
+ _(XrHolographicWindowAttachmentMSFT, XR_TYPE_HOLOGRAPHIC_WINDOW_ATTACHMENT_MSFT) \
+
+
+#else
+#define XR_LIST_STRUCTURE_TYPES_XR_USE_PLATFORM_WIN32(_)
+#endif
+
+#define XR_LIST_STRUCTURE_TYPES(_) \
+ XR_LIST_STRUCTURE_TYPES_CORE(_) \
+ XR_LIST_STRUCTURE_TYPES_XR_USE_GRAPHICS_API_D3D11(_) \
+ XR_LIST_STRUCTURE_TYPES_XR_USE_GRAPHICS_API_D3D12(_) \
+ XR_LIST_STRUCTURE_TYPES_XR_USE_GRAPHICS_API_OPENGL(_) \
+ XR_LIST_STRUCTURE_TYPES_XR_USE_GRAPHICS_API_OPENGL_XR_USE_PLATFORM_WAYLAND(_) \
+ XR_LIST_STRUCTURE_TYPES_XR_USE_GRAPHICS_API_OPENGL_XR_USE_PLATFORM_WIN32(_) \
+ XR_LIST_STRUCTURE_TYPES_XR_USE_GRAPHICS_API_OPENGL_XR_USE_PLATFORM_XCB(_) \
+ XR_LIST_STRUCTURE_TYPES_XR_USE_GRAPHICS_API_OPENGL_XR_USE_PLATFORM_XLIB(_) \
+ XR_LIST_STRUCTURE_TYPES_XR_USE_GRAPHICS_API_OPENGL_ES(_) \
+ XR_LIST_STRUCTURE_TYPES_XR_USE_GRAPHICS_API_OPENGL_ES_XR_USE_PLATFORM_ANDROID(_) \
+ XR_LIST_STRUCTURE_TYPES_XR_USE_GRAPHICS_API_VULKAN(_) \
+ XR_LIST_STRUCTURE_TYPES_XR_USE_PLATFORM_ANDROID(_) \
+ XR_LIST_STRUCTURE_TYPES_XR_USE_PLATFORM_EGL(_) \
+ XR_LIST_STRUCTURE_TYPES_XR_USE_PLATFORM_WIN32(_) \
+
+
+#define XR_LIST_EXTENSIONS(_) \
+ _(XR_KHR_android_thread_settings, 4) \
+ _(XR_KHR_android_surface_swapchain, 5) \
+ _(XR_KHR_composition_layer_cube, 7) \
+ _(XR_KHR_android_create_instance, 9) \
+ _(XR_KHR_composition_layer_depth, 11) \
+ _(XR_KHR_vulkan_swapchain_format_list, 15) \
+ _(XR_EXT_performance_settings, 16) \
+ _(XR_EXT_thermal_query, 17) \
+ _(XR_KHR_composition_layer_cylinder, 18) \
+ _(XR_KHR_composition_layer_equirect, 19) \
+ _(XR_EXT_debug_utils, 20) \
+ _(XR_KHR_opengl_enable, 24) \
+ _(XR_KHR_opengl_es_enable, 25) \
+ _(XR_KHR_vulkan_enable, 26) \
+ _(XR_KHR_D3D11_enable, 28) \
+ _(XR_KHR_D3D12_enable, 29) \
+ _(XR_EXT_eye_gaze_interaction, 31) \
+ _(XR_KHR_visibility_mask, 32) \
+ _(XR_EXTX_overlay, 34) \
+ _(XR_KHR_composition_layer_color_scale_bias, 35) \
+ _(XR_KHR_win32_convert_performance_counter_time, 36) \
+ _(XR_KHR_convert_timespec_time, 37) \
+ _(XR_VARJO_quad_views, 38) \
+ _(XR_MSFT_unbounded_reference_space, 39) \
+ _(XR_MSFT_spatial_anchor, 40) \
+ _(XR_FB_composition_layer_image_layout, 41) \
+ _(XR_FB_composition_layer_alpha_blend, 42) \
+ _(XR_MND_headless, 43) \
+ _(XR_OCULUS_android_session_state_enable, 45) \
+ _(XR_EXT_view_configuration_depth_range, 47) \
+ _(XR_EXT_conformance_automation, 48) \
+ _(XR_MNDX_egl_enable, 49) \
+ _(XR_MSFT_spatial_graph_bridge, 50) \
+ _(XR_MSFT_hand_interaction, 51) \
+ _(XR_EXT_hand_tracking, 52) \
+ _(XR_MSFT_hand_tracking_mesh, 53) \
+ _(XR_MSFT_secondary_view_configuration, 54) \
+ _(XR_MSFT_first_person_observer, 55) \
+ _(XR_MSFT_controller_model, 56) \
+ _(XR_MSFT_perception_anchor_interop, 57) \
+ _(XR_EXT_win32_appcontainer_compatible, 58) \
+ _(XR_EPIC_view_configuration_fov, 60) \
+ _(XR_MSFT_holographic_window_attachment, 64) \
+ _(XR_MSFT_composition_layer_reprojection, 67) \
+ _(XR_HUAWEI_controller_interaction, 70) \
+ _(XR_FB_android_surface_swapchain_create, 71) \
+ _(XR_FB_swapchain_update_state, 72) \
+ _(XR_FB_composition_layer_secure_content, 73) \
+ _(XR_VALVE_analog_threshold, 80) \
+ _(XR_EXT_hand_joints_motion_range, 81) \
+ _(XR_KHR_loader_init, 89) \
+ _(XR_KHR_loader_init_android, 90) \
+ _(XR_KHR_vulkan_enable2, 91) \
+ _(XR_KHR_composition_layer_equirect2, 92) \
+ _(XR_EXT_samsung_odyssey_controller, 95) \
+ _(XR_EXT_hp_mixed_reality_controller, 96) \
+ _(XR_MND_swapchain_usage_input_attachment_bit, 97) \
+ _(XR_MSFT_scene_understanding, 98) \
+ _(XR_MSFT_scene_understanding_serialization, 99) \
+ _(XR_FB_display_refresh_rate, 102) \
+ _(XR_HTC_vive_cosmos_controller_interaction, 103) \
+ _(XR_HTCX_vive_tracker_interaction, 104) \
+ _(XR_HTC_facial_tracking, 105) \
+ _(XR_HTC_vive_focus3_controller_interaction, 106) \
+ _(XR_FB_color_space, 109) \
+ _(XR_FB_hand_tracking_mesh, 111) \
+ _(XR_FB_hand_tracking_aim, 112) \
+ _(XR_FB_hand_tracking_capsules, 113) \
+ _(XR_FB_foveation, 115) \
+ _(XR_FB_foveation_configuration, 116) \
+ _(XR_FB_keyboard_tracking, 117) \
+ _(XR_FB_triangle_mesh, 118) \
+ _(XR_FB_passthrough, 119) \
+ _(XR_FB_render_model, 120) \
+ _(XR_KHR_binding_modification, 121) \
+ _(XR_VARJO_foveated_rendering, 122) \
+ _(XR_VARJO_composition_layer_depth_test, 123) \
+ _(XR_VARJO_environment_depth_estimation, 124) \
+ _(XR_VARJO_marker_tracking, 125) \
+ _(XR_MSFT_spatial_anchor_persistence, 143) \
+ _(XR_OCULUS_audio_device_guid, 160) \
+ _(XR_FB_foveation_vulkan, 161) \
+ _(XR_FB_swapchain_update_state_android_surface, 162) \
+ _(XR_FB_swapchain_update_state_opengl_es, 163) \
+ _(XR_FB_swapchain_update_state_vulkan, 164) \
+ _(XR_KHR_swapchain_usage_input_attachment_bit, 166) \
+ _(XR_FB_space_warp, 172) \
+ _(XR_ALMALENCE_digital_lens_control, 197) \
+ _(XR_FB_passthrough_keyboard_hands, 204) \
+ _(XR_EXT_uuid, 300) \
+
+
+#endif
+
diff --git a/thirdparty/openxr/src/.clang-format b/thirdparty/openxr/src/.clang-format
new file mode 100644
index 0000000000..36546cab92
--- /dev/null
+++ b/thirdparty/openxr/src/.clang-format
@@ -0,0 +1,10 @@
+---
+# Copyright (c) 2017-2022, The Khronos Group Inc.
+#
+# SPDX-License-Identifier: Apache-2.0
+# Use defaults from the Google style with the following exceptions:
+BasedOnStyle: Google
+IndentWidth: 4
+ColumnLimit: 132
+SortIncludes: false
+...
diff --git a/thirdparty/openxr/src/common/extra_algorithms.h b/thirdparty/openxr/src/common/extra_algorithms.h
new file mode 100644
index 0000000000..64af4d08ff
--- /dev/null
+++ b/thirdparty/openxr/src/common/extra_algorithms.h
@@ -0,0 +1,47 @@
+// Copyright (c) 2017-2022, The Khronos Group Inc.
+// Copyright (c) 2017-2019 Valve Corporation
+// Copyright (c) 2017-2019 LunarG, Inc.
+// Copyright (c) 2019 Collabora, Ltd.
+//
+// SPDX-License-Identifier: Apache-2.0 OR MIT
+//
+// Initial Author: Ryan Pavlik
+//
+
+/*!
+ * @file
+ *
+ * Additional functions along the lines of the standard library algorithms.
+ */
+
+#pragma once
+
+#include
+#include
+
+/// Like std::remove_if, except it works on associative containers and it actually removes this.
+///
+/// The iterator stuff in here is subtle - .erase() invalidates only that iterator, but it returns a non-invalidated iterator to the
+/// next valid element which we can use instead of incrementing.
+template
+static inline void map_erase_if(T &container, Pred &&predicate) {
+ for (auto it = container.begin(); it != container.end();) {
+ if (predicate(*it)) {
+ it = container.erase(it);
+ } else {
+ ++it;
+ }
+ }
+}
+
+/*!
+ * Moves all elements matching the predicate to the end of the vector then erases them.
+ *
+ * Combines the two parts of the erase-remove idiom to simplify things and avoid accidentally using the wrong erase overload.
+ */
+template
+static inline void vector_remove_if_and_erase(std::vector &vec, Pred &&predicate) {
+ auto b = vec.begin();
+ auto e = vec.end();
+ vec.erase(std::remove_if(b, e, std::forward(predicate)), e);
+}
diff --git a/thirdparty/openxr/src/common/filesystem_utils.cpp b/thirdparty/openxr/src/common/filesystem_utils.cpp
new file mode 100644
index 0000000000..d3d4182fb9
--- /dev/null
+++ b/thirdparty/openxr/src/common/filesystem_utils.cpp
@@ -0,0 +1,322 @@
+// Copyright (c) 2017 The Khronos Group Inc.
+// Copyright (c) 2017 Valve Corporation
+// Copyright (c) 2017 LunarG, Inc.
+//
+// SPDX-License-Identifier: Apache-2.0 OR MIT
+//
+// Initial Authors: Mark Young
+// Nat Brown
+//
+
+#include "filesystem_utils.hpp"
+
+#include "platform_utils.hpp"
+
+#include
+#include
+
+#if defined DISABLE_STD_FILESYSTEM
+#define USE_EXPERIMENTAL_FS 0
+#define USE_FINAL_FS 0
+
+#else
+#include "stdfs_conditions.h"
+#endif
+
+#if USE_FINAL_FS == 1
+#include
+#define FS_PREFIX std::filesystem
+#elif USE_EXPERIMENTAL_FS == 1
+#include
+#define FS_PREFIX std::experimental::filesystem
+#elif defined(XR_USE_PLATFORM_WIN32)
+// Windows fallback includes
+#include
+#include
+#else
+// Linux/Apple fallback includes
+#include
+#include
+#include
+#include
+#include
+#endif
+
+#if defined(XR_USE_PLATFORM_WIN32)
+#define PATH_SEPARATOR ';'
+#define DIRECTORY_SYMBOL '\\'
+#define ALTERNATE_DIRECTORY_SYMBOL '/'
+#else
+#define PATH_SEPARATOR ':'
+#define DIRECTORY_SYMBOL '/'
+#endif
+
+#if (USE_FINAL_FS == 1) || (USE_EXPERIMENTAL_FS == 1)
+// We can use one of the C++ filesystem packages
+
+bool FileSysUtilsIsRegularFile(const std::string& path) { return FS_PREFIX::is_regular_file(path); }
+
+bool FileSysUtilsIsDirectory(const std::string& path) { return FS_PREFIX::is_directory(path); }
+
+bool FileSysUtilsPathExists(const std::string& path) { return FS_PREFIX::exists(path); }
+
+bool FileSysUtilsIsAbsolutePath(const std::string& path) {
+ FS_PREFIX::path file_path(path);
+ return file_path.is_absolute();
+}
+
+bool FileSysUtilsGetCurrentPath(std::string& path) {
+ FS_PREFIX::path cur_path = FS_PREFIX::current_path();
+ path = cur_path.string();
+ return true;
+}
+
+bool FileSysUtilsGetParentPath(const std::string& file_path, std::string& parent_path) {
+ FS_PREFIX::path path_var(file_path);
+ parent_path = path_var.parent_path().string();
+ return true;
+}
+
+bool FileSysUtilsGetAbsolutePath(const std::string& path, std::string& absolute) {
+ absolute = FS_PREFIX::absolute(path).string();
+ return true;
+}
+
+bool FileSysUtilsGetCanonicalPath(const std::string& path, std::string& canonical) {
+#if defined(XR_USE_PLATFORM_WIN32)
+ // std::filesystem::canonical fails on UWP and must be avoided. Further, PathCchCanonicalize is not available on Windows 7 and
+ // PathCanonicalizeW is not available on UWP. However, symbolic links are not important on Windows since the loader uses the
+ // registry for indirection instead, and so this function can be a no-op on Windows.
+ canonical = path;
+#else
+ canonical = FS_PREFIX::canonical(path).string();
+#endif
+ return true;
+}
+
+bool FileSysUtilsCombinePaths(const std::string& parent, const std::string& child, std::string& combined) {
+ FS_PREFIX::path parent_path(parent);
+ FS_PREFIX::path child_path(child);
+ FS_PREFIX::path full_path = parent_path / child_path;
+ combined = full_path.string();
+ return true;
+}
+
+bool FileSysUtilsParsePathList(std::string& path_list, std::vector& paths) {
+ std::string::size_type start = 0;
+ std::string::size_type location = path_list.find(PATH_SEPARATOR);
+ while (location != std::string::npos) {
+ paths.push_back(path_list.substr(start, location));
+ start = location + 1;
+ location = path_list.find(PATH_SEPARATOR, start);
+ }
+ paths.push_back(path_list.substr(start, location));
+ return true;
+}
+
+bool FileSysUtilsFindFilesInPath(const std::string& path, std::vector& files) {
+ for (auto& dir_iter : FS_PREFIX::directory_iterator(path)) {
+ files.push_back(dir_iter.path().filename().string());
+ }
+ return true;
+}
+
+#elif defined(XR_OS_WINDOWS)
+
+// For pre C++17 compiler that doesn't support experimental filesystem
+
+bool FileSysUtilsIsRegularFile(const std::string& path) {
+ const DWORD attr = GetFileAttributesW(utf8_to_wide(path).c_str());
+ return attr != INVALID_FILE_ATTRIBUTES && !(attr & FILE_ATTRIBUTE_DIRECTORY);
+}
+
+bool FileSysUtilsIsDirectory(const std::string& path) {
+ const DWORD attr = GetFileAttributesW(utf8_to_wide(path).c_str());
+ return attr != INVALID_FILE_ATTRIBUTES && (attr & FILE_ATTRIBUTE_DIRECTORY);
+}
+
+bool FileSysUtilsPathExists(const std::string& path) {
+ return (GetFileAttributesW(utf8_to_wide(path).c_str()) != INVALID_FILE_ATTRIBUTES);
+}
+
+bool FileSysUtilsIsAbsolutePath(const std::string& path) {
+ bool pathStartsWithDir = (path.size() >= 1) && ((path[0] == DIRECTORY_SYMBOL) || (path[0] == ALTERNATE_DIRECTORY_SYMBOL));
+
+ bool pathStartsWithDrive =
+ (path.size() >= 3) && (path[1] == ':' && (path[2] == DIRECTORY_SYMBOL || path[2] == ALTERNATE_DIRECTORY_SYMBOL));
+
+ return pathStartsWithDir || pathStartsWithDrive;
+}
+
+bool FileSysUtilsGetCurrentPath(std::string& path) {
+ wchar_t tmp_path[MAX_PATH];
+ if (nullptr != _wgetcwd(tmp_path, MAX_PATH - 1)) {
+ path = wide_to_utf8(tmp_path);
+ return true;
+ }
+ return false;
+}
+
+bool FileSysUtilsGetParentPath(const std::string& file_path, std::string& parent_path) {
+ std::string full_path;
+ if (FileSysUtilsGetAbsolutePath(file_path, full_path)) {
+ std::string::size_type lastSeparator = full_path.find_last_of(DIRECTORY_SYMBOL);
+ parent_path = (lastSeparator == 0) ? full_path : full_path.substr(0, lastSeparator);
+ return true;
+ }
+ return false;
+}
+
+bool FileSysUtilsGetAbsolutePath(const std::string& path, std::string& absolute) {
+ wchar_t tmp_path[MAX_PATH];
+ if (0 != GetFullPathNameW(utf8_to_wide(path).c_str(), MAX_PATH, tmp_path, NULL)) {
+ absolute = wide_to_utf8(tmp_path);
+ return true;
+ }
+ return false;
+}
+
+bool FileSysUtilsGetCanonicalPath(const std::string& path, std::string& absolute) {
+ // PathCchCanonicalize is not available on Windows 7 and PathCanonicalizeW is not available on UWP. However, symbolic links are
+ // not important on Windows since the loader uses the registry for indirection instead, and so this function can be a no-op on
+ // Windows.
+ absolute = path;
+ return true;
+}
+
+bool FileSysUtilsCombinePaths(const std::string& parent, const std::string& child, std::string& combined) {
+ std::string::size_type parent_len = parent.length();
+ if (0 == parent_len || "." == parent || ".\\" == parent || "./" == parent) {
+ combined = child;
+ return true;
+ }
+ char last_char = parent[parent_len - 1];
+ if ((last_char == DIRECTORY_SYMBOL) || (last_char == ALTERNATE_DIRECTORY_SYMBOL)) {
+ parent_len--;
+ }
+ combined = parent.substr(0, parent_len) + DIRECTORY_SYMBOL + child;
+ return true;
+}
+
+bool FileSysUtilsParsePathList(std::string& path_list, std::vector& paths) {
+ std::string::size_type start = 0;
+ std::string::size_type location = path_list.find(PATH_SEPARATOR);
+ while (location != std::string::npos) {
+ paths.push_back(path_list.substr(start, location));
+ start = location + 1;
+ location = path_list.find(PATH_SEPARATOR, start);
+ }
+ paths.push_back(path_list.substr(start, location));
+ return true;
+}
+
+bool FileSysUtilsFindFilesInPath(const std::string& path, std::vector& files) {
+ std::string searchPath;
+ FileSysUtilsCombinePaths(path, "*", searchPath);
+
+ WIN32_FIND_DATAW file_data;
+ HANDLE file_handle = FindFirstFileW(utf8_to_wide(searchPath).c_str(), &file_data);
+ if (file_handle != INVALID_HANDLE_VALUE) {
+ do {
+ if (!(file_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) {
+ files.push_back(wide_to_utf8(file_data.cFileName));
+ }
+ } while (FindNextFileW(file_handle, &file_data));
+ return true;
+ }
+ return false;
+}
+
+#else // XR_OS_LINUX/XR_OS_APPLE fallback
+
+// simple POSIX-compatible implementation of the pieces used by OpenXR
+
+bool FileSysUtilsIsRegularFile(const std::string& path) {
+ struct stat path_stat;
+ stat(path.c_str(), &path_stat);
+ return S_ISREG(path_stat.st_mode);
+}
+
+bool FileSysUtilsIsDirectory(const std::string& path) {
+ struct stat path_stat;
+ stat(path.c_str(), &path_stat);
+ return S_ISDIR(path_stat.st_mode);
+}
+
+bool FileSysUtilsPathExists(const std::string& path) { return (access(path.c_str(), F_OK) != -1); }
+
+bool FileSysUtilsIsAbsolutePath(const std::string& path) { return (path[0] == DIRECTORY_SYMBOL); }
+
+bool FileSysUtilsGetCurrentPath(std::string& path) {
+ char tmp_path[PATH_MAX];
+ if (nullptr != getcwd(tmp_path, PATH_MAX - 1)) {
+ path = tmp_path;
+ return true;
+ }
+ return false;
+}
+
+bool FileSysUtilsGetParentPath(const std::string& file_path, std::string& parent_path) {
+ std::string full_path;
+ if (FileSysUtilsGetAbsolutePath(file_path, full_path)) {
+ std::string::size_type lastSeparator = full_path.find_last_of(DIRECTORY_SYMBOL);
+ parent_path = (lastSeparator == 0) ? full_path : full_path.substr(0, lastSeparator);
+ return true;
+ }
+ return false;
+}
+
+bool FileSysUtilsGetAbsolutePath(const std::string& path, std::string& absolute) {
+ // canonical path is absolute
+ return FileSysUtilsGetCanonicalPath(path, absolute);
+}
+
+bool FileSysUtilsGetCanonicalPath(const std::string& path, std::string& canonical) {
+ char buf[PATH_MAX];
+ if (nullptr != realpath(path.c_str(), buf)) {
+ canonical = buf;
+ return true;
+ }
+ return false;
+}
+
+bool FileSysUtilsCombinePaths(const std::string& parent, const std::string& child, std::string& combined) {
+ std::string::size_type parent_len = parent.length();
+ if (0 == parent_len || "." == parent || "./" == parent) {
+ combined = child;
+ return true;
+ }
+ char last_char = parent[parent_len - 1];
+ if (last_char == DIRECTORY_SYMBOL) {
+ parent_len--;
+ }
+ combined = parent.substr(0, parent_len) + DIRECTORY_SYMBOL + child;
+ return true;
+}
+
+bool FileSysUtilsParsePathList(std::string& path_list, std::vector& paths) {
+ std::string::size_type start = 0;
+ std::string::size_type location = path_list.find(PATH_SEPARATOR);
+ while (location != std::string::npos) {
+ paths.push_back(path_list.substr(start, location));
+ start = location + 1;
+ location = path_list.find(PATH_SEPARATOR, start);
+ }
+ paths.push_back(path_list.substr(start, location));
+ return true;
+}
+
+bool FileSysUtilsFindFilesInPath(const std::string& path, std::vector& files) {
+ DIR* dir = opendir(path.c_str());
+ if (dir == nullptr) {
+ return false;
+ }
+ struct dirent* entry;
+ while ((entry = readdir(dir)) != nullptr) {
+ files.emplace_back(entry->d_name);
+ }
+ closedir(dir);
+ return true;
+}
+
+#endif
diff --git a/thirdparty/openxr/src/common/filesystem_utils.hpp b/thirdparty/openxr/src/common/filesystem_utils.hpp
new file mode 100644
index 0000000000..4a5c987e7b
--- /dev/null
+++ b/thirdparty/openxr/src/common/filesystem_utils.hpp
@@ -0,0 +1,46 @@
+// Copyright (c) 2017 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
+#include
+
+// Determine if the path indicates a regular file (not a directory or symbolic link)
+bool FileSysUtilsIsRegularFile(const std::string& path);
+
+// Determine if the path indicates a directory
+bool FileSysUtilsIsDirectory(const std::string& path);
+
+// Determine if the provided path exists on the filesystem
+bool FileSysUtilsPathExists(const std::string& path);
+
+// Get the current directory
+bool FileSysUtilsGetCurrentPath(std::string& path);
+
+// Get the parent path of a file
+bool FileSysUtilsGetParentPath(const std::string& file_path, std::string& parent_path);
+
+// Determine if the provided path is an absolute path
+bool FileSysUtilsIsAbsolutePath(const std::string& path);
+
+// Get the absolute path for a provided file
+bool FileSysUtilsGetAbsolutePath(const std::string& path, std::string& absolute);
+
+// Get the absolute path for a provided file
+bool FileSysUtilsGetCanonicalPath(const std::string& path, std::string& canonical);
+
+// Combine a parent and child directory
+bool FileSysUtilsCombinePaths(const std::string& parent, const std::string& child, std::string& combined);
+
+// Parse out individual paths in a path list
+bool FileSysUtilsParsePathList(std::string& path_list, std::vector& paths);
+
+// Record all the filenames for files found in the provided path.
+bool FileSysUtilsFindFilesInPath(const std::string& path, std::vector& files);
diff --git a/thirdparty/openxr/src/common/hex_and_handles.h b/thirdparty/openxr/src/common/hex_and_handles.h
new file mode 100644
index 0000000000..341013d32b
--- /dev/null
+++ b/thirdparty/openxr/src/common/hex_and_handles.h
@@ -0,0 +1,108 @@
+// Copyright (c) 2017-2022, The Khronos Group Inc.
+// Copyright (c) 2017-2019 Valve Corporation
+// Copyright (c) 2017-2019 LunarG, Inc.
+// Copyright (c) 2019 Collabora, Ltd.
+//
+// SPDX-License-Identifier: Apache-2.0 OR MIT
+//
+// Initial Author: Ryan Pavlik
+//
+
+/*!
+ * @file
+ *
+ * Some utilities, primarily for working with OpenXR handles in a generic way.
+ */
+
+#pragma once
+
+#include
+
+#include
+#include
+
+inline std::string to_hex(const uint8_t* const data, size_t bytes) {
+ std::string out(2 + bytes * 2, '?');
+ out[0] = '0';
+ out[1] = 'x';
+ static const char* hex = "0123456789abcdef";
+ auto ch = out.end();
+ for (size_t i = 0; i < bytes; ++i) {
+ auto b = data[i];
+ *--ch = hex[(b >> 0) & 0xf];
+ *--ch = hex[(b >> 4) & 0xf];
+ }
+ return out;
+}
+
+template
+inline std::string to_hex(const T& data) {
+ return to_hex(reinterpret_cast(&data), sizeof(data));
+}
+
+#if XR_PTR_SIZE == 8
+/// Convert a handle into a same-sized integer.
+template
+static inline uint64_t MakeHandleGeneric(T handle) {
+ return reinterpret_cast(handle);
+}
+
+/// Treat an integer as a handle
+template
+static inline T& TreatIntegerAsHandle(uint64_t& handle) {
+ return reinterpret_cast(handle);
+}
+
+/// @overload
+template
+static inline T const& TreatIntegerAsHandle(uint64_t const& handle) {
+ return reinterpret_cast(handle);
+}
+
+/// Does a correctly-sized integer represent a null handle?
+static inline bool IsIntegerNullHandle(uint64_t handle) { return XR_NULL_HANDLE == reinterpret_cast(handle); }
+
+#else
+
+/// Convert a handle into a same-sized integer: no-op on 32-bit systems
+static inline uint64_t MakeHandleGeneric(uint64_t handle) { return handle; }
+
+/// Treat an integer as a handle: no-op on 32-bit systems
+template
+static inline T& TreatIntegerAsHandle(uint64_t& handle) {
+ return handle;
+}
+
+/// @overload
+template
+static inline T const& TreatIntegerAsHandle(uint64_t const& handle) {
+ return handle;
+}
+
+/// Does a correctly-sized integer represent a null handle?
+static inline bool IsIntegerNullHandle(uint64_t handle) { return XR_NULL_HANDLE == handle; }
+
+#endif
+
+/// Turns a uint64_t into a string formatted as hex.
+///
+/// The core of the HandleToHexString implementation is in here.
+inline std::string Uint64ToHexString(uint64_t val) { return to_hex(val); }
+
+/// Turns a uint32_t into a string formatted as hex.
+inline std::string Uint32ToHexString(uint32_t val) { return to_hex(val); }
+
+/// Turns an OpenXR handle into a string formatted as hex.
+template
+inline std::string HandleToHexString(T handle) {
+ return to_hex(handle);
+}
+
+/// Turns a pointer-sized integer into a string formatted as hex.
+inline std::string UintptrToHexString(uintptr_t val) { return to_hex(val); }
+
+/// Convert a pointer to a string formatted as hex.
+template
+inline std::string PointerToHexString(T const* ptr) {
+ return to_hex(ptr);
+}
diff --git a/thirdparty/openxr/src/common/loader_interfaces.h b/thirdparty/openxr/src/common/loader_interfaces.h
new file mode 100644
index 0000000000..9c74ed16f3
--- /dev/null
+++ b/thirdparty/openxr/src/common/loader_interfaces.h
@@ -0,0 +1,114 @@
+// Copyright (c) 2017-2022, 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/thirdparty/openxr/src/common/object_info.cpp b/thirdparty/openxr/src/common/object_info.cpp
new file mode 100644
index 0000000000..95b5aaf404
--- /dev/null
+++ b/thirdparty/openxr/src/common/object_info.cpp
@@ -0,0 +1,276 @@
+// Copyright (c) 2017-2022, The Khronos Group Inc.
+// Copyright (c) 2017-2019 Valve Corporation
+// Copyright (c) 2017-2019 LunarG, Inc.
+// Copyright (c) 2019 Collabora, Ltd.
+//
+// SPDX-License-Identifier: Apache-2.0 OR MIT
+//
+// Initial Authors: Mark Young
+// Ryan Pavlik
+// Dave Houlton
+//
+
+#include "object_info.h"
+
+#include "extra_algorithms.h"
+#include "hex_and_handles.h"
+
+#include
+
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include "memory.h"
+
+std::string XrSdkLogObjectInfo::ToString() const {
+ std::ostringstream oss;
+ oss << Uint64ToHexString(handle);
+ if (!name.empty()) {
+ oss << " (" << name << ")";
+ }
+ return oss.str();
+}
+
+void ObjectInfoCollection::AddObjectName(uint64_t object_handle, XrObjectType object_type, const std::string& object_name) {
+ // If name is empty, we should erase it
+ if (object_name.empty()) {
+ RemoveObject(object_handle, object_type);
+ return;
+ }
+
+ // Otherwise, add it or update the name
+ XrSdkLogObjectInfo new_obj = {object_handle, object_type};
+
+ // If it already exists, update the name
+ auto lookup_info = LookUpStoredObjectInfo(new_obj);
+ if (lookup_info != nullptr) {
+ lookup_info->name = object_name;
+ return;
+ }
+
+ // It doesn't exist, so add a new info block
+ new_obj.name = object_name;
+ object_info_.push_back(new_obj);
+}
+
+void ObjectInfoCollection::RemoveObject(uint64_t object_handle, XrObjectType object_type) {
+ vector_remove_if_and_erase(
+ object_info_, [=](XrSdkLogObjectInfo const& info) { return info.handle == object_handle && info.type == object_type; });
+}
+
+XrSdkLogObjectInfo const* ObjectInfoCollection::LookUpStoredObjectInfo(XrSdkLogObjectInfo const& info) const {
+ auto e = object_info_.end();
+ auto it = std::find_if(object_info_.begin(), e, [&](XrSdkLogObjectInfo const& stored) { return Equivalent(stored, info); });
+ if (it != e) {
+ return &(*it);
+ }
+ return nullptr;
+}
+
+XrSdkLogObjectInfo* ObjectInfoCollection::LookUpStoredObjectInfo(XrSdkLogObjectInfo const& info) {
+ auto e = object_info_.end();
+ auto it = std::find_if(object_info_.begin(), e, [&](XrSdkLogObjectInfo const& stored) { return Equivalent(stored, info); });
+ if (it != e) {
+ return &(*it);
+ }
+ return nullptr;
+}
+
+bool ObjectInfoCollection::LookUpObjectName(XrDebugUtilsObjectNameInfoEXT& info) const {
+ auto info_lookup = LookUpStoredObjectInfo(info.objectHandle, info.objectType);
+ if (info_lookup != nullptr) {
+ info.objectName = info_lookup->name.c_str();
+ return true;
+ }
+ return false;
+}
+
+bool ObjectInfoCollection::LookUpObjectName(XrSdkLogObjectInfo& info) const {
+ auto info_lookup = LookUpStoredObjectInfo(info);
+ if (info_lookup != nullptr) {
+ info.name = info_lookup->name;
+ return true;
+ }
+ return false;
+}
+
+static std::vector PopulateObjectNameInfo(std::vector const& obj) {
+ std::vector ret;
+ ret.reserve(obj.size());
+ std::transform(obj.begin(), obj.end(), std::back_inserter(ret), [](XrSdkLogObjectInfo const& info) {
+ return XrDebugUtilsObjectNameInfoEXT{XR_TYPE_DEBUG_UTILS_OBJECT_NAME_INFO_EXT, nullptr, info.type, info.handle,
+ info.name.c_str()};
+ });
+ return ret;
+}
+
+NamesAndLabels::NamesAndLabels(std::vector obj, std::vector lab)
+ : sdk_objects(std::move(obj)), objects(PopulateObjectNameInfo(sdk_objects)), labels(std::move(lab)) {}
+
+void NamesAndLabels::PopulateCallbackData(XrDebugUtilsMessengerCallbackDataEXT& callback_data) const {
+ callback_data.objects = objects.empty() ? nullptr : const_cast(objects.data());
+ callback_data.objectCount = static_cast(objects.size());
+ callback_data.sessionLabels = labels.empty() ? nullptr : const_cast(labels.data());
+ callback_data.sessionLabelCount = static_cast(labels.size());
+}
+
+void DebugUtilsData::LookUpSessionLabels(XrSession session, std::vector& labels) const {
+ auto session_label_iterator = session_labels_.find(session);
+ if (session_label_iterator != session_labels_.end()) {
+ auto& XrSdkSessionLabels = *session_label_iterator->second;
+ // Copy the debug utils labels in reverse order in the the labels vector.
+ std::transform(XrSdkSessionLabels.rbegin(), XrSdkSessionLabels.rend(), std::back_inserter(labels),
+ [](XrSdkSessionLabelPtr const& label) { return label->debug_utils_label; });
+ }
+}
+
+XrSdkSessionLabel::XrSdkSessionLabel(const XrDebugUtilsLabelEXT& label_info, bool individual)
+ : label_name(label_info.labelName), debug_utils_label(label_info), is_individual_label(individual) {
+ // Update the c string pointer to the one we hold.
+ debug_utils_label.labelName = label_name.c_str();
+}
+
+XrSdkSessionLabelPtr XrSdkSessionLabel::make(const XrDebugUtilsLabelEXT& label_info, bool individual) {
+ XrSdkSessionLabelPtr ret(new XrSdkSessionLabel(label_info, individual));
+ return ret;
+}
+void DebugUtilsData::AddObjectName(uint64_t object_handle, XrObjectType object_type, const std::string& object_name) {
+ object_info_.AddObjectName(object_handle, object_type, object_name);
+}
+
+// We always want to remove the old individual label before we do anything else.
+// So, do that in it's own method
+void DebugUtilsData::RemoveIndividualLabel(XrSdkSessionLabelList& label_vec) {
+ if (!label_vec.empty() && label_vec.back()->is_individual_label) {
+ label_vec.pop_back();
+ }
+}
+
+XrSdkSessionLabelList* DebugUtilsData::GetSessionLabelList(XrSession session) {
+ auto session_label_iterator = session_labels_.find(session);
+ if (session_label_iterator == session_labels_.end()) {
+ return nullptr;
+ }
+ return session_label_iterator->second.get();
+}
+
+XrSdkSessionLabelList& DebugUtilsData::GetOrCreateSessionLabelList(XrSession session) {
+ XrSdkSessionLabelList* vec_ptr = GetSessionLabelList(session);
+ if (vec_ptr == nullptr) {
+ std::unique_ptr vec(new XrSdkSessionLabelList);
+ vec_ptr = vec.get();
+ session_labels_[session] = std::move(vec);
+ }
+ return *vec_ptr;
+}
+
+void DebugUtilsData::BeginLabelRegion(XrSession session, const XrDebugUtilsLabelEXT& label_info) {
+ auto& vec = GetOrCreateSessionLabelList(session);
+
+ // Individual labels do not stay around in the transition into a new label region
+ RemoveIndividualLabel(vec);
+
+ // Start the new label region
+ vec.emplace_back(XrSdkSessionLabel::make(label_info, false));
+}
+
+void DebugUtilsData::EndLabelRegion(XrSession session) {
+ XrSdkSessionLabelList* vec_ptr = GetSessionLabelList(session);
+ if (vec_ptr == nullptr) {
+ return;
+ }
+
+ // Individual labels do not stay around in the transition out of label region
+ RemoveIndividualLabel(*vec_ptr);
+
+ // Remove the last label region
+ if (!vec_ptr->empty()) {
+ vec_ptr->pop_back();
+ }
+}
+
+void DebugUtilsData::InsertLabel(XrSession session, const XrDebugUtilsLabelEXT& label_info) {
+ auto& vec = GetOrCreateSessionLabelList(session);
+
+ // Remove any individual layer that might already be there
+ RemoveIndividualLabel(vec);
+
+ // Insert a new individual label
+ vec.emplace_back(XrSdkSessionLabel::make(label_info, true));
+}
+
+void DebugUtilsData::DeleteObject(uint64_t object_handle, XrObjectType object_type) {
+ object_info_.RemoveObject(object_handle, object_type);
+
+ if (object_type == XR_OBJECT_TYPE_SESSION) {
+ auto session = TreatIntegerAsHandle(object_handle);
+ XrSdkSessionLabelList* vec_ptr = GetSessionLabelList(session);
+ if (vec_ptr != nullptr) {
+ session_labels_.erase(session);
+ }
+ }
+}
+
+void DebugUtilsData::DeleteSessionLabels(XrSession session) { session_labels_.erase(session); }
+
+NamesAndLabels DebugUtilsData::PopulateNamesAndLabels(std::vector objects) const {
+ std::vector labels;
+ for (auto& obj : objects) {
+ // Check for any names that have been associated with the objects and set them up here
+ object_info_.LookUpObjectName(obj);
+ // If this is a session, see if there are any labels associated with it for us to add
+ // to the callback content.
+ if (XR_OBJECT_TYPE_SESSION == obj.type) {
+ LookUpSessionLabels(obj.GetTypedHandle(), labels);
+ }
+ }
+
+ return {objects, labels};
+}
+
+void DebugUtilsData::WrapCallbackData(AugmentedCallbackData* aug_data,
+ const XrDebugUtilsMessengerCallbackDataEXT* callback_data) const {
+ // If there's nothing to add, just return the original data as the augmented copy
+ aug_data->exported_data = callback_data;
+ if (object_info_.Empty() || callback_data->objectCount == 0) {
+ return;
+ }
+
+ // Inspect each of the callback objects
+ bool name_found = false;
+ for (uint32_t obj = 0; obj < callback_data->objectCount; ++obj) {
+ auto& current_obj = callback_data->objects[obj];
+ name_found |= (nullptr != object_info_.LookUpStoredObjectInfo(current_obj.objectHandle, current_obj.objectType));
+
+ // If this is a session, record any labels associated with it
+ if (XR_OBJECT_TYPE_SESSION == current_obj.objectType) {
+ XrSession session = TreatIntegerAsHandle(current_obj.objectHandle);
+ LookUpSessionLabels(session, aug_data->labels);
+ }
+ }
+
+ // If we found nothing to add, return the original data
+ if (!name_found && aug_data->labels.empty()) {
+ return;
+ }
+
+ // Found additional data - modify an internal copy and return that as the exported data
+ memcpy(&aug_data->modified_data, callback_data, sizeof(XrDebugUtilsMessengerCallbackDataEXT));
+ aug_data->new_objects.assign(callback_data->objects, callback_data->objects + callback_data->objectCount);
+
+ // Record (overwrite) the names of all incoming objects provided in our internal list
+ for (auto& obj : aug_data->new_objects) {
+ object_info_.LookUpObjectName(obj);
+ }
+
+ // Update local copy & point export to it
+ aug_data->modified_data.objects = aug_data->new_objects.data();
+ aug_data->modified_data.sessionLabelCount = static_cast(aug_data->labels.size());
+ aug_data->modified_data.sessionLabels = aug_data->labels.empty() ? nullptr : aug_data->labels.data();
+ aug_data->exported_data = &aug_data->modified_data;
+ return;
+}
diff --git a/thirdparty/openxr/src/common/object_info.h b/thirdparty/openxr/src/common/object_info.h
new file mode 100644
index 0000000000..8e9742b605
--- /dev/null
+++ b/thirdparty/openxr/src/common/object_info.h
@@ -0,0 +1,229 @@
+// Copyright (c) 2017-2022, The Khronos Group Inc.
+// Copyright (c) 2017-2019 Valve Corporation
+// Copyright (c) 2017-2019 LunarG, Inc.
+// Copyright (c) 2019 Collabora, Ltd.
+//
+// SPDX-License-Identifier: Apache-2.0 OR MIT
+//
+// Initial Authors: Mark Young , Ryan Pavlik
+
+#include
+#include
+#include
+#include
+
+struct XrSdkGenericObject {
+ //! Type-erased handle value
+ uint64_t handle;
+
+ //! Kind of object this handle refers to
+ XrObjectType type;
+ /// Un-erase the type of the handle and get it properly typed again.
+ ///
+ /// Note: Does not check the type before doing it!
+ template
+ HandleType& GetTypedHandle() {
+ return TreatIntegerAsHandle(handle);
+ }
+
+ //! @overload
+ template
+ HandleType const& GetTypedHandle() const {
+ return TreatIntegerAsHandle(handle);
+ }
+
+ //! Create from a typed handle and object type
+ template
+ XrSdkGenericObject(T h, XrObjectType t) : handle(MakeHandleGeneric(h)), type(t) {}
+
+ //! Create from an untyped handle value (integer) and object type
+ XrSdkGenericObject(uint64_t h, XrObjectType t) : handle(h), type(t) {}
+};
+
+struct XrSdkLogObjectInfo {
+ //! Type-erased handle value
+ uint64_t handle;
+
+ //! Kind of object this handle refers to
+ XrObjectType type;
+
+ //! To be assigned by the application - not part of this object's identity
+ std::string name;
+
+ /// Un-erase the type of the handle and get it properly typed again.
+ ///
+ /// Note: Does not check the type before doing it!
+ template
+ HandleType& GetTypedHandle() {
+ return TreatIntegerAsHandle(handle);
+ }
+
+ //! @overload
+ template
+ HandleType const& GetTypedHandle() const {
+ return TreatIntegerAsHandle(handle);
+ }
+
+ XrSdkLogObjectInfo() = default;
+
+ //! Create from a typed handle and object type
+ template
+ XrSdkLogObjectInfo(T h, XrObjectType t) : handle(MakeHandleGeneric(h)), type(t) {}
+
+ //! Create from an untyped handle value (integer) and object type
+ XrSdkLogObjectInfo(uint64_t h, XrObjectType t) : handle(h), type(t) {}
+ //! Create from an untyped handle value (integer), object type, and name
+ XrSdkLogObjectInfo(uint64_t h, XrObjectType t, const char* n) : handle(h), type(t), name(n == nullptr ? "" : n) {}
+
+ std::string ToString() const;
+};
+
+//! True if the two object infos have the same handle value and handle type
+static inline bool Equivalent(XrSdkLogObjectInfo const& a, XrSdkLogObjectInfo const& b) {
+ return a.handle == b.handle && a.type == b.type;
+}
+
+//! @overload
+static inline bool Equivalent(XrDebugUtilsObjectNameInfoEXT const& a, XrSdkLogObjectInfo const& b) {
+ return a.objectHandle == b.handle && a.objectType == b.type;
+}
+
+//! @overload
+static inline bool Equivalent(XrSdkLogObjectInfo const& a, XrDebugUtilsObjectNameInfoEXT const& b) { return Equivalent(b, a); }
+
+/// Object info registered with calls to xrSetDebugUtilsObjectNameEXT
+class ObjectInfoCollection {
+ public:
+ void AddObjectName(uint64_t object_handle, XrObjectType object_type, const std::string& object_name);
+
+ void RemoveObject(uint64_t object_handle, XrObjectType object_type);
+
+ //! Find the stored object info, if any, matching handle and type.
+ //! Return nullptr if not found.
+ XrSdkLogObjectInfo const* LookUpStoredObjectInfo(XrSdkLogObjectInfo const& info) const;
+
+ //! Find the stored object info, if any, matching handle and type.
+ //! Return nullptr if not found.
+ XrSdkLogObjectInfo* LookUpStoredObjectInfo(XrSdkLogObjectInfo const& info);
+
+ //! Find the stored object info, if any.
+ //! Return nullptr if not found.
+ XrSdkLogObjectInfo const* LookUpStoredObjectInfo(uint64_t handle, XrObjectType type) const {
+ return LookUpStoredObjectInfo({handle, type});
+ }
+
+ //! Find the object name, if any, and update debug utils info accordingly.
+ //! Return true if found and updated.
+ bool LookUpObjectName(XrDebugUtilsObjectNameInfoEXT& info) const;
+
+ //! Find the object name, if any, and update logging info accordingly.
+ //! Return true if found and updated.
+ bool LookUpObjectName(XrSdkLogObjectInfo& info) const;
+
+ //! Is the collection empty?
+ bool Empty() const { return object_info_.empty(); }
+
+ private:
+ // Object names that have been set for given objects
+ std::vector object_info_;
+};
+
+struct XrSdkSessionLabel;
+using XrSdkSessionLabelPtr = std::unique_ptr;
+using XrSdkSessionLabelList = std::vector;
+
+struct XrSdkSessionLabel {
+ static XrSdkSessionLabelPtr make(const XrDebugUtilsLabelEXT& label_info, bool individual);
+
+ std::string label_name;
+ XrDebugUtilsLabelEXT debug_utils_label;
+ bool is_individual_label;
+
+ private:
+ XrSdkSessionLabel(const XrDebugUtilsLabelEXT& label_info, bool individual);
+};
+
+/// The metadata for a collection of objects. Must persist unmodified during the entire debug messenger call!
+struct NamesAndLabels {
+ NamesAndLabels() = default;
+ NamesAndLabels(std::vector obj, std::vector lab);
+ /// C++ structure owning the data (strings) backing the objects vector.
+ std::vector sdk_objects;
+
+ std::vector objects;
+ std::vector labels;
+
+ /// Populate the debug utils callback data structure.
+ void PopulateCallbackData(XrDebugUtilsMessengerCallbackDataEXT& data) const;
+ // XrDebugUtilsMessengerCallbackDataEXT MakeCallbackData() const;
+};
+
+struct AugmentedCallbackData {
+ std::vector labels;
+ std::vector new_objects;
+ XrDebugUtilsMessengerCallbackDataEXT modified_data;
+ const XrDebugUtilsMessengerCallbackDataEXT* exported_data;
+};
+
+/// Tracks all the data (handle names and session labels) required to fully augment XR_EXT_debug_utils-related calls.
+class DebugUtilsData {
+ public:
+ DebugUtilsData() = default;
+
+ DebugUtilsData(const DebugUtilsData&) = delete;
+ DebugUtilsData& operator=(const DebugUtilsData&) = delete;
+
+ bool Empty() const { return object_info_.Empty() && session_labels_.empty(); }
+
+ //! Core of implementation for xrSetDebugUtilsObjectNameEXT
+ void AddObjectName(uint64_t object_handle, XrObjectType object_type, const std::string& object_name);
+
+ /// Core of implementation for xrSessionBeginDebugUtilsLabelRegionEXT
+ void BeginLabelRegion(XrSession session, const XrDebugUtilsLabelEXT& label_info);
+
+ /// Core of implementation for xrSessionEndDebugUtilsLabelRegionEXT
+ void EndLabelRegion(XrSession session);
+
+ /// Core of implementation for xrSessionInsertDebugUtilsLabelEXT
+ void InsertLabel(XrSession session, const XrDebugUtilsLabelEXT& label_info);
+
+ /// Removes all labels associated with a session - call in xrDestroySession and xrDestroyInstance (for all child sessions)
+ void DeleteSessionLabels(XrSession session);
+
+ /// Retrieve labels for the given session, if any, and push them in reverse order on the vector.
+ void LookUpSessionLabels(XrSession session, std::vector& labels) const;
+
+ /// Removes all data related to this object - including session labels if it's a session.
+ ///
+ /// Does not take care of handling child objects - you must do this yourself.
+ void DeleteObject(uint64_t object_handle, XrObjectType object_type);
+
+ /// Given the collection of objects, populate their names and list of labels
+ NamesAndLabels PopulateNamesAndLabels(std::vector objects) const;
+
+ void WrapCallbackData(AugmentedCallbackData* aug_data,
+ const XrDebugUtilsMessengerCallbackDataEXT* provided_callback_data) const;
+
+ private:
+ void RemoveIndividualLabel(XrSdkSessionLabelList& label_vec);
+ XrSdkSessionLabelList* GetSessionLabelList(XrSession session);
+ XrSdkSessionLabelList& GetOrCreateSessionLabelList(XrSession session);
+
+ // Session labels: one vector of them per session.
+ std::unordered_map> session_labels_;
+
+ // Names for objects.
+ ObjectInfoCollection object_info_;
+};
diff --git a/thirdparty/openxr/src/common/platform_utils.hpp b/thirdparty/openxr/src/common/platform_utils.hpp
new file mode 100644
index 0000000000..85d5cdab10
--- /dev/null
+++ b/thirdparty/openxr/src/common/platform_utils.hpp
@@ -0,0 +1,345 @@
+// Copyright (c) 2017-2022, The Khronos Group Inc.
+// Copyright (c) 2017-2019 Valve Corporation
+// Copyright (c) 2017-2019 LunarG, Inc.
+//
+// SPDX-License-Identifier: Apache-2.0 OR MIT
+//
+// Initial Authors: Mark Young , Dave Houlton
+//
+
+#pragma once
+
+#include "xr_dependencies.h"
+#include ]