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