From 998c876f369f47a54368fe8ea7f1419e857f0134 Mon Sep 17 00:00:00 2001 From: Bastiaan Olij Date: Fri, 16 Jan 2026 16:42:50 +1100 Subject: [PATCH] OpenXR: Allow setting a specific version of OpenXR to initialize. --- doc/classes/ProjectSettings.xml | 3 +++ main/main.cpp | 1 + modules/openxr/openxr_api.cpp | 17 +++++++++++++---- 3 files changed, 17 insertions(+), 4 deletions(-) diff --git a/doc/classes/ProjectSettings.xml b/doc/classes/ProjectSettings.xml index 2bd6df9015..05d213bbfa 100644 --- a/doc/classes/ProjectSettings.xml +++ b/doc/classes/ProjectSettings.xml @@ -3610,6 +3610,9 @@ If [code]true[/code], OpenXR will manage the depth buffer and use the depth buffer for advanced reprojection provided this is supported by the XR runtime. Note that some rendering features in Godot can't be used with this feature. + + Optionally sets a specific API version of OpenXR to initialize in [code]major.minor.patch[/code] notation. Some XR runtimes gate old behavior behind version checks. This is non-standard OpenXR behavior. + Specify the view configuration with which to configure OpenXR setting up either Mono or Stereo rendering. diff --git a/main/main.cpp b/main/main.cpp index 064c20dab4..026ab12d5a 100644 --- a/main/main.cpp +++ b/main/main.cpp @@ -2788,6 +2788,7 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph #ifndef _3D_DISABLED // XR project settings. GLOBAL_DEF_RST_BASIC("xr/openxr/enabled", false); + GLOBAL_DEF(PropertyInfo(Variant::STRING, "xr/openxr/target_api_version"), ""); GLOBAL_DEF_BASIC(PropertyInfo(Variant::STRING, "xr/openxr/default_action_map", PROPERTY_HINT_FILE, "*.tres"), "res://openxr_action_map.tres"); GLOBAL_DEF_BASIC(PropertyInfo(Variant::INT, "xr/openxr/form_factor", PROPERTY_HINT_ENUM, "Head Mounted,Handheld"), "0"); GLOBAL_DEF_BASIC(PropertyInfo(Variant::INT, "xr/openxr/view_configuration", PROPERTY_HINT_ENUM, "Mono,Stereo"), "1"); // "Mono,Stereo,Quad,Observer" diff --git a/modules/openxr/openxr_api.cpp b/modules/openxr/openxr_api.cpp index e9d23d6da2..759eec8250 100644 --- a/modules/openxr/openxr_api.cpp +++ b/modules/openxr/openxr_api.cpp @@ -659,12 +659,21 @@ XrResult OpenXRAPI::attempt_create_instance(XrVersion p_version) { bool OpenXRAPI::create_instance() { // Create our OpenXR instance, this will query any registered extension wrappers for extensions we need to enable. - XrResult result = attempt_create_instance(XR_API_VERSION_1_1); - if (result == XR_ERROR_API_VERSION_UNSUPPORTED) { - // Couldn't initialize OpenXR 1.1, try 1.0 + XrVersion init_version = XR_API_VERSION_1_1; + + String custom_version = GLOBAL_GET("xr/openxr/target_api_version"); + if (!custom_version.is_empty()) { + Vector ints = custom_version.split_ints(".", false); + ERR_FAIL_COND_V_MSG(ints.size() != 3, false, "OpenXR target API version must be major.minor.patch."); + init_version = XR_MAKE_VERSION(ints[0], ints[1], ints[2]); + } + + XrResult result = attempt_create_instance(init_version); + if (result == XR_ERROR_API_VERSION_UNSUPPORTED && init_version == XR_API_VERSION_1_1) { print_verbose("OpenXR: Falling back to OpenXR 1.0"); - result = attempt_create_instance(XR_API_VERSION_1_0); + init_version = XR_API_VERSION_1_0; + result = attempt_create_instance(init_version); } ERR_FAIL_COND_V_MSG(XR_FAILED(result), false, "Failed to create XR instance [" + get_error_string(result) + "].");