• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright © 2017 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_report.h"
25 
26 #include "vk_alloc.h"
27 #include "vk_util.h"
28 
vk_debug_report_instance_init(struct vk_debug_report_instance * instance)29 VkResult vk_debug_report_instance_init(struct vk_debug_report_instance *instance)
30 {
31    if (pthread_mutex_init(&instance->callbacks_mutex, NULL) != 0) {
32       return VK_ERROR_INITIALIZATION_FAILED;
33    }
34 
35    list_inithead(&instance->callbacks);
36 
37    return VK_SUCCESS;
38 }
39 
vk_debug_report_instance_destroy(struct vk_debug_report_instance * instance)40 void vk_debug_report_instance_destroy(struct vk_debug_report_instance *instance)
41 {
42    pthread_mutex_destroy(&instance->callbacks_mutex);
43 }
44 
45 VkResult
vk_create_debug_report_callback(struct vk_debug_report_instance * instance,const VkDebugReportCallbackCreateInfoEXT * pCreateInfo,const VkAllocationCallbacks * pAllocator,const VkAllocationCallbacks * instance_allocator,VkDebugReportCallbackEXT * pCallback)46 vk_create_debug_report_callback(struct vk_debug_report_instance *instance,
47                                 const VkDebugReportCallbackCreateInfoEXT* pCreateInfo,
48                                 const VkAllocationCallbacks* pAllocator,
49                                 const VkAllocationCallbacks* instance_allocator,
50                                 VkDebugReportCallbackEXT* pCallback)
51 {
52 
53    struct vk_debug_report_callback *cb =
54       vk_alloc2(instance_allocator, pAllocator,
55                 sizeof(struct vk_debug_report_callback), 8,
56                 VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
57 
58    if (!cb)
59       return VK_ERROR_OUT_OF_HOST_MEMORY;
60 
61    cb->flags = pCreateInfo->flags;
62    cb->callback = pCreateInfo->pfnCallback;
63    cb->data = pCreateInfo->pUserData;
64 
65    pthread_mutex_lock(&instance->callbacks_mutex);
66    list_addtail(&cb->link, &instance->callbacks);
67    pthread_mutex_unlock(&instance->callbacks_mutex);
68 
69    *pCallback = (VkDebugReportCallbackEXT)(uintptr_t)cb;
70 
71    return VK_SUCCESS;
72 }
73 
74 void
vk_destroy_debug_report_callback(struct vk_debug_report_instance * instance,VkDebugReportCallbackEXT _callback,const VkAllocationCallbacks * pAllocator,const VkAllocationCallbacks * instance_allocator)75 vk_destroy_debug_report_callback(struct vk_debug_report_instance *instance,
76                                  VkDebugReportCallbackEXT _callback,
77                                  const VkAllocationCallbacks* pAllocator,
78                                  const VkAllocationCallbacks* instance_allocator)
79 {
80    if (_callback == VK_NULL_HANDLE)
81       return;
82 
83    struct vk_debug_report_callback *callback =
84             (struct vk_debug_report_callback *)(uintptr_t)_callback;
85 
86    /* Remove from list and destroy given callback. */
87    pthread_mutex_lock(&instance->callbacks_mutex);
88    list_del(&callback->link);
89    vk_free2(instance_allocator, pAllocator, callback);
90    pthread_mutex_unlock(&instance->callbacks_mutex);
91 }
92 
93 
94 void
vk_debug_report(struct vk_debug_report_instance * instance,VkDebugReportFlagsEXT flags,VkDebugReportObjectTypeEXT object_type,uint64_t handle,size_t location,int32_t messageCode,const char * pLayerPrefix,const char * pMessage)95 vk_debug_report(struct vk_debug_report_instance *instance,
96                 VkDebugReportFlagsEXT flags,
97                 VkDebugReportObjectTypeEXT object_type,
98                 uint64_t handle,
99                 size_t location,
100                 int32_t messageCode,
101                 const char* pLayerPrefix,
102                 const char *pMessage)
103 {
104    /* Allow NULL for convinience, return if no callbacks registered. */
105    if (!instance || list_is_empty(&instance->callbacks))
106       return;
107 
108    pthread_mutex_lock(&instance->callbacks_mutex);
109 
110    /* Section 33.2 of the Vulkan 1.0.59 spec says:
111     *
112     *    "callback is an externally synchronized object and must not be
113     *    used on more than one thread at a time. This means that
114     *    vkDestroyDebugReportCallbackEXT must not be called when a callback
115     *    is active."
116     */
117    list_for_each_entry(struct vk_debug_report_callback, cb,
118                        &instance->callbacks, link) {
119       if (cb->flags & flags)
120          cb->callback(flags, object_type, handle, location, messageCode,
121                       pLayerPrefix, pMessage, cb->data);
122    }
123 
124    pthread_mutex_unlock(&instance->callbacks_mutex);
125 }
126