mesa/src/vulkan/runtime/vk_debug_utils.c

286 lines
9.4 KiB
C

/*
* 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_debug_utils.h"
#include "vk_common_entrypoints.h"
#include "vk_command_buffer.h"
#include "vk_device.h"
#include "vk_queue.h"
#include "vk_object.h"
#include "vk_alloc.h"
#include "vk_util.h"
#include "stdarg.h"
#include "u_dynarray.h"
void
vk_debug_message(struct vk_instance *instance,
VkDebugUtilsMessageSeverityFlagBitsEXT severity,
VkDebugUtilsMessageTypeFlagsEXT types,
const VkDebugUtilsMessengerCallbackDataEXT *pCallbackData)
{
mtx_lock(&instance->debug_utils.callbacks_mutex);
list_for_each_entry(struct vk_debug_utils_messenger, messenger,
&instance->debug_utils.callbacks, link) {
if ((messenger->severity & severity) &&
(messenger->type & types))
messenger->callback(severity, types, pCallbackData, messenger->data);
}
mtx_unlock(&instance->debug_utils.callbacks_mutex);
}
/* This function intended to be used by the drivers to report a
* message to the special messenger, provided in the pNext chain while
* creating an instance. It's only meant to be used during
* vkCreateInstance or vkDestroyInstance calls.
*/
void
vk_debug_message_instance(struct vk_instance *instance,
VkDebugUtilsMessageSeverityFlagBitsEXT severity,
VkDebugUtilsMessageTypeFlagsEXT types,
const char *pMessageIdName,
int32_t messageIdNumber,
const char *pMessage)
{
if (list_is_empty(&instance->debug_utils.instance_callbacks))
return;
const VkDebugUtilsMessengerCallbackDataEXT cbData = {
.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_MESSENGER_CALLBACK_DATA_EXT,
.pMessageIdName = pMessageIdName,
.messageIdNumber = messageIdNumber,
.pMessage = pMessage,
};
list_for_each_entry(struct vk_debug_utils_messenger, messenger,
&instance->debug_utils.instance_callbacks, link) {
if ((messenger->severity & severity) &&
(messenger->type & types))
messenger->callback(severity, types, &cbData, messenger->data);
}
}
VKAPI_ATTR VkResult VKAPI_CALL
vk_common_CreateDebugUtilsMessengerEXT(
VkInstance _instance,
const VkDebugUtilsMessengerCreateInfoEXT *pCreateInfo,
const VkAllocationCallbacks *pAllocator,
VkDebugUtilsMessengerEXT *pMessenger)
{
VK_FROM_HANDLE(vk_instance, instance, _instance);
struct vk_debug_utils_messenger *messenger =
vk_alloc2(&instance->alloc, pAllocator,
sizeof(struct vk_debug_utils_messenger), 8,
VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
if (!messenger)
return VK_ERROR_OUT_OF_HOST_MEMORY;
if (pAllocator)
messenger->alloc = *pAllocator;
else
messenger->alloc = instance->alloc;
vk_object_base_init(NULL, &messenger->base,
VK_OBJECT_TYPE_DEBUG_UTILS_MESSENGER_EXT);
messenger->severity = pCreateInfo->messageSeverity;
messenger->type = pCreateInfo->messageType;
messenger->callback = pCreateInfo->pfnUserCallback;
messenger->data = pCreateInfo->pUserData;
mtx_lock(&instance->debug_utils.callbacks_mutex);
list_addtail(&messenger->link, &instance->debug_utils.callbacks);
mtx_unlock(&instance->debug_utils.callbacks_mutex);
*pMessenger = vk_debug_utils_messenger_to_handle(messenger);
return VK_SUCCESS;
}
VKAPI_ATTR void VKAPI_CALL
vk_common_SubmitDebugUtilsMessageEXT(
VkInstance _instance,
VkDebugUtilsMessageSeverityFlagBitsEXT messageSeverity,
VkDebugUtilsMessageTypeFlagsEXT messageTypes,
const VkDebugUtilsMessengerCallbackDataEXT *pCallbackData)
{
VK_FROM_HANDLE(vk_instance, instance, _instance);
vk_debug_message(instance, messageSeverity, messageTypes, pCallbackData);
}
VKAPI_ATTR void VKAPI_CALL
vk_common_DestroyDebugUtilsMessengerEXT(
VkInstance _instance,
VkDebugUtilsMessengerEXT _messenger,
const VkAllocationCallbacks *pAllocator)
{
VK_FROM_HANDLE(vk_instance, instance, _instance);
VK_FROM_HANDLE(vk_debug_utils_messenger, messenger, _messenger);
if (messenger == NULL)
return;
mtx_lock(&instance->debug_utils.callbacks_mutex);
list_del(&messenger->link);
mtx_unlock(&instance->debug_utils.callbacks_mutex);
vk_object_base_finish(&messenger->base);
vk_free2(&instance->alloc, pAllocator, messenger);
}
VKAPI_ATTR VkResult VKAPI_CALL
vk_common_SetDebugUtilsObjectNameEXT(
VkDevice _device,
const VkDebugUtilsObjectNameInfoEXT *pNameInfo)
{
VK_FROM_HANDLE(vk_device, device, _device);
struct vk_object_base *object =
vk_object_base_from_u64_handle(pNameInfo->objectHandle,
pNameInfo->objectType);
if (object->object_name) {
vk_free(&device->alloc, object->object_name);
object->object_name = NULL;
}
object->object_name = vk_strdup(&device->alloc, pNameInfo->pObjectName,
VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
if (!object->object_name)
return VK_ERROR_OUT_OF_HOST_MEMORY;
return VK_SUCCESS;
}
VKAPI_ATTR VkResult VKAPI_CALL
vk_common_SetDebugUtilsObjectTagEXT(
VkDevice _device,
const VkDebugUtilsObjectTagInfoEXT *pTagInfo)
{
/* no-op */
return VK_SUCCESS;
}
VKAPI_ATTR void VKAPI_CALL
vk_common_CmdBeginDebugUtilsLabelEXT(
VkCommandBuffer _commandBuffer,
const VkDebugUtilsLabelEXT *pLabelInfo)
{
VK_FROM_HANDLE(vk_command_buffer, command_buffer, _commandBuffer);
/* If the latest label was submitted by CmdInsertDebugUtilsLabelEXT, we
* should remove it first.
*/
if (!command_buffer->region_begin)
(void)util_dynarray_pop(&command_buffer->labels, VkDebugUtilsLabelEXT);
util_dynarray_append(&command_buffer->labels, VkDebugUtilsLabelEXT,
*pLabelInfo);
command_buffer->region_begin = true;
}
VKAPI_ATTR void VKAPI_CALL
vk_common_CmdEndDebugUtilsLabelEXT(VkCommandBuffer _commandBuffer)
{
VK_FROM_HANDLE(vk_command_buffer, command_buffer, _commandBuffer);
/* If the latest label was submitted by CmdInsertDebugUtilsLabelEXT, we
* should remove it first.
*/
if (!command_buffer->region_begin)
(void)util_dynarray_pop(&command_buffer->labels, VkDebugUtilsLabelEXT);
(void)util_dynarray_pop(&command_buffer->labels, VkDebugUtilsLabelEXT);
command_buffer->region_begin = true;
}
VKAPI_ATTR void VKAPI_CALL
vk_common_CmdInsertDebugUtilsLabelEXT(
VkCommandBuffer _commandBuffer,
const VkDebugUtilsLabelEXT *pLabelInfo)
{
VK_FROM_HANDLE(vk_command_buffer, command_buffer, _commandBuffer);
/* If the latest label was submitted by CmdInsertDebugUtilsLabelEXT, we
* should remove it first.
*/
if (!command_buffer->region_begin)
(void)util_dynarray_pop(&command_buffer->labels, VkDebugUtilsLabelEXT);
util_dynarray_append(&command_buffer->labels, VkDebugUtilsLabelEXT,
*pLabelInfo);
command_buffer->region_begin = false;
}
VKAPI_ATTR void VKAPI_CALL
vk_common_QueueBeginDebugUtilsLabelEXT(
VkQueue _queue,
const VkDebugUtilsLabelEXT *pLabelInfo)
{
VK_FROM_HANDLE(vk_queue, queue, _queue);
/* If the latest label was submitted by QueueInsertDebugUtilsLabelEXT, we
* should remove it first.
*/
if (!queue->region_begin)
(void)util_dynarray_pop(&queue->labels, VkDebugUtilsLabelEXT);
util_dynarray_append(&queue->labels, VkDebugUtilsLabelEXT, *pLabelInfo);
queue->region_begin = true;
}
VKAPI_ATTR void VKAPI_CALL
vk_common_QueueEndDebugUtilsLabelEXT(VkQueue _queue)
{
VK_FROM_HANDLE(vk_queue, queue, _queue);
/* If the latest label was submitted by QueueInsertDebugUtilsLabelEXT, we
* should remove it first.
*/
if (!queue->region_begin)
(void)util_dynarray_pop(&queue->labels, VkDebugUtilsLabelEXT);
(void)util_dynarray_pop(&queue->labels, VkDebugUtilsLabelEXT);
queue->region_begin = true;
}
VKAPI_ATTR void VKAPI_CALL
vk_common_QueueInsertDebugUtilsLabelEXT(
VkQueue _queue,
const VkDebugUtilsLabelEXT *pLabelInfo)
{
VK_FROM_HANDLE(vk_queue, queue, _queue);
/* If the latest label was submitted by QueueInsertDebugUtilsLabelEXT, we
* should remove it first.
*/
if (!queue->region_begin)
(void)util_dynarray_pop(&queue->labels, VkDebugUtilsLabelEXT);
util_dynarray_append(&queue->labels, VkDebugUtilsLabelEXT, *pLabelInfo);
queue->region_begin = false;
}