Home | History | Annotate | Download | only in loader
      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 (at) LunarG.com>
     27  * Author: Jon Ashburn <jon (at) 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