// Copyright (c) 2017-2024, The Khronos Group Inc. // // SPDX-License-Identifier: Apache-2.0 #pragma once #ifdef XR_USE_GRAPHICS_API_VULKAN #include #include /// Utility class for assigning debug names to Vulkan objects we create. class VulkanDebugObjectNamer { public: /// Construct without initializing VulkanDebugObjectNamer() = default; /// Construct and initialize VulkanDebugObjectNamer(VkInstance instance, VkDevice device) : m_vkDevice{device} { vkSetDebugUtilsObjectNameEXT = (PFN_vkSetDebugUtilsObjectNameEXT)vkGetInstanceProcAddr(instance, "vkSetDebugUtilsObjectNameEXT"); } /// Copy constructor VulkanDebugObjectNamer(const VulkanDebugObjectNamer&) = default; /// Copy assignment operator VulkanDebugObjectNamer& operator=(const VulkanDebugObjectNamer&) = default; /// Destructor ~VulkanDebugObjectNamer() { Reset(); } /// (Re-) Initialize the namer: takes a valid `VkInstance` and `VkDevice` void Init(VkInstance instance, VkDevice device) { Reset(); *this = VulkanDebugObjectNamer(instance, device); } /// The main operation of the namer: actually set an object name. /// /// If the namer is not initialized, this exits silently. VkResult SetName(VkObjectType objectType, uint64_t objectHandle, const char* pObjectName) const { if (m_vkDevice == nullptr) { return VK_SUCCESS; } if (vkSetDebugUtilsObjectNameEXT != nullptr) { VkDebugUtilsObjectNameInfoEXT nameInfo{VK_STRUCTURE_TYPE_DEBUG_UTILS_OBJECT_NAME_INFO_EXT, nullptr, objectType, objectHandle, pObjectName}; return vkSetDebugUtilsObjectNameEXT(m_vkDevice, &nameInfo); } return VK_SUCCESS; } /// De-initialize the namer, forgetting the device and the function pointer loaded from the instance. void Reset() { vkSetDebugUtilsObjectNameEXT = nullptr; m_vkDevice = VK_NULL_HANDLE; } private: VkDevice m_vkDevice{VK_NULL_HANDLE}; PFN_vkSetDebugUtilsObjectNameEXT vkSetDebugUtilsObjectNameEXT{nullptr}; }; #endif