debug.h

cross platform rendering playground

src/backend/vulkan/debug.h

3.4 KB
#pragma once

#include <type_traits>

#include "backend/vulkan/utils.h"
#include "backend/vulkan/vk_api.h"

namespace vk {

VKAPI_ATTR VkBool32 VKAPI_CALL debug_callback(
    VkDebugUtilsMessageSeverityFlagBitsEXT severity,
    VkDebugUtilsMessageTypeFlagsEXT type,
    const VkDebugUtilsMessengerCallbackDataEXT *data,
    void *user
);

void create_debug_messenger(Device &device);
void destory_debug_messenger(Device &device);

inline void set_debug_name(Device &device, VkObjectType object_type, u64 object_handle, const char *name) {
    VkDebugUtilsObjectNameInfoEXT info{VK_STRUCTURE_TYPE_DEBUG_UTILS_OBJECT_NAME_INFO_EXT};
    info.objectType = object_type;
    info.objectHandle = object_handle;
    info.pObjectName = name;

    if (vkSetDebugUtilsObjectNameEXT) {
        vkSetDebugUtilsObjectNameEXT(device.logical, &info);
    }
}

template <typename T> struct VkTypeMap;

#define REGISTER_VK_TYPE(type, enum_val)                                                                               \
    template <> struct VkTypeMap<type> {                                                                               \
        static constexpr VkObjectType value = enum_val;                                                                \
    }

REGISTER_VK_TYPE(VkInstance, VK_OBJECT_TYPE_INSTANCE);
REGISTER_VK_TYPE(VkPhysicalDevice, VK_OBJECT_TYPE_PHYSICAL_DEVICE);
REGISTER_VK_TYPE(VkDevice, VK_OBJECT_TYPE_DEVICE);
REGISTER_VK_TYPE(VkQueue, VK_OBJECT_TYPE_QUEUE);
REGISTER_VK_TYPE(VkCommandBuffer, VK_OBJECT_TYPE_COMMAND_BUFFER);
REGISTER_VK_TYPE(VkDeviceMemory, VK_OBJECT_TYPE_DEVICE_MEMORY);

REGISTER_VK_TYPE(VkBuffer, VK_OBJECT_TYPE_BUFFER);
REGISTER_VK_TYPE(VkBufferView, VK_OBJECT_TYPE_BUFFER_VIEW);
REGISTER_VK_TYPE(VkImage, VK_OBJECT_TYPE_IMAGE);
REGISTER_VK_TYPE(VkImageView, VK_OBJECT_TYPE_IMAGE_VIEW);
REGISTER_VK_TYPE(VkSampler, VK_OBJECT_TYPE_SAMPLER);

REGISTER_VK_TYPE(VkPipeline, VK_OBJECT_TYPE_PIPELINE);
REGISTER_VK_TYPE(VkPipelineLayout, VK_OBJECT_TYPE_PIPELINE_LAYOUT);
REGISTER_VK_TYPE(VkPipelineCache, VK_OBJECT_TYPE_PIPELINE_CACHE);
REGISTER_VK_TYPE(VkDescriptorSet, VK_OBJECT_TYPE_DESCRIPTOR_SET);
REGISTER_VK_TYPE(VkShaderModule, VK_OBJECT_TYPE_SHADER_MODULE);

REGISTER_VK_TYPE(VkFence, VK_OBJECT_TYPE_FENCE);
REGISTER_VK_TYPE(VkSemaphore, VK_OBJECT_TYPE_SEMAPHORE);
REGISTER_VK_TYPE(VkEvent, VK_OBJECT_TYPE_EVENT);
REGISTER_VK_TYPE(VkCommandPool, VK_OBJECT_TYPE_COMMAND_POOL);
REGISTER_VK_TYPE(VkQueryPool, VK_OBJECT_TYPE_QUERY_POOL);

REGISTER_VK_TYPE(VkRenderPass, VK_OBJECT_TYPE_RENDER_PASS);
REGISTER_VK_TYPE(VkFramebuffer, VK_OBJECT_TYPE_FRAMEBUFFER);
REGISTER_VK_TYPE(VkSurfaceKHR, VK_OBJECT_TYPE_SURFACE_KHR);
REGISTER_VK_TYPE(VkSwapchainKHR, VK_OBJECT_TYPE_SWAPCHAIN_KHR);

REGISTER_VK_TYPE(VkAccelerationStructureKHR, VK_OBJECT_TYPE_ACCELERATION_STRUCTURE_KHR);
REGISTER_VK_TYPE(VkDeferredOperationKHR, VK_OBJECT_TYPE_DEFERRED_OPERATION_KHR);

REGISTER_VK_TYPE(VkDebugUtilsMessengerEXT, VK_OBJECT_TYPE_DEBUG_UTILS_MESSENGER_EXT);

template <typename T> inline void set_name(Device &device, T handle, const char *name) {
    if constexpr (std::is_same_v<T, u64>) {
        (void)device;
        (void)handle;
        (void)name;
        return; // no type for u64
    } else {
        set_debug_name(device, VkTypeMap<T>::value, reinterpret_cast<u64>(handle), name);
    }
}

#define VK_NAME_EX(device, obj, name) set_name(device, obj, name)
#define VK_NAME(device, obj)          set_name(device, obj, #obj)

} // namespace vk