1 /*
2  * Copyright © 2021 Intel Corporation
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining a
5  * copy of this software and associated documentation files (the "Software"),
6  * to deal in the Software without restriction, including without limitation
7  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8  * and/or sell copies of the Software, and to permit persons to whom the
9  * Software is furnished to do so, subject to the following conditions:
10  *
11  * The above copyright notice and this permission notice (including the next
12  * paragraph) shall be included in all copies or substantial portions of the
13  * Software.
14  *
15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21  * IN THE SOFTWARE.
22  */
23 
24 #include "vk_debug_utils.h"
25 
26 #include "vk_common_entrypoints.h"
27 #include "vk_command_buffer.h"
28 #include "vk_device.h"
29 #include "vk_queue.h"
30 #include "vk_object.h"
31 #include "vk_alloc.h"
32 #include "vk_util.h"
33 #include "stdarg.h"
34 #include "u_dynarray.h"
35 
36 void
vk_debug_message(struct vk_instance * instance,VkDebugUtilsMessageSeverityFlagBitsEXT severity,VkDebugUtilsMessageTypeFlagsEXT types,const VkDebugUtilsMessengerCallbackDataEXT * pCallbackData)37 vk_debug_message(struct vk_instance *instance,
38                  VkDebugUtilsMessageSeverityFlagBitsEXT severity,
39                  VkDebugUtilsMessageTypeFlagsEXT types,
40                  const VkDebugUtilsMessengerCallbackDataEXT *pCallbackData)
41 {
42    mtx_lock(&instance->debug_utils.callbacks_mutex);
43 
44    list_for_each_entry(struct vk_debug_utils_messenger, messenger,
45                        &instance->debug_utils.callbacks, link) {
46       if ((messenger->severity & severity) &&
47           (messenger->type & types))
48          messenger->callback(severity, types, pCallbackData, messenger->data);
49    }
50 
51    mtx_unlock(&instance->debug_utils.callbacks_mutex);
52 }
53 
54 /* This function intended to be used by the drivers to report a
55  * message to the special messenger, provided in the pNext chain while
56  * creating an instance. It's only meant to be used during
57  * vkCreateInstance or vkDestroyInstance calls.
58  */
59 void
vk_debug_message_instance(struct vk_instance * instance,VkDebugUtilsMessageSeverityFlagBitsEXT severity,VkDebugUtilsMessageTypeFlagsEXT types,const char * pMessageIdName,int32_t messageIdNumber,const char * pMessage)60 vk_debug_message_instance(struct vk_instance *instance,
61                           VkDebugUtilsMessageSeverityFlagBitsEXT severity,
62                           VkDebugUtilsMessageTypeFlagsEXT types,
63                           const char *pMessageIdName,
64                           int32_t messageIdNumber,
65                           const char *pMessage)
66 {
67    if (list_is_empty(&instance->debug_utils.instance_callbacks))
68       return;
69 
70    const VkDebugUtilsMessengerCallbackDataEXT cbData = {
71       .sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_MESSENGER_CALLBACK_DATA_EXT,
72       .pMessageIdName = pMessageIdName,
73       .messageIdNumber = messageIdNumber,
74       .pMessage = pMessage,
75    };
76 
77    list_for_each_entry(struct vk_debug_utils_messenger, messenger,
78                        &instance->debug_utils.instance_callbacks, link) {
79       if ((messenger->severity & severity) &&
80           (messenger->type & types))
81          messenger->callback(severity, types, &cbData, messenger->data);
82    }
83 }
84 
85 VKAPI_ATTR VkResult VKAPI_CALL
vk_common_CreateDebugUtilsMessengerEXT(VkInstance _instance,const VkDebugUtilsMessengerCreateInfoEXT * pCreateInfo,const VkAllocationCallbacks * pAllocator,VkDebugUtilsMessengerEXT * pMessenger)86 vk_common_CreateDebugUtilsMessengerEXT(
87    VkInstance _instance,
88    const VkDebugUtilsMessengerCreateInfoEXT *pCreateInfo,
89    const VkAllocationCallbacks *pAllocator,
90    VkDebugUtilsMessengerEXT *pMessenger)
91 {
92    VK_FROM_HANDLE(vk_instance, instance, _instance);
93 
94    struct vk_debug_utils_messenger *messenger =
95       vk_alloc2(&instance->alloc, pAllocator,
96                 sizeof(struct vk_debug_utils_messenger), 8,
97                 VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
98 
99    if (!messenger)
100       return VK_ERROR_OUT_OF_HOST_MEMORY;
101 
102    if (pAllocator)
103       messenger->alloc = *pAllocator;
104    else
105       messenger->alloc = instance->alloc;
106 
107    vk_object_base_init(NULL, &messenger->base,
108                        VK_OBJECT_TYPE_DEBUG_UTILS_MESSENGER_EXT);
109 
110    messenger->severity = pCreateInfo->messageSeverity;
111    messenger->type = pCreateInfo->messageType;
112    messenger->callback = pCreateInfo->pfnUserCallback;
113    messenger->data = pCreateInfo->pUserData;
114 
115    mtx_lock(&instance->debug_utils.callbacks_mutex);
116    list_addtail(&messenger->link, &instance->debug_utils.callbacks);
117    mtx_unlock(&instance->debug_utils.callbacks_mutex);
118 
119    *pMessenger = vk_debug_utils_messenger_to_handle(messenger);
120 
121    return VK_SUCCESS;
122 }
123 
124 VKAPI_ATTR void VKAPI_CALL
vk_common_SubmitDebugUtilsMessageEXT(VkInstance _instance,VkDebugUtilsMessageSeverityFlagBitsEXT messageSeverity,VkDebugUtilsMessageTypeFlagsEXT messageTypes,const VkDebugUtilsMessengerCallbackDataEXT * pCallbackData)125 vk_common_SubmitDebugUtilsMessageEXT(
126    VkInstance _instance,
127    VkDebugUtilsMessageSeverityFlagBitsEXT messageSeverity,
128    VkDebugUtilsMessageTypeFlagsEXT messageTypes,
129    const VkDebugUtilsMessengerCallbackDataEXT *pCallbackData)
130 {
131    VK_FROM_HANDLE(vk_instance, instance, _instance);
132 
133    vk_debug_message(instance, messageSeverity, messageTypes, pCallbackData);
134 }
135 
136 VKAPI_ATTR void VKAPI_CALL
vk_common_DestroyDebugUtilsMessengerEXT(VkInstance _instance,VkDebugUtilsMessengerEXT _messenger,const VkAllocationCallbacks * pAllocator)137 vk_common_DestroyDebugUtilsMessengerEXT(
138    VkInstance _instance,
139    VkDebugUtilsMessengerEXT _messenger,
140    const VkAllocationCallbacks *pAllocator)
141 {
142    VK_FROM_HANDLE(vk_instance, instance, _instance);
143    VK_FROM_HANDLE(vk_debug_utils_messenger, messenger, _messenger);
144 
145    if (messenger == NULL)
146       return;
147 
148    mtx_lock(&instance->debug_utils.callbacks_mutex);
149    list_del(&messenger->link);
150    mtx_unlock(&instance->debug_utils.callbacks_mutex);
151 
152    vk_object_base_finish(&messenger->base);
153    vk_free2(&instance->alloc, pAllocator, messenger);
154 }
155 
156 VKAPI_ATTR VkResult VKAPI_CALL
vk_common_SetDebugUtilsObjectNameEXT(VkDevice _device,const VkDebugUtilsObjectNameInfoEXT * pNameInfo)157 vk_common_SetDebugUtilsObjectNameEXT(
158    VkDevice _device,
159    const VkDebugUtilsObjectNameInfoEXT *pNameInfo)
160 {
161    VK_FROM_HANDLE(vk_device, device, _device);
162    struct vk_object_base *object =
163       vk_object_base_from_u64_handle(pNameInfo->objectHandle,
164                                      pNameInfo->objectType);
165 
166    if (object->object_name) {
167       vk_free(&device->alloc, object->object_name);
168       object->object_name = NULL;
169    }
170    object->object_name = vk_strdup(&device->alloc, pNameInfo->pObjectName,
171                                    VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
172    if (!object->object_name)
173       return VK_ERROR_OUT_OF_HOST_MEMORY;
174 
175    return VK_SUCCESS;
176 }
177 
178 VKAPI_ATTR VkResult VKAPI_CALL
vk_common_SetDebugUtilsObjectTagEXT(VkDevice _device,const VkDebugUtilsObjectTagInfoEXT * pTagInfo)179 vk_common_SetDebugUtilsObjectTagEXT(
180    VkDevice _device,
181    const VkDebugUtilsObjectTagInfoEXT *pTagInfo)
182 {
183    /* no-op */
184    return VK_SUCCESS;
185 }
186 
187 VKAPI_ATTR void VKAPI_CALL
vk_common_CmdBeginDebugUtilsLabelEXT(VkCommandBuffer _commandBuffer,const VkDebugUtilsLabelEXT * pLabelInfo)188 vk_common_CmdBeginDebugUtilsLabelEXT(
189    VkCommandBuffer _commandBuffer,
190    const VkDebugUtilsLabelEXT *pLabelInfo)
191 {
192    VK_FROM_HANDLE(vk_command_buffer, command_buffer, _commandBuffer);
193 
194    /* If the latest label was submitted by CmdInsertDebugUtilsLabelEXT, we
195     * should remove it first.
196     */
197    if (!command_buffer->region_begin)
198       (void)util_dynarray_pop(&command_buffer->labels, VkDebugUtilsLabelEXT);
199 
200    util_dynarray_append(&command_buffer->labels, VkDebugUtilsLabelEXT,
201                         *pLabelInfo);
202    command_buffer->region_begin = true;
203 }
204 
205 VKAPI_ATTR void VKAPI_CALL
vk_common_CmdEndDebugUtilsLabelEXT(VkCommandBuffer _commandBuffer)206 vk_common_CmdEndDebugUtilsLabelEXT(VkCommandBuffer _commandBuffer)
207 {
208    VK_FROM_HANDLE(vk_command_buffer, command_buffer, _commandBuffer);
209 
210    /* If the latest label was submitted by CmdInsertDebugUtilsLabelEXT, we
211     * should remove it first.
212     */
213    if (!command_buffer->region_begin)
214       (void)util_dynarray_pop(&command_buffer->labels, VkDebugUtilsLabelEXT);
215 
216    (void)util_dynarray_pop(&command_buffer->labels, VkDebugUtilsLabelEXT);
217    command_buffer->region_begin = true;
218 }
219 
220 VKAPI_ATTR void VKAPI_CALL
vk_common_CmdInsertDebugUtilsLabelEXT(VkCommandBuffer _commandBuffer,const VkDebugUtilsLabelEXT * pLabelInfo)221 vk_common_CmdInsertDebugUtilsLabelEXT(
222    VkCommandBuffer _commandBuffer,
223    const VkDebugUtilsLabelEXT *pLabelInfo)
224 {
225    VK_FROM_HANDLE(vk_command_buffer, command_buffer, _commandBuffer);
226 
227    /* If the latest label was submitted by CmdInsertDebugUtilsLabelEXT, we
228     * should remove it first.
229     */
230    if (!command_buffer->region_begin)
231       (void)util_dynarray_pop(&command_buffer->labels, VkDebugUtilsLabelEXT);
232 
233    util_dynarray_append(&command_buffer->labels, VkDebugUtilsLabelEXT,
234                         *pLabelInfo);
235    command_buffer->region_begin = false;
236 }
237 
238 VKAPI_ATTR void VKAPI_CALL
vk_common_QueueBeginDebugUtilsLabelEXT(VkQueue _queue,const VkDebugUtilsLabelEXT * pLabelInfo)239 vk_common_QueueBeginDebugUtilsLabelEXT(
240    VkQueue _queue,
241    const VkDebugUtilsLabelEXT *pLabelInfo)
242 {
243    VK_FROM_HANDLE(vk_queue, queue, _queue);
244 
245    /* If the latest label was submitted by QueueInsertDebugUtilsLabelEXT, we
246     * should remove it first.
247     */
248    if (!queue->region_begin)
249       (void)util_dynarray_pop(&queue->labels, VkDebugUtilsLabelEXT);
250 
251    util_dynarray_append(&queue->labels, VkDebugUtilsLabelEXT, *pLabelInfo);
252    queue->region_begin = true;
253 }
254 
255 VKAPI_ATTR void VKAPI_CALL
vk_common_QueueEndDebugUtilsLabelEXT(VkQueue _queue)256 vk_common_QueueEndDebugUtilsLabelEXT(VkQueue _queue)
257 {
258    VK_FROM_HANDLE(vk_queue, queue, _queue);
259 
260    /* If the latest label was submitted by QueueInsertDebugUtilsLabelEXT, we
261     * should remove it first.
262     */
263    if (!queue->region_begin)
264       (void)util_dynarray_pop(&queue->labels, VkDebugUtilsLabelEXT);
265 
266    (void)util_dynarray_pop(&queue->labels, VkDebugUtilsLabelEXT);
267    queue->region_begin = true;
268 }
269 
270 VKAPI_ATTR void VKAPI_CALL
vk_common_QueueInsertDebugUtilsLabelEXT(VkQueue _queue,const VkDebugUtilsLabelEXT * pLabelInfo)271 vk_common_QueueInsertDebugUtilsLabelEXT(
272    VkQueue _queue,
273    const VkDebugUtilsLabelEXT *pLabelInfo)
274 {
275    VK_FROM_HANDLE(vk_queue, queue, _queue);
276 
277    /* If the latest label was submitted by QueueInsertDebugUtilsLabelEXT, we
278     * should remove it first.
279     */
280    if (!queue->region_begin)
281       (void)util_dynarray_pop(&queue->labels, VkDebugUtilsLabelEXT);
282 
283    util_dynarray_append(&queue->labels, VkDebugUtilsLabelEXT, *pLabelInfo);
284    queue->region_begin = false;
285 }
286