You've already forked godot
mirror of
https://github.com/godotengine/godot.git
synced 2025-11-26 15:46:23 +00:00
Will be compiled and used in the next commit. Co-authored-by: Rémi Verschelde <rverschelde@gmail.com>
230 lines
8.4 KiB
C++
230 lines
8.4 KiB
C++
// Copyright (c) 2017-2022, The Khronos Group Inc.
|
|
// Copyright (c) 2017-2019 Valve Corporation
|
|
// Copyright (c) 2017-2019 LunarG, Inc.
|
|
// Copyright (c) 2019 Collabora, Ltd.
|
|
//
|
|
// SPDX-License-Identifier: Apache-2.0 OR MIT
|
|
//
|
|
// Initial Authors: Mark Young <marky@lunarg.com>, Ryan Pavlik <ryan.pavlik@collabora.com
|
|
//
|
|
/*!
|
|
* @file
|
|
*
|
|
* The core of an XR_EXT_debug_utils implementation, used/shared by the loader and several SDK layers.
|
|
*/
|
|
|
|
#pragma once
|
|
|
|
#include "hex_and_handles.h"
|
|
|
|
#include <openxr/openxr.h>
|
|
|
|
#include <memory>
|
|
#include <string>
|
|
#include <unordered_map>
|
|
#include <vector>
|
|
|
|
struct XrSdkGenericObject {
|
|
//! Type-erased handle value
|
|
uint64_t handle;
|
|
|
|
//! Kind of object this handle refers to
|
|
XrObjectType type;
|
|
/// Un-erase the type of the handle and get it properly typed again.
|
|
///
|
|
/// Note: Does not check the type before doing it!
|
|
template <typename HandleType>
|
|
HandleType& GetTypedHandle() {
|
|
return TreatIntegerAsHandle<HandleType&>(handle);
|
|
}
|
|
|
|
//! @overload
|
|
template <typename HandleType>
|
|
HandleType const& GetTypedHandle() const {
|
|
return TreatIntegerAsHandle<HandleType&>(handle);
|
|
}
|
|
|
|
//! Create from a typed handle and object type
|
|
template <typename T>
|
|
XrSdkGenericObject(T h, XrObjectType t) : handle(MakeHandleGeneric(h)), type(t) {}
|
|
|
|
//! Create from an untyped handle value (integer) and object type
|
|
XrSdkGenericObject(uint64_t h, XrObjectType t) : handle(h), type(t) {}
|
|
};
|
|
|
|
struct XrSdkLogObjectInfo {
|
|
//! Type-erased handle value
|
|
uint64_t handle;
|
|
|
|
//! Kind of object this handle refers to
|
|
XrObjectType type;
|
|
|
|
//! To be assigned by the application - not part of this object's identity
|
|
std::string name;
|
|
|
|
/// Un-erase the type of the handle and get it properly typed again.
|
|
///
|
|
/// Note: Does not check the type before doing it!
|
|
template <typename HandleType>
|
|
HandleType& GetTypedHandle() {
|
|
return TreatIntegerAsHandle<HandleType&>(handle);
|
|
}
|
|
|
|
//! @overload
|
|
template <typename HandleType>
|
|
HandleType const& GetTypedHandle() const {
|
|
return TreatIntegerAsHandle<HandleType&>(handle);
|
|
}
|
|
|
|
XrSdkLogObjectInfo() = default;
|
|
|
|
//! Create from a typed handle and object type
|
|
template <typename T>
|
|
XrSdkLogObjectInfo(T h, XrObjectType t) : handle(MakeHandleGeneric(h)), type(t) {}
|
|
|
|
//! Create from an untyped handle value (integer) and object type
|
|
XrSdkLogObjectInfo(uint64_t h, XrObjectType t) : handle(h), type(t) {}
|
|
//! Create from an untyped handle value (integer), object type, and name
|
|
XrSdkLogObjectInfo(uint64_t h, XrObjectType t, const char* n) : handle(h), type(t), name(n == nullptr ? "" : n) {}
|
|
|
|
std::string ToString() const;
|
|
};
|
|
|
|
//! True if the two object infos have the same handle value and handle type
|
|
static inline bool Equivalent(XrSdkLogObjectInfo const& a, XrSdkLogObjectInfo const& b) {
|
|
return a.handle == b.handle && a.type == b.type;
|
|
}
|
|
|
|
//! @overload
|
|
static inline bool Equivalent(XrDebugUtilsObjectNameInfoEXT const& a, XrSdkLogObjectInfo const& b) {
|
|
return a.objectHandle == b.handle && a.objectType == b.type;
|
|
}
|
|
|
|
//! @overload
|
|
static inline bool Equivalent(XrSdkLogObjectInfo const& a, XrDebugUtilsObjectNameInfoEXT const& b) { return Equivalent(b, a); }
|
|
|
|
/// Object info registered with calls to xrSetDebugUtilsObjectNameEXT
|
|
class ObjectInfoCollection {
|
|
public:
|
|
void AddObjectName(uint64_t object_handle, XrObjectType object_type, const std::string& object_name);
|
|
|
|
void RemoveObject(uint64_t object_handle, XrObjectType object_type);
|
|
|
|
//! Find the stored object info, if any, matching handle and type.
|
|
//! Return nullptr if not found.
|
|
XrSdkLogObjectInfo const* LookUpStoredObjectInfo(XrSdkLogObjectInfo const& info) const;
|
|
|
|
//! Find the stored object info, if any, matching handle and type.
|
|
//! Return nullptr if not found.
|
|
XrSdkLogObjectInfo* LookUpStoredObjectInfo(XrSdkLogObjectInfo const& info);
|
|
|
|
//! Find the stored object info, if any.
|
|
//! Return nullptr if not found.
|
|
XrSdkLogObjectInfo const* LookUpStoredObjectInfo(uint64_t handle, XrObjectType type) const {
|
|
return LookUpStoredObjectInfo({handle, type});
|
|
}
|
|
|
|
//! Find the object name, if any, and update debug utils info accordingly.
|
|
//! Return true if found and updated.
|
|
bool LookUpObjectName(XrDebugUtilsObjectNameInfoEXT& info) const;
|
|
|
|
//! Find the object name, if any, and update logging info accordingly.
|
|
//! Return true if found and updated.
|
|
bool LookUpObjectName(XrSdkLogObjectInfo& info) const;
|
|
|
|
//! Is the collection empty?
|
|
bool Empty() const { return object_info_.empty(); }
|
|
|
|
private:
|
|
// Object names that have been set for given objects
|
|
std::vector<XrSdkLogObjectInfo> object_info_;
|
|
};
|
|
|
|
struct XrSdkSessionLabel;
|
|
using XrSdkSessionLabelPtr = std::unique_ptr<XrSdkSessionLabel>;
|
|
using XrSdkSessionLabelList = std::vector<XrSdkSessionLabelPtr>;
|
|
|
|
struct XrSdkSessionLabel {
|
|
static XrSdkSessionLabelPtr make(const XrDebugUtilsLabelEXT& label_info, bool individual);
|
|
|
|
std::string label_name;
|
|
XrDebugUtilsLabelEXT debug_utils_label;
|
|
bool is_individual_label;
|
|
|
|
private:
|
|
XrSdkSessionLabel(const XrDebugUtilsLabelEXT& label_info, bool individual);
|
|
};
|
|
|
|
/// The metadata for a collection of objects. Must persist unmodified during the entire debug messenger call!
|
|
struct NamesAndLabels {
|
|
NamesAndLabels() = default;
|
|
NamesAndLabels(std::vector<XrSdkLogObjectInfo> obj, std::vector<XrDebugUtilsLabelEXT> lab);
|
|
/// C++ structure owning the data (strings) backing the objects vector.
|
|
std::vector<XrSdkLogObjectInfo> sdk_objects;
|
|
|
|
std::vector<XrDebugUtilsObjectNameInfoEXT> objects;
|
|
std::vector<XrDebugUtilsLabelEXT> labels;
|
|
|
|
/// Populate the debug utils callback data structure.
|
|
void PopulateCallbackData(XrDebugUtilsMessengerCallbackDataEXT& data) const;
|
|
// XrDebugUtilsMessengerCallbackDataEXT MakeCallbackData() const;
|
|
};
|
|
|
|
struct AugmentedCallbackData {
|
|
std::vector<XrDebugUtilsLabelEXT> labels;
|
|
std::vector<XrDebugUtilsObjectNameInfoEXT> new_objects;
|
|
XrDebugUtilsMessengerCallbackDataEXT modified_data;
|
|
const XrDebugUtilsMessengerCallbackDataEXT* exported_data;
|
|
};
|
|
|
|
/// Tracks all the data (handle names and session labels) required to fully augment XR_EXT_debug_utils-related calls.
|
|
class DebugUtilsData {
|
|
public:
|
|
DebugUtilsData() = default;
|
|
|
|
DebugUtilsData(const DebugUtilsData&) = delete;
|
|
DebugUtilsData& operator=(const DebugUtilsData&) = delete;
|
|
|
|
bool Empty() const { return object_info_.Empty() && session_labels_.empty(); }
|
|
|
|
//! Core of implementation for xrSetDebugUtilsObjectNameEXT
|
|
void AddObjectName(uint64_t object_handle, XrObjectType object_type, const std::string& object_name);
|
|
|
|
/// Core of implementation for xrSessionBeginDebugUtilsLabelRegionEXT
|
|
void BeginLabelRegion(XrSession session, const XrDebugUtilsLabelEXT& label_info);
|
|
|
|
/// Core of implementation for xrSessionEndDebugUtilsLabelRegionEXT
|
|
void EndLabelRegion(XrSession session);
|
|
|
|
/// Core of implementation for xrSessionInsertDebugUtilsLabelEXT
|
|
void InsertLabel(XrSession session, const XrDebugUtilsLabelEXT& label_info);
|
|
|
|
/// Removes all labels associated with a session - call in xrDestroySession and xrDestroyInstance (for all child sessions)
|
|
void DeleteSessionLabels(XrSession session);
|
|
|
|
/// Retrieve labels for the given session, if any, and push them in reverse order on the vector.
|
|
void LookUpSessionLabels(XrSession session, std::vector<XrDebugUtilsLabelEXT>& labels) const;
|
|
|
|
/// Removes all data related to this object - including session labels if it's a session.
|
|
///
|
|
/// Does not take care of handling child objects - you must do this yourself.
|
|
void DeleteObject(uint64_t object_handle, XrObjectType object_type);
|
|
|
|
/// Given the collection of objects, populate their names and list of labels
|
|
NamesAndLabels PopulateNamesAndLabels(std::vector<XrSdkLogObjectInfo> objects) const;
|
|
|
|
void WrapCallbackData(AugmentedCallbackData* aug_data,
|
|
const XrDebugUtilsMessengerCallbackDataEXT* provided_callback_data) const;
|
|
|
|
private:
|
|
void RemoveIndividualLabel(XrSdkSessionLabelList& label_vec);
|
|
XrSdkSessionLabelList* GetSessionLabelList(XrSession session);
|
|
XrSdkSessionLabelList& GetOrCreateSessionLabelList(XrSession session);
|
|
|
|
// Session labels: one vector of them per session.
|
|
std::unordered_map<XrSession, std::unique_ptr<XrSdkSessionLabelList>> session_labels_;
|
|
|
|
// Names for objects.
|
|
ObjectInfoCollection object_info_;
|
|
};
|