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  * 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 (at) LunarG.com>
     20  * Author: Jon Ashburn <jon (at) 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 void debug_report_add_instance_extensions(const struct loader_instance *inst, struct loader_extension_list *ext_list);
    103 
    104 void debug_report_create_instance(struct loader_instance *ptr_instance, const VkInstanceCreateInfo *pCreateInfo);
    105 
    106 bool debug_report_instance_gpa(struct loader_instance *ptr_instance, const char *name, void **addr);
    107 
    108 VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateDebugReportCallbackEXT(VkInstance instance,
    109                                                                        const VkDebugReportCallbackCreateInfoEXT *pCreateInfo,
    110                                                                        const VkAllocationCallbacks *pAllocator,
    111                                                                        VkDebugReportCallbackEXT *pCallback);
    112 
    113 VKAPI_ATTR void VKAPI_CALL terminator_DestroyDebugReportCallbackEXT(VkInstance instance, VkDebugReportCallbackEXT callback,
    114                                                                     const VkAllocationCallbacks *pAllocator);
    115 
    116 VKAPI_ATTR void VKAPI_CALL terminator_DebugReportMessageEXT(VkInstance instance, VkDebugReportFlagsEXT flags,
    117                                                             VkDebugReportObjectTypeEXT objType, uint64_t object, size_t location,
    118                                                             int32_t msgCode, const char *pLayerPrefix, const char *pMsg);
    119 
    120 VkResult util_CreateDebugReportCallback(struct loader_instance *inst, VkDebugReportCallbackCreateInfoEXT *pCreateInfo,
    121                                         const VkAllocationCallbacks *pAllocator, VkDebugReportCallbackEXT callback);
    122 
    123 void util_DestroyDebugReportCallback(struct loader_instance *inst, VkDebugReportCallbackEXT callback,
    124                                      const VkAllocationCallbacks *pAllocator);
    125 
    126 VkResult util_CopyDebugReportCreateInfos(const void *pChain, const VkAllocationCallbacks *pAllocator, uint32_t *num_callbacks,
    127                                          VkDebugReportCallbackCreateInfoEXT **infos, VkDebugReportCallbackEXT **callbacks);
    128 void util_FreeDebugReportCreateInfos(const VkAllocationCallbacks *pAllocator, VkDebugReportCallbackCreateInfoEXT *infos,
    129                                      VkDebugReportCallbackEXT *callbacks);
    130 VkResult util_CreateDebugReportCallbacks(struct loader_instance *inst, const VkAllocationCallbacks *pAllocator,
    131                                          uint32_t num_callbacks, VkDebugReportCallbackCreateInfoEXT *infos,
    132                                          VkDebugReportCallbackEXT *callbacks);
    133 
    134 void util_DestroyDebugReportCallbacks(struct loader_instance *inst, const VkAllocationCallbacks *pAllocator, uint32_t num_callbacks,
    135                                       VkDebugReportCallbackEXT *callbacks);
    136 
    137 VkBool32 util_DebugReportMessage(const struct loader_instance *inst, VkFlags msgFlags, VkDebugReportObjectTypeEXT objectType,
    138                                  uint64_t srcObject, size_t location, int32_t msgCode, const char *pLayerPrefix, const char *pMsg);
    139