Browse Source

Add OpenXR 1.1 support

Bastiaan Olij 4 months ago
parent
commit
c0bc43d1de
88 changed files with 639 additions and 252 deletions
  1. 8 0
      misc/extension_api_validation/4.5-stable.expected
  2. 12 12
      modules/openxr/action_map/openxr_action_map.cpp
  3. 9 2
      modules/openxr/action_map/openxr_interaction_profile.cpp
  4. 38 18
      modules/openxr/action_map/openxr_interaction_profile_metadata.cpp
  5. 13 8
      modules/openxr/action_map/openxr_interaction_profile_metadata.h
  6. 6 0
      modules/openxr/doc_classes/OpenXRAPIExtension.xml
  7. 5 3
      modules/openxr/doc_classes/OpenXRExtensionWrapper.xml
  8. 15 7
      modules/openxr/doc_classes/OpenXRInteractionProfileMetadata.xml
  9. 15 6
      modules/openxr/editor/openxr_interaction_profile_editor.cpp
  10. 7 3
      modules/openxr/editor/openxr_select_interaction_profile_dialog.cpp
  11. 1 1
      modules/openxr/extensions/openxr_android_thread_settings_extension.cpp
  12. 1 1
      modules/openxr/extensions/openxr_android_thread_settings_extension.h
  13. 1 1
      modules/openxr/extensions/openxr_composition_layer_depth_extension.cpp
  14. 1 1
      modules/openxr/extensions/openxr_composition_layer_depth_extension.h
  15. 1 1
      modules/openxr/extensions/openxr_composition_layer_extension.cpp
  16. 1 1
      modules/openxr/extensions/openxr_composition_layer_extension.h
  17. 1 1
      modules/openxr/extensions/openxr_debug_utils_extension.cpp
  18. 1 1
      modules/openxr/extensions/openxr_debug_utils_extension.h
  19. 1 1
      modules/openxr/extensions/openxr_dpad_binding_extension.cpp
  20. 1 1
      modules/openxr/extensions/openxr_dpad_binding_extension.h
  21. 28 6
      modules/openxr/extensions/openxr_extension_wrapper.cpp
  22. 12 4
      modules/openxr/extensions/openxr_extension_wrapper.h
  23. 1 1
      modules/openxr/extensions/openxr_eye_gaze_interaction.cpp
  24. 1 1
      modules/openxr/extensions/openxr_eye_gaze_interaction.h
  25. 1 1
      modules/openxr/extensions/openxr_fb_display_refresh_rate_extension.cpp
  26. 1 1
      modules/openxr/extensions/openxr_fb_display_refresh_rate_extension.h
  27. 1 1
      modules/openxr/extensions/openxr_fb_foveation_extension.cpp
  28. 1 1
      modules/openxr/extensions/openxr_fb_foveation_extension.h
  29. 1 1
      modules/openxr/extensions/openxr_fb_update_swapchain_extension.cpp
  30. 1 1
      modules/openxr/extensions/openxr_fb_update_swapchain_extension.h
  31. 1 1
      modules/openxr/extensions/openxr_frame_synthesis_extension.cpp
  32. 1 1
      modules/openxr/extensions/openxr_frame_synthesis_extension.h
  33. 1 1
      modules/openxr/extensions/openxr_future_extension.cpp
  34. 1 1
      modules/openxr/extensions/openxr_future_extension.h
  35. 3 2
      modules/openxr/extensions/openxr_hand_interaction_extension.cpp
  36. 1 1
      modules/openxr/extensions/openxr_hand_interaction_extension.h
  37. 1 1
      modules/openxr/extensions/openxr_hand_tracking_extension.cpp
  38. 1 1
      modules/openxr/extensions/openxr_hand_tracking_extension.h
  39. 12 7
      modules/openxr/extensions/openxr_htc_controller_extension.cpp
  40. 1 1
      modules/openxr/extensions/openxr_htc_controller_extension.h
  41. 1 1
      modules/openxr/extensions/openxr_htc_vive_tracker_extension.cpp
  42. 1 1
      modules/openxr/extensions/openxr_htc_vive_tracker_extension.h
  43. 3 1
      modules/openxr/extensions/openxr_huawei_controller_extension.cpp
  44. 1 1
      modules/openxr/extensions/openxr_huawei_controller_extension.h
  45. 7 2
      modules/openxr/extensions/openxr_local_floor_extension.cpp
  46. 1 1
      modules/openxr/extensions/openxr_local_floor_extension.h
  47. 134 26
      modules/openxr/extensions/openxr_meta_controller_extension.cpp
  48. 1 1
      modules/openxr/extensions/openxr_meta_controller_extension.h
  49. 7 3
      modules/openxr/extensions/openxr_ml2_controller_extension.cpp
  50. 1 1
      modules/openxr/extensions/openxr_ml2_controller_extension.h
  51. 1 1
      modules/openxr/extensions/openxr_mxink_extension.cpp
  52. 1 1
      modules/openxr/extensions/openxr_mxink_extension.h
  53. 7 2
      modules/openxr/extensions/openxr_palm_pose_extension.cpp
  54. 1 1
      modules/openxr/extensions/openxr_palm_pose_extension.h
  55. 1 1
      modules/openxr/extensions/openxr_performance_settings_extension.cpp
  56. 1 1
      modules/openxr/extensions/openxr_performance_settings_extension.h
  57. 13 8
      modules/openxr/extensions/openxr_pico_controller_extension.cpp
  58. 1 1
      modules/openxr/extensions/openxr_pico_controller_extension.h
  59. 5 2
      modules/openxr/extensions/openxr_render_model_extension.cpp
  60. 1 1
      modules/openxr/extensions/openxr_render_model_extension.h
  61. 1 1
      modules/openxr/extensions/openxr_valve_analog_threshold_extension.cpp
  62. 1 1
      modules/openxr/extensions/openxr_valve_analog_threshold_extension.h
  63. 1 1
      modules/openxr/extensions/openxr_visibility_mask_extension.cpp
  64. 1 1
      modules/openxr/extensions/openxr_visibility_mask_extension.h
  65. 12 8
      modules/openxr/extensions/openxr_wmr_controller_extension.cpp
  66. 1 1
      modules/openxr/extensions/openxr_wmr_controller_extension.h
  67. 2 2
      modules/openxr/extensions/platform/openxr_android_extension.cpp
  68. 2 2
      modules/openxr/extensions/platform/openxr_android_extension.h
  69. 1 1
      modules/openxr/extensions/platform/openxr_d3d12_extension.cpp
  70. 1 1
      modules/openxr/extensions/platform/openxr_d3d12_extension.h
  71. 1 1
      modules/openxr/extensions/platform/openxr_metal_extension.h
  72. 1 1
      modules/openxr/extensions/platform/openxr_metal_extension.mm
  73. 1 1
      modules/openxr/extensions/platform/openxr_opengl_extension.cpp
  74. 1 1
      modules/openxr/extensions/platform/openxr_opengl_extension.h
  75. 1 1
      modules/openxr/extensions/platform/openxr_vulkan_extension.cpp
  76. 1 1
      modules/openxr/extensions/platform/openxr_vulkan_extension.h
  77. 1 1
      modules/openxr/extensions/spatial_entities/openxr_spatial_anchor.cpp
  78. 1 1
      modules/openxr/extensions/spatial_entities/openxr_spatial_anchor.h
  79. 1 1
      modules/openxr/extensions/spatial_entities/openxr_spatial_entity_extension.cpp
  80. 1 1
      modules/openxr/extensions/spatial_entities/openxr_spatial_entity_extension.h
  81. 1 1
      modules/openxr/extensions/spatial_entities/openxr_spatial_marker_tracking.cpp
  82. 1 1
      modules/openxr/extensions/spatial_entities/openxr_spatial_marker_tracking.h
  83. 1 1
      modules/openxr/extensions/spatial_entities/openxr_spatial_plane_tracking.cpp
  84. 1 1
      modules/openxr/extensions/spatial_entities/openxr_spatial_plane_tracking.h
  85. 177 55
      modules/openxr/openxr_api.cpp
  86. 20 3
      modules/openxr/openxr_api.h
  87. 6 0
      modules/openxr/openxr_api_extension.cpp
  88. 1 0
      modules/openxr/openxr_api_extension.h

+ 8 - 0
misc/extension_api_validation/4.5-stable.expected

@@ -128,3 +128,11 @@ Validate extension JSON: Error: Field 'builtin_classes/PackedVector3Array/method
 Validate extension JSON: Error: Field 'builtin_classes/PackedVector4Array/methods/bsearch': is_const changed value in new API, from false to true.
 Validate extension JSON: Error: Field 'builtin_classes/PackedVector4Array/methods/bsearch': is_const changed value in new API, from false to true.
 
 
 bsearch method made const. Compatibility methods registered.
 bsearch method made const. Compatibility methods registered.
+
+
+GH-109302
+---------
+
+Validate extension JSON: Error: Field 'classes/OpenXRExtensionWrapper/methods/_set_instance_create_info_and_get_next_pointer/arguments': size changed value in new API, from 1 to 2.
+Validate extension JSON: Error: Field 'classes/OpenXRExtensionWrapper/methods/_set_instance_create_info_and_get_next_pointer/arguments/0': type changed value in new API, from "void*" to "int".
+Validate extension JSON: JSON file: Field was added in a way that breaks compatibility 'classes/OpenXRExtensionWrapper/methods/_get_requested_extensions': arguments

+ 12 - 12
modules/openxr/action_map/openxr_action_map.cpp

@@ -261,7 +261,7 @@ void OpenXRActionMap::create_default_action_sets() {
 	profile->add_new_binding(default_pose, "/user/hand/left/input/aim/pose,/user/hand/right/input/aim/pose");
 	profile->add_new_binding(default_pose, "/user/hand/left/input/aim/pose,/user/hand/right/input/aim/pose");
 	profile->add_new_binding(aim_pose, "/user/hand/left/input/aim/pose,/user/hand/right/input/aim/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(grip_pose, "/user/hand/left/input/grip/pose,/user/hand/right/input/grip/pose");
-	profile->add_new_binding(palm_pose, "/user/hand/left/input/palm_ext/pose,/user/hand/right/input/palm_ext/pose");
+	profile->add_new_binding(palm_pose, "/user/hand/left/input/grip_surface/pose,/user/hand/right/input/grip_surface/pose");
 	profile->add_new_binding(menu_button, "/user/hand/left/input/menu/click,/user/hand/right/input/menu/click");
 	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");
 	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.
 	// generic has no support for triggers, grip, A/B buttons, nor joystick/trackpad inputs.
@@ -273,7 +273,7 @@ void OpenXRActionMap::create_default_action_sets() {
 	profile->add_new_binding(default_pose, "/user/hand/left/input/aim/pose,/user/hand/right/input/aim/pose");
 	profile->add_new_binding(default_pose, "/user/hand/left/input/aim/pose,/user/hand/right/input/aim/pose");
 	profile->add_new_binding(aim_pose, "/user/hand/left/input/aim/pose,/user/hand/right/input/aim/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(grip_pose, "/user/hand/left/input/grip/pose,/user/hand/right/input/grip/pose");
-	profile->add_new_binding(palm_pose, "/user/hand/left/input/palm_ext/pose,/user/hand/right/input/palm_ext/pose");
+	profile->add_new_binding(palm_pose, "/user/hand/left/input/grip_surface/pose,/user/hand/right/input/grip_surface/pose");
 	profile->add_new_binding(menu_button, "/user/hand/left/input/menu/click,/user/hand/right/input/menu/click");
 	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");
 	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.
 	// wmr controller has no a/b/x/y buttons.
@@ -294,7 +294,7 @@ void OpenXRActionMap::create_default_action_sets() {
 	profile->add_new_binding(default_pose, "/user/hand/left/input/aim/pose,/user/hand/right/input/aim/pose");
 	profile->add_new_binding(default_pose, "/user/hand/left/input/aim/pose,/user/hand/right/input/aim/pose");
 	profile->add_new_binding(aim_pose, "/user/hand/left/input/aim/pose,/user/hand/right/input/aim/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(grip_pose, "/user/hand/left/input/grip/pose,/user/hand/right/input/grip/pose");
-	profile->add_new_binding(palm_pose, "/user/hand/left/input/palm_ext/pose,/user/hand/right/input/palm_ext/pose");
+	profile->add_new_binding(palm_pose, "/user/hand/left/input/grip_surface/pose,/user/hand/right/input/grip_surface/pose");
 	// wmr controllers have no select button we can use.
 	// 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");
 	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.
 	// wmr controller has no a/b/x/y buttons.
@@ -317,7 +317,7 @@ void OpenXRActionMap::create_default_action_sets() {
 	profile->add_new_binding(default_pose, "/user/hand/left/input/aim/pose,/user/hand/right/input/aim/pose");
 	profile->add_new_binding(default_pose, "/user/hand/left/input/aim/pose,/user/hand/right/input/aim/pose");
 	profile->add_new_binding(aim_pose, "/user/hand/left/input/aim/pose,/user/hand/right/input/aim/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(grip_pose, "/user/hand/left/input/grip/pose,/user/hand/right/input/grip/pose");
-	profile->add_new_binding(palm_pose, "/user/hand/left/input/palm_ext/pose,/user/hand/right/input/palm_ext/pose");
+	profile->add_new_binding(palm_pose, "/user/hand/left/input/grip_surface/pose,/user/hand/right/input/grip_surface/pose");
 	// touch controllers have no select button we can use.
 	// 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(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_button, "/user/hand/left/input/x/click,/user/hand/right/input/a/click"); // x on left hand, a on right hand.
@@ -342,7 +342,7 @@ void OpenXRActionMap::create_default_action_sets() {
 	profile->add_new_binding(default_pose, "/user/hand/left/input/aim/pose,/user/hand/right/input/aim/pose");
 	profile->add_new_binding(default_pose, "/user/hand/left/input/aim/pose,/user/hand/right/input/aim/pose");
 	profile->add_new_binding(aim_pose, "/user/hand/left/input/aim/pose,/user/hand/right/input/aim/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(grip_pose, "/user/hand/left/input/grip/pose,/user/hand/right/input/grip/pose");
-	profile->add_new_binding(palm_pose, "/user/hand/left/input/palm_ext/pose,/user/hand/right/input/palm_ext/pose");
+	profile->add_new_binding(palm_pose, "/user/hand/left/input/grip_surface/pose,/user/hand/right/input/grip_surface/pose");
 	profile->add_new_binding(select_button, "/user/hand/left/input/system/click,/user/hand/right/input/system/click"); // system click may not be available.
 	profile->add_new_binding(select_button, "/user/hand/left/input/system/click,/user/hand/right/input/system/click"); // system click may not be available.
 	profile->add_new_binding(menu_button, "/user/hand/left/input/menu/click");
 	profile->add_new_binding(menu_button, "/user/hand/left/input/menu/click");
 	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_button, "/user/hand/left/input/x/click,/user/hand/right/input/a/click"); // x on left hand, a on right hand.
@@ -367,7 +367,7 @@ void OpenXRActionMap::create_default_action_sets() {
 	profile->add_new_binding(default_pose, "/user/hand/left/input/aim/pose,/user/hand/right/input/aim/pose");
 	profile->add_new_binding(default_pose, "/user/hand/left/input/aim/pose,/user/hand/right/input/aim/pose");
 	profile->add_new_binding(aim_pose, "/user/hand/left/input/aim/pose,/user/hand/right/input/aim/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(grip_pose, "/user/hand/left/input/grip/pose,/user/hand/right/input/grip/pose");
-	profile->add_new_binding(palm_pose, "/user/hand/left/input/palm_ext/pose,/user/hand/right/input/palm_ext/pose");
+	profile->add_new_binding(palm_pose, "/user/hand/left/input/grip_surface/pose,/user/hand/right/input/grip_surface/pose");
 	// index controllers have no select button we can use.
 	// 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(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_button, "/user/hand/left/input/a/click,/user/hand/right/input/a/click"); // a on both controllers.
@@ -396,7 +396,7 @@ void OpenXRActionMap::create_default_action_sets() {
 	profile->add_new_binding(default_pose, "/user/hand/left/input/aim/pose,/user/hand/right/input/aim/pose");
 	profile->add_new_binding(default_pose, "/user/hand/left/input/aim/pose,/user/hand/right/input/aim/pose");
 	profile->add_new_binding(aim_pose, "/user/hand/left/input/aim/pose,/user/hand/right/input/aim/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(grip_pose, "/user/hand/left/input/grip/pose,/user/hand/right/input/grip/pose");
-	profile->add_new_binding(palm_pose, "/user/hand/left/input/palm_ext/pose,/user/hand/right/input/palm_ext/pose");
+	profile->add_new_binding(palm_pose, "/user/hand/left/input/grip_surface/pose,/user/hand/right/input/grip_surface/pose");
 	// hpmr controllers have no select button we can use.
 	// 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");
 	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.
 	// hpmr controllers only register click, not touch, on our a/b/x/y buttons.
@@ -419,7 +419,7 @@ void OpenXRActionMap::create_default_action_sets() {
 	profile->add_new_binding(default_pose, "/user/hand/left/input/aim/pose,/user/hand/right/input/aim/pose");
 	profile->add_new_binding(default_pose, "/user/hand/left/input/aim/pose,/user/hand/right/input/aim/pose");
 	profile->add_new_binding(aim_pose, "/user/hand/left/input/aim/pose,/user/hand/right/input/aim/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(grip_pose, "/user/hand/left/input/grip/pose,/user/hand/right/input/grip/pose");
-	profile->add_new_binding(palm_pose, "/user/hand/left/input/palm_ext/pose,/user/hand/right/input/palm_ext/pose");
+	profile->add_new_binding(palm_pose, "/user/hand/left/input/grip_surface/pose,/user/hand/right/input/grip_surface/pose");
 	// Odyssey controllers have no select button we can use.
 	// Odyssey 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");
 	profile->add_new_binding(menu_button, "/user/hand/left/input/menu/click,/user/hand/right/input/menu/click");
 	// Odyssey controller has no a/b/x/y buttons.
 	// Odyssey controller has no a/b/x/y buttons.
@@ -442,7 +442,7 @@ void OpenXRActionMap::create_default_action_sets() {
 	profile->add_new_binding(default_pose, "/user/hand/left/input/aim/pose,/user/hand/right/input/aim/pose");
 	profile->add_new_binding(default_pose, "/user/hand/left/input/aim/pose,/user/hand/right/input/aim/pose");
 	profile->add_new_binding(aim_pose, "/user/hand/left/input/aim/pose,/user/hand/right/input/aim/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(grip_pose, "/user/hand/left/input/grip/pose,/user/hand/right/input/grip/pose");
-	profile->add_new_binding(palm_pose, "/user/hand/left/input/palm_ext/pose,/user/hand/right/input/palm_ext/pose");
+	profile->add_new_binding(palm_pose, "/user/hand/left/input/grip_surface/pose,/user/hand/right/input/grip_surface/pose");
 	profile->add_new_binding(menu_button, "/user/hand/left/input/menu/click");
 	profile->add_new_binding(menu_button, "/user/hand/left/input/menu/click");
 	profile->add_new_binding(select_button, "/user/hand/right/input/system/click"); // we'll map system to select.
 	profile->add_new_binding(select_button, "/user/hand/right/input/system/click"); // we'll map system to select.
 	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_button, "/user/hand/left/input/x/click,/user/hand/right/input/a/click"); // x on left hand, a on right hand.
@@ -466,7 +466,7 @@ void OpenXRActionMap::create_default_action_sets() {
 	profile->add_new_binding(default_pose, "/user/hand/left/input/aim/pose,/user/hand/right/input/aim/pose");
 	profile->add_new_binding(default_pose, "/user/hand/left/input/aim/pose,/user/hand/right/input/aim/pose");
 	profile->add_new_binding(aim_pose, "/user/hand/left/input/aim/pose,/user/hand/right/input/aim/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(grip_pose, "/user/hand/left/input/grip/pose,/user/hand/right/input/grip/pose");
-	profile->add_new_binding(palm_pose, "/user/hand/left/input/palm_ext/pose,/user/hand/right/input/palm_ext/pose");
+	profile->add_new_binding(palm_pose, "/user/hand/left/input/grip_surface/pose,/user/hand/right/input/grip_surface/pose");
 	profile->add_new_binding(menu_button, "/user/hand/left/input/menu/click");
 	profile->add_new_binding(menu_button, "/user/hand/left/input/menu/click");
 	profile->add_new_binding(select_button, "/user/hand/right/input/system/click"); // we'll map system to select.
 	profile->add_new_binding(select_button, "/user/hand/right/input/system/click"); // we'll map system to select.
 	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_button, "/user/hand/left/input/x/click,/user/hand/right/input/a/click"); // x on left hand, a on right hand.
@@ -490,7 +490,7 @@ void OpenXRActionMap::create_default_action_sets() {
 	profile->add_new_binding(default_pose, "/user/hand/left/input/aim/pose,/user/hand/right/input/aim/pose");
 	profile->add_new_binding(default_pose, "/user/hand/left/input/aim/pose,/user/hand/right/input/aim/pose");
 	profile->add_new_binding(aim_pose, "/user/hand/left/input/aim/pose,/user/hand/right/input/aim/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(grip_pose, "/user/hand/left/input/grip/pose,/user/hand/right/input/grip/pose");
-	profile->add_new_binding(palm_pose, "/user/hand/left/input/palm_ext/pose,/user/hand/right/input/palm_ext/pose");
+	profile->add_new_binding(palm_pose, "/user/hand/left/input/grip_surface/pose,/user/hand/right/input/grip_surface/pose");
 	profile->add_new_binding(menu_button, "/user/hand/left/input/home/click,/user/hand/right/input/home/click");
 	profile->add_new_binding(menu_button, "/user/hand/left/input/home/click,/user/hand/right/input/home/click");
 	profile->add_new_binding(trigger, "/user/hand/left/input/trigger/value,/user/hand/right/input/trigger/value");
 	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_click, "/user/hand/left/input/trigger/click,/user/hand/right/input/trigger/click");
@@ -551,7 +551,7 @@ void OpenXRActionMap::create_default_action_sets() {
 	profile->add_new_binding(default_pose, "/user/hand/left/input/aim/pose,/user/hand/right/input/aim/pose");
 	profile->add_new_binding(default_pose, "/user/hand/left/input/aim/pose,/user/hand/right/input/aim/pose");
 	profile->add_new_binding(aim_pose, "/user/hand/left/input/aim/pose,/user/hand/right/input/aim/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(grip_pose, "/user/hand/left/input/grip/pose,/user/hand/right/input/grip/pose");
-	profile->add_new_binding(palm_pose, "/user/hand/left/input/palm_ext/pose,/user/hand/right/input/palm_ext/pose");
+	profile->add_new_binding(palm_pose, "/user/hand/left/input/grip_surface/pose,/user/hand/right/input/grip_surface/pose");
 
 
 	// Use pinch as primary.
 	// Use pinch as primary.
 	profile->add_new_binding(primary, "/user/hand/left/input/pinch_ext/value,/user/hand/right/input/pinch_ext/value");
 	profile->add_new_binding(primary, "/user/hand/left/input/pinch_ext/value,/user/hand/right/input/pinch_ext/value");

+ 9 - 2
modules/openxr/action_map/openxr_interaction_profile.cpp

@@ -79,7 +79,14 @@ Ref<OpenXRAction> OpenXRIPBinding::get_action() const {
 }
 }
 
 
 void OpenXRIPBinding::set_binding_path(const String &p_path) {
 void OpenXRIPBinding::set_binding_path(const String &p_path) {
-	binding_path = p_path;
+	OpenXRInteractionProfileMetadata *pmd = OpenXRInteractionProfileMetadata::get_singleton();
+	if (pmd) {
+		binding_path = pmd->check_path_name(p_path);
+	} else {
+		// OpenXR not enabled, ignore checks.
+		binding_path = p_path;
+	}
+
 	emit_changed();
 	emit_changed();
 }
 }
 
 
@@ -244,7 +251,7 @@ void OpenXRInteractionProfile::set_interaction_profile_path(const String &p_inpu
 	if (pmd) {
 	if (pmd) {
 		interaction_profile_path = pmd->check_profile_name(p_input_profile_path);
 		interaction_profile_path = pmd->check_profile_name(p_input_profile_path);
 	} else {
 	} else {
-		// OpenXR module not enabled, ignore checks.
+		// OpenXR not enabled, ignore checks.
 		interaction_profile_path = p_input_profile_path;
 		interaction_profile_path = p_input_profile_path;
 	}
 	}
 	emit_changed();
 	emit_changed();

+ 38 - 18
modules/openxr/action_map/openxr_interaction_profile_metadata.cpp

@@ -47,9 +47,10 @@ OpenXRInteractionProfileMetadata::~OpenXRInteractionProfileMetadata() {
 
 
 void OpenXRInteractionProfileMetadata::_bind_methods() {
 void OpenXRInteractionProfileMetadata::_bind_methods() {
 	ClassDB::bind_method(D_METHOD("register_profile_rename", "old_name", "new_name"), &OpenXRInteractionProfileMetadata::register_profile_rename);
 	ClassDB::bind_method(D_METHOD("register_profile_rename", "old_name", "new_name"), &OpenXRInteractionProfileMetadata::register_profile_rename);
-	ClassDB::bind_method(D_METHOD("register_top_level_path", "display_name", "openxr_path", "openxr_extension_name"), &OpenXRInteractionProfileMetadata::register_top_level_path);
-	ClassDB::bind_method(D_METHOD("register_interaction_profile", "display_name", "openxr_path", "openxr_extension_name"), &OpenXRInteractionProfileMetadata::register_interaction_profile);
-	ClassDB::bind_method(D_METHOD("register_io_path", "interaction_profile", "display_name", "toplevel_path", "openxr_path", "openxr_extension_name", "action_type"), &OpenXRInteractionProfileMetadata::register_io_path);
+	ClassDB::bind_method(D_METHOD("register_path_rename", "old_name", "new_name"), &OpenXRInteractionProfileMetadata::register_path_rename);
+	ClassDB::bind_method(D_METHOD("register_top_level_path", "display_name", "openxr_path", "openxr_extension_names"), &OpenXRInteractionProfileMetadata::register_top_level_path);
+	ClassDB::bind_method(D_METHOD("register_interaction_profile", "display_name", "openxr_path", "openxr_extension_names"), &OpenXRInteractionProfileMetadata::register_interaction_profile);
+	ClassDB::bind_method(D_METHOD("register_io_path", "interaction_profile", "display_name", "toplevel_path", "openxr_path", "openxr_extension_names", "action_type"), &OpenXRInteractionProfileMetadata::register_io_path);
 }
 }
 
 
 void OpenXRInteractionProfileMetadata::register_profile_rename(const String &p_old_name, const String &p_new_name) {
 void OpenXRInteractionProfileMetadata::register_profile_rename(const String &p_old_name, const String &p_new_name) {
@@ -66,30 +67,44 @@ String OpenXRInteractionProfileMetadata::check_profile_name(const String &p_name
 	return p_name;
 	return p_name;
 }
 }
 
 
-void OpenXRInteractionProfileMetadata::register_top_level_path(const String &p_display_name, const String &p_openxr_path, const String &p_openxr_extension_name) {
+void OpenXRInteractionProfileMetadata::register_path_rename(const String &p_old_name, const String &p_new_name) {
+	ERR_FAIL_COND(path_renames.has(p_old_name));
+
+	path_renames[p_old_name] = p_new_name;
+}
+
+String OpenXRInteractionProfileMetadata::check_path_name(const String &p_name) const {
+	if (path_renames.has(p_name)) {
+		return path_renames[p_name];
+	}
+
+	return p_name;
+}
+
+void OpenXRInteractionProfileMetadata::register_top_level_path(const String &p_display_name, const String &p_openxr_path, const String &p_openxr_extension_names) {
 	ERR_FAIL_COND_MSG(has_top_level_path(p_openxr_path), p_openxr_path + " had already been registered");
 	ERR_FAIL_COND_MSG(has_top_level_path(p_openxr_path), p_openxr_path + " had already been registered");
 
 
 	TopLevelPath new_toplevel_path = {
 	TopLevelPath new_toplevel_path = {
 		p_display_name,
 		p_display_name,
 		p_openxr_path,
 		p_openxr_path,
-		p_openxr_extension_name
+		p_openxr_extension_names
 	};
 	};
 
 
 	top_level_paths.push_back(new_toplevel_path);
 	top_level_paths.push_back(new_toplevel_path);
 }
 }
 
 
-void OpenXRInteractionProfileMetadata::register_interaction_profile(const String &p_display_name, const String &p_openxr_path, const String &p_openxr_extension_name) {
+void OpenXRInteractionProfileMetadata::register_interaction_profile(const String &p_display_name, const String &p_openxr_path, const String &p_openxr_extension_names) {
 	ERR_FAIL_COND_MSG(has_interaction_profile(p_openxr_path), p_openxr_path + " has already been registered");
 	ERR_FAIL_COND_MSG(has_interaction_profile(p_openxr_path), p_openxr_path + " has already been registered");
 
 
 	InteractionProfile new_profile;
 	InteractionProfile new_profile;
 	new_profile.display_name = p_display_name;
 	new_profile.display_name = p_display_name;
 	new_profile.openxr_path = p_openxr_path;
 	new_profile.openxr_path = p_openxr_path;
-	new_profile.openxr_extension_name = p_openxr_extension_name;
+	new_profile.openxr_extension_names = p_openxr_extension_names;
 
 
 	interaction_profiles.push_back(new_profile);
 	interaction_profiles.push_back(new_profile);
 }
 }
 
 
-void OpenXRInteractionProfileMetadata::register_io_path(const String &p_interaction_profile, const String &p_display_name, const String &p_toplevel_path, const String &p_openxr_path, const String &p_openxr_extension_name, OpenXRAction::ActionType p_action_type) {
+void OpenXRInteractionProfileMetadata::register_io_path(const String &p_interaction_profile, const String &p_display_name, const String &p_toplevel_path, const String &p_openxr_path, const String &p_openxr_extension_names, OpenXRAction::ActionType p_action_type) {
 	ERR_FAIL_COND_MSG(!has_interaction_profile(p_interaction_profile), "Unknown interaction profile " + p_interaction_profile);
 	ERR_FAIL_COND_MSG(!has_interaction_profile(p_interaction_profile), "Unknown interaction profile " + p_interaction_profile);
 	ERR_FAIL_COND_MSG(!has_top_level_path(p_toplevel_path), "Unknown top level path " + p_toplevel_path);
 	ERR_FAIL_COND_MSG(!has_top_level_path(p_toplevel_path), "Unknown top level path " + p_toplevel_path);
 
 
@@ -101,7 +116,7 @@ void OpenXRInteractionProfileMetadata::register_io_path(const String &p_interact
 				p_display_name,
 				p_display_name,
 				p_toplevel_path,
 				p_toplevel_path,
 				p_openxr_path,
 				p_openxr_path,
-				p_openxr_extension_name,
+				p_openxr_extension_names,
 				p_action_type
 				p_action_type
 			};
 			};
 
 
@@ -130,10 +145,10 @@ String OpenXRInteractionProfileMetadata::get_top_level_name(const String &p_open
 	return String();
 	return String();
 }
 }
 
 
-String OpenXRInteractionProfileMetadata::get_top_level_extension(const String &p_openxr_path) const {
+String OpenXRInteractionProfileMetadata::get_top_level_extensions(const String &p_openxr_path) const {
 	for (int i = 0; i < top_level_paths.size(); i++) {
 	for (int i = 0; i < top_level_paths.size(); i++) {
 		if (top_level_paths[i].openxr_path == p_openxr_path) {
 		if (top_level_paths[i].openxr_path == p_openxr_path) {
-			return top_level_paths[i].openxr_extension_name;
+			return top_level_paths[i].openxr_extension_names;
 		}
 		}
 	}
 	}
 
 
@@ -150,10 +165,10 @@ bool OpenXRInteractionProfileMetadata::has_interaction_profile(const String &p_o
 	return false;
 	return false;
 }
 }
 
 
-String OpenXRInteractionProfileMetadata::get_interaction_profile_extension(const String &p_openxr_path) const {
+String OpenXRInteractionProfileMetadata::get_interaction_profile_extensions(const String &p_openxr_path) const {
 	for (const InteractionProfile &interaction_profile : interaction_profiles) {
 	for (const InteractionProfile &interaction_profile : interaction_profiles) {
 		if (interaction_profile.openxr_path == p_openxr_path) {
 		if (interaction_profile.openxr_path == p_openxr_path) {
-			return interaction_profile.openxr_extension_name;
+			return interaction_profile.openxr_extension_names;
 		}
 		}
 	}
 	}
 
 
@@ -218,6 +233,11 @@ void OpenXRInteractionProfileMetadata::_register_core_metadata() {
 
 
 	// Note that we'll make an exception for XR_EXT_palm_pose, which is used everywhere
 	// Note that we'll make an exception for XR_EXT_palm_pose, which is used everywhere
 
 
+	// OpenXR 1.1 uses various new names.
+	// We use the new names in our action map and translate back IF OpenXR 1.1 is not supported.
+	register_path_rename("/user/hand/left/input/palm_ext/pose", "/user/hand/left/input/grip_surface/pose");
+	register_path_rename("/user/hand/right/input/palm_ext/pose", "/user/hand/right/input/grip_surface/pose");
+
 	// Our core toplevel paths
 	// Our core toplevel paths
 	register_top_level_path("Left hand controller", "/user/hand/left", "");
 	register_top_level_path("Left hand controller", "/user/hand/left", "");
 	register_top_level_path("Right hand controller", "/user/hand/right", "");
 	register_top_level_path("Right hand controller", "/user/hand/right", "");
@@ -231,7 +251,7 @@ void OpenXRInteractionProfileMetadata::_register_core_metadata() {
 		for (const String user_path : { "/user/hand/left", "/user/hand/right" }) {
 		for (const String user_path : { "/user/hand/left", "/user/hand/right" }) {
 			register_io_path(profile_path, "Grip pose", user_path, user_path + "/input/grip/pose", "", OpenXRAction::OPENXR_ACTION_POSE);
 			register_io_path(profile_path, "Grip pose", user_path, user_path + "/input/grip/pose", "", OpenXRAction::OPENXR_ACTION_POSE);
 			register_io_path(profile_path, "Aim pose", user_path, user_path + "/input/aim/pose", "", OpenXRAction::OPENXR_ACTION_POSE);
 			register_io_path(profile_path, "Aim pose", user_path, user_path + "/input/aim/pose", "", OpenXRAction::OPENXR_ACTION_POSE);
-			register_io_path(profile_path, "Palm pose", user_path, user_path + "/input/palm_ext/pose", XR_EXT_PALM_POSE_EXTENSION_NAME, OpenXRAction::OPENXR_ACTION_POSE);
+			register_io_path(profile_path, "Grip surface pose", user_path, user_path + "/input/grip_surface/pose", XR_EXT_PALM_POSE_EXTENSION_NAME "," XR_KHR_MAINTENANCE1_EXTENSION_NAME "," XR_OPENXR_1_1_NAME, OpenXRAction::OPENXR_ACTION_POSE);
 
 
 			register_io_path(profile_path, "Menu click", user_path, user_path + "/input/menu/click", "", OpenXRAction::OPENXR_ACTION_BOOL);
 			register_io_path(profile_path, "Menu click", user_path, user_path + "/input/menu/click", "", OpenXRAction::OPENXR_ACTION_BOOL);
 			register_io_path(profile_path, "Select click", user_path, user_path + "/input/select/click", "", OpenXRAction::OPENXR_ACTION_BOOL);
 			register_io_path(profile_path, "Select click", user_path, user_path + "/input/select/click", "", OpenXRAction::OPENXR_ACTION_BOOL);
@@ -246,7 +266,7 @@ void OpenXRInteractionProfileMetadata::_register_core_metadata() {
 		for (const String user_path : { "/user/hand/left", "/user/hand/right" }) {
 		for (const String user_path : { "/user/hand/left", "/user/hand/right" }) {
 			register_io_path(profile_path, "Grip pose", user_path, user_path + "/input/grip/pose", "", OpenXRAction::OPENXR_ACTION_POSE);
 			register_io_path(profile_path, "Grip pose", user_path, user_path + "/input/grip/pose", "", OpenXRAction::OPENXR_ACTION_POSE);
 			register_io_path(profile_path, "Aim pose", user_path, user_path + "/input/aim/pose", "", OpenXRAction::OPENXR_ACTION_POSE);
 			register_io_path(profile_path, "Aim pose", user_path, user_path + "/input/aim/pose", "", OpenXRAction::OPENXR_ACTION_POSE);
-			register_io_path(profile_path, "Palm pose", user_path, user_path + "/input/palm_ext/pose", XR_EXT_PALM_POSE_EXTENSION_NAME, OpenXRAction::OPENXR_ACTION_POSE);
+			register_io_path(profile_path, "Grip surface pose", user_path, user_path + "/input/grip_surface/pose", XR_EXT_PALM_POSE_EXTENSION_NAME "," XR_KHR_MAINTENANCE1_EXTENSION_NAME "," XR_OPENXR_1_1_NAME, OpenXRAction::OPENXR_ACTION_POSE);
 
 
 			register_io_path(profile_path, "Menu click", user_path, user_path + "/input/menu/click", "", OpenXRAction::OPENXR_ACTION_BOOL);
 			register_io_path(profile_path, "Menu click", user_path, user_path + "/input/menu/click", "", OpenXRAction::OPENXR_ACTION_BOOL);
 			register_io_path(profile_path, "System click", user_path, user_path + "/input/system/click", "", OpenXRAction::OPENXR_ACTION_BOOL);
 			register_io_path(profile_path, "System click", user_path, user_path + "/input/system/click", "", OpenXRAction::OPENXR_ACTION_BOOL);
@@ -275,7 +295,7 @@ void OpenXRInteractionProfileMetadata::_register_core_metadata() {
 		for (const String user_path : { "/user/hand/left", "/user/hand/right" }) {
 		for (const String user_path : { "/user/hand/left", "/user/hand/right" }) {
 			register_io_path(profile_path, "Grip pose", user_path, user_path + "/input/grip/pose", "", OpenXRAction::OPENXR_ACTION_POSE);
 			register_io_path(profile_path, "Grip pose", user_path, user_path + "/input/grip/pose", "", OpenXRAction::OPENXR_ACTION_POSE);
 			register_io_path(profile_path, "Aim pose", user_path, user_path + "/input/aim/pose", "", OpenXRAction::OPENXR_ACTION_POSE);
 			register_io_path(profile_path, "Aim pose", user_path, user_path + "/input/aim/pose", "", OpenXRAction::OPENXR_ACTION_POSE);
-			register_io_path(profile_path, "Palm pose", user_path, user_path + "/input/palm_ext/pose", XR_EXT_PALM_POSE_EXTENSION_NAME, OpenXRAction::OPENXR_ACTION_POSE);
+			register_io_path(profile_path, "Grip surface pose", user_path, user_path + "/input/grip_surface/pose", XR_EXT_PALM_POSE_EXTENSION_NAME "," XR_KHR_MAINTENANCE1_EXTENSION_NAME "," XR_OPENXR_1_1_NAME, OpenXRAction::OPENXR_ACTION_POSE);
 
 
 			register_io_path(profile_path, "Menu click", user_path, user_path + "/input/menu/click", "", OpenXRAction::OPENXR_ACTION_BOOL);
 			register_io_path(profile_path, "Menu click", user_path, user_path + "/input/menu/click", "", OpenXRAction::OPENXR_ACTION_BOOL);
 
 
@@ -310,7 +330,7 @@ void OpenXRInteractionProfileMetadata::_register_core_metadata() {
 		for (const String user_path : { "/user/hand/left", "/user/hand/right" }) {
 		for (const String user_path : { "/user/hand/left", "/user/hand/right" }) {
 			register_io_path(profile_path, "Grip pose", user_path, user_path + "/input/grip/pose", "", OpenXRAction::OPENXR_ACTION_POSE);
 			register_io_path(profile_path, "Grip pose", user_path, user_path + "/input/grip/pose", "", OpenXRAction::OPENXR_ACTION_POSE);
 			register_io_path(profile_path, "Aim pose", user_path, user_path + "/input/aim/pose", "", OpenXRAction::OPENXR_ACTION_POSE);
 			register_io_path(profile_path, "Aim pose", user_path, user_path + "/input/aim/pose", "", OpenXRAction::OPENXR_ACTION_POSE);
-			register_io_path(profile_path, "Palm pose", user_path, user_path + "/input/palm_ext/pose", XR_EXT_PALM_POSE_EXTENSION_NAME, OpenXRAction::OPENXR_ACTION_POSE);
+			register_io_path(profile_path, "Grip surface pose", user_path, user_path + "/input/grip_surface/pose", XR_EXT_PALM_POSE_EXTENSION_NAME "," XR_KHR_MAINTENANCE1_EXTENSION_NAME "," XR_OPENXR_1_1_NAME, OpenXRAction::OPENXR_ACTION_POSE);
 
 
 			register_io_path(profile_path, "Trigger", user_path, user_path + "/input/trigger/value", "", OpenXRAction::OPENXR_ACTION_FLOAT);
 			register_io_path(profile_path, "Trigger", user_path, user_path + "/input/trigger/value", "", OpenXRAction::OPENXR_ACTION_FLOAT);
 			register_io_path(profile_path, "Trigger touch", user_path, user_path + "/input/trigger/touch", "", OpenXRAction::OPENXR_ACTION_BOOL);
 			register_io_path(profile_path, "Trigger touch", user_path, user_path + "/input/trigger/touch", "", OpenXRAction::OPENXR_ACTION_BOOL);
@@ -349,7 +369,7 @@ void OpenXRInteractionProfileMetadata::_register_core_metadata() {
 		for (const String user_path : { "/user/hand/left", "/user/hand/right" }) {
 		for (const String user_path : { "/user/hand/left", "/user/hand/right" }) {
 			register_io_path(profile_path, "Grip pose", user_path, user_path + "/input/grip/pose", "", OpenXRAction::OPENXR_ACTION_POSE);
 			register_io_path(profile_path, "Grip pose", user_path, user_path + "/input/grip/pose", "", OpenXRAction::OPENXR_ACTION_POSE);
 			register_io_path(profile_path, "Aim pose", user_path, user_path + "/input/aim/pose", "", OpenXRAction::OPENXR_ACTION_POSE);
 			register_io_path(profile_path, "Aim pose", user_path, user_path + "/input/aim/pose", "", OpenXRAction::OPENXR_ACTION_POSE);
-			register_io_path(profile_path, "Palm pose", user_path, user_path + "/input/palm_ext/pose", XR_EXT_PALM_POSE_EXTENSION_NAME, OpenXRAction::OPENXR_ACTION_POSE);
+			register_io_path(profile_path, "Grip surface pose", user_path, user_path + "/input/grip_surface/pose", XR_EXT_PALM_POSE_EXTENSION_NAME "," XR_KHR_MAINTENANCE1_EXTENSION_NAME "," XR_OPENXR_1_1_NAME, OpenXRAction::OPENXR_ACTION_POSE);
 
 
 			register_io_path(profile_path, "System click", user_path, user_path + "/input/system/click", "", OpenXRAction::OPENXR_ACTION_BOOL);
 			register_io_path(profile_path, "System click", user_path, user_path + "/input/system/click", "", OpenXRAction::OPENXR_ACTION_BOOL);
 
 

+ 13 - 8
modules/openxr/action_map/openxr_interaction_profile_metadata.h

@@ -64,21 +64,21 @@ public:
 	struct TopLevelPath {
 	struct TopLevelPath {
 		String display_name; // User friendly display name (i.e. Left controller)
 		String display_name; // User friendly display name (i.e. Left controller)
 		String openxr_path; // Path in OpenXR (i.e. /user/hand/left)
 		String openxr_path; // Path in OpenXR (i.e. /user/hand/left)
-		String openxr_extension_name; // If set, only available if extension is enabled (i.e. XR_HTCX_vive_tracker_interaction)
+		String openxr_extension_names; // If set, only available if extension is enabled (i.e. XR_HTCX_vive_tracker_interaction)
 	};
 	};
 
 
 	struct IOPath {
 	struct IOPath {
 		String display_name; // User friendly display name (i.e. Grip pose (left controller))
 		String display_name; // User friendly display name (i.e. Grip pose (left controller))
 		String top_level_path; // Top level path identifying the usage of the device in relation to this input/output
 		String top_level_path; // Top level path identifying the usage of the device in relation to this input/output
 		String openxr_path; // Path in OpenXR (i.e. /user/hand/left/input/grip/pose)
 		String openxr_path; // Path in OpenXR (i.e. /user/hand/left/input/grip/pose)
-		String openxr_extension_name; // If set, only available if extension is enabled (i.e. XR_EXT_palm_pose)
+		String openxr_extension_names; // If set, only available if extension is enabled (i.e. XR_EXT_palm_pose)
 		OpenXRAction::ActionType action_type; // Type of input/output
 		OpenXRAction::ActionType action_type; // Type of input/output
 	};
 	};
 
 
 	struct InteractionProfile {
 	struct InteractionProfile {
 		String display_name; // User friendly display name (i.e. Simple controller)
 		String display_name; // User friendly display name (i.e. Simple controller)
 		String openxr_path; // Path in OpenXR (i.e. /interaction_profiles/khr/simple_controller)
 		String openxr_path; // Path in OpenXR (i.e. /interaction_profiles/khr/simple_controller)
-		String openxr_extension_name; // If set, only available if extension is enabled (i.e. XR_HTCX_vive_tracker_interaction)
+		String openxr_extension_names; // If set, only available if extension is enabled (i.e. XR_HTCX_vive_tracker_interaction)
 		Vector<IOPath> io_paths; // Inputs and outputs for this device
 		Vector<IOPath> io_paths; // Inputs and outputs for this device
 
 
 		bool has_io_path(const String &p_io_path) const;
 		bool has_io_path(const String &p_io_path) const;
@@ -89,6 +89,8 @@ private:
 	static OpenXRInteractionProfileMetadata *singleton;
 	static OpenXRInteractionProfileMetadata *singleton;
 
 
 	HashMap<String, String> profile_renames;
 	HashMap<String, String> profile_renames;
+	HashMap<String, String> path_renames;
+
 	Vector<TopLevelPath> top_level_paths;
 	Vector<TopLevelPath> top_level_paths;
 	Vector<InteractionProfile> interaction_profiles;
 	Vector<InteractionProfile> interaction_profiles;
 
 
@@ -106,17 +108,20 @@ public:
 	void register_profile_rename(const String &p_old_name, const String &p_new_name);
 	void register_profile_rename(const String &p_old_name, const String &p_new_name);
 	String check_profile_name(const String &p_name) const;
 	String check_profile_name(const String &p_name) const;
 
 
-	void register_top_level_path(const String &p_display_name, const String &p_openxr_path, const String &p_openxr_extension_name);
+	void register_path_rename(const String &p_old_name, const String &p_new_name);
+	String check_path_name(const String &p_name) const;
+
+	void register_top_level_path(const String &p_display_name, const String &p_openxr_path, const String &p_openxr_extension_names);
 	bool has_top_level_path(const String &p_openxr_path) const;
 	bool has_top_level_path(const String &p_openxr_path) const;
 	String get_top_level_name(const String &p_openxr_path) const;
 	String get_top_level_name(const String &p_openxr_path) const;
-	String get_top_level_extension(const String &p_openxr_path) const;
+	String get_top_level_extensions(const String &p_openxr_path) const;
 
 
-	void register_interaction_profile(const String &p_display_name, const String &p_openxr_path, const String &p_openxr_extension_name);
+	void register_interaction_profile(const String &p_display_name, const String &p_openxr_path, const String &p_openxr_extension_names);
 	bool has_interaction_profile(const String &p_openxr_path) const;
 	bool has_interaction_profile(const String &p_openxr_path) const;
-	String get_interaction_profile_extension(const String &p_openxr_path) const;
+	String get_interaction_profile_extensions(const String &p_openxr_path) const;
 	const InteractionProfile *get_profile(const String &p_openxr_path) const;
 	const InteractionProfile *get_profile(const String &p_openxr_path) const;
 	PackedStringArray get_interaction_profile_paths() const;
 	PackedStringArray get_interaction_profile_paths() const;
 
 
-	void register_io_path(const String &p_interaction_profile, const String &p_display_name, const String &p_toplevel_path, const String &p_openxr_path, const String &p_openxr_extension_name, OpenXRAction::ActionType p_action_type);
+	void register_io_path(const String &p_interaction_profile, const String &p_display_name, const String &p_toplevel_path, const String &p_openxr_path, const String &p_openxr_extension_names, OpenXRAction::ActionType p_action_type);
 	const IOPath *get_io_path(const String &p_interaction_profile, const String &p_io_path) const;
 	const IOPath *get_io_path(const String &p_interaction_profile, const String &p_io_path) const;
 };
 };

+ 6 - 0
modules/openxr/doc_classes/OpenXRAPIExtension.xml

@@ -85,6 +85,12 @@
 				Returns the predicted display timing for the next frame.
 				Returns the predicted display timing for the next frame.
 			</description>
 			</description>
 		</method>
 		</method>
+		<method name="get_openxr_version">
+			<return type="int" />
+			<description>
+				Returns the version of OpenXR that was initialized. Only valid after the OpenXR instance has been created. See [url=https://registry.khronos.org/OpenXR/specs/1.1/html/xrspec.html#XR_MAKE_VERSION]XR_MAKE_VERSION[/url] for how the version is calculated.
+			</description>
+		</method>
 		<method name="get_play_space">
 		<method name="get_play_space">
 			<return type="int" />
 			<return type="int" />
 			<description>
 			<description>

+ 5 - 3
modules/openxr/doc_classes/OpenXRExtensionWrapper.xml

@@ -42,8 +42,9 @@
 		</method>
 		</method>
 		<method name="_get_requested_extensions" qualifiers="virtual">
 		<method name="_get_requested_extensions" qualifiers="virtual">
 			<return type="Dictionary" />
 			<return type="Dictionary" />
+			<param index="0" name="xr_version" type="int" />
 			<description>
 			<description>
-				Returns a [Dictionary] of OpenXR extensions related to this extension. The [Dictionary] should contain the name of the extension, mapped to a [code]bool *[/code] cast to an integer:
+				Returns a [Dictionary] of OpenXR extensions related to this extension. [param xr_version] specifies the OpenXR version we're instantiating. This will be zero if the editor requests this list to flag supported features. The [Dictionary] should contain the name of the extension, mapped to a [code]bool *[/code] cast to an integer:
 				- If the [code]bool *[/code] is a [code]nullptr[/code] this extension is mandatory.
 				- If the [code]bool *[/code] is a [code]nullptr[/code] this extension is mandatory.
 				- If the [code]bool *[/code] points to a boolean, the boolean will be updated to [code]true[/code] if the extension is enabled.
 				- If the [code]bool *[/code] points to a boolean, the boolean will be updated to [code]true[/code] if the extension is enabled.
 			</description>
 			</description>
@@ -269,9 +270,10 @@
 		</method>
 		</method>
 		<method name="_set_instance_create_info_and_get_next_pointer" qualifiers="virtual">
 		<method name="_set_instance_create_info_and_get_next_pointer" qualifiers="virtual">
 			<return type="int" />
 			<return type="int" />
-			<param index="0" name="next_pointer" type="void*" />
+			<param index="0" name="xr_version" type="int" />
+			<param index="1" name="next_pointer" type="void*" />
 			<description>
 			<description>
-				Add additional data structures when the OpenXR instance is created.
+				Add additional data structures when the OpenXR instance is created. [param xr_version] specifies the OpenXR version we're instantiating.
 			</description>
 			</description>
 		</method>
 		</method>
 		<method name="_set_projection_views_and_get_next_pointer" qualifiers="virtual">
 		<method name="_set_projection_views_and_get_next_pointer" qualifiers="virtual">

+ 15 - 7
modules/openxr/doc_classes/OpenXRInteractionProfileMetadata.xml

@@ -13,10 +13,10 @@
 			<return type="void" />
 			<return type="void" />
 			<param index="0" name="display_name" type="String" />
 			<param index="0" name="display_name" type="String" />
 			<param index="1" name="openxr_path" type="String" />
 			<param index="1" name="openxr_path" type="String" />
-			<param index="2" name="openxr_extension_name" type="String" />
+			<param index="2" name="openxr_extension_names" type="String" />
 			<description>
 			<description>
 				Registers an interaction profile using its OpenXR designation (e.g. [code]/interaction_profiles/khr/simple_controller[/code] is the profile for OpenXR's simple controller profile).
 				Registers an interaction profile using its OpenXR designation (e.g. [code]/interaction_profiles/khr/simple_controller[/code] is the profile for OpenXR's simple controller profile).
-				[param display_name] is the description shown to the user. [param openxr_path] is the interaction profile path being registered. [param openxr_extension_name] optionally restricts this profile to the given extension being enabled/available. If the extension is not available, the profile and all related entries used in an action map are filtered out.
+				[param display_name] is the description shown to the user. [param openxr_path] is the interaction profile path being registered. [param openxr_extension_names] optionally restricts this profile to the given extension being enabled/available. If the extension is not available, the profile and all related entries used in an action map are filtered out.
 			</description>
 			</description>
 		</method>
 		</method>
 		<method name="register_io_path">
 		<method name="register_io_path">
@@ -25,10 +25,18 @@
 			<param index="1" name="display_name" type="String" />
 			<param index="1" name="display_name" type="String" />
 			<param index="2" name="toplevel_path" type="String" />
 			<param index="2" name="toplevel_path" type="String" />
 			<param index="3" name="openxr_path" type="String" />
 			<param index="3" name="openxr_path" type="String" />
-			<param index="4" name="openxr_extension_name" type="String" />
+			<param index="4" name="openxr_extension_names" type="String" />
 			<param index="5" name="action_type" type="int" enum="OpenXRAction.ActionType" />
 			<param index="5" name="action_type" type="int" enum="OpenXRAction.ActionType" />
 			<description>
 			<description>
-				Registers an input/output path for the given [param interaction_profile]. The profile should previously have been registered using [method register_interaction_profile]. [param display_name] is the description shown to the user. [param toplevel_path] specifies the bind path this input/output can be bound to (e.g. [code]/user/hand/left[/code] or [code]/user/hand/right[/code]). [param openxr_path] is the action input/output being registered (e.g. [code]/user/hand/left/input/aim/pose[/code]). [param openxr_extension_name] restricts this input/output to an enabled/available extension, this doesn't need to repeat the extension on the profile but relates to overlapping extension (e.g. [code]XR_EXT_palm_pose[/code] that introduces [code]…/input/palm_ext/pose[/code] input paths). [param action_type] defines the type of input or output provided by OpenXR.
+				Registers an input/output path for the given [param interaction_profile]. The profile should previously have been registered using [method register_interaction_profile]. [param display_name] is the description shown to the user. [param toplevel_path] specifies the bind path this input/output can be bound to (e.g. [code]/user/hand/left[/code] or [code]/user/hand/right[/code]). [param openxr_path] is the action input/output being registered (e.g. [code]/user/hand/left/input/aim/pose[/code]). [param openxr_extension_names] restricts this input/output to an enabled/available extension, this doesn't need to repeat the extension on the profile but relates to overlapping extension (e.g. [code]XR_EXT_palm_pose[/code] that introduces [code]…/input/palm_ext/pose[/code] input paths). [param action_type] defines the type of input or output provided by OpenXR.
+			</description>
+		</method>
+		<method name="register_path_rename">
+			<return type="void" />
+			<param index="0" name="old_name" type="String" />
+			<param index="1" name="new_name" type="String" />
+			<description>
+				Allows for renaming old input/output paths to new paths in order to load and process older action maps.
 			</description>
 			</description>
 		</method>
 		</method>
 		<method name="register_profile_rename">
 		<method name="register_profile_rename">
@@ -36,17 +44,17 @@
 			<param index="0" name="old_name" type="String" />
 			<param index="0" name="old_name" type="String" />
 			<param index="1" name="new_name" type="String" />
 			<param index="1" name="new_name" type="String" />
 			<description>
 			<description>
-				Allows for renaming old interaction profile paths to new paths to maintain backwards compatibility with older action maps.
+				Allows for renaming old interaction profile paths to new paths in order to load and process older action maps.
 			</description>
 			</description>
 		</method>
 		</method>
 		<method name="register_top_level_path">
 		<method name="register_top_level_path">
 			<return type="void" />
 			<return type="void" />
 			<param index="0" name="display_name" type="String" />
 			<param index="0" name="display_name" type="String" />
 			<param index="1" name="openxr_path" type="String" />
 			<param index="1" name="openxr_path" type="String" />
-			<param index="2" name="openxr_extension_name" type="String" />
+			<param index="2" name="openxr_extension_names" type="String" />
 			<description>
 			<description>
 				Registers a top level path to which profiles can be bound. For instance [code]/user/hand/left[/code] refers to the bind point for the player's left hand. Extensions can register additional top level paths, for instance a haptic vest extension might register [code]/user/body/vest[/code].
 				Registers a top level path to which profiles can be bound. For instance [code]/user/hand/left[/code] refers to the bind point for the player's left hand. Extensions can register additional top level paths, for instance a haptic vest extension might register [code]/user/body/vest[/code].
-				[param display_name] is the name shown to the user. [param openxr_path] is the top level path being registered. [param openxr_extension_name] is optional and ensures the top level path is only used if the specified extension is available/enabled.
+				[param display_name] is the name shown to the user. [param openxr_path] is the top level path being registered. [param openxr_extension_names] is optional and ensures the top level path is only used if the specified extension is available/enabled.
 				When a top level path ends up being bound by OpenXR, an [XRPositionalTracker] is instantiated to manage the state of the device.
 				When a top level path ends up being bound by OpenXR, an [XRPositionalTracker] is instantiated to manage the state of the device.
 			</description>
 			</description>
 		</method>
 		</method>

+ 15 - 6
modules/openxr/editor/openxr_interaction_profile_editor.cpp

@@ -198,10 +198,10 @@ void OpenXRInteractionProfileEditorBase::setup(const Ref<OpenXRActionMap> &p_act
 	if (profile_def != nullptr) {
 	if (profile_def != nullptr) {
 		profile_name = profile_def->display_name;
 		profile_name = profile_def->display_name;
 
 
-		if (!profile_def->openxr_extension_name.is_empty()) {
+		if (!profile_def->openxr_extension_names.is_empty()) {
 			profile_name += "*";
 			profile_name += "*";
 
 
-			tooltip = vformat(TTR("Note: This interaction profile requires extension %s support."), profile_def->openxr_extension_name);
+			tooltip = vformat(TTR("Note: This interaction profile requires extension %s support."), profile_def->openxr_extension_names);
 		}
 		}
 	}
 	}
 
 
@@ -242,11 +242,13 @@ void OpenXRInteractionProfileEditor::_add_io_path(VBoxContainer *p_container, co
 
 
 	Label *path_label = memnew(Label);
 	Label *path_label = memnew(Label);
 	path_label->set_focus_mode(FOCUS_ACCESSIBILITY);
 	path_label->set_focus_mode(FOCUS_ACCESSIBILITY);
-	if (p_io_path->openxr_extension_name.is_empty()) {
+	if (p_io_path->openxr_extension_names.is_empty()) {
 		path_label->set_text(p_io_path->display_name);
 		path_label->set_text(p_io_path->display_name);
 	} else {
 	} else {
 		path_label->set_text(p_io_path->display_name + "*");
 		path_label->set_text(p_io_path->display_name + "*");
-		path_hb->set_tooltip_text(vformat(TTR("Note: This binding path requires extension %s support."), p_io_path->openxr_extension_name));
+
+		String extension_names = p_io_path->openxr_extension_names.replace(",", " or ").replace(XR_OPENXR_1_1_NAME, "OpenXR 1.1");
+		path_hb->set_tooltip_text(vformat(TTR("Note: This binding path requires extension %s support."), extension_names));
 	}
 	}
 	path_label->set_h_size_flags(Control::SIZE_EXPAND_FILL);
 	path_label->set_h_size_flags(Control::SIZE_EXPAND_FILL);
 	path_hb->add_child(path_label);
 	path_hb->add_child(path_label);
@@ -334,7 +336,7 @@ void OpenXRInteractionProfileEditor::_update_interaction_profile() {
 		return;
 		return;
 	}
 	}
 
 
-	PackedStringArray requested_extensions = OpenXRAPI::get_all_requested_extensions();
+	PackedStringArray requested_extensions = OpenXRAPI::get_all_requested_extensions(0);
 
 
 	// out with the old...
 	// out with the old...
 	while (interaction_profile_hb->get_child_count() > 0) {
 	while (interaction_profile_hb->get_child_count() > 0) {
@@ -369,7 +371,14 @@ void OpenXRInteractionProfileEditor::_update_interaction_profile() {
 
 
 		for (int j = 0; j < profile_def->io_paths.size(); j++) {
 		for (int j = 0; j < profile_def->io_paths.size(); j++) {
 			const OpenXRInteractionProfileMetadata::IOPath *io_path = &profile_def->io_paths[j];
 			const OpenXRInteractionProfileMetadata::IOPath *io_path = &profile_def->io_paths[j];
-			if (io_path->top_level_path == top_level_paths[i] && (io_path->openxr_extension_name.is_empty() || requested_extensions.has(io_path->openxr_extension_name))) {
+
+			const Vector<String> extensions = io_path->openxr_extension_names.split(",", false);
+			bool extension_is_requested = extensions.is_empty(); // If none, then yes we can use this.
+			for (const String &extension : extensions) {
+				extension_is_requested |= requested_extensions.has(extension);
+			}
+
+			if (io_path->top_level_path == top_level_paths[i] && extension_is_requested) {
 				_add_io_path(container, io_path);
 				_add_io_path(container, io_path);
 			}
 			}
 		}
 		}

+ 7 - 3
modules/openxr/editor/openxr_select_interaction_profile_dialog.cpp

@@ -78,7 +78,7 @@ void OpenXRSelectInteractionProfileDialog::open(const PackedStringArray &p_do_no
 		memdelete(main_vb->get_child(1));
 		memdelete(main_vb->get_child(1));
 	}
 	}
 
 
-	PackedStringArray requested_extensions = OpenXRAPI::get_all_requested_extensions();
+	PackedStringArray requested_extensions = OpenXRAPI::get_all_requested_extensions(0);
 
 
 	selected_interaction_profile = "";
 	selected_interaction_profile = "";
 	ip_buttons.clear();
 	ip_buttons.clear();
@@ -86,8 +86,12 @@ void OpenXRSelectInteractionProfileDialog::open(const PackedStringArray &p_do_no
 	// In with the new.
 	// In with the new.
 	PackedStringArray interaction_profiles = meta_data->get_interaction_profile_paths();
 	PackedStringArray interaction_profiles = meta_data->get_interaction_profile_paths();
 	for (const String &path : interaction_profiles) {
 	for (const String &path : interaction_profiles) {
-		const String extension = meta_data->get_interaction_profile_extension(path);
-		if (!p_do_not_include.has(path) && (extension.is_empty() || requested_extensions.has(extension))) {
+		const Vector<String> extensions = meta_data->get_interaction_profile_extensions(path).split(",", false);
+		bool extension_is_requested = extensions.is_empty(); // If none, then yes we can use this.
+		for (const String &extension : extensions) {
+			extension_is_requested |= requested_extensions.has(extension);
+		}
+		if (!p_do_not_include.has(path) && extension_is_requested) {
 			Button *ip_button = memnew(Button);
 			Button *ip_button = memnew(Button);
 			ip_button->set_flat(true);
 			ip_button->set_flat(true);
 			ip_button->set_text(meta_data->get_profile(path)->display_name);
 			ip_button->set_text(meta_data->get_profile(path)->display_name);

+ 1 - 1
modules/openxr/extensions/openxr_android_thread_settings_extension.cpp

@@ -62,7 +62,7 @@ void OpenXRAndroidThreadSettingsExtension::_bind_methods() {
 	BIND_ENUM_CONSTANT(THREAD_TYPE_RENDERER_WORKER);
 	BIND_ENUM_CONSTANT(THREAD_TYPE_RENDERER_WORKER);
 }
 }
 
 
-HashMap<String, bool *> OpenXRAndroidThreadSettingsExtension::get_requested_extensions() {
+HashMap<String, bool *> OpenXRAndroidThreadSettingsExtension::get_requested_extensions(XrVersion p_version) {
 	HashMap<String, bool *> request_extensions;
 	HashMap<String, bool *> request_extensions;
 
 
 #ifdef XR_USE_PLATFORM_ANDROID
 #ifdef XR_USE_PLATFORM_ANDROID

+ 1 - 1
modules/openxr/extensions/openxr_android_thread_settings_extension.h

@@ -50,7 +50,7 @@ public:
 	OpenXRAndroidThreadSettingsExtension();
 	OpenXRAndroidThreadSettingsExtension();
 	virtual ~OpenXRAndroidThreadSettingsExtension() override;
 	virtual ~OpenXRAndroidThreadSettingsExtension() override;
 
 
-	virtual HashMap<String, bool *> get_requested_extensions() override;
+	virtual HashMap<String, bool *> get_requested_extensions(XrVersion p_version) override;
 	virtual void on_instance_created(XrInstance p_instance) override;
 	virtual void on_instance_created(XrInstance p_instance) override;
 	virtual void on_session_created(XrSession p_session) override;
 	virtual void on_session_created(XrSession p_session) override;
 
 

+ 1 - 1
modules/openxr/extensions/openxr_composition_layer_depth_extension.cpp

@@ -44,7 +44,7 @@ OpenXRCompositionLayerDepthExtension::~OpenXRCompositionLayerDepthExtension() {
 	singleton = nullptr;
 	singleton = nullptr;
 }
 }
 
 
-HashMap<String, bool *> OpenXRCompositionLayerDepthExtension::get_requested_extensions() {
+HashMap<String, bool *> OpenXRCompositionLayerDepthExtension::get_requested_extensions(XrVersion p_version) {
 	HashMap<String, bool *> request_extensions;
 	HashMap<String, bool *> request_extensions;
 
 
 	request_extensions[XR_KHR_COMPOSITION_LAYER_DEPTH_EXTENSION_NAME] = &available;
 	request_extensions[XR_KHR_COMPOSITION_LAYER_DEPTH_EXTENSION_NAME] = &available;

+ 1 - 1
modules/openxr/extensions/openxr_composition_layer_depth_extension.h

@@ -44,7 +44,7 @@ public:
 	OpenXRCompositionLayerDepthExtension();
 	OpenXRCompositionLayerDepthExtension();
 	virtual ~OpenXRCompositionLayerDepthExtension() override;
 	virtual ~OpenXRCompositionLayerDepthExtension() override;
 
 
-	virtual HashMap<String, bool *> get_requested_extensions() override;
+	virtual HashMap<String, bool *> get_requested_extensions(XrVersion p_version) override;
 	bool is_available();
 	bool is_available();
 	virtual int get_composition_layer_count() override;
 	virtual int get_composition_layer_count() override;
 	virtual XrCompositionLayerBaseHeader *get_composition_layer(int p_index) override;
 	virtual XrCompositionLayerBaseHeader *get_composition_layer(int p_index) override;

+ 1 - 1
modules/openxr/extensions/openxr_composition_layer_extension.cpp

@@ -56,7 +56,7 @@ OpenXRCompositionLayerExtension::~OpenXRCompositionLayerExtension() {
 	singleton = nullptr;
 	singleton = nullptr;
 }
 }
 
 
-HashMap<String, bool *> OpenXRCompositionLayerExtension::get_requested_extensions() {
+HashMap<String, bool *> OpenXRCompositionLayerExtension::get_requested_extensions(XrVersion p_version) {
 	HashMap<String, bool *> request_extensions;
 	HashMap<String, bool *> request_extensions;
 
 
 	request_extensions[XR_KHR_COMPOSITION_LAYER_CYLINDER_EXTENSION_NAME] = &cylinder_ext_available;
 	request_extensions[XR_KHR_COMPOSITION_LAYER_CYLINDER_EXTENSION_NAME] = &cylinder_ext_available;

+ 1 - 1
modules/openxr/extensions/openxr_composition_layer_extension.h

@@ -126,7 +126,7 @@ public:
 	OpenXRCompositionLayerExtension();
 	OpenXRCompositionLayerExtension();
 	virtual ~OpenXRCompositionLayerExtension() override;
 	virtual ~OpenXRCompositionLayerExtension() override;
 
 
-	virtual HashMap<String, bool *> get_requested_extensions() override;
+	virtual HashMap<String, bool *> get_requested_extensions(XrVersion p_version) override;
 	virtual void on_instance_created(const XrInstance p_instance) override;
 	virtual void on_instance_created(const XrInstance p_instance) override;
 	virtual void on_session_created(const XrSession p_session) override;
 	virtual void on_session_created(const XrSession p_session) override;
 	virtual void on_session_destroyed() override;
 	virtual void on_session_destroyed() override;

+ 1 - 1
modules/openxr/extensions/openxr_debug_utils_extension.cpp

@@ -50,7 +50,7 @@ OpenXRDebugUtilsExtension::~OpenXRDebugUtilsExtension() {
 	singleton = nullptr;
 	singleton = nullptr;
 }
 }
 
 
-HashMap<String, bool *> OpenXRDebugUtilsExtension::get_requested_extensions() {
+HashMap<String, bool *> OpenXRDebugUtilsExtension::get_requested_extensions(XrVersion p_version) {
 	HashMap<String, bool *> request_extensions;
 	HashMap<String, bool *> request_extensions;
 
 
 	request_extensions[XR_EXT_DEBUG_UTILS_EXTENSION_NAME] = &debug_utils_ext;
 	request_extensions[XR_EXT_DEBUG_UTILS_EXTENSION_NAME] = &debug_utils_ext;

+ 1 - 1
modules/openxr/extensions/openxr_debug_utils_extension.h

@@ -45,7 +45,7 @@ public:
 	OpenXRDebugUtilsExtension();
 	OpenXRDebugUtilsExtension();
 	virtual ~OpenXRDebugUtilsExtension() override;
 	virtual ~OpenXRDebugUtilsExtension() override;
 
 
-	virtual HashMap<String, bool *> get_requested_extensions() override;
+	virtual HashMap<String, bool *> get_requested_extensions(XrVersion p_version) override;
 	virtual void on_instance_created(const XrInstance p_instance) override;
 	virtual void on_instance_created(const XrInstance p_instance) override;
 	virtual void on_instance_destroyed() override;
 	virtual void on_instance_destroyed() override;
 
 

+ 1 - 1
modules/openxr/extensions/openxr_dpad_binding_extension.cpp

@@ -52,7 +52,7 @@ OpenXRDPadBindingExtension::~OpenXRDPadBindingExtension() {
 	singleton = nullptr;
 	singleton = nullptr;
 }
 }
 
 
-HashMap<String, bool *> OpenXRDPadBindingExtension::get_requested_extensions() {
+HashMap<String, bool *> OpenXRDPadBindingExtension::get_requested_extensions(XrVersion p_version) {
 	HashMap<String, bool *> request_extensions;
 	HashMap<String, bool *> request_extensions;
 
 
 	// Note, we're dependent on the binding modifier extension, this may be requested by multiple extension wrappers.
 	// Note, we're dependent on the binding modifier extension, this may be requested by multiple extension wrappers.

+ 1 - 1
modules/openxr/extensions/openxr_dpad_binding_extension.h

@@ -48,7 +48,7 @@ public:
 	OpenXRDPadBindingExtension();
 	OpenXRDPadBindingExtension();
 	virtual ~OpenXRDPadBindingExtension() override;
 	virtual ~OpenXRDPadBindingExtension() override;
 
 
-	virtual HashMap<String, bool *> get_requested_extensions() override;
+	virtual HashMap<String, bool *> get_requested_extensions(XrVersion p_version) override;
 
 
 	bool is_available();
 	bool is_available();
 
 

+ 28 - 6
modules/openxr/extensions/openxr_extension_wrapper.cpp

@@ -34,9 +34,9 @@
 #include "../openxr_api_extension.h"
 #include "../openxr_api_extension.h"
 
 
 void OpenXRExtensionWrapper::_bind_methods() {
 void OpenXRExtensionWrapper::_bind_methods() {
-	GDVIRTUAL_BIND(_get_requested_extensions);
+	GDVIRTUAL_BIND(_get_requested_extensions, "xr_version");
 	GDVIRTUAL_BIND(_set_system_properties_and_get_next_pointer, "next_pointer");
 	GDVIRTUAL_BIND(_set_system_properties_and_get_next_pointer, "next_pointer");
-	GDVIRTUAL_BIND(_set_instance_create_info_and_get_next_pointer, "next_pointer");
+	GDVIRTUAL_BIND(_set_instance_create_info_and_get_next_pointer, "xr_version", "next_pointer");
 	GDVIRTUAL_BIND(_set_session_create_and_get_next_pointer, "next_pointer");
 	GDVIRTUAL_BIND(_set_session_create_and_get_next_pointer, "next_pointer");
 	GDVIRTUAL_BIND(_set_swapchain_create_info_and_get_next_pointer, "next_pointer");
 	GDVIRTUAL_BIND(_set_swapchain_create_info_and_get_next_pointer, "next_pointer");
 	GDVIRTUAL_BIND(_set_hand_joint_locations_and_get_next_pointer, "hand_index", "next_pointer");
 	GDVIRTUAL_BIND(_set_hand_joint_locations_and_get_next_pointer, "hand_index", "next_pointer");
@@ -79,14 +79,29 @@ void OpenXRExtensionWrapper::_bind_methods() {
 	GDVIRTUAL_BIND(_on_viewport_composition_layer_destroyed, "layer");
 	GDVIRTUAL_BIND(_on_viewport_composition_layer_destroyed, "layer");
 	GDVIRTUAL_BIND(_set_android_surface_swapchain_create_info_and_get_next_pointer, "property_values", "next_pointer");
 	GDVIRTUAL_BIND(_set_android_surface_swapchain_create_info_and_get_next_pointer, "property_values", "next_pointer");
 
 
+#ifndef DISABLE_DEPRECATED
+	GDVIRTUAL_BIND_COMPAT(_get_requested_extensions_bind_compat_109302);
+	GDVIRTUAL_BIND_COMPAT(_set_instance_create_info_and_get_next_pointer_bind_compat_109302, "next_pointer");
+#endif
+
 	ClassDB::bind_method(D_METHOD("get_openxr_api"), &OpenXRExtensionWrapper::_gdextension_get_openxr_api);
 	ClassDB::bind_method(D_METHOD("get_openxr_api"), &OpenXRExtensionWrapper::_gdextension_get_openxr_api);
 	ClassDB::bind_method(D_METHOD("register_extension_wrapper"), &OpenXRExtensionWrapper::_gdextension_register_extension_wrapper);
 	ClassDB::bind_method(D_METHOD("register_extension_wrapper"), &OpenXRExtensionWrapper::_gdextension_register_extension_wrapper);
 }
 }
 
 
-HashMap<String, bool *> OpenXRExtensionWrapper::get_requested_extensions() {
+HashMap<String, bool *> OpenXRExtensionWrapper::get_requested_extensions(XrVersion p_xr_version) {
 	Dictionary request_extension;
 	Dictionary request_extension;
 
 
-	if (GDVIRTUAL_CALL(_get_requested_extensions, request_extension)) {
+	if (GDVIRTUAL_CALL(_get_requested_extensions, (uint64_t)p_xr_version, request_extension)) {
+		HashMap<String, bool *> result;
+		for (const KeyValue<Variant, Variant> &kv : request_extension) {
+			GDExtensionPtr<bool> value = VariantCaster<GDExtensionPtr<bool>>::cast(kv.value);
+			result.insert(kv.key, value);
+		}
+		return result;
+	}
+
+#ifndef DISABLE_DEPRECATED
+	if (GDVIRTUAL_CALL(_get_requested_extensions_bind_compat_109302, request_extension)) {
 		HashMap<String, bool *> result;
 		HashMap<String, bool *> result;
 		for (const KeyValue<Variant, Variant> &kv : request_extension) {
 		for (const KeyValue<Variant, Variant> &kv : request_extension) {
 			GDExtensionPtr<bool> value = VariantCaster<GDExtensionPtr<bool>>::cast(kv.value);
 			GDExtensionPtr<bool> value = VariantCaster<GDExtensionPtr<bool>>::cast(kv.value);
@@ -94,6 +109,7 @@ HashMap<String, bool *> OpenXRExtensionWrapper::get_requested_extensions() {
 		}
 		}
 		return result;
 		return result;
 	}
 	}
+#endif
 
 
 	return HashMap<String, bool *>();
 	return HashMap<String, bool *>();
 }
 }
@@ -108,12 +124,18 @@ void *OpenXRExtensionWrapper::set_system_properties_and_get_next_pointer(void *p
 	return nullptr;
 	return nullptr;
 }
 }
 
 
-void *OpenXRExtensionWrapper::set_instance_create_info_and_get_next_pointer(void *p_next_pointer) {
+void *OpenXRExtensionWrapper::set_instance_create_info_and_get_next_pointer(XrVersion p_xr_version, void *p_next_pointer) {
 	uint64_t pointer;
 	uint64_t pointer;
 
 
-	if (GDVIRTUAL_CALL(_set_instance_create_info_and_get_next_pointer, GDExtensionPtr<void>(p_next_pointer), pointer)) {
+	if (GDVIRTUAL_CALL(_set_instance_create_info_and_get_next_pointer, (uint64_t)p_xr_version, GDExtensionPtr<void>(p_next_pointer), pointer)) {
+		return reinterpret_cast<void *>(pointer);
+	}
+
+#ifndef DISABLE_DEPRECATED
+	if (GDVIRTUAL_CALL(_set_instance_create_info_and_get_next_pointer_bind_compat_109302, GDExtensionPtr<void>(p_next_pointer), pointer)) {
 		return reinterpret_cast<void *>(pointer);
 		return reinterpret_cast<void *>(pointer);
 	}
 	}
+#endif
 
 
 	return nullptr;
 	return nullptr;
 }
 }

+ 12 - 4
modules/openxr/extensions/openxr_extension_wrapper.h

@@ -60,12 +60,15 @@ protected:
 
 
 public:
 public:
 	// `get_requested_extensions` should return a list of OpenXR extensions related to this extension.
 	// `get_requested_extensions` should return a list of OpenXR extensions related to this extension.
+	// This function can be called multiple times.
+	// p_xr_version is the OpenXR version which we're attempting to initialize.
+	// Note: when called from the editor, p_xr_version will be 0 and we should return any extension we may initialize.
 	// If the bool * is a nullptr this extension is mandatory
 	// If the bool * is a nullptr this extension is mandatory
 	// If the bool * points to a boolean, the boolean will be updated
 	// If the bool * points to a boolean, the boolean will be updated
 	// to true if the extension is enabled.
 	// to true if the extension is enabled.
-	virtual HashMap<String, bool *> get_requested_extensions();
+	virtual HashMap<String, bool *> get_requested_extensions(XrVersion p_xr_version);
 
 
-	GDVIRTUAL0R(Dictionary, _get_requested_extensions);
+	GDVIRTUAL1R(Dictionary, _get_requested_extensions, uint64_t);
 
 
 	// These functions allow an extension to add entries to a struct chain.
 	// 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
 	// `p_next_pointer` points to the last struct that was created for this chain
@@ -74,7 +77,7 @@ public:
 	// If you are not adding any structs, just return `p_next_pointer`.
 	// If you are not adding any structs, just return `p_next_pointer`.
 	// See existing extensions for examples of this implementation.
 	// See existing extensions for examples of this implementation.
 	virtual void *set_system_properties_and_get_next_pointer(void *p_next_pointer); // Add additional data structures when we interrogate OpenXR's system abilities.
 	virtual void *set_system_properties_and_get_next_pointer(void *p_next_pointer); // Add additional data structures when we interrogate OpenXR's system abilities.
-	virtual void *set_instance_create_info_and_get_next_pointer(void *p_next_pointer); // Add additional data structures when we create our OpenXR instance.
+	virtual void *set_instance_create_info_and_get_next_pointer(XrVersion p_xr_version, void *p_next_pointer); // Add additional data structures when we create our OpenXR instance.
 	virtual void *set_session_create_and_get_next_pointer(void *p_next_pointer); // Add additional data structures when we create our OpenXR session.
 	virtual void *set_session_create_and_get_next_pointer(void *p_next_pointer); // Add additional data structures when we create our OpenXR session.
 	virtual void *set_swapchain_create_info_and_get_next_pointer(void *p_next_pointer); // Add additional data structures when creating OpenXR swap chains.
 	virtual void *set_swapchain_create_info_and_get_next_pointer(void *p_next_pointer); // Add additional data structures when creating OpenXR swap chains.
 	virtual void *set_hand_joint_locations_and_get_next_pointer(int p_hand_index, void *p_next_pointer);
 	virtual void *set_hand_joint_locations_and_get_next_pointer(int p_hand_index, void *p_next_pointer);
@@ -91,7 +94,7 @@ public:
 
 
 	//TODO workaround as GDExtensionPtr<void> return type results in build error in godot-cpp
 	//TODO workaround as GDExtensionPtr<void> return type results in build error in godot-cpp
 	GDVIRTUAL1R(uint64_t, _set_system_properties_and_get_next_pointer, GDExtensionPtr<void>);
 	GDVIRTUAL1R(uint64_t, _set_system_properties_and_get_next_pointer, GDExtensionPtr<void>);
-	GDVIRTUAL1R(uint64_t, _set_instance_create_info_and_get_next_pointer, GDExtensionPtr<void>);
+	GDVIRTUAL2R(uint64_t, _set_instance_create_info_and_get_next_pointer, uint64_t, GDExtensionPtr<void>);
 	GDVIRTUAL1R(uint64_t, _set_session_create_and_get_next_pointer, GDExtensionPtr<void>);
 	GDVIRTUAL1R(uint64_t, _set_session_create_and_get_next_pointer, GDExtensionPtr<void>);
 	GDVIRTUAL1R(uint64_t, _set_swapchain_create_info_and_get_next_pointer, GDExtensionPtr<void>);
 	GDVIRTUAL1R(uint64_t, _set_swapchain_create_info_and_get_next_pointer, GDExtensionPtr<void>);
 	GDVIRTUAL2R(uint64_t, _set_hand_joint_locations_and_get_next_pointer, int, GDExtensionPtr<void>);
 	GDVIRTUAL2R(uint64_t, _set_hand_joint_locations_and_get_next_pointer, int, GDExtensionPtr<void>);
@@ -107,6 +110,11 @@ public:
 	GDVIRTUAL2R(uint64_t, _set_view_configuration_and_get_next_pointer, uint32_t, GDExtensionPtr<void>);
 	GDVIRTUAL2R(uint64_t, _set_view_configuration_and_get_next_pointer, uint32_t, GDExtensionPtr<void>);
 	GDVIRTUAL1C(_print_view_configuration_info, int);
 	GDVIRTUAL1C(_print_view_configuration_info, int);
 
 
+#ifndef DISABLE_DEPRECATED
+	GDVIRTUAL0R_COMPAT(_get_requested_extensions_bind_compat_109302, Dictionary, _get_requested_extensions);
+	GDVIRTUAL1R_COMPAT(_set_instance_create_info_and_get_next_pointer_bind_compat_109302, uint64_t, _set_instance_create_info_and_get_next_pointer, GDExtensionPtr<void>);
+#endif
+
 	virtual PackedStringArray get_suggested_tracker_names();
 	virtual PackedStringArray get_suggested_tracker_names();
 
 
 	GDVIRTUAL0R(PackedStringArray, _get_suggested_tracker_names);
 	GDVIRTUAL0R(PackedStringArray, _get_suggested_tracker_names);

+ 1 - 1
modules/openxr/extensions/openxr_eye_gaze_interaction.cpp

@@ -51,7 +51,7 @@ OpenXREyeGazeInteractionExtension::~OpenXREyeGazeInteractionExtension() {
 	singleton = nullptr;
 	singleton = nullptr;
 }
 }
 
 
-HashMap<String, bool *> OpenXREyeGazeInteractionExtension::get_requested_extensions() {
+HashMap<String, bool *> OpenXREyeGazeInteractionExtension::get_requested_extensions(XrVersion p_version) {
 	HashMap<String, bool *> request_extensions;
 	HashMap<String, bool *> request_extensions;
 
 
 	// Only enable this extension when requested.
 	// Only enable this extension when requested.

+ 1 - 1
modules/openxr/extensions/openxr_eye_gaze_interaction.h

@@ -44,7 +44,7 @@ public:
 	OpenXREyeGazeInteractionExtension();
 	OpenXREyeGazeInteractionExtension();
 	~OpenXREyeGazeInteractionExtension();
 	~OpenXREyeGazeInteractionExtension();
 
 
-	virtual HashMap<String, bool *> get_requested_extensions() override;
+	virtual HashMap<String, bool *> get_requested_extensions(XrVersion p_version) override;
 	virtual void *set_system_properties_and_get_next_pointer(void *p_next_pointer) override;
 	virtual void *set_system_properties_and_get_next_pointer(void *p_next_pointer) override;
 
 
 	PackedStringArray get_suggested_tracker_names() override;
 	PackedStringArray get_suggested_tracker_names() override;

+ 1 - 1
modules/openxr/extensions/openxr_fb_display_refresh_rate_extension.cpp

@@ -45,7 +45,7 @@ OpenXRDisplayRefreshRateExtension::~OpenXRDisplayRefreshRateExtension() {
 	display_refresh_rate_ext = false;
 	display_refresh_rate_ext = false;
 }
 }
 
 
-HashMap<String, bool *> OpenXRDisplayRefreshRateExtension::get_requested_extensions() {
+HashMap<String, bool *> OpenXRDisplayRefreshRateExtension::get_requested_extensions(XrVersion p_version) {
 	HashMap<String, bool *> request_extensions;
 	HashMap<String, bool *> request_extensions;
 
 
 	request_extensions[XR_FB_DISPLAY_REFRESH_RATE_EXTENSION_NAME] = &display_refresh_rate_ext;
 	request_extensions[XR_FB_DISPLAY_REFRESH_RATE_EXTENSION_NAME] = &display_refresh_rate_ext;

+ 1 - 1
modules/openxr/extensions/openxr_fb_display_refresh_rate_extension.h

@@ -51,7 +51,7 @@ public:
 	OpenXRDisplayRefreshRateExtension();
 	OpenXRDisplayRefreshRateExtension();
 	virtual ~OpenXRDisplayRefreshRateExtension() override;
 	virtual ~OpenXRDisplayRefreshRateExtension() override;
 
 
-	virtual HashMap<String, bool *> get_requested_extensions() override;
+	virtual HashMap<String, bool *> get_requested_extensions(XrVersion p_version) override;
 
 
 	virtual void on_instance_created(const XrInstance p_instance) override;
 	virtual void on_instance_created(const XrInstance p_instance) override;
 	virtual void on_instance_destroyed() override;
 	virtual void on_instance_destroyed() override;

+ 1 - 1
modules/openxr/extensions/openxr_fb_foveation_extension.cpp

@@ -75,7 +75,7 @@ OpenXRFBFoveationExtension::~OpenXRFBFoveationExtension() {
 	swapchain_update_state_ext = nullptr;
 	swapchain_update_state_ext = nullptr;
 }
 }
 
 
-HashMap<String, bool *> OpenXRFBFoveationExtension::get_requested_extensions() {
+HashMap<String, bool *> OpenXRFBFoveationExtension::get_requested_extensions(XrVersion p_version) {
 	HashMap<String, bool *> request_extensions;
 	HashMap<String, bool *> request_extensions;
 
 
 	request_extensions[XR_FB_FOVEATION_EXTENSION_NAME] = &fb_foveation_ext;
 	request_extensions[XR_FB_FOVEATION_EXTENSION_NAME] = &fb_foveation_ext;

+ 1 - 1
modules/openxr/extensions/openxr_fb_foveation_extension.h

@@ -52,7 +52,7 @@ public:
 	OpenXRFBFoveationExtension(const String &p_rendering_driver);
 	OpenXRFBFoveationExtension(const String &p_rendering_driver);
 	virtual ~OpenXRFBFoveationExtension() override;
 	virtual ~OpenXRFBFoveationExtension() override;
 
 
-	virtual HashMap<String, bool *> get_requested_extensions() override;
+	virtual HashMap<String, bool *> get_requested_extensions(XrVersion p_version) override;
 
 
 	virtual void on_instance_created(const XrInstance p_instance) override;
 	virtual void on_instance_created(const XrInstance p_instance) override;
 	virtual void on_instance_destroyed() override;
 	virtual void on_instance_destroyed() override;

+ 1 - 1
modules/openxr/extensions/openxr_fb_update_swapchain_extension.cpp

@@ -61,7 +61,7 @@ OpenXRFBUpdateSwapchainExtension::~OpenXRFBUpdateSwapchainExtension() {
 	singleton = nullptr;
 	singleton = nullptr;
 }
 }
 
 
-HashMap<String, bool *> OpenXRFBUpdateSwapchainExtension::get_requested_extensions() {
+HashMap<String, bool *> OpenXRFBUpdateSwapchainExtension::get_requested_extensions(XrVersion p_version) {
 	HashMap<String, bool *> request_extensions;
 	HashMap<String, bool *> request_extensions;
 
 
 	request_extensions[XR_FB_SWAPCHAIN_UPDATE_STATE_EXTENSION_NAME] = &fb_swapchain_update_state_ext;
 	request_extensions[XR_FB_SWAPCHAIN_UPDATE_STATE_EXTENSION_NAME] = &fb_swapchain_update_state_ext;

+ 1 - 1
modules/openxr/extensions/openxr_fb_update_swapchain_extension.h

@@ -54,7 +54,7 @@ public:
 	OpenXRFBUpdateSwapchainExtension(const String &p_rendering_driver);
 	OpenXRFBUpdateSwapchainExtension(const String &p_rendering_driver);
 	virtual ~OpenXRFBUpdateSwapchainExtension() override;
 	virtual ~OpenXRFBUpdateSwapchainExtension() override;
 
 
-	virtual HashMap<String, bool *> get_requested_extensions() override;
+	virtual HashMap<String, bool *> get_requested_extensions(XrVersion p_version) override;
 
 
 	virtual void on_instance_created(const XrInstance p_instance) override;
 	virtual void on_instance_created(const XrInstance p_instance) override;
 	virtual void on_instance_destroyed() override;
 	virtual void on_instance_destroyed() override;

+ 1 - 1
modules/openxr/extensions/openxr_frame_synthesis_extension.cpp

@@ -68,7 +68,7 @@ OpenXRFrameSynthesisExtension::~OpenXRFrameSynthesisExtension() {
 	singleton = nullptr;
 	singleton = nullptr;
 }
 }
 
 
-HashMap<String, bool *> OpenXRFrameSynthesisExtension::get_requested_extensions() {
+HashMap<String, bool *> OpenXRFrameSynthesisExtension::get_requested_extensions(XrVersion p_version) {
 	HashMap<String, bool *> request_extensions;
 	HashMap<String, bool *> request_extensions;
 
 
 	if (GLOBAL_GET("xr/openxr/extensions/frame_synthesis")) {
 	if (GLOBAL_GET("xr/openxr/extensions/frame_synthesis")) {

+ 1 - 1
modules/openxr/extensions/openxr_frame_synthesis_extension.h

@@ -44,7 +44,7 @@ public:
 	OpenXRFrameSynthesisExtension();
 	OpenXRFrameSynthesisExtension();
 	virtual ~OpenXRFrameSynthesisExtension() override;
 	virtual ~OpenXRFrameSynthesisExtension() override;
 
 
-	virtual HashMap<String, bool *> get_requested_extensions() override;
+	virtual HashMap<String, bool *> get_requested_extensions(XrVersion p_version) override;
 
 
 	virtual void on_instance_created(const XrInstance p_instance) override;
 	virtual void on_instance_created(const XrInstance p_instance) override;
 	virtual void on_instance_destroyed() override;
 	virtual void on_instance_destroyed() override;

+ 1 - 1
modules/openxr/extensions/openxr_future_extension.cpp

@@ -129,7 +129,7 @@ void OpenXRFutureExtension::_bind_methods() {
 	ClassDB::bind_method(D_METHOD("cancel_future", "future"), &OpenXRFutureExtension::_cancel_future);
 	ClassDB::bind_method(D_METHOD("cancel_future", "future"), &OpenXRFutureExtension::_cancel_future);
 }
 }
 
 
-HashMap<String, bool *> OpenXRFutureExtension::get_requested_extensions() {
+HashMap<String, bool *> OpenXRFutureExtension::get_requested_extensions(XrVersion p_version) {
 	HashMap<String, bool *> request_extensions;
 	HashMap<String, bool *> request_extensions;
 
 
 	request_extensions[XR_EXT_FUTURE_EXTENSION_NAME] = &future_ext;
 	request_extensions[XR_EXT_FUTURE_EXTENSION_NAME] = &future_ext;

+ 1 - 1
modules/openxr/extensions/openxr_future_extension.h

@@ -104,7 +104,7 @@ public:
 	OpenXRFutureExtension();
 	OpenXRFutureExtension();
 	virtual ~OpenXRFutureExtension() override;
 	virtual ~OpenXRFutureExtension() override;
 
 
-	virtual HashMap<String, bool *> get_requested_extensions() override;
+	virtual HashMap<String, bool *> get_requested_extensions(XrVersion p_version) override;
 
 
 	virtual void on_instance_created(const XrInstance p_instance) override;
 	virtual void on_instance_created(const XrInstance p_instance) override;
 	virtual void on_instance_destroyed() override;
 	virtual void on_instance_destroyed() override;

+ 3 - 2
modules/openxr/extensions/openxr_hand_interaction_extension.cpp

@@ -31,6 +31,7 @@
 #include "openxr_hand_interaction_extension.h"
 #include "openxr_hand_interaction_extension.h"
 
 
 #include "../action_map/openxr_interaction_profile_metadata.h"
 #include "../action_map/openxr_interaction_profile_metadata.h"
+#include "../openxr_api.h"
 #include "core/config/project_settings.h"
 #include "core/config/project_settings.h"
 
 
 #include <openxr/openxr.h>
 #include <openxr/openxr.h>
@@ -49,7 +50,7 @@ OpenXRHandInteractionExtension::~OpenXRHandInteractionExtension() {
 	singleton = nullptr;
 	singleton = nullptr;
 }
 }
 
 
-HashMap<String, bool *> OpenXRHandInteractionExtension::get_requested_extensions() {
+HashMap<String, bool *> OpenXRHandInteractionExtension::get_requested_extensions(XrVersion p_version) {
 	HashMap<String, bool *> request_extensions;
 	HashMap<String, bool *> request_extensions;
 
 
 	// Only enable this extension when requested.
 	// Only enable this extension when requested.
@@ -78,7 +79,7 @@ void OpenXRHandInteractionExtension::on_register_metadata() {
 		openxr_metadata->register_io_path(profile_path, "Aim pose", user_path, user_path + "/input/aim/pose", "", OpenXRAction::OPENXR_ACTION_POSE);
 		openxr_metadata->register_io_path(profile_path, "Aim pose", user_path, user_path + "/input/aim/pose", "", OpenXRAction::OPENXR_ACTION_POSE);
 		openxr_metadata->register_io_path(profile_path, "Pinch pose", user_path, user_path + "/input/pinch_ext/pose", "", OpenXRAction::OPENXR_ACTION_POSE);
 		openxr_metadata->register_io_path(profile_path, "Pinch pose", user_path, user_path + "/input/pinch_ext/pose", "", OpenXRAction::OPENXR_ACTION_POSE);
 		openxr_metadata->register_io_path(profile_path, "Poke pose", user_path, user_path + "/input/poke_ext/pose", "", OpenXRAction::OPENXR_ACTION_POSE);
 		openxr_metadata->register_io_path(profile_path, "Poke pose", user_path, user_path + "/input/poke_ext/pose", "", OpenXRAction::OPENXR_ACTION_POSE);
-		openxr_metadata->register_io_path(profile_path, "Palm pose", user_path, user_path + "/input/palm_ext/pose", XR_EXT_PALM_POSE_EXTENSION_NAME, OpenXRAction::OPENXR_ACTION_POSE);
+		openxr_metadata->register_io_path(profile_path, "Grip surface pose", user_path, user_path + "/input/grip_surface/pose", XR_EXT_PALM_POSE_EXTENSION_NAME "," XR_KHR_MAINTENANCE1_EXTENSION_NAME "," XR_OPENXR_1_1_NAME, OpenXRAction::OPENXR_ACTION_POSE);
 
 
 		openxr_metadata->register_io_path(profile_path, "Pinch", user_path, user_path + "/input/pinch_ext/value", "", OpenXRAction::OPENXR_ACTION_FLOAT);
 		openxr_metadata->register_io_path(profile_path, "Pinch", user_path, user_path + "/input/pinch_ext/value", "", OpenXRAction::OPENXR_ACTION_FLOAT);
 		openxr_metadata->register_io_path(profile_path, "Pinch ready", user_path, user_path + "/input/pinch_ext/ready_ext", "", OpenXRAction::OPENXR_ACTION_BOOL);
 		openxr_metadata->register_io_path(profile_path, "Pinch ready", user_path, user_path + "/input/pinch_ext/ready_ext", "", OpenXRAction::OPENXR_ACTION_BOOL);

+ 1 - 1
modules/openxr/extensions/openxr_hand_interaction_extension.h

@@ -61,7 +61,7 @@ public:
 	OpenXRHandInteractionExtension();
 	OpenXRHandInteractionExtension();
 	virtual ~OpenXRHandInteractionExtension() override;
 	virtual ~OpenXRHandInteractionExtension() override;
 
 
-	virtual HashMap<String, bool *> get_requested_extensions() override;
+	virtual HashMap<String, bool *> get_requested_extensions(XrVersion p_version) override;
 
 
 	bool is_available();
 	bool is_available();
 
 

+ 1 - 1
modules/openxr/extensions/openxr_hand_tracking_extension.cpp

@@ -55,7 +55,7 @@ OpenXRHandTrackingExtension::~OpenXRHandTrackingExtension() {
 	singleton = nullptr;
 	singleton = nullptr;
 }
 }
 
 
-HashMap<String, bool *> OpenXRHandTrackingExtension::get_requested_extensions() {
+HashMap<String, bool *> OpenXRHandTrackingExtension::get_requested_extensions(XrVersion p_version) {
 	HashMap<String, bool *> request_extensions;
 	HashMap<String, bool *> request_extensions;
 
 
 	unobstructed_data_source = GLOBAL_GET("xr/openxr/extensions/hand_tracking_unobstructed_data_source");
 	unobstructed_data_source = GLOBAL_GET("xr/openxr/extensions/hand_tracking_unobstructed_data_source");

+ 1 - 1
modules/openxr/extensions/openxr_hand_tracking_extension.h

@@ -76,7 +76,7 @@ public:
 	OpenXRHandTrackingExtension();
 	OpenXRHandTrackingExtension();
 	virtual ~OpenXRHandTrackingExtension() override;
 	virtual ~OpenXRHandTrackingExtension() override;
 
 
-	virtual HashMap<String, bool *> get_requested_extensions() override;
+	virtual HashMap<String, bool *> get_requested_extensions(XrVersion p_version) override;
 
 
 	virtual void on_instance_created(const XrInstance p_instance) override;
 	virtual void on_instance_created(const XrInstance p_instance) override;
 	virtual void on_instance_destroyed() override;
 	virtual void on_instance_destroyed() override;

+ 12 - 7
modules/openxr/extensions/openxr_htc_controller_extension.cpp

@@ -31,12 +31,17 @@
 #include "openxr_htc_controller_extension.h"
 #include "openxr_htc_controller_extension.h"
 
 
 #include "../action_map/openxr_interaction_profile_metadata.h"
 #include "../action_map/openxr_interaction_profile_metadata.h"
+#include "../openxr_api.h"
 
 
-HashMap<String, bool *> OpenXRHTCControllerExtension::get_requested_extensions() {
+HashMap<String, bool *> OpenXRHTCControllerExtension::get_requested_extensions(XrVersion p_version) {
 	HashMap<String, bool *> request_extensions;
 	HashMap<String, bool *> request_extensions;
 
 
-	request_extensions[XR_HTC_VIVE_COSMOS_CONTROLLER_INTERACTION_EXTENSION_NAME] = &available[HTC_VIVE_COSMOS];
-	request_extensions[XR_HTC_VIVE_FOCUS3_CONTROLLER_INTERACTION_EXTENSION_NAME] = &available[HTC_VIVE_FOCUS3];
+	if (p_version < XR_API_VERSION_1_1_0) {
+		// Extensions where promoted in OpenXR 1.1, only include it in OpenXR 1.0.
+		request_extensions[XR_HTC_VIVE_COSMOS_CONTROLLER_INTERACTION_EXTENSION_NAME] = &available[HTC_VIVE_COSMOS];
+		request_extensions[XR_HTC_VIVE_FOCUS3_CONTROLLER_INTERACTION_EXTENSION_NAME] = &available[HTC_VIVE_FOCUS3];
+	}
+
 	request_extensions[XR_HTC_HAND_INTERACTION_EXTENSION_NAME] = &available[HTC_HAND_INTERACTION];
 	request_extensions[XR_HTC_HAND_INTERACTION_EXTENSION_NAME] = &available[HTC_HAND_INTERACTION];
 
 
 	return request_extensions;
 	return request_extensions;
@@ -63,11 +68,11 @@ void OpenXRHTCControllerExtension::on_register_metadata() {
 
 
 	{ // HTC Vive Cosmos controller
 	{ // HTC Vive Cosmos controller
 		const String profile_path = "/interaction_profiles/htc/vive_cosmos_controller";
 		const String profile_path = "/interaction_profiles/htc/vive_cosmos_controller";
-		openxr_metadata->register_interaction_profile("Vive Cosmos controller", profile_path, XR_HTC_VIVE_COSMOS_CONTROLLER_INTERACTION_EXTENSION_NAME);
+		openxr_metadata->register_interaction_profile("Vive Cosmos controller", profile_path, XR_HTC_VIVE_COSMOS_CONTROLLER_INTERACTION_EXTENSION_NAME "," XR_OPENXR_1_1_NAME);
 		for (const String user_path : { "/user/hand/left", "/user/hand/right" }) {
 		for (const String user_path : { "/user/hand/left", "/user/hand/right" }) {
 			openxr_metadata->register_io_path(profile_path, "Grip pose", user_path, user_path + "/input/grip/pose", "", OpenXRAction::OPENXR_ACTION_POSE);
 			openxr_metadata->register_io_path(profile_path, "Grip pose", user_path, user_path + "/input/grip/pose", "", OpenXRAction::OPENXR_ACTION_POSE);
 			openxr_metadata->register_io_path(profile_path, "Aim pose", user_path, user_path + "/input/aim/pose", "", OpenXRAction::OPENXR_ACTION_POSE);
 			openxr_metadata->register_io_path(profile_path, "Aim pose", user_path, user_path + "/input/aim/pose", "", OpenXRAction::OPENXR_ACTION_POSE);
-			openxr_metadata->register_io_path(profile_path, "Palm pose", user_path, user_path + "/input/palm_ext/pose", XR_EXT_PALM_POSE_EXTENSION_NAME, OpenXRAction::OPENXR_ACTION_POSE);
+			openxr_metadata->register_io_path(profile_path, "Grip surface pose", user_path, user_path + "/input/grip_surface/pose", XR_EXT_PALM_POSE_EXTENSION_NAME "," XR_KHR_MAINTENANCE1_EXTENSION_NAME "," XR_OPENXR_1_1_NAME, OpenXRAction::OPENXR_ACTION_POSE);
 
 
 			openxr_metadata->register_io_path(profile_path, "Shoulder click", user_path, user_path + "/input/shoulder/click", "", OpenXRAction::OPENXR_ACTION_BOOL);
 			openxr_metadata->register_io_path(profile_path, "Shoulder click", user_path, user_path + "/input/shoulder/click", "", OpenXRAction::OPENXR_ACTION_BOOL);
 
 
@@ -98,11 +103,11 @@ void OpenXRHTCControllerExtension::on_register_metadata() {
 
 
 	{ // HTC Vive Focus 3 controller
 	{ // HTC Vive Focus 3 controller
 		const String profile_path = "/interaction_profiles/htc/vive_focus3_controller";
 		const String profile_path = "/interaction_profiles/htc/vive_focus3_controller";
-		openxr_metadata->register_interaction_profile("Vive Focus 3 controller", profile_path, XR_HTC_VIVE_FOCUS3_CONTROLLER_INTERACTION_EXTENSION_NAME);
+		openxr_metadata->register_interaction_profile("Vive Focus 3 controller", profile_path, XR_HTC_VIVE_FOCUS3_CONTROLLER_INTERACTION_EXTENSION_NAME "," XR_OPENXR_1_1_NAME);
 		for (const String user_path : { "/user/hand/left", "/user/hand/right" }) {
 		for (const String user_path : { "/user/hand/left", "/user/hand/right" }) {
 			openxr_metadata->register_io_path(profile_path, "Grip pose", user_path, user_path + "/input/grip/pose", "", OpenXRAction::OPENXR_ACTION_POSE);
 			openxr_metadata->register_io_path(profile_path, "Grip pose", user_path, user_path + "/input/grip/pose", "", OpenXRAction::OPENXR_ACTION_POSE);
 			openxr_metadata->register_io_path(profile_path, "Aim pose", user_path, user_path + "/input/aim/pose", "", OpenXRAction::OPENXR_ACTION_POSE);
 			openxr_metadata->register_io_path(profile_path, "Aim pose", user_path, user_path + "/input/aim/pose", "", OpenXRAction::OPENXR_ACTION_POSE);
-			openxr_metadata->register_io_path(profile_path, "Palm pose", user_path, user_path + "/input/palm_ext/pose", XR_EXT_PALM_POSE_EXTENSION_NAME, OpenXRAction::OPENXR_ACTION_POSE);
+			openxr_metadata->register_io_path(profile_path, "Grip surface pose", user_path, user_path + "/input/grip_surface/pose", XR_EXT_PALM_POSE_EXTENSION_NAME "," XR_KHR_MAINTENANCE1_EXTENSION_NAME "," XR_OPENXR_1_1_NAME, OpenXRAction::OPENXR_ACTION_POSE);
 
 
 			openxr_metadata->register_io_path(profile_path, "Trigger", user_path, user_path + "/input/trigger/value", "", OpenXRAction::OPENXR_ACTION_FLOAT);
 			openxr_metadata->register_io_path(profile_path, "Trigger", user_path, user_path + "/input/trigger/value", "", OpenXRAction::OPENXR_ACTION_FLOAT);
 			openxr_metadata->register_io_path(profile_path, "Trigger click", user_path, user_path + "/input/trigger/click", "", OpenXRAction::OPENXR_ACTION_BOOL);
 			openxr_metadata->register_io_path(profile_path, "Trigger click", user_path, user_path + "/input/trigger/click", "", OpenXRAction::OPENXR_ACTION_BOOL);

+ 1 - 1
modules/openxr/extensions/openxr_htc_controller_extension.h

@@ -47,7 +47,7 @@ public:
 		HTC_MAX_CONTROLLERS
 		HTC_MAX_CONTROLLERS
 	};
 	};
 
 
-	virtual HashMap<String, bool *> get_requested_extensions() override;
+	virtual HashMap<String, bool *> get_requested_extensions(XrVersion p_version) override;
 
 
 	PackedStringArray get_suggested_tracker_names() override;
 	PackedStringArray get_suggested_tracker_names() override;
 
 

+ 1 - 1
modules/openxr/extensions/openxr_htc_vive_tracker_extension.cpp

@@ -34,7 +34,7 @@
 
 
 #include "core/string/print_string.h"
 #include "core/string/print_string.h"
 
 
-HashMap<String, bool *> OpenXRHTCViveTrackerExtension::get_requested_extensions() {
+HashMap<String, bool *> OpenXRHTCViveTrackerExtension::get_requested_extensions(XrVersion p_version) {
 	HashMap<String, bool *> request_extensions;
 	HashMap<String, bool *> request_extensions;
 
 
 	request_extensions[XR_HTCX_VIVE_TRACKER_INTERACTION_EXTENSION_NAME] = &available;
 	request_extensions[XR_HTCX_VIVE_TRACKER_INTERACTION_EXTENSION_NAME] = &available;

+ 1 - 1
modules/openxr/extensions/openxr_htc_vive_tracker_extension.h

@@ -39,7 +39,7 @@ protected:
 	static void _bind_methods() {}
 	static void _bind_methods() {}
 
 
 public:
 public:
-	virtual HashMap<String, bool *> get_requested_extensions() override;
+	virtual HashMap<String, bool *> get_requested_extensions(XrVersion p_version) override;
 
 
 	PackedStringArray get_suggested_tracker_names() override;
 	PackedStringArray get_suggested_tracker_names() override;
 
 

+ 3 - 1
modules/openxr/extensions/openxr_huawei_controller_extension.cpp

@@ -31,8 +31,9 @@
 #include "openxr_huawei_controller_extension.h"
 #include "openxr_huawei_controller_extension.h"
 
 
 #include "../action_map/openxr_interaction_profile_metadata.h"
 #include "../action_map/openxr_interaction_profile_metadata.h"
+#include "../openxr_api.h"
 
 
-HashMap<String, bool *> OpenXRHuaweiControllerExtension::get_requested_extensions() {
+HashMap<String, bool *> OpenXRHuaweiControllerExtension::get_requested_extensions(XrVersion p_version) {
 	HashMap<String, bool *> request_extensions;
 	HashMap<String, bool *> request_extensions;
 
 
 	request_extensions[XR_HUAWEI_CONTROLLER_INTERACTION_EXTENSION_NAME] = &available;
 	request_extensions[XR_HUAWEI_CONTROLLER_INTERACTION_EXTENSION_NAME] = &available;
@@ -55,6 +56,7 @@ void OpenXRHuaweiControllerExtension::on_register_metadata() {
 			openxr_metadata->register_io_path(profile_path, "Grip pose", user_path, user_path + "/input/grip/pose", "", OpenXRAction::OPENXR_ACTION_POSE);
 			openxr_metadata->register_io_path(profile_path, "Grip pose", user_path, user_path + "/input/grip/pose", "", OpenXRAction::OPENXR_ACTION_POSE);
 			openxr_metadata->register_io_path(profile_path, "Aim pose", user_path, user_path + "/input/aim/pose", "", OpenXRAction::OPENXR_ACTION_POSE);
 			openxr_metadata->register_io_path(profile_path, "Aim pose", user_path, user_path + "/input/aim/pose", "", OpenXRAction::OPENXR_ACTION_POSE);
 			openxr_metadata->register_io_path(profile_path, "Palm pose", user_path, user_path + "/input/palm_ext/pose", "", OpenXRAction::OPENXR_ACTION_POSE);
 			openxr_metadata->register_io_path(profile_path, "Palm pose", user_path, user_path + "/input/palm_ext/pose", "", OpenXRAction::OPENXR_ACTION_POSE);
+			openxr_metadata->register_io_path(profile_path, "Grip surface pose", user_path, user_path + "/input/grip_surface/pose", XR_OPENXR_1_1_NAME, OpenXRAction::OPENXR_ACTION_POSE);
 
 
 			openxr_metadata->register_io_path(profile_path, "Home click", user_path, user_path + "/input/home/click", "", OpenXRAction::OPENXR_ACTION_BOOL);
 			openxr_metadata->register_io_path(profile_path, "Home click", user_path, user_path + "/input/home/click", "", OpenXRAction::OPENXR_ACTION_BOOL);
 			openxr_metadata->register_io_path(profile_path, "Back click", user_path, user_path + "/input/back/click", "", OpenXRAction::OPENXR_ACTION_BOOL);
 			openxr_metadata->register_io_path(profile_path, "Back click", user_path, user_path + "/input/back/click", "", OpenXRAction::OPENXR_ACTION_BOOL);

+ 1 - 1
modules/openxr/extensions/openxr_huawei_controller_extension.h

@@ -39,7 +39,7 @@ protected:
 	static void _bind_methods() {}
 	static void _bind_methods() {}
 
 
 public:
 public:
-	virtual HashMap<String, bool *> get_requested_extensions() override;
+	virtual HashMap<String, bool *> get_requested_extensions(XrVersion p_version) override;
 
 
 	bool is_available();
 	bool is_available();
 
 

+ 7 - 2
modules/openxr/extensions/openxr_local_floor_extension.cpp

@@ -30,6 +30,8 @@
 
 
 #include "openxr_local_floor_extension.h"
 #include "openxr_local_floor_extension.h"
 
 
+#include "../openxr_api.h"
+
 OpenXRLocalFloorExtension *OpenXRLocalFloorExtension::singleton = nullptr;
 OpenXRLocalFloorExtension *OpenXRLocalFloorExtension::singleton = nullptr;
 
 
 OpenXRLocalFloorExtension *OpenXRLocalFloorExtension::get_singleton() {
 OpenXRLocalFloorExtension *OpenXRLocalFloorExtension::get_singleton() {
@@ -44,10 +46,13 @@ OpenXRLocalFloorExtension::~OpenXRLocalFloorExtension() {
 	singleton = nullptr;
 	singleton = nullptr;
 }
 }
 
 
-HashMap<String, bool *> OpenXRLocalFloorExtension::get_requested_extensions() {
+HashMap<String, bool *> OpenXRLocalFloorExtension::get_requested_extensions(XrVersion p_version) {
 	HashMap<String, bool *> request_extensions;
 	HashMap<String, bool *> request_extensions;
 
 
-	request_extensions[XR_EXT_LOCAL_FLOOR_EXTENSION_NAME] = &available;
+	if (p_version < XR_API_VERSION_1_1_0) {
+		// Extension was promoted in OpenXR 1.1, only include it in OpenXR 1.0.
+		request_extensions[XR_EXT_LOCAL_FLOOR_EXTENSION_NAME] = &available;
+	}
 
 
 	return request_extensions;
 	return request_extensions;
 }
 }

+ 1 - 1
modules/openxr/extensions/openxr_local_floor_extension.h

@@ -44,7 +44,7 @@ public:
 	OpenXRLocalFloorExtension();
 	OpenXRLocalFloorExtension();
 	virtual ~OpenXRLocalFloorExtension() override;
 	virtual ~OpenXRLocalFloorExtension() override;
 
 
-	virtual HashMap<String, bool *> get_requested_extensions() override;
+	virtual HashMap<String, bool *> get_requested_extensions(XrVersion p_version) override;
 
 
 	bool is_available();
 	bool is_available();
 
 

+ 134 - 26
modules/openxr/extensions/openxr_meta_controller_extension.cpp

@@ -31,13 +31,30 @@
 #include "openxr_meta_controller_extension.h"
 #include "openxr_meta_controller_extension.h"
 
 
 #include "../action_map/openxr_interaction_profile_metadata.h"
 #include "../action_map/openxr_interaction_profile_metadata.h"
+#include "../openxr_api.h"
 
 
-HashMap<String, bool *> OpenXRMetaControllerExtension::get_requested_extensions() {
+const char *touch_controller = "/interaction_profiles/oculus/touch_controller";
+const char *touch_pro_controller = "/interaction_profiles/meta/touch_pro_controller";
+const char *touch_plus_controller = "/interaction_profiles/meta/touch_plus_controller";
+const char *rift_cv1_controller = "/interaction_profiles/meta/touch_controller_rift_cv1";
+const char *quest1_rift_s_controller = "/interaction_profiles/meta/touch_controller_quest_1_rift_s";
+const char *quest2_controller = "/interaction_profiles/meta/touch_controller_quest_2";
+
+// Vendor extension paths (promoted)
+const char *touch_controller_pro_fb = "/interaction_profiles/facebook/touch_controller_pro";
+const char *touch_controller_plus_fb = "/interaction_profiles/facebook/touch_controller_plus";
+const char *touch_controller_plus_meta = "/interaction_profiles/meta/touch_controller_plus";
+
+HashMap<String, bool *> OpenXRMetaControllerExtension::get_requested_extensions(XrVersion p_version) {
 	HashMap<String, bool *> request_extensions;
 	HashMap<String, bool *> request_extensions;
 
 
+	if (p_version < XR_API_VERSION_1_1_0) {
+		// Extensions where promoted in OpenXR 1.1, only include it in OpenXR 1.0.
+		request_extensions[XR_FB_TOUCH_CONTROLLER_PRO_EXTENSION_NAME] = &available[META_TOUCH_PRO];
+		request_extensions[XR_META_TOUCH_CONTROLLER_PLUS_EXTENSION_NAME] = &available[META_TOUCH_PLUS];
+	}
+
 	request_extensions[XR_FB_TOUCH_CONTROLLER_PROXIMITY_EXTENSION_NAME] = &available[META_TOUCH_PROXIMITY];
 	request_extensions[XR_FB_TOUCH_CONTROLLER_PROXIMITY_EXTENSION_NAME] = &available[META_TOUCH_PROXIMITY];
-	request_extensions[XR_FB_TOUCH_CONTROLLER_PRO_EXTENSION_NAME] = &available[META_TOUCH_PRO];
-	request_extensions[XR_META_TOUCH_CONTROLLER_PLUS_EXTENSION_NAME] = &available[META_TOUCH_PLUS];
 
 
 	return request_extensions;
 	return request_extensions;
 }
 }
@@ -50,34 +67,69 @@ void OpenXRMetaControllerExtension::on_register_metadata() {
 	OpenXRInteractionProfileMetadata *openxr_metadata = OpenXRInteractionProfileMetadata::get_singleton();
 	OpenXRInteractionProfileMetadata *openxr_metadata = OpenXRInteractionProfileMetadata::get_singleton();
 	ERR_FAIL_NULL(openxr_metadata);
 	ERR_FAIL_NULL(openxr_metadata);
 
 
-	// Note, we register controllers regardless if they are supported on the current hardware.
+	// Note, we register controllers regardless if they are supported on the current hardware,
+	// this allows the editor to configure controllers for other platforms.
+	// Unsupported entries will be filtered out of the action map if applicable.
+
+	// OpenXR 1.1 uses various new names for profile and input/output paths.
+	// We use these new names in our action map and translate back IF OpenXR 1.1 is not supported.
+	openxr_metadata->register_profile_rename(touch_controller_pro_fb, touch_pro_controller);
+	openxr_metadata->register_profile_rename(touch_controller_plus_fb, touch_controller_plus_meta); // This was an incorrect profile path that we need to correct.
+	openxr_metadata->register_profile_rename(touch_controller_plus_meta, touch_plus_controller);
+
+	openxr_metadata->register_path_rename("/user/hand/left/input/stylus_fb/force", "/user/hand/left/input/stylus/force");
+	openxr_metadata->register_path_rename("/user/hand/right/input/stylus_fb/force", "/user/hand/right/input/stylus/force");
+	openxr_metadata->register_path_rename("/user/hand/left/input/trigger/proximity_fb", "/user/hand/left/input/trigger/proximity");
+	openxr_metadata->register_path_rename("/user/hand/right/input/trigger/proximity_fb", "/user/hand/right/input/trigger/proximity");
+	openxr_metadata->register_path_rename("/user/hand/left/output/haptic_trigger_fb", "/user/hand/left/output/haptic_trigger");
+	openxr_metadata->register_path_rename("/user/hand/right/output/haptic_trigger_fb", "/user/hand/right/output/haptic_trigger");
+	openxr_metadata->register_path_rename("/user/hand/left/output/haptic_thumb_fb", "/user/hand/left/output/haptic_thumb");
+	openxr_metadata->register_path_rename("/user/hand/right/output/haptic_thumb_fb", "/user/hand/right/output/haptic_thumb");
+	openxr_metadata->register_path_rename("/user/hand/left/input/thumb_fb/proximity_fb", "/user/hand/left/input/thumb_resting_surfaces/proximity");
+	openxr_metadata->register_path_rename("/user/hand/right/input/thumb_fb/proximity_fb", "/user/hand/right/input/thumb_resting_surfaces/proximity");
+	openxr_metadata->register_path_rename("/user/hand/left/input/trigger/curl_fb", "/user/hand/left/input/trigger_curl/value");
+	openxr_metadata->register_path_rename("/user/hand/right/input/trigger/curl_fb", "/user/hand/right/input/trigger_curl/value");
+	openxr_metadata->register_path_rename("/user/hand/left/input/trigger/slide_fb", "/user/hand/left/input/trigger_slide/value");
+	openxr_metadata->register_path_rename("/user/hand/right/input/trigger/slide_fb", "/user/hand/right/input/trigger_slide/value");
 
 
-	{ // Normal touch controller is part of the core spec, but we do have some extensions.
-		const String profile_path = "/interaction_profiles/oculus/touch_controller";
+	openxr_metadata->register_path_rename("/user/hand/left/input/trigger/proximity_meta", "/user/hand/left/input/trigger/proximity");
+	openxr_metadata->register_path_rename("/user/hand/right/input/trigger/proximity_meta", "/user/hand/right/input/trigger/proximity");
+	openxr_metadata->register_path_rename("/user/hand/left/input/thumb_meta/proximity_meta", "/user/hand/left/input/thumb_resting_surfaces/proximity");
+	openxr_metadata->register_path_rename("/user/hand/right/input/thumb_meta/proximity_meta", "/user/hand/right/input/thumb_resting_surfaces/proximity");
+	openxr_metadata->register_path_rename("/user/hand/left/input/trigger/curl_meta", "/user/hand/left/input/trigger_curl/value");
+	openxr_metadata->register_path_rename("/user/hand/right/input/trigger/curl_meta", "/user/hand/right/input/trigger_curl/value");
+	openxr_metadata->register_path_rename("/user/hand/left/input/trigger/slide_meta", "/user/hand/left/input/trigger_slide/value");
+	openxr_metadata->register_path_rename("/user/hand/right/input/trigger/slide_meta", "/user/hand/right/input/trigger_slide/value");
+
+	{ // Normal touch controller is part of the core spec and still relies on the XR_FB_touch_controller_proximity extension for these two new paths.
+		const String profile_path = touch_controller;
 		for (const String user_path : { "/user/hand/left", "/user/hand/right" }) {
 		for (const String user_path : { "/user/hand/left", "/user/hand/right" }) {
-			openxr_metadata->register_io_path(profile_path, "Trigger proximity", user_path, user_path + "/input/trigger/proximity_fb ", "XR_FB_touch_controller_proximity", OpenXRAction::OPENXR_ACTION_BOOL);
-			openxr_metadata->register_io_path(profile_path, "Thumb proximity", user_path, user_path + "/input/thumb_fb/proximity_fb ", "XR_FB_touch_controller_proximity", OpenXRAction::OPENXR_ACTION_BOOL);
+			openxr_metadata->register_io_path(profile_path, "Trigger proximity", user_path, user_path + "/input/trigger/proximity", XR_FB_TOUCH_CONTROLLER_PROXIMITY_EXTENSION_NAME, OpenXRAction::OPENXR_ACTION_BOOL);
+			openxr_metadata->register_io_path(profile_path, "Thumb proximity", user_path, user_path + "/input/thumb_resting_surfaces/proximity", XR_FB_TOUCH_CONTROLLER_PROXIMITY_EXTENSION_NAME, OpenXRAction::OPENXR_ACTION_BOOL);
 		}
 		}
 	}
 	}
 
 
 	{ // Touch controller pro (Quest Pro)
 	{ // Touch controller pro (Quest Pro)
-		const String profile_path = "/interaction_profiles/facebook/touch_controller_pro";
-		openxr_metadata->register_interaction_profile("Touch controller pro", profile_path, "XR_FB_touch_controller_pro");
+		const String profile_path = touch_pro_controller;
+		openxr_metadata->register_interaction_profile("Touch controller pro", profile_path, XR_FB_TOUCH_CONTROLLER_PRO_EXTENSION_NAME "," XR_OPENXR_1_1_NAME);
 		for (const String user_path : { "/user/hand/left", "/user/hand/right" }) {
 		for (const String user_path : { "/user/hand/left", "/user/hand/right" }) {
 			openxr_metadata->register_io_path(profile_path, "Grip pose", user_path, user_path + "/input/grip/pose", "", OpenXRAction::OPENXR_ACTION_POSE);
 			openxr_metadata->register_io_path(profile_path, "Grip pose", user_path, user_path + "/input/grip/pose", "", OpenXRAction::OPENXR_ACTION_POSE);
 			openxr_metadata->register_io_path(profile_path, "Aim pose", user_path, user_path + "/input/aim/pose", "", OpenXRAction::OPENXR_ACTION_POSE);
 			openxr_metadata->register_io_path(profile_path, "Aim pose", user_path, user_path + "/input/aim/pose", "", OpenXRAction::OPENXR_ACTION_POSE);
-			openxr_metadata->register_io_path(profile_path, "Palm pose", user_path, user_path + "/palm_ext/pose", XR_EXT_PALM_POSE_EXTENSION_NAME, OpenXRAction::OPENXR_ACTION_POSE);
+			openxr_metadata->register_io_path(profile_path, "Grip surface pose", user_path, user_path + "/input/grip_surface/pose", XR_EXT_PALM_POSE_EXTENSION_NAME "," XR_KHR_MAINTENANCE1_EXTENSION_NAME "," XR_OPENXR_1_1_NAME, OpenXRAction::OPENXR_ACTION_POSE);
+
+			openxr_metadata->register_io_path(profile_path, "Pinch pose", user_path, user_path + "/input/pinch_ext/pose", XR_EXT_HAND_INTERACTION_EXTENSION_NAME, OpenXRAction::OPENXR_ACTION_POSE);
+			openxr_metadata->register_io_path(profile_path, "Poke pose", user_path, user_path + "/input/poke_ext/pose", XR_EXT_HAND_INTERACTION_EXTENSION_NAME, OpenXRAction::OPENXR_ACTION_POSE);
 
 
 			openxr_metadata->register_io_path(profile_path, "Trigger", user_path, user_path + "/input/trigger/value", "", OpenXRAction::OPENXR_ACTION_FLOAT);
 			openxr_metadata->register_io_path(profile_path, "Trigger", user_path, user_path + "/input/trigger/value", "", OpenXRAction::OPENXR_ACTION_FLOAT);
 			openxr_metadata->register_io_path(profile_path, "Trigger touch", user_path, user_path + "/input/trigger/touch", "", OpenXRAction::OPENXR_ACTION_BOOL);
 			openxr_metadata->register_io_path(profile_path, "Trigger touch", user_path, user_path + "/input/trigger/touch", "", OpenXRAction::OPENXR_ACTION_BOOL);
-			openxr_metadata->register_io_path(profile_path, "Trigger proximity", user_path, user_path + "/input/trigger/proximity_fb", "", OpenXRAction::OPENXR_ACTION_BOOL);
-			openxr_metadata->register_io_path(profile_path, "Trigger curl", user_path, user_path + "/input/trigger/curl_fb", "", OpenXRAction::OPENXR_ACTION_FLOAT);
-			openxr_metadata->register_io_path(profile_path, "Trigger slide", user_path, user_path + "/input/trigger/slide_fb", "", OpenXRAction::OPENXR_ACTION_FLOAT);
+			openxr_metadata->register_io_path(profile_path, "Trigger proximity", user_path, user_path + "/input/trigger/proximity", "", OpenXRAction::OPENXR_ACTION_BOOL);
+			openxr_metadata->register_io_path(profile_path, "Trigger curl", user_path, user_path + "/input/trigger_curl/value", "", OpenXRAction::OPENXR_ACTION_FLOAT);
+			openxr_metadata->register_io_path(profile_path, "Trigger slide", user_path, user_path + "/input/trigger_slide/value", "", OpenXRAction::OPENXR_ACTION_FLOAT);
 			openxr_metadata->register_io_path(profile_path, "Trigger force", user_path, user_path + "/input/trigger/force", "", OpenXRAction::OPENXR_ACTION_FLOAT);
 			openxr_metadata->register_io_path(profile_path, "Trigger force", user_path, user_path + "/input/trigger/force", "", OpenXRAction::OPENXR_ACTION_FLOAT);
 
 
 			openxr_metadata->register_io_path(profile_path, "Squeeze", user_path, user_path + "/input/squeeze/value", "", OpenXRAction::OPENXR_ACTION_FLOAT);
 			openxr_metadata->register_io_path(profile_path, "Squeeze", user_path, user_path + "/input/squeeze/value", "", OpenXRAction::OPENXR_ACTION_FLOAT);
 
 
-			openxr_metadata->register_io_path(profile_path, "Thumb proximity", user_path, user_path + "/input/thumb_fb/proximity_fb", "", OpenXRAction::OPENXR_ACTION_BOOL);
+			openxr_metadata->register_io_path(profile_path, "Thumb proximity", user_path, user_path + "/input/thumb_resting_surfaces/proximity", "", OpenXRAction::OPENXR_ACTION_BOOL);
 
 
 			openxr_metadata->register_io_path(profile_path, "Thumbstick", user_path, user_path + "/input/thumbstick", "", OpenXRAction::OPENXR_ACTION_VECTOR2);
 			openxr_metadata->register_io_path(profile_path, "Thumbstick", user_path, user_path + "/input/thumbstick", "", OpenXRAction::OPENXR_ACTION_VECTOR2);
 			openxr_metadata->register_io_path(profile_path, "Thumbstick X", user_path, user_path + "/input/thumbstick/x", "", OpenXRAction::OPENXR_ACTION_FLOAT);
 			openxr_metadata->register_io_path(profile_path, "Thumbstick X", user_path, user_path + "/input/thumbstick/x", "", OpenXRAction::OPENXR_ACTION_FLOAT);
@@ -92,11 +144,11 @@ void OpenXRMetaControllerExtension::on_register_metadata() {
 			openxr_metadata->register_io_path(profile_path, "Thumbrest touch", user_path, user_path + "/input/thumbrest/touch", "", OpenXRAction::OPENXR_ACTION_BOOL);
 			openxr_metadata->register_io_path(profile_path, "Thumbrest touch", user_path, user_path + "/input/thumbrest/touch", "", OpenXRAction::OPENXR_ACTION_BOOL);
 			openxr_metadata->register_io_path(profile_path, "Thumbrest force", user_path, user_path + "/input/thumbrest/force", "", OpenXRAction::OPENXR_ACTION_FLOAT);
 			openxr_metadata->register_io_path(profile_path, "Thumbrest force", user_path, user_path + "/input/thumbrest/force", "", OpenXRAction::OPENXR_ACTION_FLOAT);
 
 
-			openxr_metadata->register_io_path(profile_path, "Stylus force", user_path, user_path + "/input/stylus_fb/force", "", OpenXRAction::OPENXR_ACTION_FLOAT);
+			openxr_metadata->register_io_path(profile_path, "Stylus force", user_path, user_path + "/input/stylus/force", "", OpenXRAction::OPENXR_ACTION_FLOAT);
 
 
 			openxr_metadata->register_io_path(profile_path, "Haptic output", user_path, user_path + "/output/haptic", "", OpenXRAction::OPENXR_ACTION_HAPTIC);
 			openxr_metadata->register_io_path(profile_path, "Haptic output", user_path, user_path + "/output/haptic", "", OpenXRAction::OPENXR_ACTION_HAPTIC);
-			openxr_metadata->register_io_path(profile_path, "Haptic trigger output", user_path, user_path + "/output/haptic_trigger_fb", "", OpenXRAction::OPENXR_ACTION_HAPTIC);
-			openxr_metadata->register_io_path(profile_path, "Haptic thumb output", user_path, user_path + "/output/haptic_thumb_fb", "", OpenXRAction::OPENXR_ACTION_HAPTIC);
+			openxr_metadata->register_io_path(profile_path, "Haptic trigger output", user_path, user_path + "/output/haptic_trigger", "", OpenXRAction::OPENXR_ACTION_HAPTIC);
+			openxr_metadata->register_io_path(profile_path, "Haptic thumb output", user_path, user_path + "/output/haptic_thumb", "", OpenXRAction::OPENXR_ACTION_HAPTIC);
 		}
 		}
 
 
 		openxr_metadata->register_io_path(profile_path, "Menu click", "/user/hand/left", "/user/hand/left/input/menu/click", "", OpenXRAction::OPENXR_ACTION_BOOL);
 		openxr_metadata->register_io_path(profile_path, "Menu click", "/user/hand/left", "/user/hand/left/input/menu/click", "", OpenXRAction::OPENXR_ACTION_BOOL);
@@ -112,24 +164,27 @@ void OpenXRMetaControllerExtension::on_register_metadata() {
 		openxr_metadata->register_io_path(profile_path, "B touch", "/user/hand/right", "/user/hand/right/input/b/touch", "", OpenXRAction::OPENXR_ACTION_BOOL);
 		openxr_metadata->register_io_path(profile_path, "B touch", "/user/hand/right", "/user/hand/right/input/b/touch", "", OpenXRAction::OPENXR_ACTION_BOOL);
 	}
 	}
 
 
-	{ // Touch controller plus (Quest 3)
-		const String profile_path = "/interaction_profiles/meta/touch_controller_plus";
-		openxr_metadata->register_interaction_profile("Touch controller plus", profile_path, "XR_META_touch_controller_plus");
+	{ // Touch controller plus (Quest 3 + 3S)
+		const String profile_path = touch_plus_controller;
+		openxr_metadata->register_interaction_profile("Touch controller plus", profile_path, XR_META_TOUCH_CONTROLLER_PLUS_EXTENSION_NAME "," XR_OPENXR_1_1_NAME);
 		for (const String user_path : { "/user/hand/left", "/user/hand/right" }) {
 		for (const String user_path : { "/user/hand/left", "/user/hand/right" }) {
 			openxr_metadata->register_io_path(profile_path, "Grip pose", user_path, user_path + "/input/grip/pose", "", OpenXRAction::OPENXR_ACTION_POSE);
 			openxr_metadata->register_io_path(profile_path, "Grip pose", user_path, user_path + "/input/grip/pose", "", OpenXRAction::OPENXR_ACTION_POSE);
 			openxr_metadata->register_io_path(profile_path, "Aim pose", user_path, user_path + "/input/aim/pose", "", OpenXRAction::OPENXR_ACTION_POSE);
 			openxr_metadata->register_io_path(profile_path, "Aim pose", user_path, user_path + "/input/aim/pose", "", OpenXRAction::OPENXR_ACTION_POSE);
-			openxr_metadata->register_io_path(profile_path, "Palm pose", user_path, user_path + "/input/palm_ext/pose", XR_EXT_PALM_POSE_EXTENSION_NAME, OpenXRAction::OPENXR_ACTION_POSE);
+			openxr_metadata->register_io_path(profile_path, "Grip surface pose", user_path, user_path + "/input/grip_surface/pose", XR_EXT_PALM_POSE_EXTENSION_NAME "," XR_KHR_MAINTENANCE1_EXTENSION_NAME "," XR_OPENXR_1_1_NAME, OpenXRAction::OPENXR_ACTION_POSE);
+
+			openxr_metadata->register_io_path(profile_path, "Pinch pose", user_path, user_path + "/input/pinch_ext/pose", XR_EXT_HAND_INTERACTION_EXTENSION_NAME, OpenXRAction::OPENXR_ACTION_POSE);
+			openxr_metadata->register_io_path(profile_path, "Poke pose", user_path, user_path + "/input/poke_ext/pose", XR_EXT_HAND_INTERACTION_EXTENSION_NAME, OpenXRAction::OPENXR_ACTION_POSE);
 
 
 			openxr_metadata->register_io_path(profile_path, "Trigger", user_path, user_path + "/input/trigger/value", "", OpenXRAction::OPENXR_ACTION_FLOAT);
 			openxr_metadata->register_io_path(profile_path, "Trigger", user_path, user_path + "/input/trigger/value", "", OpenXRAction::OPENXR_ACTION_FLOAT);
 			openxr_metadata->register_io_path(profile_path, "Trigger touch", user_path, user_path + "/input/trigger/touch", "", OpenXRAction::OPENXR_ACTION_BOOL);
 			openxr_metadata->register_io_path(profile_path, "Trigger touch", user_path, user_path + "/input/trigger/touch", "", OpenXRAction::OPENXR_ACTION_BOOL);
-			openxr_metadata->register_io_path(profile_path, "Trigger proximity", user_path, user_path + "/input/trigger/proximity_meta", "", OpenXRAction::OPENXR_ACTION_BOOL);
-			openxr_metadata->register_io_path(profile_path, "Trigger curl", user_path, user_path + "/input/trigger/curl_meta", "", OpenXRAction::OPENXR_ACTION_FLOAT);
-			openxr_metadata->register_io_path(profile_path, "Trigger slide", user_path, user_path + "/input/trigger/slide_meta", "", OpenXRAction::OPENXR_ACTION_FLOAT);
+			openxr_metadata->register_io_path(profile_path, "Trigger proximity", user_path, user_path + "/input/trigger/proximity", "", OpenXRAction::OPENXR_ACTION_BOOL);
+			openxr_metadata->register_io_path(profile_path, "Trigger curl", user_path, user_path + "/input/trigger_curl/value", "", OpenXRAction::OPENXR_ACTION_FLOAT);
+			openxr_metadata->register_io_path(profile_path, "Trigger slide", user_path, user_path + "/input/trigger_slide/value", "", OpenXRAction::OPENXR_ACTION_FLOAT);
 			openxr_metadata->register_io_path(profile_path, "Trigger force", user_path, user_path + "/input/trigger/force", "", OpenXRAction::OPENXR_ACTION_FLOAT);
 			openxr_metadata->register_io_path(profile_path, "Trigger force", user_path, user_path + "/input/trigger/force", "", OpenXRAction::OPENXR_ACTION_FLOAT);
 
 
 			openxr_metadata->register_io_path(profile_path, "Squeeze", user_path, user_path + "/input/squeeze/value", "", OpenXRAction::OPENXR_ACTION_FLOAT);
 			openxr_metadata->register_io_path(profile_path, "Squeeze", user_path, user_path + "/input/squeeze/value", "", OpenXRAction::OPENXR_ACTION_FLOAT);
 
 
-			openxr_metadata->register_io_path(profile_path, "Thumb proximity", user_path, user_path + "/input/thumb_meta/proximity_meta", "", OpenXRAction::OPENXR_ACTION_BOOL);
+			openxr_metadata->register_io_path(profile_path, "Thumb proximity", user_path, user_path + "/input/thumb_resting_surfaces/proximity", "", OpenXRAction::OPENXR_ACTION_BOOL);
 
 
 			openxr_metadata->register_io_path(profile_path, "Thumbstick", user_path, user_path + "/input/thumbstick", "", OpenXRAction::OPENXR_ACTION_VECTOR2);
 			openxr_metadata->register_io_path(profile_path, "Thumbstick", user_path, user_path + "/input/thumbstick", "", OpenXRAction::OPENXR_ACTION_VECTOR2);
 			openxr_metadata->register_io_path(profile_path, "Thumbstick X", user_path, user_path + "/input/thumbstick/x", "", OpenXRAction::OPENXR_ACTION_FLOAT);
 			openxr_metadata->register_io_path(profile_path, "Thumbstick X", user_path, user_path + "/input/thumbstick/x", "", OpenXRAction::OPENXR_ACTION_FLOAT);
@@ -158,4 +213,57 @@ void OpenXRMetaControllerExtension::on_register_metadata() {
 		openxr_metadata->register_io_path(profile_path, "B click", "/user/hand/right", "/user/hand/right/input/b/click", "", OpenXRAction::OPENXR_ACTION_BOOL);
 		openxr_metadata->register_io_path(profile_path, "B click", "/user/hand/right", "/user/hand/right/input/b/click", "", OpenXRAction::OPENXR_ACTION_BOOL);
 		openxr_metadata->register_io_path(profile_path, "B touch", "/user/hand/right", "/user/hand/right/input/b/touch", "", OpenXRAction::OPENXR_ACTION_BOOL);
 		openxr_metadata->register_io_path(profile_path, "B touch", "/user/hand/right", "/user/hand/right/input/b/touch", "", OpenXRAction::OPENXR_ACTION_BOOL);
 	}
 	}
+
+	{
+		// In OpenXR 1.1 we have controller profiles for Meta legacy controllers. They are all the same as the normal touch controller profile.
+		openxr_metadata->register_interaction_profile("Touch controller Rift CV1", rift_cv1_controller, XR_OPENXR_1_1_NAME);
+		openxr_metadata->register_interaction_profile("Touch controller Quest 1 or Rift S", quest1_rift_s_controller, XR_OPENXR_1_1_NAME);
+		openxr_metadata->register_interaction_profile("Touch controller Quest 2", quest2_controller, XR_OPENXR_1_1_NAME);
+
+		for (const String profile_path : { rift_cv1_controller, quest1_rift_s_controller, quest2_controller }) {
+			for (const String user_path : { "/user/hand/left", "/user/hand/right" }) {
+				openxr_metadata->register_io_path(profile_path, "Grip pose", user_path, user_path + "/input/grip/pose", "", OpenXRAction::OPENXR_ACTION_POSE);
+				openxr_metadata->register_io_path(profile_path, "Aim pose", user_path, user_path + "/input/aim/pose", "", OpenXRAction::OPENXR_ACTION_POSE);
+				openxr_metadata->register_io_path(profile_path, "Grip surface pose", user_path, user_path + "/input/grip_surface/pose", "", OpenXRAction::OPENXR_ACTION_POSE);
+
+				openxr_metadata->register_io_path(profile_path, "Pinch pose", user_path, user_path + "/input/pinch_ext/pose", XR_EXT_HAND_INTERACTION_EXTENSION_NAME, OpenXRAction::OPENXR_ACTION_POSE);
+				openxr_metadata->register_io_path(profile_path, "Poke pose", user_path, user_path + "/input/poke_ext/pose", XR_EXT_HAND_INTERACTION_EXTENSION_NAME, OpenXRAction::OPENXR_ACTION_POSE);
+
+				openxr_metadata->register_io_path(profile_path, "Trigger", user_path, user_path + "/input/trigger/value", "", OpenXRAction::OPENXR_ACTION_FLOAT);
+				openxr_metadata->register_io_path(profile_path, "Trigger touch", user_path, user_path + "/input/trigger/touch", "", OpenXRAction::OPENXR_ACTION_BOOL);
+
+				openxr_metadata->register_io_path(profile_path, "Squeeze", user_path, user_path + "/input/squeeze/value", "", OpenXRAction::OPENXR_ACTION_FLOAT);
+
+				// Note, unlike the default touch controller interaction profile, these are not dependent on the XR_FB_touch_controller_proximity extension!
+				openxr_metadata->register_io_path(profile_path, "Trigger proximity", user_path, user_path + "/input/trigger/proximity", "", OpenXRAction::OPENXR_ACTION_BOOL);
+				openxr_metadata->register_io_path(profile_path, "Thumb proximity", user_path, user_path + "/input/thumb_resting_surfaces/proximity", "", OpenXRAction::OPENXR_ACTION_BOOL);
+
+				openxr_metadata->register_io_path(profile_path, "Thumbstick", user_path, user_path + "/input/thumbstick", "", OpenXRAction::OPENXR_ACTION_VECTOR2);
+				openxr_metadata->register_io_path(profile_path, "Thumbstick X", user_path, user_path + "/input/thumbstick/x", "", OpenXRAction::OPENXR_ACTION_FLOAT);
+				openxr_metadata->register_io_path(profile_path, "Thumbstick Y", user_path, user_path + "/input/thumbstick/y", "", OpenXRAction::OPENXR_ACTION_FLOAT);
+				openxr_metadata->register_io_path(profile_path, "Thumbstick click", user_path, user_path + "/input/thumbstick/click", "", OpenXRAction::OPENXR_ACTION_BOOL);
+				openxr_metadata->register_io_path(profile_path, "Thumbstick touch", user_path, user_path + "/input/thumbstick/touch", "", OpenXRAction::OPENXR_ACTION_BOOL);
+				openxr_metadata->register_io_path(profile_path, "Thumbstick Dpad Up", user_path, user_path + "/input/thumbstick/dpad_up", "XR_EXT_dpad_binding", OpenXRAction::OPENXR_ACTION_BOOL);
+				openxr_metadata->register_io_path(profile_path, "Thumbstick Dpad Down", user_path, user_path + "/input/thumbstick/dpad_down", "XR_EXT_dpad_binding", OpenXRAction::OPENXR_ACTION_BOOL);
+				openxr_metadata->register_io_path(profile_path, "Thumbstick Dpad Left", user_path, user_path + "/input/thumbstick/dpad_left", "XR_EXT_dpad_binding", OpenXRAction::OPENXR_ACTION_BOOL);
+				openxr_metadata->register_io_path(profile_path, "Thumbstick Dpad Right", user_path, user_path + "/input/thumbstick/dpad_right", "XR_EXT_dpad_binding", OpenXRAction::OPENXR_ACTION_BOOL);
+
+				openxr_metadata->register_io_path(profile_path, "Thumbrest touch", user_path, user_path + "/input/thumbrest/touch", "", OpenXRAction::OPENXR_ACTION_BOOL);
+
+				openxr_metadata->register_io_path(profile_path, "Haptic output", user_path, user_path + "/output/haptic", "", OpenXRAction::OPENXR_ACTION_HAPTIC);
+			}
+
+			openxr_metadata->register_io_path(profile_path, "Menu click", "/user/hand/left", "/user/hand/left/input/menu/click", "", OpenXRAction::OPENXR_ACTION_BOOL);
+			openxr_metadata->register_io_path(profile_path, "System click", "/user/hand/right", "/user/hand/right/input/system/click", "", OpenXRAction::OPENXR_ACTION_BOOL);
+
+			openxr_metadata->register_io_path(profile_path, "X click", "/user/hand/left", "/user/hand/left/input/x/click", "", OpenXRAction::OPENXR_ACTION_BOOL);
+			openxr_metadata->register_io_path(profile_path, "X touch", "/user/hand/left", "/user/hand/left/input/x/touch", "", OpenXRAction::OPENXR_ACTION_BOOL);
+			openxr_metadata->register_io_path(profile_path, "Y click", "/user/hand/left", "/user/hand/left/input/y/click", "", OpenXRAction::OPENXR_ACTION_BOOL);
+			openxr_metadata->register_io_path(profile_path, "Y touch", "/user/hand/left", "/user/hand/left/input/y/touch", "", OpenXRAction::OPENXR_ACTION_BOOL);
+			openxr_metadata->register_io_path(profile_path, "A click", "/user/hand/right", "/user/hand/right/input/a/click", "", OpenXRAction::OPENXR_ACTION_BOOL);
+			openxr_metadata->register_io_path(profile_path, "A touch", "/user/hand/right", "/user/hand/right/input/a/touch", "", OpenXRAction::OPENXR_ACTION_BOOL);
+			openxr_metadata->register_io_path(profile_path, "B click", "/user/hand/right", "/user/hand/right/input/b/click", "", OpenXRAction::OPENXR_ACTION_BOOL);
+			openxr_metadata->register_io_path(profile_path, "B touch", "/user/hand/right", "/user/hand/right/input/b/touch", "", OpenXRAction::OPENXR_ACTION_BOOL);
+		}
+	}
 }
 }

+ 1 - 1
modules/openxr/extensions/openxr_meta_controller_extension.h

@@ -46,7 +46,7 @@ public:
 		META_MAX_CONTROLLERS
 		META_MAX_CONTROLLERS
 	};
 	};
 
 
-	virtual HashMap<String, bool *> get_requested_extensions() override;
+	virtual HashMap<String, bool *> get_requested_extensions(XrVersion p_version) override;
 
 
 	bool is_available(MetaControllers p_type);
 	bool is_available(MetaControllers p_type);
 
 

+ 7 - 3
modules/openxr/extensions/openxr_ml2_controller_extension.cpp

@@ -31,11 +31,15 @@
 #include "openxr_ml2_controller_extension.h"
 #include "openxr_ml2_controller_extension.h"
 
 
 #include "../action_map/openxr_interaction_profile_metadata.h"
 #include "../action_map/openxr_interaction_profile_metadata.h"
+#include "../openxr_api.h"
 
 
-HashMap<String, bool *> OpenXRML2ControllerExtension::get_requested_extensions() {
+HashMap<String, bool *> OpenXRML2ControllerExtension::get_requested_extensions(XrVersion p_version) {
 	HashMap<String, bool *> request_extensions;
 	HashMap<String, bool *> request_extensions;
 
 
-	request_extensions[XR_ML_ML2_CONTROLLER_INTERACTION_EXTENSION_NAME] = &available;
+	if (p_version < XR_API_VERSION_1_1_0) {
+		// Extension was promoted in OpenXR 1.1, only include it in OpenXR 1.0.
+		request_extensions[XR_ML_ML2_CONTROLLER_INTERACTION_EXTENSION_NAME] = &available;
+	}
 
 
 	return request_extensions;
 	return request_extensions;
 }
 }
@@ -50,7 +54,7 @@ void OpenXRML2ControllerExtension::on_register_metadata() {
 
 
 	// Magic Leap 2 Controller
 	// Magic Leap 2 Controller
 	const String profile_path = "/interaction_profiles/ml/ml2_controller";
 	const String profile_path = "/interaction_profiles/ml/ml2_controller";
-	openxr_metadata->register_interaction_profile("Magic Leap 2 controller", profile_path, XR_ML_ML2_CONTROLLER_INTERACTION_EXTENSION_NAME);
+	openxr_metadata->register_interaction_profile("Magic Leap 2 controller", profile_path, XR_ML_ML2_CONTROLLER_INTERACTION_EXTENSION_NAME "," XR_OPENXR_1_1_NAME);
 	for (const String user_path : { "/user/hand/left", "/user/hand/right" }) {
 	for (const String user_path : { "/user/hand/left", "/user/hand/right" }) {
 		openxr_metadata->register_io_path(profile_path, "Grip pose", user_path, user_path + "/input/grip/pose", "", OpenXRAction::OPENXR_ACTION_POSE);
 		openxr_metadata->register_io_path(profile_path, "Grip pose", user_path, user_path + "/input/grip/pose", "", OpenXRAction::OPENXR_ACTION_POSE);
 		openxr_metadata->register_io_path(profile_path, "Aim pose", user_path, user_path + "/input/aim/pose", "", OpenXRAction::OPENXR_ACTION_POSE);
 		openxr_metadata->register_io_path(profile_path, "Aim pose", user_path, user_path + "/input/aim/pose", "", OpenXRAction::OPENXR_ACTION_POSE);

+ 1 - 1
modules/openxr/extensions/openxr_ml2_controller_extension.h

@@ -39,7 +39,7 @@ protected:
 	static void _bind_methods() {}
 	static void _bind_methods() {}
 
 
 public:
 public:
-	virtual HashMap<String, bool *> get_requested_extensions() override;
+	virtual HashMap<String, bool *> get_requested_extensions(XrVersion p_version) override;
 
 
 	bool is_available();
 	bool is_available();
 
 

+ 1 - 1
modules/openxr/extensions/openxr_mxink_extension.cpp

@@ -35,7 +35,7 @@
 // Not in base XR libs needs def
 // Not in base XR libs needs def
 #define XR_LOGITECH_MX_INK_STYLUS_INTERACTION_EXTENSION_NAME "XR_LOGITECH_mx_ink_stylus_interaction"
 #define XR_LOGITECH_MX_INK_STYLUS_INTERACTION_EXTENSION_NAME "XR_LOGITECH_mx_ink_stylus_interaction"
 
 
-HashMap<String, bool *> OpenXRMxInkExtension::get_requested_extensions() {
+HashMap<String, bool *> OpenXRMxInkExtension::get_requested_extensions(XrVersion p_version) {
 	HashMap<String, bool *> request_extensions;
 	HashMap<String, bool *> request_extensions;
 
 
 	request_extensions[XR_LOGITECH_MX_INK_STYLUS_INTERACTION_EXTENSION_NAME] = &available;
 	request_extensions[XR_LOGITECH_MX_INK_STYLUS_INTERACTION_EXTENSION_NAME] = &available;

+ 1 - 1
modules/openxr/extensions/openxr_mxink_extension.h

@@ -39,7 +39,7 @@ protected:
 	static void _bind_methods() {}
 	static void _bind_methods() {}
 
 
 public:
 public:
-	virtual HashMap<String, bool *> get_requested_extensions() override;
+	virtual HashMap<String, bool *> get_requested_extensions(XrVersion p_version) override;
 
 
 	bool is_available();
 	bool is_available();
 
 

+ 7 - 2
modules/openxr/extensions/openxr_palm_pose_extension.cpp

@@ -30,6 +30,8 @@
 
 
 #include "openxr_palm_pose_extension.h"
 #include "openxr_palm_pose_extension.h"
 
 
+#include "../openxr_api.h"
+
 OpenXRPalmPoseExtension *OpenXRPalmPoseExtension::singleton = nullptr;
 OpenXRPalmPoseExtension *OpenXRPalmPoseExtension::singleton = nullptr;
 
 
 OpenXRPalmPoseExtension *OpenXRPalmPoseExtension::get_singleton() {
 OpenXRPalmPoseExtension *OpenXRPalmPoseExtension::get_singleton() {
@@ -44,10 +46,13 @@ OpenXRPalmPoseExtension::~OpenXRPalmPoseExtension() {
 	singleton = nullptr;
 	singleton = nullptr;
 }
 }
 
 
-HashMap<String, bool *> OpenXRPalmPoseExtension::get_requested_extensions() {
+HashMap<String, bool *> OpenXRPalmPoseExtension::get_requested_extensions(XrVersion p_version) {
 	HashMap<String, bool *> request_extensions;
 	HashMap<String, bool *> request_extensions;
 
 
-	request_extensions[XR_EXT_PALM_POSE_EXTENSION_NAME] = &available;
+	if (p_version < XR_API_VERSION_1_1_0) {
+		// Extension was promoted in OpenXR 1.1, only include it in OpenXR 1.0.
+		request_extensions[XR_EXT_PALM_POSE_EXTENSION_NAME] = &available;
+	}
 
 
 	return request_extensions;
 	return request_extensions;
 }
 }

+ 1 - 1
modules/openxr/extensions/openxr_palm_pose_extension.h

@@ -44,7 +44,7 @@ public:
 	OpenXRPalmPoseExtension();
 	OpenXRPalmPoseExtension();
 	virtual ~OpenXRPalmPoseExtension() override;
 	virtual ~OpenXRPalmPoseExtension() override;
 
 
-	virtual HashMap<String, bool *> get_requested_extensions() override;
+	virtual HashMap<String, bool *> get_requested_extensions(XrVersion p_version) override;
 
 
 	bool is_available();
 	bool is_available();
 
 

+ 1 - 1
modules/openxr/extensions/openxr_performance_settings_extension.cpp

@@ -46,7 +46,7 @@ OpenXRPerformanceSettingsExtension::~OpenXRPerformanceSettingsExtension() {
 	singleton = nullptr;
 	singleton = nullptr;
 }
 }
 
 
-HashMap<String, bool *> OpenXRPerformanceSettingsExtension::get_requested_extensions() {
+HashMap<String, bool *> OpenXRPerformanceSettingsExtension::get_requested_extensions(XrVersion p_version) {
 	HashMap<String, bool *> request_extensions;
 	HashMap<String, bool *> request_extensions;
 
 
 	request_extensions[XR_EXT_PERFORMANCE_SETTINGS_EXTENSION_NAME] = &available;
 	request_extensions[XR_EXT_PERFORMANCE_SETTINGS_EXTENSION_NAME] = &available;

+ 1 - 1
modules/openxr/extensions/openxr_performance_settings_extension.h

@@ -41,7 +41,7 @@ public:
 	OpenXRPerformanceSettingsExtension();
 	OpenXRPerformanceSettingsExtension();
 	virtual ~OpenXRPerformanceSettingsExtension() override;
 	virtual ~OpenXRPerformanceSettingsExtension() override;
 
 
-	virtual HashMap<String, bool *> get_requested_extensions() override;
+	virtual HashMap<String, bool *> get_requested_extensions(XrVersion p_version) override;
 
 
 	virtual void on_instance_created(const XrInstance p_instance) override;
 	virtual void on_instance_created(const XrInstance p_instance) override;
 	virtual bool on_event_polled(const XrEventDataBuffer &event) override;
 	virtual bool on_event_polled(const XrEventDataBuffer &event) override;

+ 13 - 8
modules/openxr/extensions/openxr_pico_controller_extension.cpp

@@ -31,15 +31,20 @@
 #include "openxr_pico_controller_extension.h"
 #include "openxr_pico_controller_extension.h"
 
 
 #include "../action_map/openxr_interaction_profile_metadata.h"
 #include "../action_map/openxr_interaction_profile_metadata.h"
+#include "../openxr_api.h"
 
 
-HashMap<String, bool *> OpenXRPicoControllerExtension::get_requested_extensions() {
+HashMap<String, bool *> OpenXRPicoControllerExtension::get_requested_extensions(XrVersion p_version) {
 	HashMap<String, bool *> request_extensions;
 	HashMap<String, bool *> request_extensions;
 
 
 	// Note, this used to be XR_PICO_controller_interaction but that has since been retired
 	// Note, this used to be XR_PICO_controller_interaction but that has since been retired
 	// and was never part of the OpenXX specification.
 	// and was never part of the OpenXX specification.
 	// All PICO devices should be updated to an OS supporting the official extension.
 	// All PICO devices should be updated to an OS supporting the official extension.
 
 
-	request_extensions[XR_BD_CONTROLLER_INTERACTION_EXTENSION_NAME] = &available;
+	if (true || p_version < XR_API_VERSION_1_1_0) {
+		// Extension was promoted in OpenXR 1.1, only include it in OpenXR 1.0.
+		// Note, we still need it for pico4_interaction, hence the temporary `if (true || ...`
+		request_extensions[XR_BD_CONTROLLER_INTERACTION_EXTENSION_NAME] = &available;
+	}
 
 
 	return request_extensions;
 	return request_extensions;
 }
 }
@@ -57,11 +62,11 @@ void OpenXRPicoControllerExtension::on_register_metadata() {
 
 
 	{ // Pico neo 3 controller.
 	{ // Pico neo 3 controller.
 		const String profile_path = "/interaction_profiles/bytedance/pico_neo3_controller";
 		const String profile_path = "/interaction_profiles/bytedance/pico_neo3_controller";
-		openxr_metadata->register_interaction_profile("Pico Neo3 controller", profile_path, XR_BD_CONTROLLER_INTERACTION_EXTENSION_NAME);
+		openxr_metadata->register_interaction_profile("Pico Neo3 controller", profile_path, XR_BD_CONTROLLER_INTERACTION_EXTENSION_NAME "," XR_OPENXR_1_1_NAME);
 		for (const String user_path : { "/user/hand/left", "/user/hand/right" }) {
 		for (const String user_path : { "/user/hand/left", "/user/hand/right" }) {
 			openxr_metadata->register_io_path(profile_path, "Grip pose", user_path, user_path + "/input/grip/pose", "", OpenXRAction::OPENXR_ACTION_POSE);
 			openxr_metadata->register_io_path(profile_path, "Grip pose", user_path, user_path + "/input/grip/pose", "", OpenXRAction::OPENXR_ACTION_POSE);
 			openxr_metadata->register_io_path(profile_path, "Aim pose", user_path, user_path + "/input/aim/pose", "", OpenXRAction::OPENXR_ACTION_POSE);
 			openxr_metadata->register_io_path(profile_path, "Aim pose", user_path, user_path + "/input/aim/pose", "", OpenXRAction::OPENXR_ACTION_POSE);
-			openxr_metadata->register_io_path(profile_path, "Palm pose", user_path, user_path + "/input/palm_ext/pose", XR_EXT_PALM_POSE_EXTENSION_NAME, OpenXRAction::OPENXR_ACTION_POSE);
+			openxr_metadata->register_io_path(profile_path, "Grip surface pose", user_path, user_path + "/input/grip_surface/pose", XR_EXT_PALM_POSE_EXTENSION_NAME "," XR_KHR_MAINTENANCE1_EXTENSION_NAME "," XR_OPENXR_1_1_NAME, OpenXRAction::OPENXR_ACTION_POSE);
 
 
 			openxr_metadata->register_io_path(profile_path, "Menu click", user_path, user_path + "/input/menu/click", "", OpenXRAction::OPENXR_ACTION_BOOL);
 			openxr_metadata->register_io_path(profile_path, "Menu click", user_path, user_path + "/input/menu/click", "", OpenXRAction::OPENXR_ACTION_BOOL);
 			openxr_metadata->register_io_path(profile_path, "System click", user_path, user_path + "/input/system/click", "", OpenXRAction::OPENXR_ACTION_BOOL);
 			openxr_metadata->register_io_path(profile_path, "System click", user_path, user_path + "/input/system/click", "", OpenXRAction::OPENXR_ACTION_BOOL);
@@ -94,11 +99,11 @@ void OpenXRPicoControllerExtension::on_register_metadata() {
 
 
 	{ // Pico 4 controller.
 	{ // Pico 4 controller.
 		const String profile_path = "/interaction_profiles/bytedance/pico4_controller";
 		const String profile_path = "/interaction_profiles/bytedance/pico4_controller";
-		openxr_metadata->register_interaction_profile("Pico 4 controller", profile_path, XR_BD_CONTROLLER_INTERACTION_EXTENSION_NAME);
+		openxr_metadata->register_interaction_profile("Pico 4 controller", profile_path, XR_BD_CONTROLLER_INTERACTION_EXTENSION_NAME "," XR_OPENXR_1_1_NAME);
 		for (const String user_path : { "/user/hand/left", "/user/hand/right" }) {
 		for (const String user_path : { "/user/hand/left", "/user/hand/right" }) {
 			openxr_metadata->register_io_path(profile_path, "Grip pose", user_path, user_path + "/input/grip/pose", "", OpenXRAction::OPENXR_ACTION_POSE);
 			openxr_metadata->register_io_path(profile_path, "Grip pose", user_path, user_path + "/input/grip/pose", "", OpenXRAction::OPENXR_ACTION_POSE);
 			openxr_metadata->register_io_path(profile_path, "Aim pose", user_path, user_path + "/input/aim/pose", "", OpenXRAction::OPENXR_ACTION_POSE);
 			openxr_metadata->register_io_path(profile_path, "Aim pose", user_path, user_path + "/input/aim/pose", "", OpenXRAction::OPENXR_ACTION_POSE);
-			openxr_metadata->register_io_path(profile_path, "Palm pose", user_path, user_path + "/input/palm_ext/pose", XR_EXT_PALM_POSE_EXTENSION_NAME, OpenXRAction::OPENXR_ACTION_POSE);
+			openxr_metadata->register_io_path(profile_path, "Grip surface pose", user_path, user_path + "/input/grip_surface/pose", XR_EXT_PALM_POSE_EXTENSION_NAME "," XR_KHR_MAINTENANCE1_EXTENSION_NAME "," XR_OPENXR_1_1_NAME, OpenXRAction::OPENXR_ACTION_POSE);
 
 
 			openxr_metadata->register_io_path(profile_path, "System click", user_path, user_path + "/input/system/click", "", OpenXRAction::OPENXR_ACTION_BOOL);
 			openxr_metadata->register_io_path(profile_path, "System click", user_path, user_path + "/input/system/click", "", OpenXRAction::OPENXR_ACTION_BOOL);
 
 
@@ -131,13 +136,13 @@ void OpenXRPicoControllerExtension::on_register_metadata() {
 		openxr_metadata->register_io_path(profile_path, "B touch", "/user/hand/right", "/user/hand/right/input/b/touch", "", OpenXRAction::OPENXR_ACTION_BOOL);
 		openxr_metadata->register_io_path(profile_path, "B touch", "/user/hand/right", "/user/hand/right/input/b/touch", "", OpenXRAction::OPENXR_ACTION_BOOL);
 	}
 	}
 
 
-	{ // Pico 4 Ultra controller.
+	{ // Pico 4 Ultra controller, note: not provided by OpenXR 1.1
 		const String profile_path = "/interaction_profiles/bytedance/pico4s_controller";
 		const String profile_path = "/interaction_profiles/bytedance/pico4s_controller";
 		openxr_metadata->register_interaction_profile("Pico 4 Ultra controller", profile_path, XR_BD_CONTROLLER_INTERACTION_EXTENSION_NAME);
 		openxr_metadata->register_interaction_profile("Pico 4 Ultra controller", profile_path, XR_BD_CONTROLLER_INTERACTION_EXTENSION_NAME);
 		for (const String user_path : { "/user/hand/left", "/user/hand/right" }) {
 		for (const String user_path : { "/user/hand/left", "/user/hand/right" }) {
 			openxr_metadata->register_io_path(profile_path, "Grip pose", user_path, user_path + "/input/grip/pose", "", OpenXRAction::OPENXR_ACTION_POSE);
 			openxr_metadata->register_io_path(profile_path, "Grip pose", user_path, user_path + "/input/grip/pose", "", OpenXRAction::OPENXR_ACTION_POSE);
 			openxr_metadata->register_io_path(profile_path, "Aim pose", user_path, user_path + "/input/aim/pose", "", OpenXRAction::OPENXR_ACTION_POSE);
 			openxr_metadata->register_io_path(profile_path, "Aim pose", user_path, user_path + "/input/aim/pose", "", OpenXRAction::OPENXR_ACTION_POSE);
-			openxr_metadata->register_io_path(profile_path, "Palm pose", user_path, user_path + "/input/palm_ext/pose", XR_EXT_PALM_POSE_EXTENSION_NAME, OpenXRAction::OPENXR_ACTION_POSE);
+			openxr_metadata->register_io_path(profile_path, "Grip surface pose", user_path, user_path + "/input/grip_surface/pose", XR_EXT_PALM_POSE_EXTENSION_NAME "," XR_KHR_MAINTENANCE1_EXTENSION_NAME "," XR_OPENXR_1_1_NAME, OpenXRAction::OPENXR_ACTION_POSE);
 
 
 			openxr_metadata->register_io_path(profile_path, "System click", user_path, user_path + "/input/system/click", "", OpenXRAction::OPENXR_ACTION_BOOL);
 			openxr_metadata->register_io_path(profile_path, "System click", user_path, user_path + "/input/system/click", "", OpenXRAction::OPENXR_ACTION_BOOL);
 
 

+ 1 - 1
modules/openxr/extensions/openxr_pico_controller_extension.h

@@ -39,7 +39,7 @@ protected:
 	static void _bind_methods() {}
 	static void _bind_methods() {}
 
 
 public:
 public:
-	virtual HashMap<String, bool *> get_requested_extensions() override;
+	virtual HashMap<String, bool *> get_requested_extensions(XrVersion p_version) override;
 
 
 	bool is_available();
 	bool is_available();
 
 

+ 5 - 2
modules/openxr/extensions/openxr_render_model_extension.cpp

@@ -71,11 +71,14 @@ OpenXRRenderModelExtension::~OpenXRRenderModelExtension() {
 	singleton = nullptr;
 	singleton = nullptr;
 }
 }
 
 
-HashMap<String, bool *> OpenXRRenderModelExtension::get_requested_extensions() {
+HashMap<String, bool *> OpenXRRenderModelExtension::get_requested_extensions(XrVersion p_version) {
 	HashMap<String, bool *> request_extensions;
 	HashMap<String, bool *> request_extensions;
 
 
 	if (GLOBAL_GET("xr/openxr/extensions/render_model")) {
 	if (GLOBAL_GET("xr/openxr/extensions/render_model")) {
-		request_extensions[XR_EXT_UUID_EXTENSION_NAME] = &uuid_ext;
+		if (p_version < XR_API_VERSION_1_1_0) {
+			// Extension was promoted in OpenXR 1.1, only include it in OpenXR 1.0.
+			request_extensions[XR_EXT_UUID_EXTENSION_NAME] = &uuid_ext;
+		}
 		request_extensions[XR_EXT_RENDER_MODEL_EXTENSION_NAME] = &render_model_ext;
 		request_extensions[XR_EXT_RENDER_MODEL_EXTENSION_NAME] = &render_model_ext;
 		request_extensions[XR_EXT_INTERACTION_RENDER_MODEL_EXTENSION_NAME] = &interaction_render_model_ext;
 		request_extensions[XR_EXT_INTERACTION_RENDER_MODEL_EXTENSION_NAME] = &interaction_render_model_ext;
 	}
 	}

+ 1 - 1
modules/openxr/extensions/openxr_render_model_extension.h

@@ -74,7 +74,7 @@ public:
 	OpenXRRenderModelExtension();
 	OpenXRRenderModelExtension();
 	virtual ~OpenXRRenderModelExtension() override;
 	virtual ~OpenXRRenderModelExtension() override;
 
 
-	virtual HashMap<String, bool *> get_requested_extensions() override;
+	virtual HashMap<String, bool *> get_requested_extensions(XrVersion p_version) override;
 
 
 	virtual void on_instance_created(const XrInstance p_instance) override;
 	virtual void on_instance_created(const XrInstance p_instance) override;
 	virtual void on_session_created(const XrSession p_session) override;
 	virtual void on_session_created(const XrSession p_session) override;

+ 1 - 1
modules/openxr/extensions/openxr_valve_analog_threshold_extension.cpp

@@ -53,7 +53,7 @@ OpenXRValveAnalogThresholdExtension::~OpenXRValveAnalogThresholdExtension() {
 	singleton = nullptr;
 	singleton = nullptr;
 }
 }
 
 
-HashMap<String, bool *> OpenXRValveAnalogThresholdExtension::get_requested_extensions() {
+HashMap<String, bool *> OpenXRValveAnalogThresholdExtension::get_requested_extensions(XrVersion p_version) {
 	HashMap<String, bool *> request_extensions;
 	HashMap<String, bool *> request_extensions;
 
 
 	// Note, we're dependent on the binding modifier extension, this may be requested by multiple extension wrappers.
 	// Note, we're dependent on the binding modifier extension, this may be requested by multiple extension wrappers.

+ 1 - 1
modules/openxr/extensions/openxr_valve_analog_threshold_extension.h

@@ -48,7 +48,7 @@ public:
 	OpenXRValveAnalogThresholdExtension();
 	OpenXRValveAnalogThresholdExtension();
 	virtual ~OpenXRValveAnalogThresholdExtension() override;
 	virtual ~OpenXRValveAnalogThresholdExtension() override;
 
 
-	virtual HashMap<String, bool *> get_requested_extensions() override;
+	virtual HashMap<String, bool *> get_requested_extensions(XrVersion p_version) override;
 
 
 	bool is_available();
 	bool is_available();
 
 

+ 1 - 1
modules/openxr/extensions/openxr_visibility_mask_extension.cpp

@@ -69,7 +69,7 @@ OpenXRVisibilityMaskExtension::~OpenXRVisibilityMaskExtension() {
 	singleton = nullptr;
 	singleton = nullptr;
 }
 }
 
 
-HashMap<String, bool *> OpenXRVisibilityMaskExtension::get_requested_extensions() {
+HashMap<String, bool *> OpenXRVisibilityMaskExtension::get_requested_extensions(XrVersion p_version) {
 	HashMap<String, bool *> request_extensions;
 	HashMap<String, bool *> request_extensions;
 
 
 	request_extensions[XR_KHR_VISIBILITY_MASK_EXTENSION_NAME] = &available;
 	request_extensions[XR_KHR_VISIBILITY_MASK_EXTENSION_NAME] = &available;

+ 1 - 1
modules/openxr/extensions/openxr_visibility_mask_extension.h

@@ -58,7 +58,7 @@ public:
 	OpenXRVisibilityMaskExtension();
 	OpenXRVisibilityMaskExtension();
 	virtual ~OpenXRVisibilityMaskExtension() override;
 	virtual ~OpenXRVisibilityMaskExtension() override;
 
 
-	virtual HashMap<String, bool *> get_requested_extensions() override;
+	virtual HashMap<String, bool *> get_requested_extensions(XrVersion p_version) override;
 
 
 	virtual void on_instance_created(const XrInstance p_instance) override;
 	virtual void on_instance_created(const XrInstance p_instance) override;
 
 

+ 12 - 8
modules/openxr/extensions/openxr_wmr_controller_extension.cpp

@@ -31,13 +31,17 @@
 #include "openxr_wmr_controller_extension.h"
 #include "openxr_wmr_controller_extension.h"
 
 
 #include "../action_map/openxr_interaction_profile_metadata.h"
 #include "../action_map/openxr_interaction_profile_metadata.h"
+#include "../openxr_api.h"
 
 
-HashMap<String, bool *> OpenXRWMRControllerExtension::get_requested_extensions() {
+HashMap<String, bool *> OpenXRWMRControllerExtension::get_requested_extensions(XrVersion p_version) {
 	HashMap<String, bool *> request_extensions;
 	HashMap<String, bool *> request_extensions;
 
 
 	// Note HP G2 is available on WMR and SteamVR, but Odessey is only available on WMR
 	// Note HP G2 is available on WMR and SteamVR, but Odessey is only available on WMR
-	request_extensions[XR_EXT_HP_MIXED_REALITY_CONTROLLER_EXTENSION_NAME] = &available[WMR_HPMR];
-	request_extensions[XR_EXT_SAMSUNG_ODYSSEY_CONTROLLER_EXTENSION_NAME] = &available[WMR_SAMSUNG_ODESSY];
+	if (p_version < XR_API_VERSION_1_1_0) {
+		// Extensions where promoted in OpenXR 1.1, only include it in OpenXR 1.0.
+		request_extensions[XR_EXT_HP_MIXED_REALITY_CONTROLLER_EXTENSION_NAME] = &available[WMR_HPMR];
+		request_extensions[XR_EXT_SAMSUNG_ODYSSEY_CONTROLLER_EXTENSION_NAME] = &available[WMR_SAMSUNG_ODESSY];
+	}
 	request_extensions[XR_MSFT_HAND_INTERACTION_EXTENSION_NAME] = &available[WMR_HAND_INTERACTION];
 	request_extensions[XR_MSFT_HAND_INTERACTION_EXTENSION_NAME] = &available[WMR_HAND_INTERACTION];
 
 
 	return request_extensions;
 	return request_extensions;
@@ -53,11 +57,11 @@ void OpenXRWMRControllerExtension::on_register_metadata() {
 
 
 	{ // HP MR controller (newer G2 controllers)
 	{ // HP MR controller (newer G2 controllers)
 		const String profile_path = "/interaction_profiles/hp/mixed_reality_controller";
 		const String profile_path = "/interaction_profiles/hp/mixed_reality_controller";
-		openxr_metadata->register_interaction_profile("HPMR controller", profile_path, XR_EXT_HP_MIXED_REALITY_CONTROLLER_EXTENSION_NAME);
+		openxr_metadata->register_interaction_profile("HPMR controller", profile_path, XR_EXT_HP_MIXED_REALITY_CONTROLLER_EXTENSION_NAME "," XR_OPENXR_1_1_NAME);
 		for (const String user_path : { "/user/hand/left", "/user/hand/right" }) {
 		for (const String user_path : { "/user/hand/left", "/user/hand/right" }) {
 			openxr_metadata->register_io_path(profile_path, "Grip pose", user_path, user_path + "/input/grip/pose", "", OpenXRAction::OPENXR_ACTION_POSE);
 			openxr_metadata->register_io_path(profile_path, "Grip pose", user_path, user_path + "/input/grip/pose", "", OpenXRAction::OPENXR_ACTION_POSE);
 			openxr_metadata->register_io_path(profile_path, "Aim pose", user_path, user_path + "/input/aim/pose", "", OpenXRAction::OPENXR_ACTION_POSE);
 			openxr_metadata->register_io_path(profile_path, "Aim pose", user_path, user_path + "/input/aim/pose", "", OpenXRAction::OPENXR_ACTION_POSE);
-			openxr_metadata->register_io_path(profile_path, "Palm pose", user_path, user_path + "/input/palm_ext/pose", XR_EXT_PALM_POSE_EXTENSION_NAME, OpenXRAction::OPENXR_ACTION_POSE);
+			openxr_metadata->register_io_path(profile_path, "Grip surface pose", user_path, user_path + "/input/grip_surface/pose", XR_EXT_PALM_POSE_EXTENSION_NAME "," XR_KHR_MAINTENANCE1_EXTENSION_NAME "," XR_OPENXR_1_1_NAME, OpenXRAction::OPENXR_ACTION_POSE);
 
 
 			openxr_metadata->register_io_path(profile_path, "Menu click", user_path, user_path + "/input/menu/click", "", OpenXRAction::OPENXR_ACTION_BOOL);
 			openxr_metadata->register_io_path(profile_path, "Menu click", user_path, user_path + "/input/menu/click", "", OpenXRAction::OPENXR_ACTION_BOOL);
 
 
@@ -84,11 +88,11 @@ void OpenXRWMRControllerExtension::on_register_metadata() {
 
 
 	{ // Samsung Odyssey controller
 	{ // Samsung Odyssey controller
 		const String profile_path = "/interaction_profiles/samsung/odyssey_controller";
 		const String profile_path = "/interaction_profiles/samsung/odyssey_controller";
-		openxr_metadata->register_interaction_profile("Samsung Odyssey controller", profile_path, XR_EXT_SAMSUNG_ODYSSEY_CONTROLLER_EXTENSION_NAME);
+		openxr_metadata->register_interaction_profile("Samsung Odyssey controller", profile_path, XR_EXT_SAMSUNG_ODYSSEY_CONTROLLER_EXTENSION_NAME "," XR_OPENXR_1_1_NAME);
 		for (const String user_path : { "/user/hand/left", "/user/hand/right" }) {
 		for (const String user_path : { "/user/hand/left", "/user/hand/right" }) {
 			openxr_metadata->register_io_path(profile_path, "Grip pose", user_path, user_path + "/input/grip/pose", "", OpenXRAction::OPENXR_ACTION_POSE);
 			openxr_metadata->register_io_path(profile_path, "Grip pose", user_path, user_path + "/input/grip/pose", "", OpenXRAction::OPENXR_ACTION_POSE);
 			openxr_metadata->register_io_path(profile_path, "Aim pose", user_path, user_path + "/input/aim/pose", "", OpenXRAction::OPENXR_ACTION_POSE);
 			openxr_metadata->register_io_path(profile_path, "Aim pose", user_path, user_path + "/input/aim/pose", "", OpenXRAction::OPENXR_ACTION_POSE);
-			openxr_metadata->register_io_path(profile_path, "Palm pose", user_path, user_path + "/input/palm_ext/pose", XR_EXT_PALM_POSE_EXTENSION_NAME, OpenXRAction::OPENXR_ACTION_POSE);
+			openxr_metadata->register_io_path(profile_path, "Grip surface pose", user_path, user_path + "/input/grip_surface/pose", XR_EXT_PALM_POSE_EXTENSION_NAME "," XR_KHR_MAINTENANCE1_EXTENSION_NAME "," XR_OPENXR_1_1_NAME, OpenXRAction::OPENXR_ACTION_POSE);
 
 
 			openxr_metadata->register_io_path(profile_path, "Menu click", user_path, user_path + "/input/menu/click", "", OpenXRAction::OPENXR_ACTION_BOOL);
 			openxr_metadata->register_io_path(profile_path, "Menu click", user_path, user_path + "/input/menu/click", "", OpenXRAction::OPENXR_ACTION_BOOL);
 
 
@@ -125,7 +129,7 @@ void OpenXRWMRControllerExtension::on_register_metadata() {
 			openxr_metadata->register_io_path(profile_path, "Aim pose", user_path, user_path + "/input/aim/pose", "", OpenXRAction::OPENXR_ACTION_POSE);
 			openxr_metadata->register_io_path(profile_path, "Aim pose", user_path, user_path + "/input/aim/pose", "", OpenXRAction::OPENXR_ACTION_POSE);
 			openxr_metadata->register_io_path(profile_path, "Pinch pose", user_path, user_path + "/input/pinch_ext/pose", XR_EXT_HAND_INTERACTION_EXTENSION_NAME, OpenXRAction::OPENXR_ACTION_POSE);
 			openxr_metadata->register_io_path(profile_path, "Pinch pose", user_path, user_path + "/input/pinch_ext/pose", XR_EXT_HAND_INTERACTION_EXTENSION_NAME, OpenXRAction::OPENXR_ACTION_POSE);
 			openxr_metadata->register_io_path(profile_path, "Poke pose", user_path, user_path + "/input/poke_ext/pose", XR_EXT_HAND_INTERACTION_EXTENSION_NAME, OpenXRAction::OPENXR_ACTION_POSE);
 			openxr_metadata->register_io_path(profile_path, "Poke pose", user_path, user_path + "/input/poke_ext/pose", XR_EXT_HAND_INTERACTION_EXTENSION_NAME, OpenXRAction::OPENXR_ACTION_POSE);
-			openxr_metadata->register_io_path(profile_path, "Palm pose", user_path, user_path + "/input/palm_ext/pose", XR_EXT_PALM_POSE_EXTENSION_NAME, OpenXRAction::OPENXR_ACTION_POSE);
+			openxr_metadata->register_io_path(profile_path, "Grip surface pose", user_path, user_path + "/input/grip_surface/pose", XR_EXT_PALM_POSE_EXTENSION_NAME "," XR_KHR_MAINTENANCE1_EXTENSION_NAME "," XR_OPENXR_1_1_NAME, OpenXRAction::OPENXR_ACTION_POSE);
 
 
 			openxr_metadata->register_io_path(profile_path, "Select (pinch)", user_path, user_path + "/input/select/value", "", OpenXRAction::OPENXR_ACTION_FLOAT);
 			openxr_metadata->register_io_path(profile_path, "Select (pinch)", user_path, user_path + "/input/select/value", "", OpenXRAction::OPENXR_ACTION_FLOAT);
 
 

+ 1 - 1
modules/openxr/extensions/openxr_wmr_controller_extension.h

@@ -46,7 +46,7 @@ public:
 		WMR_MAX_CONTROLLERS
 		WMR_MAX_CONTROLLERS
 	};
 	};
 
 
-	virtual HashMap<String, bool *> get_requested_extensions() override;
+	virtual HashMap<String, bool *> get_requested_extensions(XrVersion p_version) override;
 
 
 	bool is_available(WMRControllers p_type);
 	bool is_available(WMRControllers p_type);
 
 

+ 2 - 2
modules/openxr/extensions/platform/openxr_android_extension.cpp

@@ -55,7 +55,7 @@ OpenXRAndroidExtension::OpenXRAndroidExtension() {
 	activity_object = env->NewGlobalRef(static_cast<OS_Android *>(OS::get_singleton())->get_godot_java()->get_activity());
 	activity_object = env->NewGlobalRef(static_cast<OS_Android *>(OS::get_singleton())->get_godot_java()->get_activity());
 }
 }
 
 
-HashMap<String, bool *> OpenXRAndroidExtension::get_requested_extensions() {
+HashMap<String, bool *> OpenXRAndroidExtension::get_requested_extensions(XrVersion p_version) {
 	HashMap<String, bool *> request_extensions;
 	HashMap<String, bool *> request_extensions;
 
 
 	// XR_KHR_LOADER_INIT_EXTENSION_NAME is a dependency of XR_KHR_LOADER_INIT_ANDROID_EXTENSION_NAME
 	// XR_KHR_LOADER_INIT_EXTENSION_NAME is a dependency of XR_KHR_LOADER_INIT_ANDROID_EXTENSION_NAME
@@ -87,7 +87,7 @@ void OpenXRAndroidExtension::on_before_instance_created() {
 // This is reasonably safe as the struct is only used during initialization and the extension is a singleton.
 // This is reasonably safe as the struct is only used during initialization and the extension is a singleton.
 static XrInstanceCreateInfoAndroidKHR instance_create_info;
 static XrInstanceCreateInfoAndroidKHR instance_create_info;
 
 
-void *OpenXRAndroidExtension::set_instance_create_info_and_get_next_pointer(void *p_next_pointer) {
+void *OpenXRAndroidExtension::set_instance_create_info_and_get_next_pointer(XrVersion p_xr_version, void *p_next_pointer) {
 	if (!create_instance_extension_available) {
 	if (!create_instance_extension_available) {
 		if (!loader_init_android_extension_available) {
 		if (!loader_init_android_extension_available) {
 			WARN_PRINT("No Android extensions available, couldn't pass JVM and Activity to OpenXR");
 			WARN_PRINT("No Android extensions available, couldn't pass JVM and Activity to OpenXR");

+ 2 - 2
modules/openxr/extensions/platform/openxr_android_extension.h

@@ -41,9 +41,9 @@ public:
 
 
 	OpenXRAndroidExtension();
 	OpenXRAndroidExtension();
 
 
-	virtual HashMap<String, bool *> get_requested_extensions() override;
+	virtual HashMap<String, bool *> get_requested_extensions(XrVersion p_version) override;
 	virtual void on_before_instance_created() override;
 	virtual void on_before_instance_created() override;
-	virtual void *set_instance_create_info_and_get_next_pointer(void *p_next_pointer) override;
+	virtual void *set_instance_create_info_and_get_next_pointer(XrVersion p_xr_version, void *p_next_pointer) override;
 
 
 	virtual ~OpenXRAndroidExtension() override;
 	virtual ~OpenXRAndroidExtension() override;
 
 

+ 1 - 1
modules/openxr/extensions/platform/openxr_d3d12_extension.cpp

@@ -37,7 +37,7 @@
 #include "servers/rendering/rendering_server.h"
 #include "servers/rendering/rendering_server.h"
 #include "servers/rendering/rendering_server_globals.h"
 #include "servers/rendering/rendering_server_globals.h"
 
 
-HashMap<String, bool *> OpenXRD3D12Extension::get_requested_extensions() {
+HashMap<String, bool *> OpenXRD3D12Extension::get_requested_extensions(XrVersion p_version) {
 	HashMap<String, bool *> request_extensions;
 	HashMap<String, bool *> request_extensions;
 
 
 	request_extensions[XR_KHR_D3D12_ENABLE_EXTENSION_NAME] = nullptr;
 	request_extensions[XR_KHR_D3D12_ENABLE_EXTENSION_NAME] = nullptr;

+ 1 - 1
modules/openxr/extensions/platform/openxr_d3d12_extension.h

@@ -44,7 +44,7 @@
 
 
 class OpenXRD3D12Extension : public OpenXRGraphicsExtensionWrapper, D3D12Hooks {
 class OpenXRD3D12Extension : public OpenXRGraphicsExtensionWrapper, D3D12Hooks {
 public:
 public:
-	virtual HashMap<String, bool *> get_requested_extensions() override;
+	virtual HashMap<String, bool *> get_requested_extensions(XrVersion p_version) override;
 
 
 	virtual void on_instance_created(const XrInstance p_instance) 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 void *set_session_create_and_get_next_pointer(void *p_next_pointer) override;

+ 1 - 1
modules/openxr/extensions/platform/openxr_metal_extension.h

@@ -41,7 +41,7 @@
 
 
 class OpenXRMetalExtension : public OpenXRGraphicsExtensionWrapper {
 class OpenXRMetalExtension : public OpenXRGraphicsExtensionWrapper {
 public:
 public:
-	virtual HashMap<String, bool *> get_requested_extensions() override;
+	virtual HashMap<String, bool *> get_requested_extensions(XrVersion p_version) override;
 
 
 	virtual void on_instance_created(const XrInstance p_instance) 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 void *set_session_create_and_get_next_pointer(void *p_next_pointer) override;

+ 1 - 1
modules/openxr/extensions/platform/openxr_metal_extension.mm

@@ -35,7 +35,7 @@
 #import "drivers/metal/rendering_device_driver_metal.h"
 #import "drivers/metal/rendering_device_driver_metal.h"
 #include "servers/rendering/rendering_server_globals.h"
 #include "servers/rendering/rendering_server_globals.h"
 
 
-HashMap<String, bool *> OpenXRMetalExtension::get_requested_extensions() {
+HashMap<String, bool *> OpenXRMetalExtension::get_requested_extensions(XrVersion p_version) {
 	HashMap<String, bool *> request_extensions;
 	HashMap<String, bool *> request_extensions;
 
 
 	request_extensions[XR_KHR_METAL_ENABLE_EXTENSION_NAME] = nullptr;
 	request_extensions[XR_KHR_METAL_ENABLE_EXTENSION_NAME] = nullptr;

+ 1 - 1
modules/openxr/extensions/platform/openxr_opengl_extension.cpp

@@ -56,7 +56,7 @@
 // feature off.
 // feature off.
 // See: https://registry.khronos.org/OpenGL/extensions/EXT/EXT_sRGB_write_control.txt
 // See: https://registry.khronos.org/OpenGL/extensions/EXT/EXT_sRGB_write_control.txt
 
 
-HashMap<String, bool *> OpenXROpenGLExtension::get_requested_extensions() {
+HashMap<String, bool *> OpenXROpenGLExtension::get_requested_extensions(XrVersion p_version) {
 	HashMap<String, bool *> request_extensions;
 	HashMap<String, bool *> request_extensions;
 
 
 #ifdef ANDROID_ENABLED
 #ifdef ANDROID_ENABLED

+ 1 - 1
modules/openxr/extensions/platform/openxr_opengl_extension.h

@@ -43,7 +43,7 @@
 
 
 class OpenXROpenGLExtension : public OpenXRGraphicsExtensionWrapper {
 class OpenXROpenGLExtension : public OpenXRGraphicsExtensionWrapper {
 public:
 public:
-	virtual HashMap<String, bool *> get_requested_extensions() override;
+	virtual HashMap<String, bool *> get_requested_extensions(XrVersion p_version) override;
 
 
 	virtual void on_instance_created(const XrInstance p_instance) 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 void *set_session_create_and_get_next_pointer(void *p_next_pointer) override;

+ 1 - 1
modules/openxr/extensions/platform/openxr_vulkan_extension.cpp

@@ -39,7 +39,7 @@
 #include "servers/rendering/rendering_server.h"
 #include "servers/rendering/rendering_server.h"
 #include "servers/rendering/rendering_server_globals.h"
 #include "servers/rendering/rendering_server_globals.h"
 
 
-HashMap<String, bool *> OpenXRVulkanExtension::get_requested_extensions() {
+HashMap<String, bool *> OpenXRVulkanExtension::get_requested_extensions(XrVersion p_version) {
 	HashMap<String, bool *> request_extensions;
 	HashMap<String, bool *> request_extensions;
 
 
 	request_extensions[XR_KHR_VULKAN_ENABLE2_EXTENSION_NAME] = nullptr; // must be available
 	request_extensions[XR_KHR_VULKAN_ENABLE2_EXTENSION_NAME] = nullptr; // must be available

+ 1 - 1
modules/openxr/extensions/platform/openxr_vulkan_extension.h

@@ -45,7 +45,7 @@ public:
 	OpenXRVulkanExtension() = default;
 	OpenXRVulkanExtension() = default;
 	virtual ~OpenXRVulkanExtension() override = default;
 	virtual ~OpenXRVulkanExtension() override = default;
 
 
-	virtual HashMap<String, bool *> get_requested_extensions() override;
+	virtual HashMap<String, bool *> get_requested_extensions(XrVersion p_version) override;
 
 
 	virtual void on_instance_created(const XrInstance p_instance) 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 void *set_session_create_and_get_next_pointer(void *p_next_pointer) override;

+ 1 - 1
modules/openxr/extensions/spatial_entities/openxr_spatial_anchor.cpp

@@ -332,7 +332,7 @@ void OpenXRSpatialAnchorCapability::_bind_methods() {
 	BIND_ENUM_CONSTANT(PERSISTENCE_SCOPE_LOCAL_ANCHORS);
 	BIND_ENUM_CONSTANT(PERSISTENCE_SCOPE_LOCAL_ANCHORS);
 }
 }
 
 
-HashMap<String, bool *> OpenXRSpatialAnchorCapability::get_requested_extensions() {
+HashMap<String, bool *> OpenXRSpatialAnchorCapability::get_requested_extensions(XrVersion p_version) {
 	HashMap<String, bool *> request_extensions;
 	HashMap<String, bool *> request_extensions;
 
 
 	if (GLOBAL_GET_CACHED(bool, "xr/openxr/extensions/spatial_entity/enabled") && GLOBAL_GET_CACHED(bool, "xr/openxr/extensions/spatial_entity/enable_spatial_anchors")) {
 	if (GLOBAL_GET_CACHED(bool, "xr/openxr/extensions/spatial_entity/enabled") && GLOBAL_GET_CACHED(bool, "xr/openxr/extensions/spatial_entity/enable_spatial_anchors")) {

+ 1 - 1
modules/openxr/extensions/spatial_entities/openxr_spatial_anchor.h

@@ -158,7 +158,7 @@ public:
 	OpenXRSpatialAnchorCapability();
 	OpenXRSpatialAnchorCapability();
 	virtual ~OpenXRSpatialAnchorCapability() override;
 	virtual ~OpenXRSpatialAnchorCapability() override;
 
 
-	virtual HashMap<String, bool *> get_requested_extensions() override;
+	virtual HashMap<String, bool *> get_requested_extensions(XrVersion p_version) override;
 
 
 	virtual void on_instance_created(const XrInstance p_instance) override;
 	virtual void on_instance_created(const XrInstance p_instance) override;
 	virtual void on_instance_destroyed() override;
 	virtual void on_instance_destroyed() override;

+ 1 - 1
modules/openxr/extensions/spatial_entities/openxr_spatial_entity_extension.cpp

@@ -106,7 +106,7 @@ OpenXRSpatialEntityExtension::~OpenXRSpatialEntityExtension() {
 	singleton = nullptr;
 	singleton = nullptr;
 }
 }
 
 
-HashMap<String, bool *> OpenXRSpatialEntityExtension::get_requested_extensions() {
+HashMap<String, bool *> OpenXRSpatialEntityExtension::get_requested_extensions(XrVersion p_version) {
 	HashMap<String, bool *> request_extensions;
 	HashMap<String, bool *> request_extensions;
 
 
 	if (GLOBAL_GET_CACHED(bool, "xr/openxr/extensions/spatial_entity/enabled")) {
 	if (GLOBAL_GET_CACHED(bool, "xr/openxr/extensions/spatial_entity/enabled")) {

+ 1 - 1
modules/openxr/extensions/spatial_entities/openxr_spatial_entity_extension.h

@@ -69,7 +69,7 @@ public:
 	OpenXRSpatialEntityExtension();
 	OpenXRSpatialEntityExtension();
 	virtual ~OpenXRSpatialEntityExtension() override;
 	virtual ~OpenXRSpatialEntityExtension() override;
 
 
-	virtual HashMap<String, bool *> get_requested_extensions() override;
+	virtual HashMap<String, bool *> get_requested_extensions(XrVersion p_version) override;
 
 
 	virtual void on_instance_created(const XrInstance p_instance) override;
 	virtual void on_instance_created(const XrInstance p_instance) override;
 	virtual void on_instance_destroyed() override;
 	virtual void on_instance_destroyed() override;

+ 1 - 1
modules/openxr/extensions/spatial_entities/openxr_spatial_marker_tracking.cpp

@@ -444,7 +444,7 @@ void OpenXRSpatialMarkerTrackingCapability::_bind_methods() {
 	ClassDB::bind_method(D_METHOD("is_april_tag_supported"), &OpenXRSpatialMarkerTrackingCapability::is_april_tag_supported);
 	ClassDB::bind_method(D_METHOD("is_april_tag_supported"), &OpenXRSpatialMarkerTrackingCapability::is_april_tag_supported);
 }
 }
 
 
-HashMap<String, bool *> OpenXRSpatialMarkerTrackingCapability::get_requested_extensions() {
+HashMap<String, bool *> OpenXRSpatialMarkerTrackingCapability::get_requested_extensions(XrVersion p_version) {
 	HashMap<String, bool *> request_extensions;
 	HashMap<String, bool *> request_extensions;
 
 
 	if (GLOBAL_GET_CACHED(bool, "xr/openxr/extensions/spatial_entity/enabled") && GLOBAL_GET_CACHED(bool, "xr/openxr/extensions/spatial_entity/enable_marker_tracking")) {
 	if (GLOBAL_GET_CACHED(bool, "xr/openxr/extensions/spatial_entity/enabled") && GLOBAL_GET_CACHED(bool, "xr/openxr/extensions/spatial_entity/enable_marker_tracking")) {

+ 1 - 1
modules/openxr/extensions/spatial_entities/openxr_spatial_marker_tracking.h

@@ -228,7 +228,7 @@ public:
 	OpenXRSpatialMarkerTrackingCapability();
 	OpenXRSpatialMarkerTrackingCapability();
 	virtual ~OpenXRSpatialMarkerTrackingCapability() override;
 	virtual ~OpenXRSpatialMarkerTrackingCapability() override;
 
 
-	virtual HashMap<String, bool *> get_requested_extensions() override;
+	virtual HashMap<String, bool *> get_requested_extensions(XrVersion p_version) override;
 
 
 	virtual void on_session_created(const XrSession p_session) override;
 	virtual void on_session_created(const XrSession p_session) override;
 	virtual void on_session_destroyed() override;
 	virtual void on_session_destroyed() override;

+ 1 - 1
modules/openxr/extensions/spatial_entities/openxr_spatial_plane_tracking.cpp

@@ -583,7 +583,7 @@ void OpenXRSpatialPlaneTrackingCapability::_bind_methods() {
 	ClassDB::bind_method(D_METHOD("is_supported"), &OpenXRSpatialPlaneTrackingCapability::is_supported);
 	ClassDB::bind_method(D_METHOD("is_supported"), &OpenXRSpatialPlaneTrackingCapability::is_supported);
 }
 }
 
 
-HashMap<String, bool *> OpenXRSpatialPlaneTrackingCapability::get_requested_extensions() {
+HashMap<String, bool *> OpenXRSpatialPlaneTrackingCapability::get_requested_extensions(XrVersion p_version) {
 	HashMap<String, bool *> request_extensions;
 	HashMap<String, bool *> request_extensions;
 
 
 	if (GLOBAL_GET_CACHED(bool, "xr/openxr/extensions/spatial_entity/enabled") && GLOBAL_GET_CACHED(bool, "xr/openxr/extensions/spatial_entity/enable_plane_tracking")) {
 	if (GLOBAL_GET_CACHED(bool, "xr/openxr/extensions/spatial_entity/enabled") && GLOBAL_GET_CACHED(bool, "xr/openxr/extensions/spatial_entity/enable_plane_tracking")) {

+ 1 - 1
modules/openxr/extensions/spatial_entities/openxr_spatial_plane_tracking.h

@@ -219,7 +219,7 @@ public:
 	OpenXRSpatialPlaneTrackingCapability();
 	OpenXRSpatialPlaneTrackingCapability();
 	virtual ~OpenXRSpatialPlaneTrackingCapability() override;
 	virtual ~OpenXRSpatialPlaneTrackingCapability() override;
 
 
-	virtual HashMap<String, bool *> get_requested_extensions() override;
+	virtual HashMap<String, bool *> get_requested_extensions(XrVersion p_version) override;
 
 
 	virtual void on_session_created(const XrSession p_session) override;
 	virtual void on_session_created(const XrSession p_session) override;
 	virtual void on_session_destroyed() override;
 	virtual void on_session_destroyed() override;

+ 177 - 55
modules/openxr/openxr_api.cpp

@@ -445,11 +445,14 @@ bool OpenXRAPI::is_extension_supported(const String &p_extension) const {
 	return false;
 	return false;
 }
 }
 
 
-bool OpenXRAPI::is_extension_enabled(const String &p_extension) const {
-	CharString extension = p_extension.ascii();
-
-	for (int i = 0; i < enabled_extensions.size(); i++) {
-		if (strcmp(enabled_extensions[i].ptr(), extension.ptr()) == 0) {
+bool OpenXRAPI::is_any_extension_enabled(const String &p_extensions) const {
+	// We allow a comma separated list of extensions here, only one needs to be supported.
+	// This allows us to check for extensions that were renamed or that were embedded in core
+	// at a specific OpenXR version.
+	for (const String &name : p_extensions.split(",", false)) {
+		CharString extension = name.utf8();
+
+		if (enabled_extensions.has(extension)) {
 			return true;
 			return true;
 		}
 		}
 	}
 	}
@@ -458,19 +461,19 @@ bool OpenXRAPI::is_extension_enabled(const String &p_extension) const {
 }
 }
 
 
 bool OpenXRAPI::is_top_level_path_supported(const String &p_toplevel_path) {
 bool OpenXRAPI::is_top_level_path_supported(const String &p_toplevel_path) {
-	String required_extension = OpenXRInteractionProfileMetadata::get_singleton()->get_top_level_extension(p_toplevel_path);
+	String required_extensions = OpenXRInteractionProfileMetadata::get_singleton()->get_top_level_extensions(p_toplevel_path);
 
 
 	// If unsupported is returned we likely have a misspelled interaction profile path in our action map. Always output that as an error.
 	// If unsupported is returned we likely have a misspelled interaction profile path in our action map. Always output that as an error.
-	ERR_FAIL_COND_V_MSG(required_extension == XR_PATH_UNSUPPORTED_NAME, false, "OpenXR: Unsupported toplevel path " + p_toplevel_path);
+	ERR_FAIL_COND_V_MSG(required_extensions == XR_PATH_UNSUPPORTED_NAME, false, "OpenXR: Unsupported toplevel path " + p_toplevel_path);
 
 
-	if (required_extension == "") {
+	if (required_extensions == "") {
 		// no extension needed, core top level are always "supported", they just won't be used if not really supported
 		// no extension needed, core top level are always "supported", they just won't be used if not really supported
 		return true;
 		return true;
 	}
 	}
 
 
-	if (!is_extension_enabled(required_extension)) {
+	if (!is_any_extension_enabled(required_extensions)) {
 		// It is very likely we have top level paths for which the extension is not available so don't flood the logs with unnecessary spam.
 		// It is very likely we have top level paths for which the extension is not available so don't flood the logs with unnecessary spam.
-		print_verbose("OpenXR: Top level path " + p_toplevel_path + " requires extension " + required_extension);
+		print_verbose("OpenXR: Top level path " + p_toplevel_path + " requires extension " + required_extensions.replace(",", " or "));
 		return false;
 		return false;
 	}
 	}
 
 
@@ -478,19 +481,19 @@ bool OpenXRAPI::is_top_level_path_supported(const String &p_toplevel_path) {
 }
 }
 
 
 bool OpenXRAPI::is_interaction_profile_supported(const String &p_ip_path) {
 bool OpenXRAPI::is_interaction_profile_supported(const String &p_ip_path) {
-	String required_extension = OpenXRInteractionProfileMetadata::get_singleton()->get_interaction_profile_extension(p_ip_path);
+	String required_extensions = OpenXRInteractionProfileMetadata::get_singleton()->get_interaction_profile_extensions(p_ip_path);
 
 
 	// If unsupported is returned we likely have a misspelled interaction profile path in our action map. Always output that as an error.
 	// If unsupported is returned we likely have a misspelled interaction profile path in our action map. Always output that as an error.
-	ERR_FAIL_COND_V_MSG(required_extension == XR_PATH_UNSUPPORTED_NAME, false, "OpenXR: Unsupported interaction profile " + p_ip_path);
+	ERR_FAIL_COND_V_MSG(required_extensions == XR_PATH_UNSUPPORTED_NAME, false, "OpenXR: Unsupported interaction profile " + p_ip_path);
 
 
-	if (required_extension == "") {
+	if (required_extensions == "") {
 		// no extension needed, core interaction profiles are always "supported", they just won't be used if not really supported
 		// no extension needed, core interaction profiles are always "supported", they just won't be used if not really supported
 		return true;
 		return true;
 	}
 	}
 
 
-	if (!is_extension_enabled(required_extension)) {
+	if (!is_any_extension_enabled(required_extensions)) {
 		// It is very likely we have interaction profiles for which the extension is not available so don't flood the logs with unnecessary spam.
 		// It is very likely we have interaction profiles for which the extension is not available so don't flood the logs with unnecessary spam.
-		print_verbose("OpenXR: Interaction profile " + p_ip_path + " requires extension " + required_extension);
+		print_verbose("OpenXR: Interaction profile " + p_ip_path + " requires extension " + required_extensions.replace(",", " or "));
 		return false;
 		return false;
 	}
 	}
 
 
@@ -507,14 +510,14 @@ bool OpenXRAPI::interaction_profile_supports_io_path(const String &p_ip_path, co
 	// If the io_path is not part of our metadata we've likely got a misspelled name or a bad action map, report
 	// If the io_path is not part of our metadata we've likely got a misspelled name or a bad action map, report
 	ERR_FAIL_NULL_V_MSG(io_path, false, "OpenXR: Unsupported io path " + String(p_ip_path) + String(p_io_path));
 	ERR_FAIL_NULL_V_MSG(io_path, false, "OpenXR: Unsupported io path " + String(p_ip_path) + String(p_io_path));
 
 
-	if (io_path->openxr_extension_name == "") {
+	if (io_path->openxr_extension_names == "") {
 		// no extension needed, core io paths are always "supported", they just won't be used if not really supported
 		// no extension needed, core io paths are always "supported", they just won't be used if not really supported
 		return true;
 		return true;
 	}
 	}
 
 
-	if (!is_extension_enabled(io_path->openxr_extension_name)) {
+	if (!is_any_extension_enabled(io_path->openxr_extension_names)) {
 		// It is very likely we have io paths for which the extension is not available so don't flood the logs with unnecessary spam.
 		// It is very likely we have io paths for which the extension is not available so don't flood the logs with unnecessary spam.
-		print_verbose("OpenXR: IO path " + String(p_ip_path) + String(p_io_path) + " requires extension " + io_path->openxr_extension_name);
+		print_verbose("OpenXR: IO path " + String(p_ip_path) + String(p_io_path) + " requires extension " + io_path->openxr_extension_names.replace(",", " or "));
 		return false;
 		return false;
 	}
 	}
 
 
@@ -534,13 +537,13 @@ void OpenXRAPI::copy_string_to_char_buffer(const String &p_string, char *p_buffe
 	}
 	}
 }
 }
 
 
-PackedStringArray OpenXRAPI::get_all_requested_extensions() {
+PackedStringArray OpenXRAPI::get_all_requested_extensions(XrVersion p_xr_version) {
 	// This returns all extensions we will request regardless of whether they are available.
 	// This returns all extensions we will request regardless of whether they are available.
-	// This is mostly used by the editor to filter features not enabled through project settings.
+	// This is used by the editor to filter features not enabled through project settings.
 
 
 	PackedStringArray requested_extensions;
 	PackedStringArray requested_extensions;
 	for (OpenXRExtensionWrapper *wrapper : registered_extension_wrappers) {
 	for (OpenXRExtensionWrapper *wrapper : registered_extension_wrappers) {
-		const HashMap<String, bool *> &wrapper_request_extensions = wrapper->get_requested_extensions();
+		const HashMap<String, bool *> &wrapper_request_extensions = wrapper->get_requested_extensions(p_xr_version);
 
 
 		for (const KeyValue<String, bool *> &requested_extension : wrapper_request_extensions) {
 		for (const KeyValue<String, bool *> &requested_extension : wrapper_request_extensions) {
 			if (!requested_extensions.has(requested_extension.key)) {
 			if (!requested_extensions.has(requested_extension.key)) {
@@ -549,36 +552,30 @@ PackedStringArray OpenXRAPI::get_all_requested_extensions() {
 		}
 		}
 	}
 	}
 
 
+	// Also add in our OpenXR Version "extension", so we can switch logic on that.
+	requested_extensions.push_back(XR_OPENXR_1_1_NAME);
+
 	return requested_extensions;
 	return requested_extensions;
 }
 }
 
 
-bool OpenXRAPI::create_instance() {
-	// Create our OpenXR instance, this will query any registered extension wrappers for extensions we need to enable.
-
-	// We can request an extension multiple times if there are dependencies
-	struct RequestExtension {
-		String name;
-		bool *enabled;
-	};
+XrResult OpenXRAPI::attempt_create_instance(XrVersion p_version) {
+	enabled_extensions.clear();
 
 
-	// Find all extensions we wish to enable.
-	Vector<RequestExtension> requested_extensions;
+	// Find all extensions we wish to enable for the requested OpenXR version.
+	LocalVector<RequestExtension> requested_extensions;
 	for (OpenXRExtensionWrapper *wrapper : registered_extension_wrappers) {
 	for (OpenXRExtensionWrapper *wrapper : registered_extension_wrappers) {
-		const HashMap<String, bool *> &wrapper_request_extensions = wrapper->get_requested_extensions();
+		const HashMap<String, bool *> &wrapper_request_extensions = wrapper->get_requested_extensions(p_version);
 
 
 		for (const KeyValue<String, bool *> &requested_extension : wrapper_request_extensions) {
 		for (const KeyValue<String, bool *> &requested_extension : wrapper_request_extensions) {
 			requested_extensions.push_back({ requested_extension.key, requested_extension.value });
 			requested_extensions.push_back({ requested_extension.key, requested_extension.value });
 		}
 		}
 	}
 	}
 
 
-	// Check which extensions are supported.
-	enabled_extensions.clear();
-
-	for (RequestExtension &requested_extension : requested_extensions) {
+	for (const RequestExtension &requested_extension : requested_extensions) {
 		if (!is_extension_supported(requested_extension.name)) {
 		if (!is_extension_supported(requested_extension.name)) {
 			if (requested_extension.enabled == nullptr) {
 			if (requested_extension.enabled == nullptr) {
 				// Null means this is a mandatory extension so we fail.
 				// Null means this is a mandatory extension so we fail.
-				ERR_FAIL_V_MSG(false, String("OpenXR: OpenXR Runtime does not support ") + requested_extension.name + String(" extension!"));
+				ERR_FAIL_V_MSG(XR_ERROR_INITIALIZATION_FAILED, String("OpenXR: OpenXR Runtime does not support ") + requested_extension.name + String(" extension!"));
 			} else {
 			} else {
 				// Set this extension as not supported.
 				// Set this extension as not supported.
 				*requested_extension.enabled = false;
 				*requested_extension.enabled = false;
@@ -590,41 +587,41 @@ bool OpenXRAPI::create_instance() {
 			}
 			}
 
 
 			// And record that we want to enable it (dependent extensions may be requested multiple times).
 			// And record that we want to enable it (dependent extensions may be requested multiple times).
-			CharString ext_name = requested_extension.name.ascii();
+			CharString ext_name = requested_extension.name.utf8();
 			if (!enabled_extensions.has(ext_name)) {
 			if (!enabled_extensions.has(ext_name)) {
 				enabled_extensions.push_back(ext_name);
 				enabled_extensions.push_back(ext_name);
 			}
 			}
 		}
 		}
 	}
 	}
 
 
-	Vector<const char *> extension_ptrs;
-	for (int i = 0; i < enabled_extensions.size(); i++) {
-		print_verbose(String("OpenXR: Enabling extension ") + String(enabled_extensions[i].get_data()));
-		extension_ptrs.push_back(enabled_extensions[i].get_data());
-	}
+	// Convert our enabled extensions so we can send it to OpenXR.
+	LocalVector<const char *> extension_ptrs;
+	extension_ptrs.reserve(enabled_extensions.size());
 
 
-	// We explicitly set the version to 1.0.48 in order to workaround a bug (see #108850) in Meta's runtime.
-	// Once that is fixed, restore this to using XR_API_VERSION_1_0, which is the version associated with the
-	// OpenXR headers that we're using.
-	XrVersion openxr_version = XR_MAKE_VERSION(1, 0, 48);
+	for (const CharString &enabled_extension : enabled_extensions) {
+		const char *extension = enabled_extension.get_data();
+		extension_ptrs.push_back(extension);
+	}
 
 
-	// Create our OpenXR instance
+	// Attempt to create our OpenXR instance for the requested version.
 	XrApplicationInfo application_info{
 	XrApplicationInfo application_info{
 		"Godot Engine", // applicationName, if we're running a game we'll update this down below.
 		"Godot Engine", // applicationName, if we're running a game we'll update this down below.
 		1, // applicationVersion, we don't currently have this
 		1, // applicationVersion, we don't currently have this
 		"Godot Engine", // engineName
 		"Godot Engine", // engineName
 		GODOT_VERSION_MAJOR * 10000 + GODOT_VERSION_MINOR * 100 + GODOT_VERSION_PATCH, // engineVersion 4.0 -> 40000, 4.0.1 -> 40001, 4.1 -> 40100, etc.
 		GODOT_VERSION_MAJOR * 10000 + GODOT_VERSION_MINOR * 100 + GODOT_VERSION_PATCH, // engineVersion 4.0 -> 40000, 4.0.1 -> 40001, 4.1 -> 40100, etc.
-		openxr_version, // apiVersion
+		p_version // apiVersion
 	};
 	};
 
 
+	// Get additional entries from our extension wrappers.
 	void *next_pointer = nullptr;
 	void *next_pointer = nullptr;
 	for (OpenXRExtensionWrapper *wrapper : registered_extension_wrappers) {
 	for (OpenXRExtensionWrapper *wrapper : registered_extension_wrappers) {
-		void *np = wrapper->set_instance_create_info_and_get_next_pointer(next_pointer);
+		void *np = wrapper->set_instance_create_info_and_get_next_pointer(p_version, next_pointer);
 		if (np != nullptr) {
 		if (np != nullptr) {
 			next_pointer = np;
 			next_pointer = np;
 		}
 		}
 	}
 	}
 
 
+	// Try and create this instance.
 	XrInstanceCreateInfo instance_create_info = {
 	XrInstanceCreateInfo instance_create_info = {
 		XR_TYPE_INSTANCE_CREATE_INFO, // type
 		XR_TYPE_INSTANCE_CREATE_INFO, // type
 		next_pointer, // next
 		next_pointer, // next
@@ -636,16 +633,44 @@ bool OpenXRAPI::create_instance() {
 		extension_ptrs.ptr() // enabledExtensionNames
 		extension_ptrs.ptr() // enabledExtensionNames
 	};
 	};
 
 
-	// Get our project name
+	// Get our project name.
 	String project_name = GLOBAL_GET("application/config/name");
 	String project_name = GLOBAL_GET("application/config/name");
 	if (!project_name.is_empty()) {
 	if (!project_name.is_empty()) {
 		copy_string_to_char_buffer(project_name, instance_create_info.applicationInfo.applicationName, XR_MAX_APPLICATION_NAME_SIZE);
 		copy_string_to_char_buffer(project_name, instance_create_info.applicationInfo.applicationName, XR_MAX_APPLICATION_NAME_SIZE);
 	}
 	}
 
 
 	XrResult result = xrCreateInstance(&instance_create_info, &instance);
 	XrResult result = xrCreateInstance(&instance_create_info, &instance);
-	ERR_FAIL_COND_V_MSG(XR_FAILED(result), false, "Failed to create XR instance [" + get_error_string(result) + "].");
+	if (XR_SUCCEEDED(result)) {
+		// Record version we've successfully enabled.
+		openxr_version = p_version;
+		print_line("OpenXR: Created instance for OpenXR", OpenXRUtil::make_xr_version_string(openxr_version));
+
+		if (is_print_verbose_enabled()) {
+			// Print out enabled extensions.
+			for (const char *extension : extension_ptrs) {
+				print_line("OpenXR: Enabled extension ", extension);
+			}
+		}
+	}
+
+	return result;
+}
 
 
-	// from this point on we can use get_error_string to get more info about our errors...
+bool OpenXRAPI::create_instance() {
+	// Create our OpenXR instance, this will query any registered extension wrappers for extensions we need to enable.
+
+	// We explicitly set the version to 1.x.48 in order to workaround a bug (see #108850) in Meta's runtime.
+	// Once that is fixed, restore this to using XR_API_VERSION_1_x, which is the version associated with the
+	// OpenXR headers that we're using.
+
+	XrResult result = attempt_create_instance(XR_MAKE_VERSION(1, 1, 48)); // Replace with XR_API_VERSION_1_1
+	if (result == XR_ERROR_API_VERSION_UNSUPPORTED) {
+		// Couldn't initialize OpenXR 1.1, try 1.0
+		print_verbose("OpenXR: Falling back to OpenXR 1.0");
+
+		result = attempt_create_instance(XR_MAKE_VERSION(1, 0, 48)); // Replace with XR_API_VERSION_1_0
+	}
+	ERR_FAIL_COND_V_MSG(XR_FAILED(result), false, "Failed to create XR instance [" + get_error_string(result) + "].");
 
 
 	XrInstanceProperties instanceProps = {
 	XrInstanceProperties instanceProps = {
 		XR_TYPE_INSTANCE_PROPERTIES, // type;
 		XR_TYPE_INSTANCE_PROPERTIES, // type;
@@ -669,6 +694,12 @@ bool OpenXRAPI::create_instance() {
 		print_line("OpenXR: Running on OpenXR runtime: ", runtime_name, " ", runtime_version);
 		print_line("OpenXR: Running on OpenXR runtime: ", runtime_name, " ", runtime_version);
 	}
 	}
 
 
+	// We add an extension string to indicate we're on OpenXR 1.1,
+	// this makes it easier to check for this in various places where we're already checking on extensions.
+	if (XR_VERSION_MAJOR(openxr_version) == 1 && XR_VERSION_MINOR(openxr_version) == 1) {
+		enabled_extensions.push_back(XR_OPENXR_1_1_NAME);
+	}
+
 	for (OpenXRExtensionWrapper *wrapper : registered_extension_wrappers) {
 	for (OpenXRExtensionWrapper *wrapper : registered_extension_wrappers) {
 		wrapper->on_instance_created(instance);
 		wrapper->on_instance_created(instance);
 	}
 	}
@@ -979,6 +1010,8 @@ bool OpenXRAPI::setup_play_space() {
 	} else if (is_reference_space_supported(requested_reference_space)) {
 	} else if (is_reference_space_supported(requested_reference_space)) {
 		new_reference_space = requested_reference_space;
 		new_reference_space = requested_reference_space;
 	} else if (requested_reference_space == XR_REFERENCE_SPACE_TYPE_LOCAL_FLOOR_EXT && is_reference_space_supported(XR_REFERENCE_SPACE_TYPE_STAGE)) {
 	} else if (requested_reference_space == XR_REFERENCE_SPACE_TYPE_LOCAL_FLOOR_EXT && is_reference_space_supported(XR_REFERENCE_SPACE_TYPE_STAGE)) {
+		// Note, in OpenXR 1.0 XR_EXT_LOCAL_FLOOR_EXTENSION_NAME needs to be enabled
+		// but from OpenXR 1.1 onwards this should always be available.
 		print_verbose("OpenXR: LOCAL_FLOOR space isn't supported, emulating using STAGE and LOCAL spaces.");
 		print_verbose("OpenXR: LOCAL_FLOOR space isn't supported, emulating using STAGE and LOCAL spaces.");
 
 
 		new_reference_space = XR_REFERENCE_SPACE_TYPE_LOCAL;
 		new_reference_space = XR_REFERENCE_SPACE_TYPE_LOCAL;
@@ -3410,7 +3443,9 @@ RID OpenXRAPI::interaction_profile_create(const String &p_name) {
 
 
 	InteractionProfile new_interaction_profile;
 	InteractionProfile new_interaction_profile;
 
 
-	XrResult result = xrStringToPath(instance, p_name.utf8().get_data(), &new_interaction_profile.path);
+	new_interaction_profile.internal_name = get_interaction_profile_internal_name(p_name);
+
+	XrResult result = xrStringToPath(instance, new_interaction_profile.internal_name.get_data(), &new_interaction_profile.path);
 	if (XR_FAILED(result)) {
 	if (XR_FAILED(result)) {
 		print_line("OpenXR: failed to get path for ", p_name, "! [", get_error_string(result), "]");
 		print_line("OpenXR: failed to get path for ", p_name, "! [", get_error_string(result), "]");
 		return RID();
 		return RID();
@@ -3443,6 +3478,93 @@ void OpenXRAPI::interaction_profile_clear_bindings(RID p_interaction_profile) {
 	ip->bindings.clear();
 	ip->bindings.clear();
 }
 }
 
 
+CharString OpenXRAPI::get_interaction_profile_internal_name(const String &p_interaction_profile_name) const {
+	CharString internal_name = p_interaction_profile_name.utf8();
+
+	if (openxr_version < XR_API_VERSION_1_1_0) {
+		// These interaction profiles were renamed in OpenXR 1.1,
+		// if we don't support OpenXR 1.1, rename them back.
+		if (internal_name == "/interaction_profiles/meta/touch_pro_controller") {
+			return "/interaction_profiles/facebook/touch_controller_pro";
+		} else if (internal_name == "/interaction_profiles/meta/touch_plus_controller") {
+			return "/interaction_profiles/meta/touch_controller_plus";
+		}
+	}
+
+	return internal_name;
+}
+
+const char *OpenXRAPI::check_profile_path(const CharString &p_interaction_profile_name, const char *p_path) const {
+	// We store the new names of these paths in our action map, so if we're on older versions of OpenXR,
+	// we need to use the old names.
+
+	struct RenameMap {
+		const XrVersion before_version; // If we're on an older version of OpenXR than this (if none zero).
+		const char *from; // Rename from this
+		const char *to; // to this
+		const char *profile; // limiting to this profile (unless nullptr)
+	};
+
+	// The order of entries is important as we early exit when we encounter a before_version value before our current value (excluding 0).
+	const RenameMap renames[] = {
+		// The touch_controller is an exception where it is still using the vendor names because they were introduced after OpenXR 1.1 was defined.
+		{ 0, "/user/hand/left/input/trigger/proximity", "/user/hand/left/input/trigger/proximity_fb", "/interaction_profiles/oculus/touch_controller" },
+		{ 0, "/user/hand/right/input/trigger/proximity", "/user/hand/right/input/trigger/proximity_fb", "/interaction_profiles/oculus/touch_controller" },
+		{ 0, "/user/hand/left/input/thumb_resting_surfaces/proximity", "/user/hand/left/input/thumb_fb/proximity_fb", "/interaction_profiles/oculus/touch_controller" },
+		{ 0, "/user/hand/right/input/thumb_resting_surfaces/proximity", "/user/hand/right/input/thumb_fb/proximity_fb", "/interaction_profiles/oculus/touch_controller" },
+
+		// Once applicable, add XR_API_VERSION_1_2 here.
+
+		// Before OpenXR 1.1 we're using palm_ext/pose (we're checking for enabled palm pose extension elsewhere).
+		{ XR_API_VERSION_1_1_0, "/user/hand/left/input/grip_surface/pose", "/user/hand/left/input/palm_ext/pose", nullptr },
+		{ XR_API_VERSION_1_1_0, "/user/hand/right/input/grip_surface/pose", "/user/hand/right/input/palm_ext/pose", nullptr },
+
+		// Specific renames for touch_controller_pro, note that we would have already renamed it to the old name.
+		{ XR_API_VERSION_1_1_0, "/user/hand/left/input/grip_surface/pose", "/user/hand/left/input/palm_ext/pose", "/interaction_profiles/facebook/touch_controller_pro" },
+		{ XR_API_VERSION_1_1_0, "/user/hand/right/input/grip_surface/pose", "/user/hand/right/input/palm_ext/pose", "/interaction_profiles/facebook/touch_controller_pro" },
+		{ XR_API_VERSION_1_1_0, "/user/hand/left/input/stylus/force", "/user/hand/left/input/stylus_fb/force", "/interaction_profiles/facebook/touch_controller_pro" },
+		{ XR_API_VERSION_1_1_0, "/user/hand/right/input/stylus/force", "/user/hand/right/input/stylus_fb/force", "/interaction_profiles/facebook/touch_controller_pro" },
+		{ XR_API_VERSION_1_1_0, "/user/hand/left/input/trigger/proximity", "/user/hand/left/input/trigger/proximity_fb", "/interaction_profiles/facebook/touch_controller_pro" },
+		{ XR_API_VERSION_1_1_0, "/user/hand/right/input/trigger/proximity", "/user/hand/right/input/trigger/proximity_fb", "/interaction_profiles/facebook/touch_controller_pro" },
+		{ XR_API_VERSION_1_1_0, "/user/hand/left/output/haptic_trigger", "/user/hand/left/output/haptic_trigger_fb", "/interaction_profiles/facebook/touch_controller_pro" },
+		{ XR_API_VERSION_1_1_0, "/user/hand/right/output/haptic_trigger", "/user/hand/right/output/haptic_trigger_fb", "/interaction_profiles/facebook/touch_controller_pro" },
+		{ XR_API_VERSION_1_1_0, "/user/hand/left/output/haptic_thumb", "/user/hand/left/output/haptic_thumb_fb", "/interaction_profiles/facebook/touch_controller_pro" },
+		{ XR_API_VERSION_1_1_0, "/user/hand/right/output/haptic_thumb", "/user/hand/right/output/haptic_thumb_fb", "/interaction_profiles/facebook/touch_controller_pro" },
+		{ XR_API_VERSION_1_1_0, "/user/hand/left/input/thumb_resting_surfaces/proximity", "/user/hand/left/input/thumb_fb/proximity_fb", "/interaction_profiles/facebook/touch_controller_pro" },
+		{ XR_API_VERSION_1_1_0, "/user/hand/right/input/thumb_resting_surfaces/proximity", "/user/hand/right/input/thumb_fb/proximity_fb", "/interaction_profiles/facebook/touch_controller_pro" },
+		{ XR_API_VERSION_1_1_0, "/user/hand/left/input/trigger_curl/value", "/user/hand/left/input/trigger/curl_fb", "/interaction_profiles/facebook/touch_controller_pro" },
+		{ XR_API_VERSION_1_1_0, "/user/hand/right/input/trigger_curl/value", "/user/hand/right/input/trigger/curl_fb", "/interaction_profiles/facebook/touch_controller_pro" },
+		{ XR_API_VERSION_1_1_0, "/user/hand/left/input/trigger_slide/value", "/user/hand/left/input/trigger/slide_fb", "/interaction_profiles/facebook/touch_controller_pro" },
+		{ XR_API_VERSION_1_1_0, "/user/hand/right/input/trigger_slide/value", "/user/hand/right/input/trigger/slide_fb", "/interaction_profiles/facebook/touch_controller_pro" },
+
+		// Specific renames for touch_controller_plus, note that we would have already renamed it to the old name.
+		{ XR_API_VERSION_1_1_0, "/user/hand/left/input/trigger/proximity", "/user/hand/left/input/trigger/proximity_meta", "/interaction_profiles/facebook/touch_controller_plus" },
+		{ XR_API_VERSION_1_1_0, "/user/hand/right/input/trigger/proximity", "/user/hand/right/input/trigger/proximity_meta", "/interaction_profiles/facebook/touch_controller_plus" },
+		{ XR_API_VERSION_1_1_0, "/user/hand/left/input/thumb_resting_surfaces/proximity", "/user/hand/left/input/thumb_meta/proximity_meta", "/interaction_profiles/facebook/touch_controller_plus" },
+		{ XR_API_VERSION_1_1_0, "/user/hand/right/input/thumb_resting_surfaces/proximity", "/user/hand/right/input/thumb_meta/proximity_meta", "/interaction_profiles/facebook/touch_controller_plus" },
+		{ XR_API_VERSION_1_1_0, "/user/hand/left/input/trigger_curl/value", "/user/hand/left/input/trigger/curl_meta", "/interaction_profiles/facebook/touch_controller_plus" },
+		{ XR_API_VERSION_1_1_0, "/user/hand/right/input/trigger_curl/value", "/user/hand/right/input/trigger/curl_meta", "/interaction_profiles/facebook/touch_controller_plus" },
+		{ XR_API_VERSION_1_1_0, "/user/hand/left/input/trigger_slide/value", "/user/hand/left/input/trigger/slide_meta", "/interaction_profiles/facebook/touch_controller_plus" },
+		{ XR_API_VERSION_1_1_0, "/user/hand/right/input/trigger_slide/value", "/user/hand/right/input/trigger/slide_meta", "/interaction_profiles/facebook/touch_controller_plus" },
+	};
+	constexpr size_t length = sizeof(renames) / sizeof(renames[0]);
+
+	for (size_t i = 0; i < length; i++) {
+		const RenameMap &rename = renames[i];
+
+		if (rename.before_version != 0 && openxr_version >= rename.before_version) {
+			// We're done, we are on a new version than this, no need to check further.
+			return p_path;
+		}
+
+		if ((rename.profile == nullptr || p_interaction_profile_name == rename.profile) && strcmp(p_path, rename.from) == 0) {
+			return rename.to;
+		}
+	}
+
+	return p_path;
+}
+
 int OpenXRAPI::interaction_profile_add_binding(RID p_interaction_profile, RID p_action, const String &p_path) {
 int OpenXRAPI::interaction_profile_add_binding(RID p_interaction_profile, RID p_action, const String &p_path) {
 	InteractionProfile *ip = interaction_profile_owner.get_or_null(p_interaction_profile);
 	InteractionProfile *ip = interaction_profile_owner.get_or_null(p_interaction_profile);
 	ERR_FAIL_NULL_V(ip, -1);
 	ERR_FAIL_NULL_V(ip, -1);
@@ -3458,7 +3580,7 @@ int OpenXRAPI::interaction_profile_add_binding(RID p_interaction_profile, RID p_
 
 
 	binding.action = action->handle;
 	binding.action = action->handle;
 
 
-	XrResult result = xrStringToPath(instance, p_path.utf8().get_data(), &binding.binding);
+	XrResult result = xrStringToPath(instance, check_profile_path(ip->internal_name, p_path.utf8().get_data()), &binding.binding);
 	if (XR_FAILED(result)) {
 	if (XR_FAILED(result)) {
 		print_line("OpenXR: failed to get path for ", p_path, "! [", get_error_string(result), "]");
 		print_line("OpenXR: failed to get path for ", p_path, "! [", get_error_string(result), "]");
 		return -1;
 		return -1;

+ 20 - 3
modules/openxr/openxr_api.h

@@ -46,6 +46,11 @@
 
 
 #include <openxr/openxr.h>
 #include <openxr/openxr.h>
 
 
+// Name we add to our extensions if OpenXR 1.1 context is available.
+#define XR_OPENXR_1_1_NAME "OPENXR_1_1"
+
+#define XR_API_VERSION_1_1_0 XR_MAKE_VERSION(1, 1, 0)
+
 // forward declarations, we don't want to include these fully
 // forward declarations, we don't want to include these fully
 class OpenXRInterface;
 class OpenXRInterface;
 
 
@@ -91,7 +96,7 @@ private:
 
 
 	// extensions
 	// extensions
 	LocalVector<XrExtensionProperties> supported_extensions;
 	LocalVector<XrExtensionProperties> supported_extensions;
-	Vector<CharString> enabled_extensions;
+	LocalVector<CharString> enabled_extensions;
 
 
 	// composition layer providers
 	// composition layer providers
 	Vector<OpenXRExtensionWrapper *> composition_layer_providers;
 	Vector<OpenXRExtensionWrapper *> composition_layer_providers;
@@ -112,6 +117,7 @@ private:
 	PackedInt64Array supported_swapchain_formats;
 	PackedInt64Array supported_swapchain_formats;
 
 
 	// system info
 	// system info
+	XrVersion openxr_version;
 	String runtime_name;
 	String runtime_name;
 	String runtime_version;
 	String runtime_version;
 
 
@@ -180,7 +186,13 @@ private:
 	bool load_layer_properties();
 	bool load_layer_properties();
 	bool load_supported_extensions();
 	bool load_supported_extensions();
 	bool is_extension_supported(const String &p_extension) const;
 	bool is_extension_supported(const String &p_extension) const;
-	bool is_extension_enabled(const String &p_extension) const;
+	bool is_any_extension_enabled(const String &p_extensions) const;
+
+	struct RequestExtension {
+		String name;
+		bool *enabled;
+	};
+	XrResult attempt_create_instance(XrVersion p_version);
 
 
 	bool openxr_loader_init();
 	bool openxr_loader_init();
 	bool resolve_instance_openxr_symbols();
 	bool resolve_instance_openxr_symbols();
@@ -299,6 +311,7 @@ private:
 
 
 	struct InteractionProfile { // Interaction profiles define suggested bindings between the physical inputs on controller types and our actions
 	struct InteractionProfile { // Interaction profiles define suggested bindings between the physical inputs on controller types and our actions
 		String name; // Name of the interaction profile (i.e. "/interaction_profiles/valve/index_controller")
 		String name; // Name of the interaction profile (i.e. "/interaction_profiles/valve/index_controller")
+		CharString internal_name; // Internal name of the interaction profile (translated if required)
 		XrPath path; // OpenXR path for this profile
 		XrPath path; // OpenXR path for this profile
 		Vector<XrActionSuggestedBinding> bindings; // OpenXR action bindings
 		Vector<XrActionSuggestedBinding> bindings; // OpenXR action bindings
 		Vector<PackedByteArray> modifiers; // Array of modifiers we'll add into XrBindingModificationsKHR
 		Vector<PackedByteArray> modifiers; // Array of modifiers we'll add into XrBindingModificationsKHR
@@ -307,6 +320,9 @@ private:
 	RID get_interaction_profile_rid(XrPath p_path);
 	RID get_interaction_profile_rid(XrPath p_path);
 	XrPath get_interaction_profile_path(RID p_interaction_profile);
 	XrPath get_interaction_profile_path(RID p_interaction_profile);
 
 
+	CharString get_interaction_profile_internal_name(const String &p_interaction_profile_name) const;
+	const char *check_profile_path(const CharString &p_interaction_profile_name, const char *p_path) const;
+
 	struct OrderedCompositionLayer {
 	struct OrderedCompositionLayer {
 		const XrCompositionLayerBaseHeader *composition_layer;
 		const XrCompositionLayerBaseHeader *composition_layer;
 		int sort_order;
 		int sort_order;
@@ -436,6 +452,7 @@ public:
 		rendering_server->call_on_render_thread(callable_mp_static(&OpenXRAPI::_update_main_swapchain_size_rt));
 		rendering_server->call_on_render_thread(callable_mp_static(&OpenXRAPI::_update_main_swapchain_size_rt));
 	}
 	}
 
 
+	XrVersion get_openxr_version() const { return openxr_version; }
 	XrInstance get_instance() const { return instance; }
 	XrInstance get_instance() const { return instance; }
 	XrSystemId get_system_id() const { return system_id; }
 	XrSystemId get_system_id() const { return system_id; }
 	XrSession get_session() const { return session; }
 	XrSession get_session() const { return session; }
@@ -480,7 +497,7 @@ public:
 	static const Vector<OpenXRExtensionWrapper *> &get_registered_extension_wrappers();
 	static const Vector<OpenXRExtensionWrapper *> &get_registered_extension_wrappers();
 	static void register_extension_metadata();
 	static void register_extension_metadata();
 	static void cleanup_extension_wrappers();
 	static void cleanup_extension_wrappers();
-	static PackedStringArray get_all_requested_extensions();
+	static PackedStringArray get_all_requested_extensions(XrVersion p_xr_version);
 
 
 	void set_form_factor(XrFormFactor p_form_factor);
 	void set_form_factor(XrFormFactor p_form_factor);
 	XrFormFactor get_form_factor() const { return form_factor; }
 	XrFormFactor get_form_factor() const { return form_factor; }

+ 6 - 0
modules/openxr/openxr_api_extension.cpp

@@ -34,6 +34,7 @@
 #include "openxr_api_extension.compat.inc"
 #include "openxr_api_extension.compat.inc"
 
 
 void OpenXRAPIExtension::_bind_methods() {
 void OpenXRAPIExtension::_bind_methods() {
+	ClassDB::bind_method(D_METHOD("get_openxr_version"), &OpenXRAPIExtension::get_openxr_version);
 	ClassDB::bind_method(D_METHOD("get_instance"), &OpenXRAPIExtension::get_instance);
 	ClassDB::bind_method(D_METHOD("get_instance"), &OpenXRAPIExtension::get_instance);
 	ClassDB::bind_method(D_METHOD("get_system_id"), &OpenXRAPIExtension::get_system_id);
 	ClassDB::bind_method(D_METHOD("get_system_id"), &OpenXRAPIExtension::get_system_id);
 	ClassDB::bind_method(D_METHOD("get_session"), &OpenXRAPIExtension::get_session);
 	ClassDB::bind_method(D_METHOD("get_session"), &OpenXRAPIExtension::get_session);
@@ -102,6 +103,11 @@ void OpenXRAPIExtension::_bind_methods() {
 	BIND_ENUM_CONSTANT(OPENXR_ALPHA_BLEND_MODE_SUPPORT_EMULATING);
 	BIND_ENUM_CONSTANT(OPENXR_ALPHA_BLEND_MODE_SUPPORT_EMULATING);
 }
 }
 
 
+uint64_t OpenXRAPIExtension::get_openxr_version() {
+	ERR_FAIL_NULL_V(OpenXRAPI::get_singleton(), 0);
+	return (uint64_t)OpenXRAPI::get_singleton()->get_openxr_version();
+}
+
 uint64_t OpenXRAPIExtension::get_instance() {
 uint64_t OpenXRAPIExtension::get_instance() {
 	ERR_FAIL_NULL_V(OpenXRAPI::get_singleton(), 0);
 	ERR_FAIL_NULL_V(OpenXRAPI::get_singleton(), 0);
 	return (uint64_t)OpenXRAPI::get_singleton()->get_instance();
 	return (uint64_t)OpenXRAPI::get_singleton()->get_instance();

+ 1 - 0
modules/openxr/openxr_api_extension.h

@@ -56,6 +56,7 @@ protected:
 #endif
 #endif
 
 
 public:
 public:
+	uint64_t get_openxr_version();
 	uint64_t get_instance();
 	uint64_t get_instance();
 	uint64_t get_system_id();
 	uint64_t get_system_id();
 	uint64_t get_session();
 	uint64_t get_session();