mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2025-12-25 08:40:11 +01:00
vulkan: Implement VK_EXT_debug_utils
This implements all the necessary features of VK_EXT_debug_utils in common code. Signed-off-by: Yevhenii Kolesnikov <yevhenii.kolesnikov@globallogic.com> Reviewed-by: Jason Ekstrand <jason@jlekstrand.net> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/10318>
This commit is contained in:
parent
879defa3be
commit
3b361b234a
11 changed files with 519 additions and 0 deletions
|
|
@ -56,6 +56,8 @@ files_vulkan_util = files(
|
|||
'vk_command_buffer.h',
|
||||
'vk_debug_report.c',
|
||||
'vk_debug_report.h',
|
||||
'vk_debug_utils.c',
|
||||
'vk_debug_utils.h',
|
||||
'vk_deferred_operation.c',
|
||||
'vk_deferred_operation.h',
|
||||
'vk_descriptors.c',
|
||||
|
|
|
|||
|
|
@ -31,16 +31,22 @@ vk_command_buffer_init(struct vk_command_buffer *command_buffer,
|
|||
vk_object_base_init(device, &command_buffer->base,
|
||||
VK_OBJECT_TYPE_COMMAND_BUFFER);
|
||||
|
||||
util_dynarray_init(&command_buffer->labels, NULL);
|
||||
command_buffer->region_begin = true;
|
||||
|
||||
return VK_SUCCESS;
|
||||
}
|
||||
|
||||
void
|
||||
vk_command_buffer_reset(struct vk_command_buffer *command_buffer)
|
||||
{
|
||||
util_dynarray_clear(&command_buffer->labels);
|
||||
command_buffer->region_begin = true;
|
||||
}
|
||||
|
||||
void
|
||||
vk_command_buffer_finish(struct vk_command_buffer *command_buffer)
|
||||
{
|
||||
util_dynarray_fini(&command_buffer->labels);
|
||||
vk_object_base_finish(&command_buffer->base);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -33,6 +33,46 @@ extern "C" {
|
|||
|
||||
struct vk_command_buffer {
|
||||
struct vk_object_base base;
|
||||
|
||||
/**
|
||||
* VK_EXT_debug_utils
|
||||
*
|
||||
* The next two fields represent debug labels storage.
|
||||
*
|
||||
* VK_EXT_debug_utils spec requires that upon triggering a debug message
|
||||
* with a command buffer attached to it, all "active" labels will also be
|
||||
* provided to the callback. The spec describes two distinct ways of
|
||||
* attaching a debug label to the command buffer: opening a label region
|
||||
* and inserting a single label.
|
||||
*
|
||||
* Label region is active between the corresponding `*BeginDebugUtilsLabel`
|
||||
* and `*EndDebugUtilsLabel` calls. The spec doesn't mention any limits on
|
||||
* nestedness of label regions. This implementation assumes that there
|
||||
* aren't any.
|
||||
*
|
||||
* The spec, however, doesn't explain the lifetime of a label submitted by
|
||||
* an `*InsertDebugUtilsLabel` call. The LunarG whitepaper [1] (pp 12-15)
|
||||
* provides a more detailed explanation along with some examples. According
|
||||
* to those, such label remains active until the next `*DebugUtilsLabel`
|
||||
* call. This means that there can be no more than one such label at a
|
||||
* time.
|
||||
*
|
||||
* \c labels contains all active labels at this point in order of submission
|
||||
* \c region_begin denotes whether the most recent label opens a new region
|
||||
* If \t labels is empty \t region_begin must be true.
|
||||
*
|
||||
* Anytime we modify labels, we first check for \c region_begin. If it's
|
||||
* false, it means that the most recent label was submitted by
|
||||
* `*InsertDebugUtilsLabel` and we need to remove it before doing anything
|
||||
* else.
|
||||
*
|
||||
* See the discussion here:
|
||||
* https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/10318#note_1061317
|
||||
*
|
||||
* [1] https://www.lunarg.com/wp-content/uploads/2018/05/Vulkan-Debug-Utils_05_18_v1.pdf
|
||||
*/
|
||||
struct util_dynarray labels;
|
||||
bool region_begin;
|
||||
};
|
||||
|
||||
VK_DEFINE_HANDLE_CASTS(vk_command_buffer, base, VkCommandBuffer,
|
||||
|
|
|
|||
285
src/vulkan/util/vk_debug_utils.c
Normal file
285
src/vulkan/util/vk_debug_utils.c
Normal file
|
|
@ -0,0 +1,285 @@
|
|||
/*
|
||||
* 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;
|
||||
}
|
||||
67
src/vulkan/util/vk_debug_utils.h
Normal file
67
src/vulkan/util/vk_debug_utils.h
Normal file
|
|
@ -0,0 +1,67 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef VK_DEBUG_UTILS_H
|
||||
#define VK_DEBUG_UTILS_H
|
||||
|
||||
#include "vk_instance.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
struct vk_debug_utils_messenger {
|
||||
struct vk_object_base base;
|
||||
VkAllocationCallbacks alloc;
|
||||
|
||||
struct list_head link;
|
||||
|
||||
VkDebugUtilsMessageSeverityFlagsEXT severity;
|
||||
VkDebugUtilsMessageTypeFlagsEXT type;
|
||||
PFN_vkDebugUtilsMessengerCallbackEXT callback;
|
||||
void *data;
|
||||
};
|
||||
|
||||
VK_DEFINE_NONDISP_HANDLE_CASTS(vk_debug_utils_messenger, base,
|
||||
VkDebugUtilsMessengerEXT,
|
||||
VK_OBJECT_TYPE_DEBUG_UTILS_MESSENGER_EXT)
|
||||
|
||||
void
|
||||
vk_debug_message(struct vk_instance *instance,
|
||||
VkDebugUtilsMessageSeverityFlagBitsEXT severity,
|
||||
VkDebugUtilsMessageTypeFlagsEXT types,
|
||||
const VkDebugUtilsMessengerCallbackDataEXT *pCallbackData);
|
||||
|
||||
void
|
||||
vk_debug_message_instance(struct vk_instance *instance,
|
||||
VkDebugUtilsMessageSeverityFlagBitsEXT severity,
|
||||
VkDebugUtilsMessageTypeFlagsEXT types,
|
||||
const char *pMessageIdName,
|
||||
int32_t messageIdNumber,
|
||||
const char *pMessage);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* VK_DEBUG_UTILS_H */
|
||||
|
|
@ -26,6 +26,7 @@
|
|||
#include "vk_alloc.h"
|
||||
#include "vk_common_entrypoints.h"
|
||||
#include "vk_util.h"
|
||||
#include "vk_debug_utils.h"
|
||||
|
||||
#include "compiler/glsl_types.h"
|
||||
|
||||
|
|
@ -40,6 +41,37 @@ vk_instance_init(struct vk_instance *instance,
|
|||
vk_object_base_init(NULL, &instance->base, VK_OBJECT_TYPE_INSTANCE);
|
||||
instance->alloc = *alloc;
|
||||
|
||||
/* VK_EXT_debug_utils */
|
||||
/* These messengers will only be used during vkCreateInstance or
|
||||
* vkDestroyInstance calls.
|
||||
*/
|
||||
list_inithead(&instance->debug_utils.instance_callbacks);
|
||||
vk_foreach_struct_const(ext, pCreateInfo->pNext) {
|
||||
if (ext->sType ==
|
||||
VK_STRUCTURE_TYPE_DEBUG_UTILS_MESSENGER_CREATE_INFO_EXT) {
|
||||
const VkDebugUtilsMessengerCreateInfoEXT *debugMessengerCreateInfo =
|
||||
(const VkDebugUtilsMessengerCreateInfoEXT *)ext;
|
||||
struct vk_debug_utils_messenger *messenger =
|
||||
vk_alloc2(alloc, alloc, sizeof(struct vk_debug_utils_messenger), 8,
|
||||
VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
|
||||
|
||||
if (!messenger)
|
||||
return VK_ERROR_OUT_OF_HOST_MEMORY;
|
||||
|
||||
vk_object_base_init(NULL, &messenger->base,
|
||||
VK_OBJECT_TYPE_DEBUG_UTILS_MESSENGER_EXT);
|
||||
|
||||
messenger->alloc = *alloc;
|
||||
messenger->severity = debugMessengerCreateInfo->messageSeverity;
|
||||
messenger->type = debugMessengerCreateInfo->messageType;
|
||||
messenger->callback = debugMessengerCreateInfo->pfnUserCallback;
|
||||
messenger->data = debugMessengerCreateInfo->pUserData;
|
||||
|
||||
list_addtail(&messenger->link,
|
||||
&instance->debug_utils.instance_callbacks);
|
||||
}
|
||||
}
|
||||
|
||||
instance->app_info = (struct vk_app_info) { .api_version = 0 };
|
||||
if (pCreateInfo->pApplicationInfo) {
|
||||
const VkApplicationInfo *app = pCreateInfo->pApplicationInfo;
|
||||
|
|
@ -93,6 +125,13 @@ vk_instance_init(struct vk_instance *instance,
|
|||
|
||||
list_inithead(&instance->debug_report.callbacks);
|
||||
|
||||
if (mtx_init(&instance->debug_utils.callbacks_mutex, mtx_plain) != 0) {
|
||||
mtx_destroy(&instance->debug_report.callbacks_mutex);
|
||||
return VK_ERROR_INITIALIZATION_FAILED;
|
||||
}
|
||||
|
||||
list_inithead(&instance->debug_utils.callbacks);
|
||||
|
||||
glsl_type_singleton_init_or_ref();
|
||||
|
||||
return VK_SUCCESS;
|
||||
|
|
@ -102,7 +141,25 @@ void
|
|||
vk_instance_finish(struct vk_instance *instance)
|
||||
{
|
||||
glsl_type_singleton_decref();
|
||||
if (unlikely(!list_is_empty(&instance->debug_utils.callbacks))) {
|
||||
list_for_each_entry_safe(struct vk_debug_utils_messenger, messenger,
|
||||
&instance->debug_utils.callbacks, link) {
|
||||
list_del(&messenger->link);
|
||||
vk_object_base_finish(&messenger->base);
|
||||
vk_free2(&instance->alloc, &messenger->alloc, messenger);
|
||||
}
|
||||
}
|
||||
if (unlikely(!list_is_empty(&instance->debug_utils.instance_callbacks))) {
|
||||
list_for_each_entry_safe(struct vk_debug_utils_messenger, messenger,
|
||||
&instance->debug_utils.instance_callbacks,
|
||||
link) {
|
||||
list_del(&messenger->link);
|
||||
vk_object_base_finish(&messenger->base);
|
||||
vk_free2(&instance->alloc, &messenger->alloc, messenger);
|
||||
}
|
||||
}
|
||||
mtx_destroy(&instance->debug_report.callbacks_mutex);
|
||||
mtx_destroy(&instance->debug_utils.callbacks_mutex);
|
||||
vk_free(&instance->alloc, (char *)instance->app_info.app_name);
|
||||
vk_free(&instance->alloc, (char *)instance->app_info.engine_name);
|
||||
vk_object_base_finish(&instance->base);
|
||||
|
|
|
|||
|
|
@ -56,6 +56,17 @@ struct vk_instance {
|
|||
mtx_t callbacks_mutex;
|
||||
struct list_head callbacks;
|
||||
} debug_report;
|
||||
|
||||
/* VK_EXT_debug_utils */
|
||||
struct {
|
||||
/* These callbacks are only used while creating or destroying an
|
||||
* instance
|
||||
*/
|
||||
struct list_head instance_callbacks;
|
||||
mtx_t callbacks_mutex;
|
||||
/* Persistent callbacks */
|
||||
struct list_head callbacks;
|
||||
} debug_utils;
|
||||
};
|
||||
|
||||
VK_DEFINE_HANDLE_CASTS(vk_instance, base, VkInstance,
|
||||
|
|
|
|||
|
|
@ -44,12 +44,16 @@ vk_object_base_init(struct vk_device *device,
|
|||
vk_object_base_reinit(base);
|
||||
base->type = obj_type;
|
||||
base->device = device;
|
||||
base->object_name = NULL;
|
||||
}
|
||||
|
||||
void
|
||||
vk_object_base_finish(struct vk_object_base *base)
|
||||
{
|
||||
util_sparse_array_finish(&base->private_data);
|
||||
|
||||
if (base->object_name != NULL)
|
||||
vk_free(&base->device->alloc, base->object_name);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
|||
|
|
@ -46,6 +46,9 @@ struct vk_object_base {
|
|||
|
||||
/* For VK_EXT_private_data */
|
||||
struct util_sparse_array private_data;
|
||||
|
||||
/* VK_EXT_debug_utils */
|
||||
char *object_name;
|
||||
};
|
||||
|
||||
void vk_object_base_init(UNUSED struct vk_device *device,
|
||||
|
|
|
|||
|
|
@ -29,11 +29,15 @@ vk_queue_init(struct vk_queue *queue, struct vk_device *device)
|
|||
memset(queue, 0, sizeof(*queue));
|
||||
vk_object_base_init(device, &queue->base, VK_OBJECT_TYPE_QUEUE);
|
||||
|
||||
util_dynarray_init(&queue->labels, NULL);
|
||||
queue->region_begin = true;
|
||||
|
||||
return VK_SUCCESS;
|
||||
}
|
||||
|
||||
void
|
||||
vk_queue_finish(struct vk_queue *queue)
|
||||
{
|
||||
util_dynarray_fini(&queue->labels);
|
||||
vk_object_base_finish(&queue->base);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -33,6 +33,46 @@ extern "C" {
|
|||
|
||||
struct vk_queue {
|
||||
struct vk_object_base base;
|
||||
|
||||
/**
|
||||
* VK_EXT_debug_utils
|
||||
*
|
||||
* The next two fields represent debug labels storage.
|
||||
*
|
||||
* VK_EXT_debug_utils spec requires that upon triggering a debug message
|
||||
* with a queue attached to it, all "active" labels will also be provided
|
||||
* to the callback. The spec describes two distinct ways of attaching a
|
||||
* debug label to the queue: opening a label region and inserting a single
|
||||
* label.
|
||||
*
|
||||
* Label region is active between the corresponding `*BeginDebugUtilsLabel`
|
||||
* and `*EndDebugUtilsLabel` calls. The spec doesn't mention any limits on
|
||||
* nestedness of label regions. This implementation assumes that there
|
||||
* aren't any.
|
||||
*
|
||||
* The spec, however, doesn't explain the lifetime of a label submitted by
|
||||
* an `*InsertDebugUtilsLabel` call. The LunarG whitepaper [1] (pp 12-15)
|
||||
* provides a more detailed explanation along with some examples. According
|
||||
* to those, such label remains active until the next `*DebugUtilsLabel`
|
||||
* call. This means that there can be no more than one such label at a
|
||||
* time.
|
||||
*
|
||||
* \c labels contains all active labels at this point in order of submission
|
||||
* \c region_begin denotes whether the most recent label opens a new region
|
||||
* If \t labels is empty \t region_begin must be true.
|
||||
*
|
||||
* Anytime we modify labels, we first check for \c region_begin. If it's
|
||||
* false, it means that the most recent label was submitted by
|
||||
* `*InsertDebugUtilsLabel` and we need to remove it before doing anything
|
||||
* else.
|
||||
*
|
||||
* See the discussion here:
|
||||
* https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/10318#note_1061317
|
||||
*
|
||||
* [1] https://www.lunarg.com/wp-content/uploads/2018/05/Vulkan-Debug-Utils_05_18_v1.pdf
|
||||
*/
|
||||
struct util_dynarray labels;
|
||||
bool region_begin;
|
||||
};
|
||||
|
||||
VK_DEFINE_HANDLE_CASTS(vk_queue, base, VkQueue, VK_OBJECT_TYPE_QUEUE)
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue