blob: b7057e6c9feaeb200effc0526454682e998abc38 [file] [log] [blame]
Courtney Goeltzenleuchterf579fa62015-06-10 17:39:03 -06001/*
Courtney Goeltzenleuchterf579fa62015-06-10 17:39:03 -06002 *
Courtney Goeltzenleuchterfcbe16f2015-10-29 13:50:34 -06003 * Copyright (C) 2015 Valve Corporation
Courtney Goeltzenleuchterf579fa62015-06-10 17:39:03 -06004 *
5 * Permission is hereby granted, free of charge, to any person obtaining a
6 * copy of this software and associated documentation files (the "Software"),
7 * to deal in the Software without restriction, including without limitation
8 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9 * and/or sell copies of the Software, and to permit persons to whom the
10 * Software is furnished to do so, subject to the following conditions:
11 *
12 * The above copyright notice and this permission notice shall be included
13 * in all copies or substantial portions of the 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
21 * DEALINGS IN THE SOFTWARE.
22 *
Courtney Goeltzenleuchter05559522015-10-30 11:14:30 -060023 * Author: Courtney Goeltzenleuchter <courtney@LunarG.com>
24 *
Courtney Goeltzenleuchterf579fa62015-06-10 17:39:03 -060025 */
26
Courtney Goeltzenleuchter7f5aafc2015-07-05 11:28:29 -060027#define _GNU_SOURCE
Courtney Goeltzenleuchter7dcc6a72015-06-11 16:01:11 -060028#include <stdio.h>
Courtney Goeltzenleuchterf579fa62015-06-10 17:39:03 -060029#include <string.h>
30#include <stdlib.h>
Courtney Goeltzenleuchter7dcc6a72015-06-11 16:01:11 -060031#include <inttypes.h>
Tony Barbour1d825c72015-06-18 16:29:32 -060032#ifndef WIN32
Courtney Goeltzenleuchter03663d02015-07-22 11:01:53 -060033#include <signal.h>
34#else
Tony Barbour1d825c72015-06-18 16:29:32 -060035#endif
Jon Ashburn480a50a2015-08-28 14:58:46 -070036#include "vk_loader_platform.h"
Courtney Goeltzenleuchterf579fa62015-06-10 17:39:03 -060037#include "debug_report.h"
David Pinedo9316d3b2015-11-06 12:54:48 -070038#include "vulkan/vk_layer.h"
Courtney Goeltzenleuchterf579fa62015-06-10 17:39:03 -060039
Chia-I Wu9ab61502015-11-06 06:42:02 +080040typedef void (VKAPI_PTR *PFN_stringCallback)(char *message);
Courtney Goeltzenleuchter7dcc6a72015-06-11 16:01:11 -060041
Jon Ashburn5c042ea2015-08-04 11:14:18 -060042static const VkExtensionProperties debug_report_extension_info = {
Courtney Goeltzenleuchter09197ae2015-11-25 13:40:37 -070043 .extensionName = VK_EXT_LUNARG_DEBUG_REPORT_EXTENSION_NAME,
44 .specVersion = VK_EXT_LUNARG_DEBUG_REPORT_EXTENSION_REVISION,
Courtney Goeltzenleuchterf579fa62015-06-10 17:39:03 -060045};
46
47void debug_report_add_instance_extensions(
Jon Ashburne39a4f82015-08-28 13:38:21 -060048 const struct loader_instance *inst,
Courtney Goeltzenleuchterf579fa62015-06-10 17:39:03 -060049 struct loader_extension_list *ext_list)
50{
Jon Ashburne39a4f82015-08-28 13:38:21 -060051 loader_add_to_ext_list(inst, ext_list, 1, &debug_report_extension_info);
Courtney Goeltzenleuchterf579fa62015-06-10 17:39:03 -060052}
53
54void debug_report_create_instance(
Courtney Goeltzenleuchter110fdf92015-06-29 15:39:26 -060055 struct loader_instance *ptr_instance,
56 const VkInstanceCreateInfo *pCreateInfo)
Courtney Goeltzenleuchterf579fa62015-06-10 17:39:03 -060057{
Courtney Goeltzenleuchter110fdf92015-06-29 15:39:26 -060058 ptr_instance->debug_report_enabled = false;
59
Chia-I Wud50a7d72015-10-26 20:48:51 +080060 for (uint32_t i = 0; i < pCreateInfo->enabledExtensionNameCount; i++) {
Courtney Goeltzenleuchter09197ae2015-11-25 13:40:37 -070061 if (strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_EXT_LUNARG_DEBUG_REPORT_EXTENSION_NAME) == 0) {
Courtney Goeltzenleuchter110fdf92015-06-29 15:39:26 -060062 ptr_instance->debug_report_enabled = true;
63 return;
64 }
65 }
Courtney Goeltzenleuchterf579fa62015-06-10 17:39:03 -060066}
67
Jon Ashburn4f232582015-11-06 15:31:44 -070068static VKAPI_ATTR VkResult VKAPI_CALL debug_report_DbgCreateMsgCallback(
Courtney Goeltzenleuchterf579fa62015-06-10 17:39:03 -060069 VkInstance instance,
70 VkFlags msgFlags,
71 const PFN_vkDbgMsgCallback pfnMsgCallback,
72 void* pUserData,
Courtney Goeltzenleuchter107a0d22015-11-25 14:07:05 -070073 VkDebugReportCallbackLUNARG* pMsgCallback)
Courtney Goeltzenleuchterf579fa62015-06-10 17:39:03 -060074{
Chia-I Wu3432a0c2015-10-27 18:04:07 +080075 VkLayerDbgFunctionNode *pNewDbgFuncNode = (VkLayerDbgFunctionNode *) loader_heap_alloc((struct loader_instance *)instance, sizeof(VkLayerDbgFunctionNode), VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
Courtney Goeltzenleuchterf579fa62015-06-10 17:39:03 -060076 if (!pNewDbgFuncNode)
77 return VK_ERROR_OUT_OF_HOST_MEMORY;
78
Jon Ashburne0e64572015-09-30 12:56:42 -060079 struct loader_instance *inst = loader_get_instance(instance);
Jon Ashburn6301a0f2015-05-29 13:15:39 -060080 loader_platform_thread_lock_mutex(&loader_lock);
Courtney Goeltzenleuchterf579fa62015-06-10 17:39:03 -060081 VkResult result = inst->disp->DbgCreateMsgCallback(instance, msgFlags, pfnMsgCallback, pUserData, pMsgCallback);
82 if (result == VK_SUCCESS) {
83 pNewDbgFuncNode->msgCallback = *pMsgCallback;
84 pNewDbgFuncNode->pfnMsgCallback = pfnMsgCallback;
85 pNewDbgFuncNode->msgFlags = msgFlags;
86 pNewDbgFuncNode->pUserData = pUserData;
87 pNewDbgFuncNode->pNext = inst->DbgFunctionHead;
88 inst->DbgFunctionHead = pNewDbgFuncNode;
89 } else {
Jon Ashburne39a4f82015-08-28 13:38:21 -060090 loader_heap_free((struct loader_instance *) instance, pNewDbgFuncNode);
Courtney Goeltzenleuchterf579fa62015-06-10 17:39:03 -060091 }
Jon Ashburn6301a0f2015-05-29 13:15:39 -060092 loader_platform_thread_unlock_mutex(&loader_lock);
Courtney Goeltzenleuchterf579fa62015-06-10 17:39:03 -060093 return result;
94}
95
Jon Ashburn4f232582015-11-06 15:31:44 -070096static VKAPI_ATTR VkResult VKAPI_CALL debug_report_DbgDestroyMsgCallback(
Courtney Goeltzenleuchterf579fa62015-06-10 17:39:03 -060097 VkInstance instance,
Courtney Goeltzenleuchter107a0d22015-11-25 14:07:05 -070098 VkDebugReportCallbackLUNARG msg_callback)
Courtney Goeltzenleuchterf579fa62015-06-10 17:39:03 -060099{
Jon Ashburne0e64572015-09-30 12:56:42 -0600100 struct loader_instance *inst = loader_get_instance(instance);
Jon Ashburn6301a0f2015-05-29 13:15:39 -0600101 loader_platform_thread_lock_mutex(&loader_lock);
Courtney Goeltzenleuchterf579fa62015-06-10 17:39:03 -0600102 VkLayerDbgFunctionNode *pTrav = inst->DbgFunctionHead;
103 VkLayerDbgFunctionNode *pPrev = pTrav;
104
Courtney Goeltzenleuchter7d0023c2015-06-08 15:09:22 -0600105 VkResult result = inst->disp->DbgDestroyMsgCallback(instance, msg_callback);
Courtney Goeltzenleuchterf579fa62015-06-10 17:39:03 -0600106
107 while (pTrav) {
Chia-I Wue2fc5522015-10-26 20:04:44 +0800108 if (pTrav->msgCallback == msg_callback) {
Courtney Goeltzenleuchterf579fa62015-06-10 17:39:03 -0600109 pPrev->pNext = pTrav->pNext;
110 if (inst->DbgFunctionHead == pTrav)
111 inst->DbgFunctionHead = pTrav->pNext;
Jon Ashburne39a4f82015-08-28 13:38:21 -0600112 loader_heap_free((struct loader_instance *) instance, pTrav);
Courtney Goeltzenleuchterf579fa62015-06-10 17:39:03 -0600113 break;
114 }
115 pPrev = pTrav;
116 pTrav = pTrav->pNext;
117 }
118
Jon Ashburn6301a0f2015-05-29 13:15:39 -0600119 loader_platform_thread_unlock_mutex(&loader_lock);
Courtney Goeltzenleuchterf579fa62015-06-10 17:39:03 -0600120 return result;
121}
122
123
124/*
125 * This is the instance chain terminator function
126 * for DbgCreateMsgCallback
127 */
Tony Barbour1d2cd3f2015-07-03 10:33:54 -0600128
Chia-I Wu9ab61502015-11-06 06:42:02 +0800129VKAPI_ATTR VkResult VKAPI_CALL loader_DbgCreateMsgCallback(
Courtney Goeltzenleuchterf579fa62015-06-10 17:39:03 -0600130 VkInstance instance,
131 VkFlags msgFlags,
132 const PFN_vkDbgMsgCallback pfnMsgCallback,
Jon Ashburne67741a2015-08-06 13:56:43 -0600133 void* pUserData,
Courtney Goeltzenleuchter107a0d22015-11-25 14:07:05 -0700134 VkDebugReportCallbackLUNARG* pMsgCallback)
Courtney Goeltzenleuchterf579fa62015-06-10 17:39:03 -0600135{
Courtney Goeltzenleuchter107a0d22015-11-25 14:07:05 -0700136 VkDebugReportCallbackLUNARG *icd_info;
Courtney Goeltzenleuchterf579fa62015-06-10 17:39:03 -0600137 const struct loader_icd *icd;
138 struct loader_instance *inst;
139 VkResult res;
140 uint32_t storage_idx;
141
Courtney Goeltzenleuchterf579fa62015-06-10 17:39:03 -0600142 for (inst = loader.instances; inst; inst = inst->next) {
143 if ((VkInstance) inst == instance)
144 break;
145 }
146
Courtney Goeltzenleuchter107a0d22015-11-25 14:07:05 -0700147 icd_info = calloc(sizeof(VkDebugReportCallbackLUNARG), inst->total_icd_count);
Courtney Goeltzenleuchterf579fa62015-06-10 17:39:03 -0600148 if (!icd_info) {
149 return VK_ERROR_OUT_OF_HOST_MEMORY;
150 }
151
152 storage_idx = 0;
153 for (icd = inst->icds; icd; icd = icd->next) {
154 if (!icd->DbgCreateMsgCallback) {
155 continue;
156 }
157
158 res = icd->DbgCreateMsgCallback(
159 icd->instance,
160 msgFlags,
161 pfnMsgCallback,
162 pUserData,
163 &icd_info[storage_idx]);
164
165 if (res != VK_SUCCESS) {
166 break;
167 }
168 storage_idx++;
169 }
170
171 /* roll back on errors */
172 if (icd) {
173 storage_idx = 0;
174 for (icd = inst->icds; icd; icd = icd->next) {
Chia-I Wue2fc5522015-10-26 20:04:44 +0800175 if (icd_info[storage_idx]) {
Courtney Goeltzenleuchterf579fa62015-06-10 17:39:03 -0600176 icd->DbgDestroyMsgCallback(
177 icd->instance,
178 icd_info[storage_idx]);
179 }
180 storage_idx++;
181 }
182
183 return res;
184 }
185
Courtney Goeltzenleuchter107a0d22015-11-25 14:07:05 -0700186 *(VkDebugReportCallbackLUNARG **)pMsgCallback = icd_info;
Courtney Goeltzenleuchterf579fa62015-06-10 17:39:03 -0600187
188 return VK_SUCCESS;
189}
190
191/*
192 * This is the instance chain terminator function
193 * for DbgDestroyMsgCallback
194 */
Chia-I Wu9ab61502015-11-06 06:42:02 +0800195VKAPI_ATTR VkResult VKAPI_CALL loader_DbgDestroyMsgCallback(
Courtney Goeltzenleuchterf579fa62015-06-10 17:39:03 -0600196 VkInstance instance,
Courtney Goeltzenleuchter107a0d22015-11-25 14:07:05 -0700197 VkDebugReportCallbackLUNARG msgCallback)
Courtney Goeltzenleuchterf579fa62015-06-10 17:39:03 -0600198{
199 uint32_t storage_idx;
Courtney Goeltzenleuchter107a0d22015-11-25 14:07:05 -0700200 VkDebugReportCallbackLUNARG *icd_info;
Courtney Goeltzenleuchterf579fa62015-06-10 17:39:03 -0600201 const struct loader_icd *icd;
202 VkResult res = VK_SUCCESS;
203 struct loader_instance *inst;
204
Courtney Goeltzenleuchterf579fa62015-06-10 17:39:03 -0600205 for (inst = loader.instances; inst; inst = inst->next) {
206 if ((VkInstance) inst == instance)
207 break;
208 }
209
Courtney Goeltzenleuchter107a0d22015-11-25 14:07:05 -0700210 icd_info = *(VkDebugReportCallbackLUNARG **) &msgCallback;
Courtney Goeltzenleuchterf579fa62015-06-10 17:39:03 -0600211 storage_idx = 0;
212 for (icd = inst->icds; icd; icd = icd->next) {
Chia-I Wue2fc5522015-10-26 20:04:44 +0800213 if (icd_info[storage_idx]) {
Courtney Goeltzenleuchterf579fa62015-06-10 17:39:03 -0600214 icd->DbgDestroyMsgCallback(
Courtney Goeltzenleuchter7d0023c2015-06-08 15:09:22 -0600215 icd->instance,
Courtney Goeltzenleuchterf579fa62015-06-10 17:39:03 -0600216 icd_info[storage_idx]);
217 }
218 storage_idx++;
219 }
220 return res;
221}
222
Jon Ashburnf7a48db2015-10-01 12:03:17 -0600223bool debug_report_instance_gpa(
Courtney Goeltzenleuchterf579fa62015-06-10 17:39:03 -0600224 struct loader_instance *ptr_instance,
Jon Ashburnf7a48db2015-10-01 12:03:17 -0600225 const char* name,
226 void **addr)
Courtney Goeltzenleuchterf579fa62015-06-10 17:39:03 -0600227{
Jon Ashburn8a39efc2015-11-06 11:02:40 -0700228 // debug_report is currently advertised to be supported by the loader,
229 // so always return the entry points if name matches and it's enabled
Jon Ashburnf7a48db2015-10-01 12:03:17 -0600230 *addr = NULL;
Courtney Goeltzenleuchterf579fa62015-06-10 17:39:03 -0600231
Jon Ashburnf7a48db2015-10-01 12:03:17 -0600232 if (!strcmp("vkDbgCreateMsgCallback", name)) {
233 *addr = ptr_instance->debug_report_enabled ? (void *) debug_report_DbgCreateMsgCallback : NULL;
234 return true;
235 }
236 if (!strcmp("vkDbgDestroyMsgCallback", name)) {
237 *addr = ptr_instance->debug_report_enabled ? (void *) debug_report_DbgDestroyMsgCallback : NULL;
238 return true;
239 }
Jon Ashburnf7a48db2015-10-01 12:03:17 -0600240 return false;
Courtney Goeltzenleuchterf579fa62015-06-10 17:39:03 -0600241}