Home | History | Annotate | Download | only in loader
      1 /*
      2  *
      3  * Copyright (c) 2014-2016 The Khronos Group Inc.
      4  * Copyright (c) 2014-2016 Valve Corporation
      5  * Copyright (c) 2014-2016 LunarG, Inc.
      6  * Copyright (C) 2015 Google Inc.
      7  *
      8  * Licensed under the Apache License, Version 2.0 (the "License");
      9  * you may not use this file except in compliance with the License.
     10  * You may obtain a copy of the License at
     11  *
     12  *     http://www.apache.org/licenses/LICENSE-2.0
     13  *
     14  * Unless required by applicable law or agreed to in writing, software
     15  * distributed under the License is distributed on an "AS IS" BASIS,
     16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     17  * See the License for the specific language governing permissions and
     18  * limitations under the License.
     19  *
     20  * Author: Jon Ashburn <jon (at) lunarg.com>
     21  * Author: Courtney Goeltzenleuchter <courtney (at) LunarG.com>
     22  * Author: Chia-I Wu <olvaffe (at) gmail.com>
     23  * Author: Chia-I Wu <olv (at) lunarg.com>
     24  * Author: Mark Lobodzinski <mark (at) LunarG.com>
     25  *
     26  */
     27 
     28 #ifndef LOADER_H
     29 #define LOADER_H
     30 
     31 #include <vulkan/vulkan.h>
     32 #include "vk_loader_platform.h"
     33 #include "vk_loader_layer.h"
     34 #include <vulkan/vk_layer.h>
     35 
     36 #include <vulkan/vk_icd.h>
     37 #include <assert.h>
     38 
     39 #if defined(__GNUC__) && __GNUC__ >= 4
     40 #define LOADER_EXPORT __attribute__((visibility("default")))
     41 #elif defined(__SUNPRO_C) && (__SUNPRO_C >= 0x590)
     42 #define LOADER_EXPORT __attribute__((visibility("default")))
     43 #else
     44 #define LOADER_EXPORT
     45 #endif
     46 
     47 // A debug option to disable allocators at compile time to investigate future issues.
     48 #define DEBUG_DISABLE_APP_ALLOCATORS 0
     49 
     50 #define MAX_STRING_SIZE 1024
     51 #define VK_MAJOR(version) (version >> 22)
     52 #define VK_MINOR(version) ((version >> 12) & 0x3ff)
     53 #define VK_PATCH(version) (version & 0xfff)
     54 
     55 enum layer_type {
     56     VK_LAYER_TYPE_INSTANCE_EXPLICIT = 0x1,
     57     VK_LAYER_TYPE_INSTANCE_IMPLICIT = 0x2,
     58     VK_LAYER_TYPE_META_EXPLICT = 0x4,
     59 };
     60 
     61 typedef enum VkStringErrorFlagBits {
     62     VK_STRING_ERROR_NONE = 0x00000000,
     63     VK_STRING_ERROR_LENGTH = 0x00000001,
     64     VK_STRING_ERROR_BAD_DATA = 0x00000002,
     65 } VkStringErrorFlagBits;
     66 typedef VkFlags VkStringErrorFlags;
     67 
     68 static const int MaxLoaderStringLength = 256;
     69 static const char UTF8_ONE_BYTE_CODE = 0xC0;
     70 static const char UTF8_ONE_BYTE_MASK = 0xE0;
     71 static const char UTF8_TWO_BYTE_CODE = 0xE0;
     72 static const char UTF8_TWO_BYTE_MASK = 0xF0;
     73 static const char UTF8_THREE_BYTE_CODE = 0xF0;
     74 static const char UTF8_THREE_BYTE_MASK = 0xF8;
     75 static const char UTF8_DATA_BYTE_CODE = 0x80;
     76 static const char UTF8_DATA_BYTE_MASK = 0xC0;
     77 
     78 static const char std_validation_names[7][VK_MAX_EXTENSION_NAME_SIZE] = {
     79     "VK_LAYER_GOOGLE_threading",       "VK_LAYER_LUNARG_parameter_validation",
     80     "VK_LAYER_LUNARG_object_tracker",  "VK_LAYER_LUNARG_image",
     81     "VK_LAYER_LUNARG_core_validation", "VK_LAYER_LUNARG_swapchain",
     82      "VK_LAYER_GOOGLE_unique_objects"};
     83 
     84 // form of all dynamic lists/arrays
     85 // only the list element should be changed
     86 struct loader_generic_list {
     87     size_t capacity;
     88     uint32_t count;
     89     void *list;
     90 };
     91 
     92 struct loader_extension_list {
     93     size_t capacity;
     94     uint32_t count;
     95     VkExtensionProperties *list;
     96 };
     97 
     98 struct loader_dev_ext_props {
     99     VkExtensionProperties props;
    100     uint32_t entrypoint_count;
    101     char **entrypoints;
    102 };
    103 
    104 struct loader_device_extension_list {
    105     size_t capacity;
    106     uint32_t count;
    107     struct loader_dev_ext_props *list;
    108 };
    109 
    110 struct loader_name_value {
    111     char name[MAX_STRING_SIZE];
    112     char value[MAX_STRING_SIZE];
    113 };
    114 
    115 struct loader_layer_functions {
    116     char str_gipa[MAX_STRING_SIZE];
    117     char str_gdpa[MAX_STRING_SIZE];
    118     PFN_vkGetInstanceProcAddr get_instance_proc_addr;
    119     PFN_vkGetDeviceProcAddr get_device_proc_addr;
    120 };
    121 
    122 struct loader_layer_properties {
    123     VkLayerProperties info;
    124     enum layer_type type;
    125     char lib_name[MAX_STRING_SIZE];
    126     loader_platform_dl_handle lib_handle;
    127     struct loader_layer_functions functions;
    128     struct loader_extension_list instance_extension_list;
    129     struct loader_device_extension_list device_extension_list;
    130     struct loader_name_value disable_env_var;
    131     struct loader_name_value enable_env_var;
    132 };
    133 
    134 struct loader_layer_list {
    135     size_t capacity;
    136     uint32_t count;
    137     struct loader_layer_properties *list;
    138 };
    139 
    140 struct loader_dispatch_hash_list {
    141     size_t capacity;
    142     uint32_t count;
    143     uint32_t *index; // index into the dev_ext dispatch table
    144 };
    145 
    146 #define MAX_NUM_DEV_EXTS 250
    147 // loader_dispatch_hash_entry and loader_dev_ext_dispatch_table.dev_ext have
    148 // one to one correspondence; one loader_dispatch_hash_entry for one dev_ext
    149 // dispatch entry.
    150 // Also have a one to one correspondence with functions in dev_ext_trampoline.c
    151 struct loader_dispatch_hash_entry {
    152     char *func_name;
    153     struct loader_dispatch_hash_list list; // to handle hashing collisions
    154 };
    155 
    156 typedef void(VKAPI_PTR *PFN_vkDevExt)(VkDevice device);
    157 struct loader_dev_ext_dispatch_table {
    158     PFN_vkDevExt dev_ext[MAX_NUM_DEV_EXTS];
    159 };
    160 
    161 struct loader_dev_dispatch_table {
    162     VkLayerDispatchTable core_dispatch;
    163     struct loader_dev_ext_dispatch_table ext_dispatch;
    164 };
    165 
    166 // per CreateDevice structure
    167 struct loader_device {
    168     struct loader_dev_dispatch_table loader_dispatch;
    169     VkDevice device; // device object from the icd
    170 
    171     struct loader_layer_list activated_layer_list;
    172 
    173     VkAllocationCallbacks alloc_callbacks;
    174 
    175     struct loader_device *next;
    176 };
    177 
    178 /* per ICD structure */
    179 struct loader_icd {
    180     // pointers to find other structs
    181     const struct loader_scanned_icds *this_icd_lib;
    182     const struct loader_instance *this_instance;
    183     struct loader_device *logical_device_list;
    184     VkInstance instance; // instance object from the icd
    185     PFN_vkGetDeviceProcAddr GetDeviceProcAddr;
    186     PFN_vkDestroyInstance DestroyInstance;
    187     PFN_vkEnumeratePhysicalDevices EnumeratePhysicalDevices;
    188     PFN_vkGetPhysicalDeviceFeatures GetPhysicalDeviceFeatures;
    189     PFN_vkGetPhysicalDeviceFormatProperties GetPhysicalDeviceFormatProperties;
    190     PFN_vkGetPhysicalDeviceImageFormatProperties
    191         GetPhysicalDeviceImageFormatProperties;
    192     PFN_vkCreateDevice CreateDevice;
    193     PFN_vkGetPhysicalDeviceProperties GetPhysicalDeviceProperties;
    194     PFN_vkGetPhysicalDeviceQueueFamilyProperties
    195         GetPhysicalDeviceQueueFamilyProperties;
    196     PFN_vkGetPhysicalDeviceMemoryProperties GetPhysicalDeviceMemoryProperties;
    197     PFN_vkEnumerateDeviceExtensionProperties EnumerateDeviceExtensionProperties;
    198     PFN_vkGetPhysicalDeviceSparseImageFormatProperties
    199         GetPhysicalDeviceSparseImageFormatProperties;
    200     PFN_vkCreateDebugReportCallbackEXT CreateDebugReportCallbackEXT;
    201     PFN_vkDestroyDebugReportCallbackEXT DestroyDebugReportCallbackEXT;
    202     PFN_vkDebugReportMessageEXT DebugReportMessageEXT;
    203     PFN_vkGetPhysicalDeviceSurfaceSupportKHR GetPhysicalDeviceSurfaceSupportKHR;
    204     PFN_vkGetPhysicalDeviceSurfaceCapabilitiesKHR
    205         GetPhysicalDeviceSurfaceCapabilitiesKHR;
    206     PFN_vkGetPhysicalDeviceSurfaceFormatsKHR GetPhysicalDeviceSurfaceFormatsKHR;
    207     PFN_vkGetPhysicalDeviceSurfacePresentModesKHR
    208         GetPhysicalDeviceSurfacePresentModesKHR;
    209     PFN_vkGetPhysicalDeviceExternalImageFormatPropertiesNV
    210         GetPhysicalDeviceExternalImageFormatPropertiesNV;
    211 #ifdef VK_USE_PLATFORM_WIN32_KHR
    212     PFN_vkCreateWin32SurfaceKHR CreateWin32SurfaceKHR;
    213     PFN_vkGetPhysicalDeviceWin32PresentationSupportKHR
    214         GetPhysicalDeviceWin32PresentationSupportKHR;
    215 #endif
    216 #ifdef VK_USE_PLATFORM_MIR_KHR
    217     PFN_vkCreateMirSurfaceKHR CreateMirSurfaceKHR;
    218     PFN_vkGetPhysicalDeviceMirPresentationSupportKHR
    219         GetPhysicalDeviceMirPresentationSupportKHR;
    220 #endif
    221 #ifdef VK_USE_PLATFORM_WAYLAND_KHR
    222     PFN_vkCreateWaylandSurfaceKHR CreateWaylandSurfaceKHR;
    223     PFN_vkGetPhysicalDeviceWaylandPresentationSupportKHR
    224         GetPhysicalDeviceWaylandPresentationSupportKHR;
    225 #endif
    226 #ifdef VK_USE_PLATFORM_XCB_KHR
    227     PFN_vkCreateXcbSurfaceKHR CreateXcbSurfaceKHR;
    228     PFN_vkGetPhysicalDeviceXcbPresentationSupportKHR
    229         GetPhysicalDeviceXcbPresentationSupportKHR;
    230 #endif
    231 #ifdef VK_USE_PLATFORM_XLIB_KHR
    232     PFN_vkCreateXlibSurfaceKHR CreateXlibSurfaceKHR;
    233     PFN_vkGetPhysicalDeviceXlibPresentationSupportKHR
    234         GetPhysicalDeviceXlibPresentationSupportKHR;
    235 #endif
    236     PFN_vkGetPhysicalDeviceDisplayPropertiesKHR
    237         GetPhysicalDeviceDisplayPropertiesKHR;
    238     PFN_vkGetPhysicalDeviceDisplayPlanePropertiesKHR
    239         GetPhysicalDeviceDisplayPlanePropertiesKHR;
    240     PFN_vkGetDisplayPlaneSupportedDisplaysKHR
    241         GetDisplayPlaneSupportedDisplaysKHR;
    242     PFN_vkGetDisplayModePropertiesKHR GetDisplayModePropertiesKHR;
    243     PFN_vkCreateDisplayModeKHR CreateDisplayModeKHR;
    244     PFN_vkGetDisplayPlaneCapabilitiesKHR GetDisplayPlaneCapabilitiesKHR;
    245     PFN_vkCreateDisplayPlaneSurfaceKHR CreateDisplayPlaneSurfaceKHR;
    246     PFN_vkDestroySurfaceKHR DestroySurfaceKHR;
    247     PFN_vkCreateSwapchainKHR CreateSwapchainKHR;
    248     struct loader_icd *next;
    249 };
    250 
    251 // per ICD library structure
    252 struct loader_icd_libs {
    253     size_t capacity;
    254     uint32_t count;
    255     struct loader_scanned_icds *list;
    256 };
    257 
    258 union loader_instance_extension_enables {
    259     struct {
    260         uint8_t ext_debug_report                : 1;
    261         uint8_t nv_external_memory_capabilities : 1;
    262     };
    263     uint64_t padding[4];
    264 };
    265 
    266 // per instance structure
    267 struct loader_instance {
    268     VkLayerInstanceDispatchTable *disp; // must be first entry in structure
    269 
    270     uint32_t total_gpu_count; // count of the next two arrays
    271     struct loader_physical_device *phys_devs_term;
    272     struct loader_physical_device_tramp *
    273         phys_devs; // tramp wrapped physDev obj list
    274     uint32_t total_icd_count;
    275     struct loader_icd *icds;
    276     struct loader_instance *next;
    277     struct loader_extension_list ext_list; // icds and loaders extensions
    278     union loader_instance_extension_enables enabled_known_extensions;
    279     struct loader_icd_libs icd_libs;
    280     struct loader_layer_list instance_layer_list;
    281     struct loader_dispatch_hash_entry disp_hash[MAX_NUM_DEV_EXTS];
    282 
    283     struct loader_msg_callback_map_entry *icd_msg_callback_map;
    284 
    285     struct loader_layer_list activated_layer_list;
    286     bool activated_layers_are_std_val;
    287     VkInstance instance; // layers/ICD instance returned to trampoline
    288 
    289     VkLayerDbgFunctionNode *DbgFunctionHead;
    290     uint32_t num_tmp_callbacks;
    291     VkDebugReportCallbackCreateInfoEXT *tmp_dbg_create_infos;
    292     VkDebugReportCallbackEXT *tmp_callbacks;
    293 
    294     VkAllocationCallbacks alloc_callbacks;
    295 
    296     bool wsi_surface_enabled;
    297 #ifdef VK_USE_PLATFORM_WIN32_KHR
    298     bool wsi_win32_surface_enabled;
    299 #endif
    300 #ifdef VK_USE_PLATFORM_MIR_KHR
    301     bool wsi_mir_surface_enabled;
    302 #endif
    303 #ifdef VK_USE_PLATFORM_WAYLAND_KHR
    304     bool wsi_wayland_surface_enabled;
    305 #endif
    306 #ifdef VK_USE_PLATFORM_XCB_KHR
    307     bool wsi_xcb_surface_enabled;
    308 #endif
    309 #ifdef VK_USE_PLATFORM_XLIB_KHR
    310     bool wsi_xlib_surface_enabled;
    311 #endif
    312 #ifdef VK_USE_PLATFORM_ANDROID_KHR
    313     bool wsi_android_surface_enabled;
    314 #endif
    315     bool wsi_display_enabled;
    316 };
    317 
    318 /* VkPhysicalDevice requires special treatment by loader.  Firstly, terminator
    319  * code must be able to get the struct loader_icd  to call into the proper
    320  * driver  (multiple ICD/gpu case). This can be accomplished by wrapping the
    321  * created VkPhysicalDevice in loader terminate_EnumeratePhysicalDevices().
    322  * Secondly, the loader must be able to handle wrapped by layer VkPhysicalDevice
    323  * in trampoline code.  This implies, that the loader trampoline code must also
    324  * wrap the VkPhysicalDevice object in trampoline code.  Thus, loader has to
    325  * wrap the VkPhysicalDevice created object twice. In trampoline code it can't
    326  * rely on the terminator object wrapping since a layer may also wrap. Since
    327  * trampoline code wraps the VkPhysicalDevice this means all loader trampoline
    328  * code that passes a VkPhysicalDevice should unwrap it. */
    329 
    330 /* per enumerated PhysicalDevice structure, used to wrap in trampoline code and
    331    also same structure used to wrap in terminator code */
    332 struct loader_physical_device_tramp {
    333     VkLayerInstanceDispatchTable *disp; // must be first entry in structure
    334     struct loader_instance *this_instance;
    335     VkPhysicalDevice phys_dev; // object from layers/loader terminator
    336 };
    337 
    338 /* per enumerated PhysicalDevice structure, used to wrap in terminator code */
    339 struct loader_physical_device {
    340     VkLayerInstanceDispatchTable *disp; // must be first entry in structure
    341     struct loader_icd *this_icd;
    342     uint8_t icd_index;
    343     VkPhysicalDevice phys_dev; // object from ICD
    344 };
    345 
    346 struct loader_struct {
    347     struct loader_instance *instances;
    348 };
    349 
    350 struct loader_scanned_icds {
    351     char *lib_name;
    352     loader_platform_dl_handle handle;
    353     uint32_t api_version;
    354     uint32_t interface_version;
    355     PFN_vkGetInstanceProcAddr GetInstanceProcAddr;
    356     PFN_vkCreateInstance CreateInstance;
    357     PFN_vkEnumerateInstanceExtensionProperties
    358         EnumerateInstanceExtensionProperties;
    359 };
    360 
    361 static inline struct loader_instance *loader_instance(VkInstance instance) {
    362     return (struct loader_instance *)instance;
    363 }
    364 
    365 static inline VkPhysicalDevice
    366 loader_unwrap_physical_device(VkPhysicalDevice physicalDevice) {
    367     struct loader_physical_device_tramp *phys_dev =
    368         (struct loader_physical_device_tramp *)physicalDevice;
    369     return phys_dev->phys_dev;
    370 }
    371 
    372 static inline void loader_set_dispatch(void *obj, const void *data) {
    373     *((const void **)obj) = data;
    374 }
    375 
    376 static inline VkLayerDispatchTable *loader_get_dispatch(const void *obj) {
    377     return *((VkLayerDispatchTable **)obj);
    378 }
    379 
    380 static inline struct loader_dev_dispatch_table *
    381 loader_get_dev_dispatch(const void *obj) {
    382     return *((struct loader_dev_dispatch_table **)obj);
    383 }
    384 
    385 static inline VkLayerInstanceDispatchTable *
    386 loader_get_instance_dispatch(const void *obj) {
    387     return *((VkLayerInstanceDispatchTable **)obj);
    388 }
    389 
    390 static inline void loader_init_dispatch(void *obj, const void *data) {
    391 #ifdef DEBUG
    392     assert(valid_loader_magic_value(obj) &&
    393            "Incompatible ICD, first dword must be initialized to "
    394            "ICD_LOADER_MAGIC. See loader/README.md for details.");
    395 #endif
    396 
    397     loader_set_dispatch(obj, data);
    398 }
    399 
    400 /* global variables used across files */
    401 extern struct loader_struct loader;
    402 extern THREAD_LOCAL_DECL struct loader_instance *tls_instance;
    403 extern LOADER_PLATFORM_THREAD_ONCE_DEFINITION(once_init);
    404 extern loader_platform_thread_mutex loader_lock;
    405 extern loader_platform_thread_mutex loader_json_lock;
    406 extern const VkLayerInstanceDispatchTable instance_disp;
    407 extern const char *std_validation_str;
    408 
    409 struct loader_msg_callback_map_entry {
    410     VkDebugReportCallbackEXT icd_obj;
    411     VkDebugReportCallbackEXT loader_obj;
    412 };
    413 
    414 /* helper function definitions */
    415 void *loader_instance_heap_alloc(const struct loader_instance *instance, size_t size, VkSystemAllocationScope allocationScope);
    416 void loader_instance_heap_free(const struct loader_instance *instance, void *pMemory);
    417 void *loader_instance_heap_realloc(const struct loader_instance *instance, void *pMemory, size_t orig_size, size_t size, VkSystemAllocationScope alloc_scope);
    418 void *loader_instance_tls_heap_alloc(size_t size);
    419 void loader_instance_tls_heap_free(void *pMemory);
    420 void *loader_device_heap_alloc(const struct loader_device *device, size_t size, VkSystemAllocationScope allocationScope);
    421 void loader_device_heap_free(const struct loader_device *device, void *pMemory);
    422 void *loader_device_heap_realloc(const struct loader_device *device, void *pMemory, size_t orig_size, size_t size, VkSystemAllocationScope alloc_scope);
    423 
    424 void loader_log(const struct loader_instance *inst, VkFlags msg_type,
    425                 int32_t msg_code, const char *format, ...);
    426 
    427 bool compare_vk_extension_properties(const VkExtensionProperties *op1,
    428                                      const VkExtensionProperties *op2);
    429 
    430 VkResult loader_validate_layers(const struct loader_instance *inst,
    431                                 const uint32_t layer_count,
    432                                 const char *const *ppEnabledLayerNames,
    433                                 const struct loader_layer_list *list);
    434 
    435 VkResult loader_validate_instance_extensions(
    436     const struct loader_instance *inst,
    437     const struct loader_extension_list *icd_exts,
    438     const struct loader_layer_list *instance_layer,
    439     const VkInstanceCreateInfo *pCreateInfo);
    440 
    441 void loader_initialize(void);
    442 VkResult loader_copy_layer_properties(const struct loader_instance *inst,
    443                                       struct loader_layer_properties *dst,
    444                                       struct loader_layer_properties *src);
    445 bool has_vk_extension_property_array(const VkExtensionProperties *vk_ext_prop,
    446                                      const uint32_t count,
    447                                      const VkExtensionProperties *ext_array);
    448 bool has_vk_extension_property(const VkExtensionProperties *vk_ext_prop,
    449                                const struct loader_extension_list *ext_list);
    450 
    451 VkResult loader_add_to_ext_list(const struct loader_instance *inst,
    452                                 struct loader_extension_list *ext_list,
    453                                 uint32_t prop_list_count,
    454                                 const VkExtensionProperties *props);
    455 VkResult
    456 loader_add_to_dev_ext_list(const struct loader_instance *inst,
    457                            struct loader_device_extension_list *ext_list,
    458                            const VkExtensionProperties *props,
    459                            uint32_t entry_count, char **entrys);
    460 VkResult loader_add_device_extensions(const struct loader_instance *inst,
    461                                       PFN_vkEnumerateDeviceExtensionProperties
    462                                           fpEnumerateDeviceExtensionProperties,
    463                                       VkPhysicalDevice physical_device,
    464                                       const char *lib_name,
    465                                       struct loader_extension_list *ext_list);
    466 VkResult loader_init_generic_list(const struct loader_instance *inst,
    467                                   struct loader_generic_list *list_info,
    468                                   size_t element_size);
    469 void loader_destroy_generic_list(const struct loader_instance *inst,
    470                                  struct loader_generic_list *list);
    471 void loader_destroy_layer_list(const struct loader_instance *inst,
    472                                struct loader_device *device,
    473                                struct loader_layer_list *layer_list);
    474 void loader_delete_layer_properties(const struct loader_instance *inst,
    475                                     struct loader_layer_list *layer_list);
    476 bool loader_find_layer_name_array(const char *name, uint32_t layer_count,
    477                         const char layer_list[][VK_MAX_EXTENSION_NAME_SIZE]);
    478 VkResult loader_expand_layer_names(
    479     struct loader_instance *inst, const char *key_name,
    480     uint32_t expand_count,
    481     const char expand_names[][VK_MAX_EXTENSION_NAME_SIZE],
    482     uint32_t *layer_count, char const *const **ppp_layer_names);
    483 void loader_init_std_validation_props(struct loader_layer_properties *props);
    484 void loader_delete_shadow_dev_layer_names(const struct loader_instance *inst,
    485                                           const VkDeviceCreateInfo *orig,
    486                                           VkDeviceCreateInfo *ours);
    487 void loader_delete_shadow_inst_layer_names(const struct loader_instance *inst,
    488                                            const VkInstanceCreateInfo *orig,
    489                                            VkInstanceCreateInfo *ours);
    490 VkResult loader_add_to_layer_list(const struct loader_instance *inst,
    491                                   struct loader_layer_list *list,
    492                                   uint32_t prop_list_count,
    493                                   const struct loader_layer_properties *props);
    494 void loader_find_layer_name_add_list(
    495     const struct loader_instance *inst, const char *name,
    496     const enum layer_type type, const struct loader_layer_list *search_list,
    497     struct loader_layer_list *found_list);
    498 void loader_scanned_icd_clear(const struct loader_instance *inst,
    499                               struct loader_icd_libs *icd_libs);
    500 VkResult loader_icd_scan(const struct loader_instance *inst,
    501                      struct loader_icd_libs *icds);
    502 void loader_layer_scan(const struct loader_instance *inst,
    503                        struct loader_layer_list *instance_layers);
    504 void loader_implicit_layer_scan(const struct loader_instance *inst,
    505                                 struct loader_layer_list *instance_layers);
    506 VkResult loader_get_icd_loader_instance_extensions(
    507     const struct loader_instance *inst, struct loader_icd_libs *icd_libs,
    508     struct loader_extension_list *inst_exts);
    509 struct loader_icd *loader_get_icd_and_device(const VkDevice device,
    510                                              struct loader_device **found_dev,
    511                                              uint32_t *icd_index);
    512 void loader_init_dispatch_dev_ext(struct loader_instance *inst,
    513                                   struct loader_device *dev);
    514 void *loader_dev_ext_gpa(struct loader_instance *inst, const char *funcName);
    515 void *loader_get_dev_ext_trampoline(uint32_t index);
    516 void loader_override_terminating_device_proc(VkDevice device, struct loader_dev_dispatch_table *disp_table);
    517 struct loader_instance *loader_get_instance(const VkInstance instance);
    518 void loader_deactivate_layers(const struct loader_instance *instance,
    519                               struct loader_device *device,
    520                               struct loader_layer_list *list);
    521 struct loader_device *
    522 loader_create_logical_device(const struct loader_instance *inst, const VkAllocationCallbacks *pAllocator);
    523 void loader_add_logical_device(const struct loader_instance *inst,
    524                                struct loader_icd *icd,
    525                                struct loader_device *found_dev);
    526 void loader_remove_logical_device(const struct loader_instance *inst,
    527                                   struct loader_icd *icd,
    528                                   struct loader_device *found_dev,
    529                                   const VkAllocationCallbacks *pAllocator);
    530 // NOTE: Outside of loader, this entry-point is only proivided for error cleanup.
    531 void loader_destroy_logical_device(const struct loader_instance *inst,
    532                                    struct loader_device *dev,
    533                                    const VkAllocationCallbacks *pAllocator);
    534 
    535 VkResult
    536 loader_enable_instance_layers(struct loader_instance *inst,
    537                               const VkInstanceCreateInfo *pCreateInfo,
    538                               const struct loader_layer_list *instance_layers);
    539 void loader_deactivate_instance_layers(struct loader_instance *instance);
    540 
    541 VkResult loader_create_instance_chain(const VkInstanceCreateInfo *pCreateInfo,
    542                                       const VkAllocationCallbacks *pAllocator,
    543                                       struct loader_instance *inst,
    544                                       VkInstance *created_instance);
    545 
    546 void loader_activate_instance_layer_extensions(struct loader_instance *inst,
    547                                                VkInstance created_inst);
    548 VkResult
    549 loader_enable_device_layers(const struct loader_instance *inst,
    550                             struct loader_layer_list *activated_layer_list,
    551                             const VkDeviceCreateInfo *pCreateInfo,
    552                             const struct loader_layer_list *device_layers);
    553 
    554 VkResult
    555 loader_create_device_chain(const struct loader_physical_device_tramp *pd,
    556                            const VkDeviceCreateInfo *pCreateInfo,
    557                            const VkAllocationCallbacks *pAllocator,
    558                            const struct loader_instance *inst,
    559                            struct loader_device *dev);
    560 VkResult loader_validate_device_extensions(
    561     struct loader_physical_device_tramp *phys_dev,
    562     const struct loader_layer_list *activated_device_layers,
    563     const struct loader_extension_list *icd_exts,
    564     const VkDeviceCreateInfo *pCreateInfo);
    565 
    566 /* instance layer chain termination entrypoint definitions */
    567 VKAPI_ATTR VkResult VKAPI_CALL
    568 terminator_CreateInstance(const VkInstanceCreateInfo *pCreateInfo,
    569                           const VkAllocationCallbacks *pAllocator,
    570                           VkInstance *pInstance);
    571 
    572 VKAPI_ATTR void VKAPI_CALL
    573 terminator_DestroyInstance(VkInstance instance,
    574                            const VkAllocationCallbacks *pAllocator);
    575 
    576 VKAPI_ATTR VkResult VKAPI_CALL
    577 terminator_EnumeratePhysicalDevices(VkInstance instance,
    578                                     uint32_t *pPhysicalDeviceCount,
    579                                     VkPhysicalDevice *pPhysicalDevices);
    580 
    581 VKAPI_ATTR void VKAPI_CALL
    582 terminator_GetPhysicalDeviceFeatures(VkPhysicalDevice physicalDevice,
    583                                      VkPhysicalDeviceFeatures *pFeatures);
    584 
    585 VKAPI_ATTR void VKAPI_CALL
    586 terminator_GetPhysicalDeviceFormatProperties(VkPhysicalDevice physicalDevice,
    587                                              VkFormat format,
    588                                              VkFormatProperties *pFormatInfo);
    589 
    590 VKAPI_ATTR VkResult VKAPI_CALL
    591 terminator_GetPhysicalDeviceImageFormatProperties(
    592     VkPhysicalDevice physicalDevice, VkFormat format, VkImageType type,
    593     VkImageTiling tiling, VkImageUsageFlags usage, VkImageCreateFlags flags,
    594     VkImageFormatProperties *pImageFormatProperties);
    595 
    596 VKAPI_ATTR void VKAPI_CALL
    597 terminator_GetPhysicalDeviceSparseImageFormatProperties(
    598     VkPhysicalDevice physicalDevice, VkFormat format, VkImageType type,
    599     VkSampleCountFlagBits samples, VkImageUsageFlags usage,
    600     VkImageTiling tiling, uint32_t *pNumProperties,
    601     VkSparseImageFormatProperties *pProperties);
    602 
    603 VKAPI_ATTR void VKAPI_CALL
    604 terminator_GetPhysicalDeviceProperties(VkPhysicalDevice physicalDevice,
    605                                        VkPhysicalDeviceProperties *pProperties);
    606 
    607 VKAPI_ATTR VkResult VKAPI_CALL terminator_EnumerateDeviceExtensionProperties(
    608     VkPhysicalDevice physicalDevice, const char *pLayerName, uint32_t *pCount,
    609     VkExtensionProperties *pProperties);
    610 
    611 VKAPI_ATTR VkResult VKAPI_CALL
    612 terminator_EnumerateDeviceLayerProperties(VkPhysicalDevice physicalDevice,
    613                                           uint32_t *pCount,
    614                                           VkLayerProperties *pProperties);
    615 
    616 VKAPI_ATTR void VKAPI_CALL terminator_GetPhysicalDeviceQueueFamilyProperties(
    617     VkPhysicalDevice physicalDevice, uint32_t *pCount,
    618     VkQueueFamilyProperties *pProperties);
    619 
    620 VKAPI_ATTR void VKAPI_CALL terminator_GetPhysicalDeviceMemoryProperties(
    621     VkPhysicalDevice physicalDevice,
    622     VkPhysicalDeviceMemoryProperties *pProperties);
    623 
    624 VKAPI_ATTR VkResult VKAPI_CALL
    625 terminator_CreateDevice(VkPhysicalDevice gpu,
    626                         const VkDeviceCreateInfo *pCreateInfo,
    627                         const VkAllocationCallbacks *pAllocator,
    628                         VkDevice *pDevice);
    629 
    630 VkStringErrorFlags vk_string_validate(const int max_length,
    631                                       const char *char_array);
    632 
    633 #endif /* LOADER_H */
    634