Module: Mesa
Branch: main
Commit: d55d1fcda2f5f1cd20dcc240fd75ade66f8177f7
URL:    
http://cgit.freedesktop.org/mesa/mesa/commit/?id=d55d1fcda2f5f1cd20dcc240fd75ade66f8177f7

Author: Yevhenii Kolesnikov <[email protected]>
Date:   Wed Sep 22 01:56:38 2021 +0300

vulkan: Add convenience debug message helpers

Forwards the message to both VK_EXT_debug_utils and
VK_EXT_debug_report provided callbacks.

Signed-off-by: Yevhenii Kolesnikov <[email protected]>
Reviewed-by: Jason Ekstrand <[email protected]>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/10318>

---

 src/vulkan/util/meson.build |   2 +
 src/vulkan/util/vk_log.c    | 200 ++++++++++++++++++++++++++++++++++++++++++++
 src/vulkan/util/vk_log.h    |  73 ++++++++++++++++
 src/vulkan/util/vk_object.c |  16 ++++
 src/vulkan/util/vk_object.h |   3 +
 5 files changed, 294 insertions(+)

diff --git a/src/vulkan/util/meson.build b/src/vulkan/util/meson.build
index 1bfd7a6cddd..dddcfad3e0c 100644
--- a/src/vulkan/util/meson.build
+++ b/src/vulkan/util/meson.build
@@ -69,6 +69,8 @@ files_vulkan_util = files(
   'vk_image.h',
   'vk_instance.c',
   'vk_instance.h',
+  'vk_log.c',
+  'vk_log.h',
   'vk_object.c',
   'vk_object.h',
   'vk_physical_device.c',
diff --git a/src/vulkan/util/vk_log.c b/src/vulkan/util/vk_log.c
new file mode 100644
index 00000000000..66929ab40a3
--- /dev/null
+++ b/src/vulkan/util/vk_log.c
@@ -0,0 +1,200 @@
+/*
+ * Copyright © 2021 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+#include "vk_log.h"
+#include "vk_debug_utils.h"
+#include "vk_debug_report.h"
+
+#include "vk_command_buffer.h"
+#include "vk_queue.h"
+#include "vk_device.h"
+#include "vk_physical_device.h"
+
+#include "ralloc.h"
+
+#include "log.h"
+
+void
+__vk_log_impl(VkDebugUtilsMessageSeverityFlagBitsEXT severity,
+              VkDebugUtilsMessageTypeFlagsEXT types,
+              int object_count,
+              const void **objects_or_instance,
+              const char *file,
+              int line,
+              const char *format,
+              ...)
+{
+   struct vk_instance *instance = NULL;
+   struct vk_object_base **objects = NULL;
+   if (object_count == 0) {
+      instance = (struct vk_instance *) objects_or_instance;
+   } else {
+      objects = (struct vk_object_base **) objects_or_instance;
+      instance = objects[0]->device->physical->instance;
+   }
+
+#ifndef DEBUG
+   if (unlikely(!instance) ||
+       (likely(list_is_empty(&instance->debug_utils.callbacks)) &&
+        likely(list_is_empty(&instance->debug_report.callbacks))))
+      return;
+#endif
+
+   va_list va;
+   char *message = NULL;
+
+   va_start(va, format);
+   message = ralloc_vasprintf(NULL, format, va);
+   va_end(va);
+
+   char *message_idname = ralloc_asprintf(NULL, "%s:%d", file, line);
+
+#if DEBUG
+   switch (severity) {
+   case VK_DEBUG_UTILS_MESSAGE_SEVERITY_VERBOSE_BIT_EXT:
+      mesa_logd("%s: %s", message_idname, message);
+      break;
+   case VK_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT:
+      mesa_logi("%s: %s", message_idname, message);
+      break;
+   case VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT:
+      if (types & VK_DEBUG_UTILS_MESSAGE_TYPE_PERFORMANCE_BIT_EXT)
+         mesa_logw("%s: PERF: %s", message_idname, message);
+      else
+         mesa_logw("%s: %s", message_idname, message);
+      break;
+   case VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT:
+      mesa_loge("%s: %s", message_idname, message);
+      break;
+   default:
+      unreachable("Invalid debug message severity");
+      break;
+   }
+
+   if (!instance) {
+      ralloc_free(message);
+      ralloc_free(message_idname);
+      return;
+   }
+#endif
+
+   /* If VK_EXT_debug_utils messengers have been set up, form the
+    * message */
+   if (!list_is_empty(&instance->debug_utils.callbacks)) {
+      VkDebugUtilsMessengerCallbackDataEXT cb_data = {
+         .sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_MESSENGER_CALLBACK_DATA_EXT,
+         .pMessageIdName = message_idname,
+         .messageIdNumber = 0,
+         .pMessage = message,
+      };
+
+      VkDebugUtilsObjectNameInfoEXT *object_name_infos =
+         ralloc_array(NULL, VkDebugUtilsObjectNameInfoEXT, object_count);
+
+      ASSERTED int cmdbuf_n = 0, queue_n = 0;
+      for (int i = 0; i < object_count; i++) {
+         struct vk_object_base *base = objects[i];
+
+         switch (base->type) {
+         case VK_OBJECT_TYPE_COMMAND_BUFFER: {
+            /* We allow at most one command buffer to be submitted at a time */
+            assert(++cmdbuf_n <= 1);
+            struct vk_command_buffer *cmd_buffer =
+               (struct vk_command_buffer *)base;
+            if (cmd_buffer->labels.size > 0) {
+               cb_data.cmdBufLabelCount = util_dynarray_num_elements(
+                  &cmd_buffer->labels, VkDebugUtilsLabelEXT);
+               cb_data.pCmdBufLabels = cmd_buffer->labels.data;
+            }
+            break;
+         }
+
+         case VK_OBJECT_TYPE_QUEUE: {
+            /* We allow at most one queue to be submitted at a time */
+            assert(++queue_n <= 1);
+            struct vk_queue *queue = (struct vk_queue *)base;
+            if (queue->labels.size > 0) {
+               cb_data.queueLabelCount =
+                  util_dynarray_num_elements(&queue->labels, 
VkDebugUtilsLabelEXT);
+               cb_data.pQueueLabels = queue->labels.data;
+            }
+            break;
+         }
+         default:
+            break;
+         }
+
+         object_name_infos[i] = (VkDebugUtilsObjectNameInfoEXT){
+            .sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_OBJECT_NAME_INFO_EXT,
+            .pNext = NULL,
+            .objectType = base->type,
+            .objectHandle = (uint64_t)(uintptr_t)base,
+            .pObjectName = base->object_name,
+         };
+      }
+      cb_data.objectCount = object_count;
+      cb_data.pObjects = object_name_infos;
+
+      vk_debug_message(instance, severity, types, &cb_data);
+
+      ralloc_free(object_name_infos);
+   }
+
+   /* If VK_EXT_debug_report callbacks also have been set up, forward
+    * the message there as well */
+   if (!list_is_empty(&instance->debug_report.callbacks)) {
+      VkDebugReportFlagsEXT flags = 0;
+
+      switch (severity) {
+      case VK_DEBUG_UTILS_MESSAGE_SEVERITY_VERBOSE_BIT_EXT:
+         flags |= VK_DEBUG_REPORT_DEBUG_BIT_EXT;
+         break;
+      case VK_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT:
+         flags |= VK_DEBUG_REPORT_INFORMATION_BIT_EXT;
+         break;
+      case VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT:
+         if (types & VK_DEBUG_UTILS_MESSAGE_TYPE_PERFORMANCE_BIT_EXT)
+            flags |= VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT;
+         else
+            flags |= VK_DEBUG_REPORT_WARNING_BIT_EXT;
+         break;
+      case VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT:
+         flags |= VK_DEBUG_REPORT_ERROR_BIT_EXT;
+         break;
+      default:
+         unreachable("Invalid debug message severity");
+         break;
+      }
+
+      /* VK_EXT_debug_report-provided callback accepts only one object
+       * related to the message. Since they are given to us in
+       * decreasing order of importance, we're forwarding the first
+       * one.
+       */
+      vk_debug_report(instance, flags, object_count ? objects[0] : NULL, 0,
+                      0, message_idname, message);
+   }
+
+   ralloc_free(message);
+   ralloc_free(message_idname);
+}
diff --git a/src/vulkan/util/vk_log.h b/src/vulkan/util/vk_log.h
new file mode 100644
index 00000000000..0e33d8949c5
--- /dev/null
+++ b/src/vulkan/util/vk_log.h
@@ -0,0 +1,73 @@
+/*
+ * Copyright © 2021 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+#include "vk_instance.h"
+
+/* __VK_ARG_N(...) returns the number of arguments provided to it  */
+#define __VK_ARG_SEQ(_1,_2,_3,_4,_5,_6,_7,_8,N,...) N
+#define __VK_ARG_N(...) __VK_ARG_SEQ(__VA_ARGS__,8,7,6,5,4,3,2,1,0)
+
+#define VK_LOG_OBJS(...)                                        \
+   __VK_ARG_N(__VA_ARGS__), (const void*[]){__VA_ARGS__}
+
+#define VK_LOG_NO_OBJS(instance) 0, (const void**)instance
+
+#define vk_logd(objects_macro, format, ...)                             \
+   __vk_log(VK_DEBUG_UTILS_MESSAGE_SEVERITY_VERBOSE_BIT_EXT,            \
+            VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT,                \
+            objects_macro, __FILE__, __LINE__, format, ## __VA_ARGS__)
+
+#define vk_logi(objects_macro, format, ...)                             \
+   __vk_log(VK_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT,               \
+            VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT,                \
+            objects_macro, __FILE__, __LINE__, format, ## __VA_ARGS__)
+
+#define vk_logw(objects_macro, format, ...)                             \
+   __vk_log(VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT,            \
+            VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT,                \
+            objects_macro, __FILE__, __LINE__, format, ## __VA_ARGS__)
+
+#define vk_loge(objects_macro, format, ...)                             \
+   __vk_log(VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT,              \
+            VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT,                \
+            objects_macro, __FILE__, __LINE__, format, ## __VA_ARGS__)
+
+#define vk_perf(objects_macro, format, ...)                             \
+   __vk_log(VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT,            \
+            VK_DEBUG_UTILS_MESSAGE_TYPE_PERFORMANCE_BIT_EXT,            \
+            objects_macro, __FILE__, __LINE__, format, ## __VA_ARGS__)
+
+#define __vk_log(severity, type, object_count,                          \
+                 objects_or_instance, file, line, format, ...)          \
+   __vk_log_impl(severity, type, object_count, objects_or_instance,     \
+                 file, line, format, ## __VA_ARGS__)
+
+void PRINTFLIKE(7, 8)
+__vk_log_impl(VkDebugUtilsMessageSeverityFlagBitsEXT severity,
+              VkDebugUtilsMessageTypeFlagsEXT types,
+              int object_count,
+              const void **objects_or_instance,
+              const char *file,
+              int line,
+              const char *format,
+              ...);
diff --git a/src/vulkan/util/vk_object.c b/src/vulkan/util/vk_object.c
index 08f1eeea5ad..b3e482ef133 100644
--- a/src/vulkan/util/vk_object.c
+++ b/src/vulkan/util/vk_object.c
@@ -28,6 +28,7 @@
 #include "vk_device.h"
 #include "util/hash_table.h"
 #include "util/ralloc.h"
+#include "vk_enum_to_str.h"
 
 static void
 vk_object_base_reinit(struct vk_object_base *base)
@@ -326,3 +327,18 @@ vk_common_GetPrivateDataEXT(VkDevice _device,
                                    objectType, objectHandle,
                                    privateDataSlot, pData);
 }
+
+const char *
+vk_object_base_name(struct vk_object_base *obj)
+{
+   if (obj->object_name)
+      return obj->object_name;
+
+   obj->object_name = vk_asprintf(&obj->device->alloc,
+                                  VK_SYSTEM_ALLOCATION_SCOPE_DEVICE,
+                                  "%s(0x%"PRIx64")",
+                                  vk_ObjectType_to_ObjectName(obj->type),
+                                  (uint64_t)(uintptr_t)obj);
+
+   return obj->object_name;
+}
diff --git a/src/vulkan/util/vk_object.h b/src/vulkan/util/vk_object.h
index ebaa2376997..d23713580aa 100644
--- a/src/vulkan/util/vk_object.h
+++ b/src/vulkan/util/vk_object.h
@@ -173,6 +173,9 @@ vk_object_base_get_private_data(struct vk_device *device,
                                 VkPrivateDataSlotEXT privateDataSlot,
                                 uint64_t *pData);
 
+const char *
+vk_object_base_name(struct vk_object_base *obj);
+
 #ifdef __cplusplus
 }
 #endif

Reply via email to