Skip to content

Commit

Permalink
Add support for the debug utils extension in OpenXR
Browse files Browse the repository at this point in the history
  • Loading branch information
BastiaanOlij committed Aug 5, 2024
1 parent 3978628 commit 4fe9a79
Show file tree
Hide file tree
Showing 5 changed files with 243 additions and 0 deletions.
3 changes: 3 additions & 0 deletions doc/classes/ProjectSettings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -2924,6 +2924,9 @@
<member name="xr/openxr/environment_blend_mode" type="int" setter="" getter="" default="&quot;0&quot;">
Specify how OpenXR should blend in the environment. This is specific to certain AR and passthrough devices where camera images are blended in by the XR compositor.
</member>
<member name="xr/openxr/extensions/debug_utils" type="int" setter="" getter="" default="&quot;0&quot;">
Enables debug utilities on XR runtimes that supports the debug utils extension. Sets the maximum severity being reported (0 = disabled, 1 = error, 2 = warning, 3 = info, 4 = verbose).
</member>
<member name="xr/openxr/extensions/eye_gaze_interaction" type="bool" setter="" getter="" default="false">
Specify whether to enable eye tracking for this project. Depending on the platform, additional export configuration may be needed.
</member>
Expand Down
1 change: 1 addition & 0 deletions main/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2437,6 +2437,7 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph
GLOBAL_DEF_BASIC("xr/openxr/startup_alert", true);

// OpenXR project extensions settings.
GLOBAL_DEF_BASIC(PropertyInfo(Variant::INT, "xr/openxr/extensions/debug_utils", PROPERTY_HINT_ENUM, "Disabled,Error,Warning,Info,Verbose"), "0");
GLOBAL_DEF_BASIC("xr/openxr/extensions/hand_tracking", true);
GLOBAL_DEF_RST_BASIC("xr/openxr/extensions/hand_interaction_profile", false);
GLOBAL_DEF_BASIC("xr/openxr/extensions/eye_gaze_interaction", false);
Expand Down
168 changes: 168 additions & 0 deletions modules/openxr/extensions/openxr_debug_utils_extension.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,168 @@
/**************************************************************************/
/* openxr_debug_utils_extension.cpp */
/**************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* https://godotengine.org */
/**************************************************************************/
/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
/* "Software"), to deal in the Software without restriction, including */
/* without limitation the rights to use, copy, modify, merge, publish, */
/* distribute, sublicense, and/or sell copies of the Software, and to */
/* permit persons to whom the Software is furnished to do so, subject to */
/* the following conditions: */
/* */
/* The above copyright notice and this permission notice shall be */
/* included in all copies or substantial portions of the Software. */
/* */
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/**************************************************************************/

#include "openxr_debug_utils_extension.h"

#include "../openxr_api.h"
#include "core/config/project_settings.h"
#include "core/string/print_string.h"

#include <openxr/openxr.h>

OpenXRDebugUtilsExtension *OpenXRDebugUtilsExtension::singleton = nullptr;

OpenXRDebugUtilsExtension *OpenXRDebugUtilsExtension::get_singleton() {
return singleton;
}

OpenXRDebugUtilsExtension::OpenXRDebugUtilsExtension() {
singleton = this;
}

OpenXRDebugUtilsExtension::~OpenXRDebugUtilsExtension() {
singleton = nullptr;
}

HashMap<String, bool *> OpenXRDebugUtilsExtension::get_requested_extensions() {
HashMap<String, bool *> request_extensions;

request_extensions[XR_EXT_DEBUG_UTILS_EXTENSION_NAME] = &debug_utils_ext;

return request_extensions;
}

void OpenXRDebugUtilsExtension::on_instance_created(const XrInstance p_instance) {
if (debug_utils_ext) {
EXT_INIT_XR_FUNC(xrCreateDebugUtilsMessengerEXT);
EXT_INIT_XR_FUNC(xrDestroyDebugUtilsMessengerEXT);

debug_utils_ext = xrCreateDebugUtilsMessengerEXT_ptr && xrDestroyDebugUtilsMessengerEXT_ptr;
}

// On successfull init, setup our default messenger.
if (debug_utils_ext) {
int max_severity = GLOBAL_GET("xr/openxr/extensions/debug_utils");
XrDebugUtilsMessageSeverityFlagsEXT message_severities = 0;

if (max_severity >= 1) {
message_severities |= XR_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT;
}
if (max_severity >= 2) {
message_severities |= XR_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT;
}
if (max_severity >= 3) {
message_severities |= XR_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT;
}
if (max_severity >= 4) {
message_severities |= XR_DEBUG_UTILS_MESSAGE_SEVERITY_VERBOSE_BIT_EXT;
}

XrDebugUtilsMessengerCreateInfoEXT callback_info = {
XR_TYPE_DEBUG_UTILS_MESSENGER_CREATE_INFO_EXT, // type
nullptr, // next
message_severities, // messageSeverities
XR_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT | XR_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT | XR_DEBUG_UTILS_MESSAGE_TYPE_PERFORMANCE_BIT_EXT | XR_DEBUG_UTILS_MESSAGE_TYPE_CONFORMANCE_BIT_EXT, // messageTypes
&OpenXRDebugUtilsExtension::_debug_callback, // userCallback
nullptr, // userData
};

xrCreateDebugUtilsMessengerEXT(p_instance, &callback_info, &default_messenger);
}
}

void OpenXRDebugUtilsExtension::on_instance_destroyed() {
if (default_messenger != XR_NULL_HANDLE) {
xrDestroyDebugUtilsMessengerEXT(default_messenger);
default_messenger = XR_NULL_HANDLE;
}

xrCreateDebugUtilsMessengerEXT_ptr = nullptr;
xrDestroyDebugUtilsMessengerEXT_ptr = nullptr;
}

bool OpenXRDebugUtilsExtension::get_active() {
return debug_utils_ext;
}

XrBool32 OpenXRDebugUtilsExtension::_debug_callback(XrDebugUtilsMessageSeverityFlagsEXT p_message_severity, XrDebugUtilsMessageTypeFlagsEXT p_message_types, const XrDebugUtilsMessengerCallbackDataEXT *p_callback_data, void *p_user_data) {
OpenXRDebugUtilsExtension *debug_utils = OpenXRDebugUtilsExtension::get_singleton();

if (debug_utils) {
return debug_utils->debug_callback(p_message_severity, p_message_types, p_callback_data, p_user_data);
}

return XR_FALSE;
}

XrBool32 OpenXRDebugUtilsExtension::debug_callback(XrDebugUtilsMessageSeverityFlagsEXT p_message_severity, XrDebugUtilsMessageTypeFlagsEXT p_message_types, const XrDebugUtilsMessengerCallbackDataEXT *p_callback_data, void *p_user_data) {
String msg;

ERR_FAIL_NULL_V(p_callback_data, XR_FALSE);

if (p_message_types == XR_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT) {
msg += "\nType: General";
} else if (p_message_types == XR_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT) {
msg += "\nType: Validation";
} else if (p_message_types == XR_DEBUG_UTILS_MESSAGE_TYPE_PERFORMANCE_BIT_EXT) {
msg += "\nType: Performance";
} else if (p_message_types == XR_DEBUG_UTILS_MESSAGE_TYPE_CONFORMANCE_BIT_EXT) {
msg += "\nType: Conformance";
}

if (p_callback_data->messageId) {
msg += "\nMessage ID: " + String(p_callback_data->messageId);
}
if (p_callback_data->functionName) {
msg += "\nFunction Name: " + String(p_callback_data->functionName);
}
if (p_callback_data->message) {
msg += "\nMessage: " + String(p_callback_data->message);
}

/*
TODO: add in:
uint32_t objectCount;
XrDebugUtilsObjectNameInfoEXT* objects;
uint32_t sessionLabelCount;
XrDebugUtilsLabelEXT* sessionLabels;
*/

if (p_message_severity == XR_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT) {
ERR_PRINT("OpenXR Error" + msg);
} else if (p_message_severity == XR_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT) {
WARN_PRINT("OpenXR Warning" + msg);
} else if (p_message_severity == XR_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT) {
print_line("OpenXR Info" + msg);
} else if (p_message_severity == XR_DEBUG_UTILS_MESSAGE_SEVERITY_VERBOSE_BIT_EXT) {
print_line("OpenXR Verbose" + msg);
}

return XR_FALSE;
}
67 changes: 67 additions & 0 deletions modules/openxr/extensions/openxr_debug_utils_extension.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
/**************************************************************************/
/* openxr_debug_utils_extension.h */
/**************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* https://godotengine.org */
/**************************************************************************/
/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
/* "Software"), to deal in the Software without restriction, including */
/* without limitation the rights to use, copy, modify, merge, publish, */
/* distribute, sublicense, and/or sell copies of the Software, and to */
/* permit persons to whom the Software is furnished to do so, subject to */
/* the following conditions: */
/* */
/* The above copyright notice and this permission notice shall be */
/* included in all copies or substantial portions of the Software. */
/* */
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/**************************************************************************/

#ifndef OPENXR_DEBUG_UTILS_EXTENSION_H
#define OPENXR_DEBUG_UTILS_EXTENSION_H

#include "../util.h"
#include "openxr_extension_wrapper.h"

class OpenXRDebugUtilsExtension : public OpenXRExtensionWrapper {
public:
static OpenXRDebugUtilsExtension *get_singleton();

OpenXRDebugUtilsExtension();
virtual ~OpenXRDebugUtilsExtension() override;

virtual HashMap<String, bool *> get_requested_extensions() override;
virtual void on_instance_created(const XrInstance p_instance) override;
virtual void on_instance_destroyed() override;

bool get_active();

private:
static OpenXRDebugUtilsExtension *singleton;

// related extensions
bool debug_utils_ext = false;

// debug handlers
XrDebugUtilsMessengerEXT default_messenger = XR_NULL_HANDLE;

static XrBool32 _debug_callback(XrDebugUtilsMessageSeverityFlagsEXT p_message_severity, XrDebugUtilsMessageTypeFlagsEXT p_message_types, const XrDebugUtilsMessengerCallbackDataEXT *p_callback_data, void *p_user_data);
XrBool32 debug_callback(XrDebugUtilsMessageSeverityFlagsEXT p_message_severity, XrDebugUtilsMessageTypeFlagsEXT p_message_types, const XrDebugUtilsMessengerCallbackDataEXT *p_callback_data, void *p_user_data);

// OpenXR API call wrappers
EXT_PROTO_XRRESULT_FUNC3(xrCreateDebugUtilsMessengerEXT, (XrInstance), p_instance, (const XrDebugUtilsMessengerCreateInfoEXT *), p_create_info, (XrDebugUtilsMessengerEXT *), p_messenger)
EXT_PROTO_XRRESULT_FUNC1(xrDestroyDebugUtilsMessengerEXT, (XrDebugUtilsMessengerEXT), p_messenger)
};

#endif // OPENXR_DEBUG_UTILS_EXTENSION_H
4 changes: 4 additions & 0 deletions modules/openxr/register_types.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@

#include "extensions/openxr_composition_layer_depth_extension.h"
#include "extensions/openxr_composition_layer_extension.h"
#include "extensions/openxr_debug_utils_extension.h"
#include "extensions/openxr_eye_gaze_interaction.h"
#include "extensions/openxr_fb_display_refresh_rate_extension.h"
#include "extensions/openxr_hand_interaction_extension.h"
Expand Down Expand Up @@ -128,6 +129,9 @@ void initialize_openxr_module(ModuleInitializationLevel p_level) {
OpenXRAPI::register_extension_wrapper(memnew(OpenXRHandInteractionExtension));

// register gated extensions
if (int(GLOBAL_GET("xr/openxr/extensions/debug_utils")) > 0) {
OpenXRAPI::register_extension_wrapper(memnew(OpenXRDebugUtilsExtension));
}
if (GLOBAL_GET("xr/openxr/extensions/hand_tracking")) {
OpenXRAPI::register_extension_wrapper(memnew(OpenXRHandTrackingExtension));
}
Expand Down

0 comments on commit 4fe9a79

Please sign in to comment.