// Copyright (c) 2017-2024, The Khronos Group Inc.
//
// SPDX-License-Identifier: Apache-2.0
#pragma once
#ifdef XR_USE_GRAPHICS_API_VULKAN
#include <vulkan/vulkan_core.h>
#include <stdexcept>
/// 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