blob: 1e6fe4cebc4da00c31b851e47e270f6656755aed [file] [log] [blame]
Jon Ashburnd6badbc2015-02-16 08:26:50 -07001/*
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -06002 * Vulkan
Jon Ashburnd6badbc2015-02-16 08:26:50 -07003 *
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#include <stdio.h>
Jon Ashburna8aa8372015-03-03 15:07:15 -070025#include <stdbool.h>
Tobin Ehlis0c6f9ee2015-07-03 09:42:57 -060026#include "vk_layer.h"
Jon Ashburnd6badbc2015-02-16 08:26:50 -070027
Courtney Goeltzenleuchterf579fa62015-06-10 17:39:03 -060028static VkLayerDbgFunctionNode *g_pDbgFunctionHead = NULL;
29static VkFlags g_reportFlags = (VkFlags) 0;
30static VkLayerDbgAction g_debugAction = VK_DBG_LAYER_ACTION_LOG_MSG;
Jon Ashburna8aa8372015-03-03 15:07:15 -070031static bool g_actionIsDefault = true;
Courtney Goeltzenleuchterf579fa62015-06-10 17:39:03 -060032static bool g_DEBUG_REPORT = false;
Jon Ashburnd6badbc2015-02-16 08:26:50 -070033static FILE *g_logFile = NULL;
34
Courtney Goeltzenleuchterf579fa62015-06-10 17:39:03 -060035static void enable_debug_report(
Courtney Goeltzenleuchter110fdf92015-06-29 15:39:26 -060036 uint32_t extension_count,
37 const char * const * ppEnabledExtensionNames) // extension name to be enabled
Courtney Goeltzenleuchterf579fa62015-06-10 17:39:03 -060038{
39 for (uint32_t i = 0; i < extension_count; i++) {
40 /* TODO: Check other property fields */
Courtney Goeltzenleuchter110fdf92015-06-29 15:39:26 -060041 if (strcmp(ppEnabledExtensionNames[i], DEBUG_REPORT_EXTENSION_NAME) == 0) {
Courtney Goeltzenleuchterf579fa62015-06-10 17:39:03 -060042 g_DEBUG_REPORT = true;
43 }
44 }
45}
46
47static VkResult layer_create_msg_callback(
48 VkInstance instance,
49 VkLayerInstanceDispatchTable* nextTable,
50 VkFlags msgFlags,
51 const PFN_vkDbgMsgCallback pfnMsgCallback,
52 void* pUserData,
53 VkDbgMsgCallback* pMsgCallback)
54{
55 VkLayerDbgFunctionNode *pNewDbgFuncNode = (VkLayerDbgFunctionNode*)malloc(sizeof(VkLayerDbgFunctionNode));
56 if (!pNewDbgFuncNode)
57 return VK_ERROR_OUT_OF_HOST_MEMORY;
58 VkResult result = nextTable->DbgCreateMsgCallback(instance, msgFlags, pfnMsgCallback, pUserData, pMsgCallback);
59 if (result == VK_SUCCESS) {
60 pNewDbgFuncNode->msgCallback = *pMsgCallback;
61 pNewDbgFuncNode->pfnMsgCallback = pfnMsgCallback;
62 pNewDbgFuncNode->msgFlags = msgFlags;
63 pNewDbgFuncNode->pUserData = pUserData;
64 pNewDbgFuncNode->pNext = g_pDbgFunctionHead;
Courtney Goeltzenleuchterd971b612015-06-17 20:51:59 -060065
66 /* TODO: This should be a per-instance resource */
Courtney Goeltzenleuchterf579fa62015-06-10 17:39:03 -060067 g_pDbgFunctionHead = pNewDbgFuncNode;
68 } else {
69 free(pNewDbgFuncNode);
70 }
71 return result;
72}
73
74static VkResult layer_destroy_msg_callback(
75 VkInstance instance,
76 VkLayerInstanceDispatchTable *nextTable,
77 VkDbgMsgCallback msg_callback)
78{
79 VkLayerDbgFunctionNode *pTrav = g_pDbgFunctionHead;
80 VkLayerDbgFunctionNode *pPrev = pTrav;
81
82 VkResult result = nextTable->DbgDestroyMsgCallback(instance, msg_callback);
83
84 while (pTrav) {
85 if (pTrav->msgCallback == msg_callback) {
86 pPrev->pNext = pTrav->pNext;
87 if (g_pDbgFunctionHead == pTrav)
88 g_pDbgFunctionHead = pTrav->pNext;
89 free(pTrav);
90 break;
91 }
92 pPrev = pTrav;
93 pTrav = pTrav->pNext;
94 }
95
96 return result;
97}
98
Courtney Goeltzenleuchterd02a9642015-06-08 14:58:39 -060099static inline void debug_report_init_instance_extension_dispatch_table(
100 VkLayerInstanceDispatchTable *table,
101 PFN_vkGetInstanceProcAddr gpa,
102 VkInstance inst)
103{
104 table->DbgCreateMsgCallback = (PFN_vkDbgCreateMsgCallback) gpa(inst, "vkDbgCreateMsgCallback");
105 table->DbgDestroyMsgCallback = (PFN_vkDbgDestroyMsgCallback) gpa(inst, "vkDbgDestroyMsgCallback");
106}
107
Courtney Goeltzenleuchterd971b612015-06-17 20:51:59 -0600108static void* msg_callback_get_proc_addr(
109 const char *funcName)
110{
111 if (!g_DEBUG_REPORT) {
112 return NULL;
113 }
114
115 if (!strcmp(funcName, "vkDbgCreateMsgCallback")) {
116 return (void *) vkDbgCreateMsgCallback;
117 }
118 if (!strcmp(funcName, "vkDbgDestroyMsgCallback")) {
119 return (void *) vkDbgDestroyMsgCallback;
120 }
121
122 return NULL;
123}
124
Jon Ashburnd6badbc2015-02-16 08:26:50 -0700125// Utility function to handle reporting
126// If callbacks are enabled, use them, otherwise use printf
Courtney Goeltzenleuchterf579fa62015-06-10 17:39:03 -0600127static void layerCbMsg(
Courtney Goeltzenleuchterd971b612015-06-17 20:51:59 -0600128 VkFlags msgFlags,
Courtney Goeltzenleuchterf579fa62015-06-10 17:39:03 -0600129 VkObjectType objectType,
130 VkObject srcObject,
131 size_t location,
132 int32_t msgCode,
133 const char* pLayerPrefix,
134 const char* pMsg)
Jon Ashburnd6badbc2015-02-16 08:26:50 -0700135{
Courtney Goeltzenleuchterab5636c2015-02-22 16:15:32 -0700136 if (g_logFile == NULL) {
137 g_logFile = stdout;
138 }
139
Courtney Goeltzenleuchterf579fa62015-06-10 17:39:03 -0600140 VkLayerDbgFunctionNode *pTrav = g_pDbgFunctionHead;
141 while (pTrav) {
142 if (pTrav->msgFlags & msgFlags) {
143 pTrav->pfnMsgCallback(msgFlags,
144 objectType, srcObject,
145 location,
146 msgCode,
147 pLayerPrefix,
148 pMsg,
149 (void *) pTrav->pUserData);
150 }
151 pTrav = pTrav->pNext;
152 }
Jon Ashburnd6badbc2015-02-16 08:26:50 -0700153}