1 /* 2 * Copyright (c) 2015-2016 The Khronos Group Inc. 3 * Copyright (c) 2015-2016 Valve Corporation 4 * Copyright (c) 2015-2016 LunarG, Inc. 5 * Copyright (C) 2015-2016 Google Inc. 6 * 7 * Licensed under the Apache License, Version 2.0 (the "License"); 8 * you may not use this file except in compliance with the License. 9 * You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, software 14 * distributed under the License is distributed on an "AS IS" BASIS, 15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 * See the License for the specific language governing permissions and 17 * limitations under the License. 18 * 19 * Author: Courtney Goeltzenleuchter <courtney@LunarG.com> 20 * Author: Jon Ashburn <jon@lunarg.com> 21 * 22 */ 23 24 #include "vk_loader_platform.h" 25 #include "loader.h" 26 /* 27 * CreateMsgCallback is global and needs to be 28 * applied to all layers and ICDs. 29 * What happens if a layer is enabled on both the instance chain 30 * as well as the device chain and a call to CreateMsgCallback is made? 31 * Do we need to make sure that each layer / driver only gets called once? 32 * Should a layer implementing support for CreateMsgCallback only be allowed (?) 33 * to live on one chain? Or maybe make it the application's responsibility. 34 * If the app enables DRAW_STATE on at both CreateInstance time and CreateDevice 35 * time, CreateMsgCallback will call the DRAW_STATE layer twice. Once via 36 * the instance chain and once via the device chain. 37 * The loader should only return the DEBUG_REPORT extension as supported 38 * for the GetGlobalExtensionSupport call. That should help eliminate one 39 * duplication. 40 * Since the instance chain requires us iterating over the available ICDs 41 * and each ICD will have it's own unique MsgCallback object we need to 42 * track those objects to give back the right one. 43 * This also implies that the loader has to intercept vkDestroyObject and 44 * if the extension is enabled and the object type is a MsgCallback then 45 * we must translate the object into the proper ICD specific ones. 46 * DestroyObject works on a device chain. Should not be what's destroying 47 * the MsgCallback object. That needs to be an instance thing. So, since 48 * we used an instance to create it, we need a custom Destroy that also 49 * takes an instance. That way we can iterate over the ICDs properly. 50 * Example use: 51 * CreateInstance: DEBUG_REPORT 52 * Loader will create instance chain with enabled extensions. 53 * TODO: Should validation layers be enabled here? If not, they will not be in 54 * the instance chain. 55 * fn = GetProcAddr(INSTANCE, "vkCreateMsgCallback") -> point to loader's 56 * vkCreateMsgCallback 57 * App creates a callback object: fn(..., &MsgCallbackObject1) 58 * Have only established the instance chain so far. Loader will call the 59 * instance chain. 60 * Each layer in the instance chain will call down to the next layer, 61 * terminating with 62 * the CreateMsgCallback loader terminator function that creates the actual 63 * MsgCallbackObject1 object. 64 * The loader CreateMsgCallback terminator will iterate over the ICDs. 65 * Calling each ICD that supports vkCreateMsgCallback and collect answers in 66 * icd_msg_callback_map here. 67 * As result is sent back up the chain each layer has opportunity to record the 68 * callback operation and 69 * appropriate MsgCallback object. 70 * ... 71 * Any reports matching the flags set in MsgCallbackObject1 will generate the 72 * defined callback behavior 73 * in the layer / ICD that initiated that report. 74 * ... 75 * CreateDevice: MemTracker:... 76 * App does not include DEBUG_REPORT as that is a global extension. 77 * TODO: GetExtensionSupport must not report DEBUG_REPORT when using instance. 78 * App MUST include any desired validation layers or they will not participate 79 * in the device call chain. 80 * App creates a callback object: fn(..., &MsgCallbackObject2) 81 * Loader's vkCreateMsgCallback is called. 82 * Loader sends call down instance chain - this is a global extension - any 83 * validation layer that was 84 * enabled at CreateInstance will be able to register the callback. Loader will 85 * iterate over the ICDs and 86 * will record the ICD's version of the MsgCallback2 object here. 87 * ... 88 * Any report will go to the layer's report function and it will check the flags 89 * for MsgCallbackObject1 90 * and MsgCallbackObject2 and take the appropriate action as indicated by the 91 * app. 92 * ... 93 * App calls vkDestroyMsgCallback( MsgCallbackObject1 ) 94 * Loader's DestroyMsgCallback is where call starts. DestroyMsgCallback will be 95 * sent down instance chain 96 * ending in the loader's DestroyMsgCallback terminator which will iterate over 97 * the ICD's destroying each 98 * ICD version of that MsgCallback object and then destroy the loader's version 99 * of the object. 100 * Any reports generated after this will only have MsgCallbackObject2 available. 101 */ 102 103 void debug_report_add_instance_extensions( 104 const struct loader_instance *inst, struct loader_extension_list *ext_list); 105 106 void debug_report_create_instance(struct loader_instance *ptr_instance, 107 const VkInstanceCreateInfo *pCreateInfo); 108 109 bool debug_report_instance_gpa(struct loader_instance *ptr_instance, 110 const char *name, void **addr); 111 112 VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateDebugReportCallback( 113 VkInstance instance, const VkDebugReportCallbackCreateInfoEXT *pCreateInfo, 114 const VkAllocationCallbacks *pAllocator, 115 VkDebugReportCallbackEXT *pCallback); 116 117 VKAPI_ATTR void VKAPI_CALL 118 terminator_DestroyDebugReportCallback(VkInstance instance, 119 VkDebugReportCallbackEXT callback, 120 const VkAllocationCallbacks *pAllocator); 121 122 VKAPI_ATTR void VKAPI_CALL 123 terminator_DebugReportMessage(VkInstance instance, VkDebugReportFlagsEXT flags, 124 VkDebugReportObjectTypeEXT objType, 125 uint64_t object, size_t location, int32_t msgCode, 126 const char *pLayerPrefix, const char *pMsg); 127 128 VkResult 129 util_CreateDebugReportCallback(struct loader_instance *inst, 130 VkDebugReportCallbackCreateInfoEXT *pCreateInfo, 131 const VkAllocationCallbacks *pAllocator, 132 VkDebugReportCallbackEXT callback); 133 134 void util_DestroyDebugReportCallback(struct loader_instance *inst, 135 VkDebugReportCallbackEXT callback, 136 const VkAllocationCallbacks *pAllocator); 137 138 VkResult util_CopyDebugReportCreateInfos( 139 const void *pChain, const VkAllocationCallbacks *pAllocator, 140 uint32_t *num_callbacks, VkDebugReportCallbackCreateInfoEXT **infos, 141 VkDebugReportCallbackEXT **callbacks); 142 void util_FreeDebugReportCreateInfos(const VkAllocationCallbacks *pAllocator, 143 VkDebugReportCallbackCreateInfoEXT *infos, 144 VkDebugReportCallbackEXT *callbacks); 145 VkResult util_CreateDebugReportCallbacks( 146 struct loader_instance *inst, const VkAllocationCallbacks *pAllocator, 147 uint32_t num_callbacks, VkDebugReportCallbackCreateInfoEXT *infos, 148 VkDebugReportCallbackEXT *callbacks); 149 150 void util_DestroyDebugReportCallbacks(struct loader_instance *inst, 151 const VkAllocationCallbacks *pAllocator, 152 uint32_t num_callbacks, 153 VkDebugReportCallbackEXT *callbacks); 154 155 VkBool32 util_DebugReportMessage(const struct loader_instance *inst, 156 VkFlags msgFlags, 157 VkDebugReportObjectTypeEXT objectType, 158 uint64_t srcObject, size_t location, 159 int32_t msgCode, const char *pLayerPrefix, 160 const char *pMsg); 161