17ec681f3Smrg/*
27ec681f3Smrg * Copyright © 2021 Intel Corporation
37ec681f3Smrg *
47ec681f3Smrg * Permission is hereby granted, free of charge, to any person obtaining a
57ec681f3Smrg * copy of this software and associated documentation files (the "Software"),
67ec681f3Smrg * to deal in the Software without restriction, including without limitation
77ec681f3Smrg * the rights to use, copy, modify, merge, publish, distribute, sublicense,
87ec681f3Smrg * and/or sell copies of the Software, and to permit persons to whom the
97ec681f3Smrg * Software is furnished to do so, subject to the following conditions:
107ec681f3Smrg *
117ec681f3Smrg * The above copyright notice and this permission notice (including the next
127ec681f3Smrg * paragraph) shall be included in all copies or substantial portions of the
137ec681f3Smrg * Software.
147ec681f3Smrg *
157ec681f3Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
167ec681f3Smrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
177ec681f3Smrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
187ec681f3Smrg * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
197ec681f3Smrg * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
207ec681f3Smrg * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
217ec681f3Smrg * IN THE SOFTWARE.
227ec681f3Smrg */
237ec681f3Smrg
247ec681f3Smrg#include "vk_debug_utils.h"
257ec681f3Smrg
267ec681f3Smrg#include "vk_common_entrypoints.h"
277ec681f3Smrg#include "vk_command_buffer.h"
287ec681f3Smrg#include "vk_device.h"
297ec681f3Smrg#include "vk_queue.h"
307ec681f3Smrg#include "vk_object.h"
317ec681f3Smrg#include "vk_alloc.h"
327ec681f3Smrg#include "vk_util.h"
337ec681f3Smrg#include "stdarg.h"
347ec681f3Smrg#include "u_dynarray.h"
357ec681f3Smrg
367ec681f3Smrgvoid
377ec681f3Smrgvk_debug_message(struct vk_instance *instance,
387ec681f3Smrg                 VkDebugUtilsMessageSeverityFlagBitsEXT severity,
397ec681f3Smrg                 VkDebugUtilsMessageTypeFlagsEXT types,
407ec681f3Smrg                 const VkDebugUtilsMessengerCallbackDataEXT *pCallbackData)
417ec681f3Smrg{
427ec681f3Smrg   mtx_lock(&instance->debug_utils.callbacks_mutex);
437ec681f3Smrg
447ec681f3Smrg   list_for_each_entry(struct vk_debug_utils_messenger, messenger,
457ec681f3Smrg                       &instance->debug_utils.callbacks, link) {
467ec681f3Smrg      if ((messenger->severity & severity) &&
477ec681f3Smrg          (messenger->type & types))
487ec681f3Smrg         messenger->callback(severity, types, pCallbackData, messenger->data);
497ec681f3Smrg   }
507ec681f3Smrg
517ec681f3Smrg   mtx_unlock(&instance->debug_utils.callbacks_mutex);
527ec681f3Smrg}
537ec681f3Smrg
547ec681f3Smrg/* This function intended to be used by the drivers to report a
557ec681f3Smrg * message to the special messenger, provided in the pNext chain while
567ec681f3Smrg * creating an instance. It's only meant to be used during
577ec681f3Smrg * vkCreateInstance or vkDestroyInstance calls.
587ec681f3Smrg */
597ec681f3Smrgvoid
607ec681f3Smrgvk_debug_message_instance(struct vk_instance *instance,
617ec681f3Smrg                          VkDebugUtilsMessageSeverityFlagBitsEXT severity,
627ec681f3Smrg                          VkDebugUtilsMessageTypeFlagsEXT types,
637ec681f3Smrg                          const char *pMessageIdName,
647ec681f3Smrg                          int32_t messageIdNumber,
657ec681f3Smrg                          const char *pMessage)
667ec681f3Smrg{
677ec681f3Smrg   if (list_is_empty(&instance->debug_utils.instance_callbacks))
687ec681f3Smrg      return;
697ec681f3Smrg
707ec681f3Smrg   const VkDebugUtilsMessengerCallbackDataEXT cbData = {
717ec681f3Smrg      .sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_MESSENGER_CALLBACK_DATA_EXT,
727ec681f3Smrg      .pMessageIdName = pMessageIdName,
737ec681f3Smrg      .messageIdNumber = messageIdNumber,
747ec681f3Smrg      .pMessage = pMessage,
757ec681f3Smrg   };
767ec681f3Smrg
777ec681f3Smrg   list_for_each_entry(struct vk_debug_utils_messenger, messenger,
787ec681f3Smrg                       &instance->debug_utils.instance_callbacks, link) {
797ec681f3Smrg      if ((messenger->severity & severity) &&
807ec681f3Smrg          (messenger->type & types))
817ec681f3Smrg         messenger->callback(severity, types, &cbData, messenger->data);
827ec681f3Smrg   }
837ec681f3Smrg}
847ec681f3Smrg
857ec681f3SmrgVKAPI_ATTR VkResult VKAPI_CALL
867ec681f3Smrgvk_common_CreateDebugUtilsMessengerEXT(
877ec681f3Smrg   VkInstance _instance,
887ec681f3Smrg   const VkDebugUtilsMessengerCreateInfoEXT *pCreateInfo,
897ec681f3Smrg   const VkAllocationCallbacks *pAllocator,
907ec681f3Smrg   VkDebugUtilsMessengerEXT *pMessenger)
917ec681f3Smrg{
927ec681f3Smrg   VK_FROM_HANDLE(vk_instance, instance, _instance);
937ec681f3Smrg
947ec681f3Smrg   struct vk_debug_utils_messenger *messenger =
957ec681f3Smrg      vk_alloc2(&instance->alloc, pAllocator,
967ec681f3Smrg                sizeof(struct vk_debug_utils_messenger), 8,
977ec681f3Smrg                VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
987ec681f3Smrg
997ec681f3Smrg   if (!messenger)
1007ec681f3Smrg      return VK_ERROR_OUT_OF_HOST_MEMORY;
1017ec681f3Smrg
1027ec681f3Smrg   if (pAllocator)
1037ec681f3Smrg      messenger->alloc = *pAllocator;
1047ec681f3Smrg   else
1057ec681f3Smrg      messenger->alloc = instance->alloc;
1067ec681f3Smrg
1077ec681f3Smrg   vk_object_base_init(NULL, &messenger->base,
1087ec681f3Smrg                       VK_OBJECT_TYPE_DEBUG_UTILS_MESSENGER_EXT);
1097ec681f3Smrg
1107ec681f3Smrg   messenger->severity = pCreateInfo->messageSeverity;
1117ec681f3Smrg   messenger->type = pCreateInfo->messageType;
1127ec681f3Smrg   messenger->callback = pCreateInfo->pfnUserCallback;
1137ec681f3Smrg   messenger->data = pCreateInfo->pUserData;
1147ec681f3Smrg
1157ec681f3Smrg   mtx_lock(&instance->debug_utils.callbacks_mutex);
1167ec681f3Smrg   list_addtail(&messenger->link, &instance->debug_utils.callbacks);
1177ec681f3Smrg   mtx_unlock(&instance->debug_utils.callbacks_mutex);
1187ec681f3Smrg
1197ec681f3Smrg   *pMessenger = vk_debug_utils_messenger_to_handle(messenger);
1207ec681f3Smrg
1217ec681f3Smrg   return VK_SUCCESS;
1227ec681f3Smrg}
1237ec681f3Smrg
1247ec681f3SmrgVKAPI_ATTR void VKAPI_CALL
1257ec681f3Smrgvk_common_SubmitDebugUtilsMessageEXT(
1267ec681f3Smrg   VkInstance _instance,
1277ec681f3Smrg   VkDebugUtilsMessageSeverityFlagBitsEXT messageSeverity,
1287ec681f3Smrg   VkDebugUtilsMessageTypeFlagsEXT messageTypes,
1297ec681f3Smrg   const VkDebugUtilsMessengerCallbackDataEXT *pCallbackData)
1307ec681f3Smrg{
1317ec681f3Smrg   VK_FROM_HANDLE(vk_instance, instance, _instance);
1327ec681f3Smrg
1337ec681f3Smrg   vk_debug_message(instance, messageSeverity, messageTypes, pCallbackData);
1347ec681f3Smrg}
1357ec681f3Smrg
1367ec681f3SmrgVKAPI_ATTR void VKAPI_CALL
1377ec681f3Smrgvk_common_DestroyDebugUtilsMessengerEXT(
1387ec681f3Smrg   VkInstance _instance,
1397ec681f3Smrg   VkDebugUtilsMessengerEXT _messenger,
1407ec681f3Smrg   const VkAllocationCallbacks *pAllocator)
1417ec681f3Smrg{
1427ec681f3Smrg   VK_FROM_HANDLE(vk_instance, instance, _instance);
1437ec681f3Smrg   VK_FROM_HANDLE(vk_debug_utils_messenger, messenger, _messenger);
1447ec681f3Smrg
1457ec681f3Smrg   if (messenger == NULL)
1467ec681f3Smrg      return;
1477ec681f3Smrg
1487ec681f3Smrg   mtx_lock(&instance->debug_utils.callbacks_mutex);
1497ec681f3Smrg   list_del(&messenger->link);
1507ec681f3Smrg   mtx_unlock(&instance->debug_utils.callbacks_mutex);
1517ec681f3Smrg
1527ec681f3Smrg   vk_object_base_finish(&messenger->base);
1537ec681f3Smrg   vk_free2(&instance->alloc, pAllocator, messenger);
1547ec681f3Smrg}
1557ec681f3Smrg
1567ec681f3SmrgVKAPI_ATTR VkResult VKAPI_CALL
1577ec681f3Smrgvk_common_SetDebugUtilsObjectNameEXT(
1587ec681f3Smrg   VkDevice _device,
1597ec681f3Smrg   const VkDebugUtilsObjectNameInfoEXT *pNameInfo)
1607ec681f3Smrg{
1617ec681f3Smrg   VK_FROM_HANDLE(vk_device, device, _device);
1627ec681f3Smrg   struct vk_object_base *object =
1637ec681f3Smrg      vk_object_base_from_u64_handle(pNameInfo->objectHandle,
1647ec681f3Smrg                                     pNameInfo->objectType);
1657ec681f3Smrg
1667ec681f3Smrg   if (object->object_name) {
1677ec681f3Smrg      vk_free(&device->alloc, object->object_name);
1687ec681f3Smrg      object->object_name = NULL;
1697ec681f3Smrg   }
1707ec681f3Smrg   object->object_name = vk_strdup(&device->alloc, pNameInfo->pObjectName,
1717ec681f3Smrg                                   VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
1727ec681f3Smrg   if (!object->object_name)
1737ec681f3Smrg      return VK_ERROR_OUT_OF_HOST_MEMORY;
1747ec681f3Smrg
1757ec681f3Smrg   return VK_SUCCESS;
1767ec681f3Smrg}
1777ec681f3Smrg
1787ec681f3SmrgVKAPI_ATTR VkResult VKAPI_CALL
1797ec681f3Smrgvk_common_SetDebugUtilsObjectTagEXT(
1807ec681f3Smrg   VkDevice _device,
1817ec681f3Smrg   const VkDebugUtilsObjectTagInfoEXT *pTagInfo)
1827ec681f3Smrg{
1837ec681f3Smrg   /* no-op */
1847ec681f3Smrg   return VK_SUCCESS;
1857ec681f3Smrg}
1867ec681f3Smrg
1877ec681f3SmrgVKAPI_ATTR void VKAPI_CALL
1887ec681f3Smrgvk_common_CmdBeginDebugUtilsLabelEXT(
1897ec681f3Smrg   VkCommandBuffer _commandBuffer,
1907ec681f3Smrg   const VkDebugUtilsLabelEXT *pLabelInfo)
1917ec681f3Smrg{
1927ec681f3Smrg   VK_FROM_HANDLE(vk_command_buffer, command_buffer, _commandBuffer);
1937ec681f3Smrg
1947ec681f3Smrg   /* If the latest label was submitted by CmdInsertDebugUtilsLabelEXT, we
1957ec681f3Smrg    * should remove it first.
1967ec681f3Smrg    */
1977ec681f3Smrg   if (!command_buffer->region_begin)
1987ec681f3Smrg      (void)util_dynarray_pop(&command_buffer->labels, VkDebugUtilsLabelEXT);
1997ec681f3Smrg
2007ec681f3Smrg   util_dynarray_append(&command_buffer->labels, VkDebugUtilsLabelEXT,
2017ec681f3Smrg                        *pLabelInfo);
2027ec681f3Smrg   command_buffer->region_begin = true;
2037ec681f3Smrg}
2047ec681f3Smrg
2057ec681f3SmrgVKAPI_ATTR void VKAPI_CALL
2067ec681f3Smrgvk_common_CmdEndDebugUtilsLabelEXT(VkCommandBuffer _commandBuffer)
2077ec681f3Smrg{
2087ec681f3Smrg   VK_FROM_HANDLE(vk_command_buffer, command_buffer, _commandBuffer);
2097ec681f3Smrg
2107ec681f3Smrg   /* If the latest label was submitted by CmdInsertDebugUtilsLabelEXT, we
2117ec681f3Smrg    * should remove it first.
2127ec681f3Smrg    */
2137ec681f3Smrg   if (!command_buffer->region_begin)
2147ec681f3Smrg      (void)util_dynarray_pop(&command_buffer->labels, VkDebugUtilsLabelEXT);
2157ec681f3Smrg
2167ec681f3Smrg   (void)util_dynarray_pop(&command_buffer->labels, VkDebugUtilsLabelEXT);
2177ec681f3Smrg   command_buffer->region_begin = true;
2187ec681f3Smrg}
2197ec681f3Smrg
2207ec681f3SmrgVKAPI_ATTR void VKAPI_CALL
2217ec681f3Smrgvk_common_CmdInsertDebugUtilsLabelEXT(
2227ec681f3Smrg   VkCommandBuffer _commandBuffer,
2237ec681f3Smrg   const VkDebugUtilsLabelEXT *pLabelInfo)
2247ec681f3Smrg{
2257ec681f3Smrg   VK_FROM_HANDLE(vk_command_buffer, command_buffer, _commandBuffer);
2267ec681f3Smrg
2277ec681f3Smrg   /* If the latest label was submitted by CmdInsertDebugUtilsLabelEXT, we
2287ec681f3Smrg    * should remove it first.
2297ec681f3Smrg    */
2307ec681f3Smrg   if (!command_buffer->region_begin)
2317ec681f3Smrg      (void)util_dynarray_pop(&command_buffer->labels, VkDebugUtilsLabelEXT);
2327ec681f3Smrg
2337ec681f3Smrg   util_dynarray_append(&command_buffer->labels, VkDebugUtilsLabelEXT,
2347ec681f3Smrg                        *pLabelInfo);
2357ec681f3Smrg   command_buffer->region_begin = false;
2367ec681f3Smrg}
2377ec681f3Smrg
2387ec681f3SmrgVKAPI_ATTR void VKAPI_CALL
2397ec681f3Smrgvk_common_QueueBeginDebugUtilsLabelEXT(
2407ec681f3Smrg   VkQueue _queue,
2417ec681f3Smrg   const VkDebugUtilsLabelEXT *pLabelInfo)
2427ec681f3Smrg{
2437ec681f3Smrg   VK_FROM_HANDLE(vk_queue, queue, _queue);
2447ec681f3Smrg
2457ec681f3Smrg   /* If the latest label was submitted by QueueInsertDebugUtilsLabelEXT, we
2467ec681f3Smrg    * should remove it first.
2477ec681f3Smrg    */
2487ec681f3Smrg   if (!queue->region_begin)
2497ec681f3Smrg      (void)util_dynarray_pop(&queue->labels, VkDebugUtilsLabelEXT);
2507ec681f3Smrg
2517ec681f3Smrg   util_dynarray_append(&queue->labels, VkDebugUtilsLabelEXT, *pLabelInfo);
2527ec681f3Smrg   queue->region_begin = true;
2537ec681f3Smrg}
2547ec681f3Smrg
2557ec681f3SmrgVKAPI_ATTR void VKAPI_CALL
2567ec681f3Smrgvk_common_QueueEndDebugUtilsLabelEXT(VkQueue _queue)
2577ec681f3Smrg{
2587ec681f3Smrg   VK_FROM_HANDLE(vk_queue, queue, _queue);
2597ec681f3Smrg
2607ec681f3Smrg   /* If the latest label was submitted by QueueInsertDebugUtilsLabelEXT, we
2617ec681f3Smrg    * should remove it first.
2627ec681f3Smrg    */
2637ec681f3Smrg   if (!queue->region_begin)
2647ec681f3Smrg      (void)util_dynarray_pop(&queue->labels, VkDebugUtilsLabelEXT);
2657ec681f3Smrg
2667ec681f3Smrg   (void)util_dynarray_pop(&queue->labels, VkDebugUtilsLabelEXT);
2677ec681f3Smrg   queue->region_begin = true;
2687ec681f3Smrg}
2697ec681f3Smrg
2707ec681f3SmrgVKAPI_ATTR void VKAPI_CALL
2717ec681f3Smrgvk_common_QueueInsertDebugUtilsLabelEXT(
2727ec681f3Smrg   VkQueue _queue,
2737ec681f3Smrg   const VkDebugUtilsLabelEXT *pLabelInfo)
2747ec681f3Smrg{
2757ec681f3Smrg   VK_FROM_HANDLE(vk_queue, queue, _queue);
2767ec681f3Smrg
2777ec681f3Smrg   /* If the latest label was submitted by QueueInsertDebugUtilsLabelEXT, we
2787ec681f3Smrg    * should remove it first.
2797ec681f3Smrg    */
2807ec681f3Smrg   if (!queue->region_begin)
2817ec681f3Smrg      (void)util_dynarray_pop(&queue->labels, VkDebugUtilsLabelEXT);
2827ec681f3Smrg
2837ec681f3Smrg   util_dynarray_append(&queue->labels, VkDebugUtilsLabelEXT, *pLabelInfo);
2847ec681f3Smrg   queue->region_begin = false;
2857ec681f3Smrg}
286