From: Józef Kucia jkucia@codeweavers.com
For debug messages from Vulkan drivers.
Signed-off-by: Józef Kucia jkucia@codeweavers.com --- libs/vkd3d/device.c | 74 +++++++++++++++++++++++++++++++++++++++------- libs/vkd3d/utils.c | 5 +++- libs/vkd3d/vkd3d_private.h | 6 +++- libs/vkd3d/vulkan_procs.h | 8 +++++ 4 files changed, 80 insertions(+), 13 deletions(-)
diff --git a/libs/vkd3d/device.c b/libs/vkd3d/device.c index 0dc13cb1abb8..805d477f89b0 100644 --- a/libs/vkd3d/device.c +++ b/libs/vkd3d/device.c @@ -24,12 +24,14 @@ struct vkd3d_optional_extension_info { const char *extension_name; ptrdiff_t vulkan_info_offset; + bool is_debug_only; };
static const struct vkd3d_optional_extension_info optional_instance_extensions[] = { {VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME, offsetof(struct vkd3d_vulkan_info, KHR_get_physical_device_properties2)}, + {VK_EXT_DEBUG_REPORT_EXTENSION_NAME, offsetof(struct vkd3d_vulkan_info, EXT_debug_report), true}, };
static const char * const required_device_extensions[] = @@ -59,7 +61,7 @@ static bool is_extension_disabled(const char *extension_name) }
static bool has_extension(const VkExtensionProperties *extensions, - unsigned int count, const char *extension_name) + unsigned int count, const char *extension_name, bool is_debug_only) { unsigned int i;
@@ -72,6 +74,11 @@ static bool has_extension(const VkExtensionProperties *extensions, WARN("Extension %s is disabled.\n", debugstr_a(extension_name)); continue; } + if (is_debug_only && vkd3d_dbg_get_level() < VKD3D_DBG_LEVEL_WARN) + { + TRACE("Skipping debug-only extension %s.\n", debugstr_a(extension_name)); + continue; + } return true; } return false; @@ -88,7 +95,7 @@ static unsigned int vkd3d_check_extensions(const VkExtensionProperties *extensio
for (i = 0; i < required_extension_count; ++i) { - if (!has_extension(extensions, count, required_extensions[i])) + if (!has_extension(extensions, count, required_extensions[i], false)) ERR("Required %s extension %s is not supported.\n", extension_type, debugstr_a(required_extensions[i])); ++extension_count; @@ -98,9 +105,10 @@ static unsigned int vkd3d_check_extensions(const VkExtensionProperties *extensio { const char *extension_name = optional_extensions[i].extension_name; ptrdiff_t offset = optional_extensions[i].vulkan_info_offset; + bool is_debug_only = optional_extensions[i].is_debug_only; bool *supported = (void *)((uintptr_t)vulkan_info + offset);
- if ((*supported = has_extension(extensions, count, extension_name))) + if ((*supported = has_extension(extensions, count, extension_name, is_debug_only))) { TRACE("Found %s extension.\n", debugstr_a(extension_name)); ++extension_count; @@ -109,7 +117,7 @@ static unsigned int vkd3d_check_extensions(const VkExtensionProperties *extensio
for (i = 0; i < user_extension_count; ++i) { - if (!has_extension(extensions, count, user_extensions[i])) + if (!has_extension(extensions, count, user_extensions[i], false)) ERR("Required user %s extension %s is not supported.\n", extension_type, debugstr_a(user_extensions[i])); ++extension_count; @@ -234,6 +242,36 @@ static HRESULT vkd3d_init_vk_global_procs(struct vkd3d_instance *instance, return S_OK; }
+static VkBool32 VKAPI_PTR vkd3d_debug_report_callback(VkDebugReportFlagsEXT flags, + VkDebugReportObjectTypeEXT object_type, uint64_t object, size_t location, + int32_t message_code, const char *layer_prefix, const char *message, void *user_data) +{ + FIXME("%s\n", debugstr_a(message)); + return VK_FALSE; +} + +static void vkd3d_init_debug_report(struct vkd3d_instance *instance) +{ + const struct vkd3d_vk_instance_procs *vk_procs = &instance->vk_procs; + VkDebugReportCallbackCreateInfoEXT callback_info; + VkInstance vk_instance = instance->vk_instance; + VkDebugReportCallbackEXT callback; + VkResult vr; + + callback_info.sType = VK_STRUCTURE_TYPE_DEBUG_REPORT_CALLBACK_CREATE_INFO_EXT; + callback_info.pNext = NULL; + callback_info.flags = VK_DEBUG_REPORT_ERROR_BIT_EXT | VK_DEBUG_REPORT_WARNING_BIT_EXT; + callback_info.pfnCallback = vkd3d_debug_report_callback; + callback_info.pUserData = NULL; + if ((vr = VK_CALL(vkCreateDebugReportCallbackEXT(vk_instance, &callback_info, NULL, &callback)) < 0)) + { + WARN("Failed to create debug report callback, vr %d.\n", vr); + return; + } + + instance->vk_debug_callback = callback; +} + static HRESULT vkd3d_instance_init(struct vkd3d_instance *instance, const struct vkd3d_instance_create_info *create_info) { @@ -333,6 +371,10 @@ static HRESULT vkd3d_instance_init(struct vkd3d_instance *instance,
instance->refcount = 1;
+ instance->vk_debug_callback = VK_NULL_HANDLE; + if (instance->vk_info.EXT_debug_report) + vkd3d_init_debug_report(instance); + return S_OK; }
@@ -370,6 +412,22 @@ HRESULT vkd3d_create_instance(const struct vkd3d_instance_create_info *create_in return S_OK; }
+static void vkd3d_destroy_instance(struct vkd3d_instance *instance) +{ + const struct vkd3d_vk_instance_procs *vk_procs = &instance->vk_procs; + VkInstance vk_instance = instance->vk_instance; + + if (instance->vk_debug_callback) + VK_CALL(vkDestroyDebugReportCallbackEXT(vk_instance, instance->vk_debug_callback, NULL)); + + VK_CALL(vkDestroyInstance(vk_instance, NULL)); + + if (instance->libvulkan) + dlclose(instance->libvulkan); + + vkd3d_free(instance); +} + ULONG vkd3d_instance_incref(struct vkd3d_instance *instance) { ULONG refcount = InterlockedIncrement(&instance->refcount); @@ -386,13 +444,7 @@ ULONG vkd3d_instance_decref(struct vkd3d_instance *instance) TRACE("%p decreasing refcount to %u.\n", instance, refcount);
if (!refcount) - { - const struct vkd3d_vk_instance_procs *vk_procs = &instance->vk_procs; - VK_CALL(vkDestroyInstance(instance->vk_instance, NULL)); - if (instance->libvulkan) - dlclose(instance->libvulkan); - vkd3d_free(instance); - } + vkd3d_destroy_instance(instance);
return refcount; } diff --git a/libs/vkd3d/utils.c b/libs/vkd3d/utils.c index a62a74677981..43c8356203f5 100644 --- a/libs/vkd3d/utils.c +++ b/libs/vkd3d/utils.c @@ -399,13 +399,16 @@ HRESULT vkd3d_load_vk_global_procs(struct vkd3d_vk_global_procs *procs, ERR("Could not get instance proc addr for '" #name "'.\n"); \ return E_FAIL; \ } +#define LOAD_INSTANCE_OPTIONAL_PFN(name) \ + procs->name = (void *)global_procs->vkGetInstanceProcAddr(instance, #name);
HRESULT vkd3d_load_vk_instance_procs(struct vkd3d_vk_instance_procs *procs, const struct vkd3d_vk_global_procs *global_procs, VkInstance instance) { memset(procs, 0, sizeof(*procs));
-#define VK_INSTANCE_PFN LOAD_INSTANCE_PFN +#define VK_INSTANCE_PFN LOAD_INSTANCE_PFN +#define VK_INSTANCE_EXT_PFN LOAD_INSTANCE_OPTIONAL_PFN #include "vulkan_procs.h"
TRACE("Loaded procs for VkInstance %p.\n", instance); diff --git a/libs/vkd3d/vkd3d_private.h b/libs/vkd3d/vkd3d_private.h index cf3112e845b3..246c42bed937 100644 --- a/libs/vkd3d/vkd3d_private.h +++ b/libs/vkd3d/vkd3d_private.h @@ -58,7 +58,8 @@ struct vkd3d_vk_global_procs #define DECLARE_VK_PFN(name) PFN_##name name; struct vkd3d_vk_instance_procs { -#define VK_INSTANCE_PFN DECLARE_VK_PFN +#define VK_INSTANCE_PFN DECLARE_VK_PFN +#define VK_INSTANCE_EXT_PFN DECLARE_VK_PFN #include "vulkan_procs.h" };
@@ -75,6 +76,7 @@ struct vkd3d_vulkan_info { /* instance extensions */ bool KHR_get_physical_device_properties2; + bool EXT_debug_report; /* device extensions */ bool KHR_push_descriptor;
@@ -96,6 +98,8 @@ struct vkd3d_instance struct vkd3d_vk_global_procs vk_global_procs; void *libvulkan;
+ VkDebugReportCallbackEXT vk_debug_callback; + LONG refcount; };
diff --git a/libs/vkd3d/vulkan_procs.h b/libs/vkd3d/vulkan_procs.h index cbdcda80f2c7..690a1a2b5acf 100644 --- a/libs/vkd3d/vulkan_procs.h +++ b/libs/vkd3d/vulkan_procs.h @@ -20,6 +20,10 @@ # define VK_INSTANCE_PFN(x) #endif
+#ifndef VK_INSTANCE_EXT_PFN +# define VK_INSTANCE_EXT_PFN(x) +#endif + #ifndef VK_DEVICE_PFN # define VK_DEVICE_PFN(x) #endif @@ -42,6 +46,9 @@ VK_INSTANCE_PFN(vkGetPhysicalDeviceMemoryProperties) VK_INSTANCE_PFN(vkGetPhysicalDeviceProperties) VK_INSTANCE_PFN(vkGetPhysicalDeviceQueueFamilyProperties) VK_INSTANCE_PFN(vkGetPhysicalDeviceSparseImageFormatProperties) +/* VK_EXT_debug_report */ +VK_INSTANCE_EXT_PFN(vkCreateDebugReportCallbackEXT) +VK_INSTANCE_EXT_PFN(vkDestroyDebugReportCallbackEXT)
/* Device functions (obtained by vkGetDeviceProcAddr). */ VK_DEVICE_PFN(vkDestroyDevice) /* Load vkDestroyDevice() first. */ @@ -168,5 +175,6 @@ VK_DEVICE_PFN(vkWaitForFences) VK_DEVICE_EXT_PFN(vkCmdPushDescriptorSetKHR)
#undef VK_INSTANCE_PFN +#undef VK_INSTANCE_EXT_PFN #undef VK_DEVICE_PFN #undef VK_DEVICE_EXT_PFN