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 * Permission is hereby granted, free of charge, to any person obtaining a copy 8 * of this software and/or associated documentation files (the "Materials"), to 9 * deal in the Materials without restriction, including without limitation the 10 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 11 * sell copies of the Materials, and to permit persons to whom the Materials are 12 * furnished to do so, subject to the following conditions: 13 * 14 * The above copyright notice(s) and this permission notice shall be included in 15 * all copies or substantial portions of the Materials. 16 * 17 * THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 20 * 21 * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 22 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 23 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE MATERIALS OR THE 24 * USE OR OTHER DEALINGS IN THE MATERIALS. 25 * 26 * Author: Courtney Goeltzenleuchter <courtney@LunarG.com> 27 * Author: Jon Ashburn <jon@lunarg.com> 28 * 29 */ 30 31 #include "vk_loader_platform.h" 32 #include "loader.h" 33 /* 34 * CreateMsgCallback is global and needs to be 35 * applied to all layers and ICDs. 36 * What happens if a layer is enabled on both the instance chain 37 * as well as the device chain and a call to CreateMsgCallback is made? 38 * Do we need to make sure that each layer / driver only gets called once? 39 * Should a layer implementing support for CreateMsgCallback only be allowed (?) 40 * to live on one chain? Or maybe make it the application's responsibility. 41 * If the app enables DRAW_STATE on at both CreateInstance time and CreateDevice 42 * time, CreateMsgCallback will call the DRAW_STATE layer twice. Once via 43 * the instance chain and once via the device chain. 44 * The loader should only return the DEBUG_REPORT extension as supported 45 * for the GetGlobalExtensionSupport call. That should help eliminate one 46 * duplication. 47 * Since the instance chain requires us iterating over the available ICDs 48 * and each ICD will have it's own unique MsgCallback object we need to 49 * track those objects to give back the right one. 50 * This also implies that the loader has to intercept vkDestroyObject and 51 * if the extension is enabled and the object type is a MsgCallback then 52 * we must translate the object into the proper ICD specific ones. 53 * DestroyObject works on a device chain. Should not be what's destroying 54 * the MsgCallback object. That needs to be an instance thing. So, since 55 * we used an instance to create it, we need a custom Destroy that also 56 * takes an instance. That way we can iterate over the ICDs properly. 57 * Example use: 58 * CreateInstance: DEBUG_REPORT 59 * Loader will create instance chain with enabled extensions. 60 * TODO: Should validation layers be enabled here? If not, they will not be in 61 * the instance chain. 62 * fn = GetProcAddr(INSTANCE, "vkCreateMsgCallback") -> point to loader's 63 * vkCreateMsgCallback 64 * App creates a callback object: fn(..., &MsgCallbackObject1) 65 * Have only established the instance chain so far. Loader will call the 66 * instance chain. 67 * Each layer in the instance chain will call down to the next layer, 68 * terminating with 69 * the CreateMsgCallback loader terminator function that creates the actual 70 * MsgCallbackObject1 object. 71 * The loader CreateMsgCallback terminator will iterate over the ICDs. 72 * Calling each ICD that supports vkCreateMsgCallback and collect answers in 73 * icd_msg_callback_map here. 74 * As result is sent back up the chain each layer has opportunity to record the 75 * callback operation and 76 * appropriate MsgCallback object. 77 * ... 78 * Any reports matching the flags set in MsgCallbackObject1 will generate the 79 * defined callback behavior 80 * in the layer / ICD that initiated that report. 81 * ... 82 * CreateDevice: MemTracker:... 83 * App does not include DEBUG_REPORT as that is a global extension. 84 * TODO: GetExtensionSupport must not report DEBUG_REPORT when using instance. 85 * App MUST include any desired validation layers or they will not participate 86 * in the device call chain. 87 * App creates a callback object: fn(..., &MsgCallbackObject2) 88 * Loader's vkCreateMsgCallback is called. 89 * Loader sends call down instance chain - this is a global extension - any 90 * validation layer that was 91 * enabled at CreateInstance will be able to register the callback. Loader will 92 * iterate over the ICDs and 93 * will record the ICD's version of the MsgCallback2 object here. 94 * ... 95 * Any report will go to the layer's report function and it will check the flags 96 * for MsgCallbackObject1 97 * and MsgCallbackObject2 and take the appropriate action as indicated by the 98 * app. 99 * ... 100 * App calls vkDestroyMsgCallback( MsgCallbackObject1 ) 101 * Loader's DestroyMsgCallback is where call starts. DestroyMsgCallback will be 102 * sent down instance chain 103 * ending in the loader's DestroyMsgCallback terminator which will iterate over 104 * the ICD's destroying each 105 * ICD version of that MsgCallback object and then destroy the loader's version 106 * of the object. 107 * Any reports generated after this will only have MsgCallbackObject2 available. 108 */ 109 110 void debug_report_add_instance_extensions( 111 const struct loader_instance *inst, struct loader_extension_list *ext_list); 112 113 void debug_report_create_instance(struct loader_instance *ptr_instance, 114 const VkInstanceCreateInfo *pCreateInfo); 115 116 bool debug_report_instance_gpa(struct loader_instance *ptr_instance, 117 const char *name, void **addr); 118 119 VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateDebugReportCallback( 120 VkInstance instance, const VkDebugReportCallbackCreateInfoEXT *pCreateInfo, 121 const VkAllocationCallbacks *pAllocator, 122 VkDebugReportCallbackEXT *pCallback); 123 124 VKAPI_ATTR void VKAPI_CALL 125 terminator_DestroyDebugReportCallback(VkInstance instance, 126 VkDebugReportCallbackEXT callback, 127 const VkAllocationCallbacks *pAllocator); 128 129 VKAPI_ATTR void VKAPI_CALL 130 terminator_DebugReportMessage(VkInstance instance, VkDebugReportFlagsEXT flags, 131 VkDebugReportObjectTypeEXT objType, 132 uint64_t object, size_t location, int32_t msgCode, 133 const char *pLayerPrefix, const char *pMsg); 134 135 VkResult 136 util_CreateDebugReportCallback(struct loader_instance *inst, 137 VkDebugReportCallbackCreateInfoEXT *pCreateInfo, 138 const VkAllocationCallbacks *pAllocator, 139 VkDebugReportCallbackEXT callback); 140 141 void util_DestroyDebugReportCallback(struct loader_instance *inst, 142 VkDebugReportCallbackEXT callback, 143 const VkAllocationCallbacks *pAllocator); 144 145 VkBool32 util_DebugReportMessage(const struct loader_instance *inst, 146 VkFlags msgFlags, 147 VkDebugReportObjectTypeEXT objectType, 148 uint64_t srcObject, size_t location, 149 int32_t msgCode, const char *pLayerPrefix, 150 const char *pMsg); 151