#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