blob: 109592aea58bacf8485a169d6d4b3c77a09257e4 [file] [log] [blame]
Courtney Goeltzenleuchter41fa5b02015-06-11 15:58:51 -06001/*
2 * Vulkan
3 *
4 * Copyright (C) 2014 LunarG, Inc.
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the "Software"),
8 * to deal in the Software without restriction, including without limitation
9 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10 * and/or sell copies of the Software, and to permit persons to whom the
11 * Software is furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included
14 * in all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22 * DEALINGS IN THE SOFTWARE.
23 *
24 * Authors:
25 * Courtney Goeltzenleuchter <courtney@lunarg.com>
26 */
27
28#ifndef LAYER_LOGGING_H
29#define LAYER_LOGGING_H
30
31#include <stdio.h>
32#include <stdbool.h>
33#include <unordered_map>
34#include "vkLayer.h"
Courtney Goeltzenleuchterf1eb2492015-06-11 16:01:11 -060035#include "layer_data.h"
Courtney Goeltzenleuchter41fa5b02015-06-11 15:58:51 -060036#include "layers_table.h"
37
Courtney Goeltzenleuchter1f1fbbd2015-06-14 12:03:26 -060038typedef struct _debug_report_data {
Courtney Goeltzenleuchter41fa5b02015-06-11 15:58:51 -060039 VkLayerDbgFunctionNode *g_pDbgFunctionHead;
40 bool g_DEBUG_REPORT;
Courtney Goeltzenleuchter1f1fbbd2015-06-14 12:03:26 -060041} debug_report_data;
Courtney Goeltzenleuchter41fa5b02015-06-11 15:58:51 -060042
Courtney Goeltzenleuchter1f1fbbd2015-06-14 12:03:26 -060043template debug_report_data *get_my_data_ptr<debug_report_data>(
Courtney Goeltzenleuchterf1eb2492015-06-11 16:01:11 -060044 void *data_key,
Courtney Goeltzenleuchter1f1fbbd2015-06-14 12:03:26 -060045 std::unordered_map<void *, debug_report_data *> &data_map);
Courtney Goeltzenleuchter41fa5b02015-06-11 15:58:51 -060046
47// Utility function to handle reporting
48static void debug_report_log_msg(
Courtney Goeltzenleuchter1f1fbbd2015-06-14 12:03:26 -060049 debug_report_data *debug_data,
Courtney Goeltzenleuchter41fa5b02015-06-11 15:58:51 -060050 VkFlags msgFlags,
51 VkObjectType objectType,
52 VkObject srcObject,
53 size_t location,
54 int32_t msgCode,
55 const char* pLayerPrefix,
56 const char* pMsg)
57{
58 VkLayerDbgFunctionNode *pTrav = debug_data->g_pDbgFunctionHead;
59 while (pTrav) {
60 if (pTrav->msgFlags & msgFlags) {
61 pTrav->pfnMsgCallback(msgFlags,
62 objectType, srcObject,
63 location,
64 msgCode,
65 pLayerPrefix,
66 pMsg,
67 (void *) pTrav->pUserData);
68 }
69 pTrav = pTrav->pNext;
70 }
71}
72
Courtney Goeltzenleuchter1f1fbbd2015-06-14 12:03:26 -060073static inline debug_report_data *debug_report_create_instance(
74 VkLayerInstanceDispatchTable *table,
75 VkInstance inst,
Courtney Goeltzenleuchter41fa5b02015-06-11 15:58:51 -060076 uint32_t extension_count,
77 const VkExtensionProperties* pEnabledExtensions) // layer or extension name to be enabled
78{
Courtney Goeltzenleuchter1f1fbbd2015-06-14 12:03:26 -060079 debug_report_data *debug_data;
80 PFN_vkGetInstanceProcAddr gpa = table->GetInstanceProcAddr;
Courtney Goeltzenleuchter41fa5b02015-06-11 15:58:51 -060081
Courtney Goeltzenleuchter1f1fbbd2015-06-14 12:03:26 -060082 table->DbgCreateMsgCallback = (PFN_vkDbgCreateMsgCallback) gpa(inst, "vkDbgCreateMsgCallback");
83 table->DbgDestroyMsgCallback = (PFN_vkDbgDestroyMsgCallback) gpa(inst, "vkDbgDestroyMsgCallback");
84
85 debug_data = (debug_report_data *) malloc(sizeof(debug_report_data));
86 if (!debug_data) return NULL;
87
88 memset(debug_data, 0, sizeof(debug_report_data));
Courtney Goeltzenleuchter41fa5b02015-06-11 15:58:51 -060089 for (uint32_t i = 0; i < extension_count; i++) {
90 /* TODO: Check other property fields */
91 if (strcmp(pEnabledExtensions[i].name, DEBUG_REPORT_EXTENSION_NAME) == 0) {
92 debug_data->g_DEBUG_REPORT = true;
93 }
94 }
Courtney Goeltzenleuchter1f1fbbd2015-06-14 12:03:26 -060095 return debug_data;
Courtney Goeltzenleuchter41fa5b02015-06-11 15:58:51 -060096}
97
Courtney Goeltzenleuchter1f1fbbd2015-06-14 12:03:26 -060098static inline void layer_debug_report_destroy_instance(debug_report_data *debug_data)
Courtney Goeltzenleuchter41fa5b02015-06-11 15:58:51 -060099{
Courtney Goeltzenleuchter41fa5b02015-06-11 15:58:51 -0600100 VkLayerDbgFunctionNode *pTrav = debug_data->g_pDbgFunctionHead;
101 VkLayerDbgFunctionNode *pTravNext;
102
103 /* Clear out any leftover callbacks */
104 while (pTrav) {
105 pTravNext = pTrav->pNext;
106
107 debug_report_log_msg(
108 debug_data, VK_DBG_REPORT_WARN_BIT,
Courtney Goeltzenleuchter1f1fbbd2015-06-14 12:03:26 -0600109 VK_OBJECT_TYPE_MSG_CALLBACK, pTrav->msgCallback,
Courtney Goeltzenleuchter41fa5b02015-06-11 15:58:51 -0600110 0, DEBUG_REPORT_CALLBACK_REF,
111 "DebugReport",
112 "Debug Report callbacks not removed before DestroyInstance");
113
114 free(pTrav);
115 pTrav = pTravNext;
116 }
117 debug_data->g_pDbgFunctionHead = NULL;
Courtney Goeltzenleuchter1f1fbbd2015-06-14 12:03:26 -0600118
119 free(debug_data);
Courtney Goeltzenleuchter41fa5b02015-06-11 15:58:51 -0600120}
121
Courtney Goeltzenleuchter1f1fbbd2015-06-14 12:03:26 -0600122static inline debug_report_data *layer_debug_report_create_device(
123 debug_report_data *debug_data,
Courtney Goeltzenleuchter41fa5b02015-06-11 15:58:51 -0600124 VkDevice device)
125{
Courtney Goeltzenleuchter1f1fbbd2015-06-14 12:03:26 -0600126 return debug_data;
Courtney Goeltzenleuchter41fa5b02015-06-11 15:58:51 -0600127}
128
129static inline void layer_debug_report_destroy_device(VkDevice device)
130{
Courtney Goeltzenleuchter41fa5b02015-06-11 15:58:51 -0600131}
132
133static inline VkResult layer_create_msg_callback(
Courtney Goeltzenleuchter1f1fbbd2015-06-14 12:03:26 -0600134 debug_report_data *debug_data,
Courtney Goeltzenleuchter41fa5b02015-06-11 15:58:51 -0600135 VkFlags msgFlags,
136 const PFN_vkDbgMsgCallback pfnMsgCallback,
137 void *pUserData,
138 VkDbgMsgCallback *pMsgCallback)
139{
140 VkLayerDbgFunctionNode *pNewDbgFuncNode = (VkLayerDbgFunctionNode*)malloc(sizeof(VkLayerDbgFunctionNode));
141 if (!pNewDbgFuncNode)
142 return VK_ERROR_OUT_OF_HOST_MEMORY;
143
Courtney Goeltzenleuchter1f1fbbd2015-06-14 12:03:26 -0600144 pNewDbgFuncNode->msgCallback = *pMsgCallback;
145 pNewDbgFuncNode->pfnMsgCallback = pfnMsgCallback;
146 pNewDbgFuncNode->msgFlags = msgFlags;
147 pNewDbgFuncNode->pUserData = pUserData;
148 pNewDbgFuncNode->pNext = debug_data->g_pDbgFunctionHead;
Courtney Goeltzenleuchter41fa5b02015-06-11 15:58:51 -0600149
Courtney Goeltzenleuchter1f1fbbd2015-06-14 12:03:26 -0600150 debug_data->g_pDbgFunctionHead = pNewDbgFuncNode;
Courtney Goeltzenleuchter41fa5b02015-06-11 15:58:51 -0600151
Courtney Goeltzenleuchter1f1fbbd2015-06-14 12:03:26 -0600152 debug_report_log_msg(
153 debug_data, VK_DBG_REPORT_DEBUG_BIT,
154 VK_OBJECT_TYPE_MSG_CALLBACK, *pMsgCallback,
155 0, DEBUG_REPORT_CALLBACK_REF,
156 "DebugReport",
157 "Added callback");
158 return VK_SUCCESS;
Courtney Goeltzenleuchter41fa5b02015-06-11 15:58:51 -0600159}
160
Courtney Goeltzenleuchter1f1fbbd2015-06-14 12:03:26 -0600161static void layer_destroy_msg_callback(
162 debug_report_data *debug_data,
Courtney Goeltzenleuchter41fa5b02015-06-11 15:58:51 -0600163 VkDbgMsgCallback msg_callback)
164{
Courtney Goeltzenleuchter41fa5b02015-06-11 15:58:51 -0600165 VkLayerDbgFunctionNode *pTrav = debug_data->g_pDbgFunctionHead;
166 VkLayerDbgFunctionNode *pPrev = pTrav;
167
Courtney Goeltzenleuchter41fa5b02015-06-11 15:58:51 -0600168 while (pTrav) {
169 if (pTrav->msgCallback == msg_callback) {
170 pPrev->pNext = pTrav->pNext;
171 if (debug_data->g_pDbgFunctionHead == pTrav) {
172 debug_data->g_pDbgFunctionHead = pTrav->pNext;
173 }
174 free(pTrav);
175 debug_report_log_msg(
176 debug_data, VK_DBG_REPORT_DEBUG_BIT,
Courtney Goeltzenleuchter1f1fbbd2015-06-14 12:03:26 -0600177 VK_OBJECT_TYPE_MSG_CALLBACK, pTrav->msgCallback,
Courtney Goeltzenleuchter41fa5b02015-06-11 15:58:51 -0600178 0, DEBUG_REPORT_CALLBACK_REF,
179 "DebugReport",
Courtney Goeltzenleuchter1f1fbbd2015-06-14 12:03:26 -0600180 "Destroyed callback");
Courtney Goeltzenleuchter41fa5b02015-06-11 15:58:51 -0600181 break;
182 }
183 pPrev = pTrav;
184 pTrav = pTrav->pNext;
185 }
Courtney Goeltzenleuchter41fa5b02015-06-11 15:58:51 -0600186}
187
188static void* debug_report_get_instance_proc_addr(
Courtney Goeltzenleuchter1f1fbbd2015-06-14 12:03:26 -0600189 debug_report_data *debug_data,
Courtney Goeltzenleuchter41fa5b02015-06-11 15:58:51 -0600190 const char *funcName)
191{
Courtney Goeltzenleuchter1f1fbbd2015-06-14 12:03:26 -0600192 if (!debug_data || !debug_data->g_DEBUG_REPORT) {
Courtney Goeltzenleuchter41fa5b02015-06-11 15:58:51 -0600193 return NULL;
194 }
195
196 if (!strcmp(funcName, "vkDbgCreateMsgCallback")) {
197 return (void *) vkDbgCreateMsgCallback;
198 }
199 if (!strcmp(funcName, "vkDbgDestroyMsgCallback")) {
200 return (void *) vkDbgDestroyMsgCallback;
201 }
202
203 return NULL;
204}
205
206/*
207 * Devices, Queue, SwapChain and Command buffers all
208 * use the same device dispatch table.
209 */
210static void device_log_msg(
Courtney Goeltzenleuchter1f1fbbd2015-06-14 12:03:26 -0600211 debug_report_data *debug_data,
Courtney Goeltzenleuchter41fa5b02015-06-11 15:58:51 -0600212 VkFlags msgFlags,
213 VkObjectType objectType,
214 VkObject srcObject,
215 size_t location,
216 int32_t msgCode,
217 const char* pLayerPrefix,
218 const char* pMsg)
219{
Courtney Goeltzenleuchter41fa5b02015-06-11 15:58:51 -0600220 debug_report_log_msg(debug_data, msgFlags, objectType,
221 srcObject, location, msgCode,
222 pLayerPrefix, pMsg);
223}
224
225static void instance_log_msg(
Courtney Goeltzenleuchter1f1fbbd2015-06-14 12:03:26 -0600226 debug_report_data *debug_data,
Courtney Goeltzenleuchter41fa5b02015-06-11 15:58:51 -0600227 VkFlags msgFlags,
228 VkObjectType objectType,
229 VkObject srcObject,
230 size_t location,
231 int32_t msgCode,
232 const char* pLayerPrefix,
233 const char* pMsg)
234{
Courtney Goeltzenleuchter41fa5b02015-06-11 15:58:51 -0600235 debug_report_log_msg(debug_data, msgFlags, objectType,
236 srcObject, location, msgCode,
237 pLayerPrefix, pMsg);
238}
239
240#endif // LAYER_LOGGING_H
241