diff options
Diffstat (limited to 'thirdparty/openxr/src/common/object_info.h')
-rw-r--r-- | thirdparty/openxr/src/common/object_info.h | 229 |
1 files changed, 229 insertions, 0 deletions
diff --git a/thirdparty/openxr/src/common/object_info.h b/thirdparty/openxr/src/common/object_info.h new file mode 100644 index 0000000000..8e9742b605 --- /dev/null +++ b/thirdparty/openxr/src/common/object_info.h @@ -0,0 +1,229 @@ +// Copyright (c) 2017-2022, The Khronos Group Inc. +// Copyright (c) 2017-2019 Valve Corporation +// Copyright (c) 2017-2019 LunarG, Inc. +// Copyright (c) 2019 Collabora, Ltd. +// +// SPDX-License-Identifier: Apache-2.0 OR MIT +// +// Initial Authors: Mark Young <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_; +}; |