Home | History | Annotate | Download | only in loader
      1 /*
      2  *
      3  * Copyright (c) 2014-2017 The Khronos Group Inc.
      4  * Copyright (c) 2014-2017 Valve Corporation
      5  * Copyright (c) 2014-2017 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 #include <vulkan/vk_icd.h>
     36 #include <assert.h>
     37 #include "vk_loader_extensions.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 
     52 // This is defined in vk_layer.h, but if there's problems we need to create the define
     53 // here.
     54 #ifndef MAX_NUM_UNKNOWN_EXTS
     55 #define MAX_NUM_UNKNOWN_EXTS 250
     56 #endif
     57 
     58 enum layer_type_flags {
     59     VK_LAYER_TYPE_FLAG_INSTANCE_LAYER = 0x1,  // If not set, indicates Device layer
     60     VK_LAYER_TYPE_FLAG_EXPLICIT_LAYER = 0x2,  // If not set, indicates Implicit layer
     61     VK_LAYER_TYPE_FLAG_META_LAYER = 0x4,      // If not set, indicates standard layer
     62 };
     63 
     64 typedef enum VkStringErrorFlagBits {
     65     VK_STRING_ERROR_NONE = 0x00000000,
     66     VK_STRING_ERROR_LENGTH = 0x00000001,
     67     VK_STRING_ERROR_BAD_DATA = 0x00000002,
     68 } VkStringErrorFlagBits;
     69 typedef VkFlags VkStringErrorFlags;
     70 
     71 static const int MaxLoaderStringLength = 256;
     72 static const char UTF8_ONE_BYTE_CODE = 0xC0;
     73 static const char UTF8_ONE_BYTE_MASK = 0xE0;
     74 static const char UTF8_TWO_BYTE_CODE = 0xE0;
     75 static const char UTF8_TWO_BYTE_MASK = 0xF0;
     76 static const char UTF8_THREE_BYTE_CODE = 0xF0;
     77 static const char UTF8_THREE_BYTE_MASK = 0xF8;
     78 static const char UTF8_DATA_BYTE_CODE = 0x80;
     79 static const char UTF8_DATA_BYTE_MASK = 0xC0;
     80 
     81 struct VkStructureHeader {
     82     VkStructureType sType;
     83     const void *pNext;
     84 };
     85 
     86 // form of all dynamic lists/arrays
     87 // only the list element should be changed
     88 struct loader_generic_list {
     89     size_t capacity;
     90     uint32_t count;
     91     void *list;
     92 };
     93 
     94 struct loader_extension_list {
     95     size_t capacity;
     96     uint32_t count;
     97     VkExtensionProperties *list;
     98 };
     99 
    100 struct loader_dev_ext_props {
    101     VkExtensionProperties props;
    102     uint32_t entrypoint_count;
    103     char **entrypoints;
    104 };
    105 
    106 struct loader_device_extension_list {
    107     size_t capacity;
    108     uint32_t count;
    109     struct loader_dev_ext_props *list;
    110 };
    111 
    112 struct loader_name_value {
    113     char name[MAX_STRING_SIZE];
    114     char value[MAX_STRING_SIZE];
    115 };
    116 
    117 struct loader_layer_functions {
    118     char str_gipa[MAX_STRING_SIZE];
    119     char str_gdpa[MAX_STRING_SIZE];
    120     char str_negotiate_interface[MAX_STRING_SIZE];
    121     PFN_vkNegotiateLoaderLayerInterfaceVersion negotiate_layer_interface;
    122     PFN_vkGetInstanceProcAddr get_instance_proc_addr;
    123     PFN_vkGetDeviceProcAddr get_device_proc_addr;
    124     PFN_GetPhysicalDeviceProcAddr get_physical_device_proc_addr;
    125 };
    126 
    127 struct loader_layer_properties {
    128     VkLayerProperties info;
    129     enum layer_type_flags type_flags;
    130     uint32_t interface_version;  // PFN_vkNegotiateLoaderLayerInterfaceVersion
    131     char lib_name[MAX_STRING_SIZE];
    132     loader_platform_dl_handle lib_handle;
    133     struct loader_layer_functions functions;
    134     struct loader_extension_list instance_extension_list;
    135     struct loader_device_extension_list device_extension_list;
    136     struct loader_name_value disable_env_var;
    137     struct loader_name_value enable_env_var;
    138     uint32_t num_component_layers;
    139     char (*component_layer_names)[MAX_STRING_SIZE];
    140     struct {
    141         char enumerate_instance_extension_properties[MAX_STRING_SIZE];
    142         char enumerate_instance_layer_properties[MAX_STRING_SIZE];
    143     } pre_instance_functions;
    144 };
    145 
    146 struct loader_layer_list {
    147     size_t capacity;
    148     uint32_t count;
    149     struct loader_layer_properties *list;
    150 };
    151 
    152 struct loader_dispatch_hash_list {
    153     size_t capacity;
    154     uint32_t count;
    155     uint32_t *index;  // index into the dev_ext dispatch table
    156 };
    157 
    158 // loader_dispatch_hash_entry and loader_dev_ext_dispatch_table.dev_ext have
    159 // one to one correspondence; one loader_dispatch_hash_entry for one dev_ext
    160 // dispatch entry.
    161 // Also have a one to one correspondence with functions in dev_ext_trampoline.c
    162 struct loader_dispatch_hash_entry {
    163     char *func_name;
    164     struct loader_dispatch_hash_list list;  // to handle hashing collisions
    165 };
    166 
    167 typedef void(VKAPI_PTR *PFN_vkDevExt)(VkDevice device);
    168 struct loader_dev_ext_dispatch_table {
    169     PFN_vkDevExt dev_ext[MAX_NUM_UNKNOWN_EXTS];
    170 };
    171 
    172 struct loader_dev_dispatch_table {
    173     VkLayerDispatchTable core_dispatch;
    174     struct loader_dev_ext_dispatch_table ext_dispatch;
    175 };
    176 
    177 // per CreateDevice structure
    178 struct loader_device {
    179     struct loader_dev_dispatch_table loader_dispatch;
    180     VkDevice chain_device;  // device object from the dispatch chain
    181     VkDevice icd_device;    // device object from the icd
    182     struct loader_physical_device_term *phys_dev_term;
    183 
    184     // List of activated layers.
    185     //  app_      is the version based on exactly what the application asked for.
    186     //            This is what must be returned to the application on Enumerate calls.
    187     //  expanded_ is the version based on expanding meta-layers into their
    188     //            individual component layers.  This is what is used internally.
    189     struct loader_layer_list app_activated_layer_list;
    190     struct loader_layer_list expanded_activated_layer_list;
    191 
    192     VkAllocationCallbacks alloc_callbacks;
    193 
    194     struct loader_device *next;
    195 };
    196 
    197 // Per ICD information
    198 
    199 // Per ICD structure
    200 struct loader_icd_term {
    201     // pointers to find other structs
    202     const struct loader_scanned_icd *scanned_icd;
    203     const struct loader_instance *this_instance;
    204     struct loader_device *logical_device_list;
    205     VkInstance instance;  // instance object from the icd
    206     struct loader_icd_term_dispatch dispatch;
    207 
    208     struct loader_icd_term *next;
    209 
    210     PFN_PhysDevExt phys_dev_ext[MAX_NUM_UNKNOWN_EXTS];
    211 };
    212 
    213 // Per ICD library structure
    214 struct loader_icd_tramp_list {
    215     size_t capacity;
    216     uint32_t count;
    217     struct loader_scanned_icd *scanned_list;
    218 };
    219 
    220 struct loader_instance_dispatch_table {
    221     VkLayerInstanceDispatchTable layer_inst_disp;  // must be first entry in structure
    222 
    223     // Physical device functions unknown to the loader
    224     PFN_PhysDevExt phys_dev_ext[MAX_NUM_UNKNOWN_EXTS];
    225 };
    226 
    227 // Per instance structure
    228 struct loader_instance {
    229     struct loader_instance_dispatch_table *disp;  // must be first entry in structure
    230 
    231     // We need to manually track physical devices over time.  If the user
    232     // re-queries the information, we don't want to delete old data or
    233     // create new data unless necessary.
    234     uint32_t total_gpu_count;
    235     uint32_t phys_dev_count_term;
    236     struct loader_physical_device_term **phys_devs_term;
    237     uint32_t phys_dev_count_tramp;
    238     struct loader_physical_device_tramp **phys_devs_tramp;
    239 
    240     // We also need to manually track physical device groups, but we don't need
    241     // loader specific structures since we have that content in the physical
    242     // device stored internal to the public structures.
    243     uint32_t phys_dev_group_count_term;
    244     struct VkPhysicalDeviceGroupPropertiesKHX **phys_dev_groups_term;
    245     uint32_t phys_dev_group_count_tramp;
    246     struct VkPhysicalDeviceGroupPropertiesKHX **phys_dev_groups_tramp;
    247 
    248     struct loader_instance *next;
    249 
    250     uint32_t total_icd_count;
    251     struct loader_icd_term *icd_terms;
    252     struct loader_icd_tramp_list icd_tramp_list;
    253 
    254     struct loader_dispatch_hash_entry dev_ext_disp_hash[MAX_NUM_UNKNOWN_EXTS];
    255     struct loader_dispatch_hash_entry phys_dev_ext_disp_hash[MAX_NUM_UNKNOWN_EXTS];
    256 
    257     struct loader_msg_callback_map_entry *icd_msg_callback_map;
    258 
    259     struct loader_layer_list instance_layer_list;
    260 
    261     // List of activated layers.
    262     //  app_      is the version based on exactly what the application asked for.
    263     //            This is what must be returned to the application on Enumerate calls.
    264     //  expanded_ is the version based on expanding meta-layers into their
    265     //            individual component layers.  This is what is used internally.
    266     struct loader_layer_list app_activated_layer_list;
    267     struct loader_layer_list expanded_activated_layer_list;
    268 
    269     VkInstance instance;  // layers/ICD instance returned to trampoline
    270 
    271     struct loader_extension_list ext_list;  // icds and loaders extensions
    272     union loader_instance_extension_enables enabled_known_extensions;
    273 
    274     VkLayerDbgFunctionNode *DbgFunctionHead;
    275     uint32_t num_tmp_callbacks;
    276     VkDebugReportCallbackCreateInfoEXT *tmp_dbg_create_infos;
    277     VkDebugReportCallbackEXT *tmp_callbacks;
    278 
    279     VkAllocationCallbacks alloc_callbacks;
    280 
    281     bool wsi_surface_enabled;
    282 #ifdef VK_USE_PLATFORM_WIN32_KHR
    283     bool wsi_win32_surface_enabled;
    284 #endif
    285 #ifdef VK_USE_PLATFORM_MIR_KHR
    286     bool wsi_mir_surface_enabled;
    287 #endif
    288 #ifdef VK_USE_PLATFORM_WAYLAND_KHR
    289     bool wsi_wayland_surface_enabled;
    290 #endif
    291 #ifdef VK_USE_PLATFORM_XCB_KHR
    292     bool wsi_xcb_surface_enabled;
    293 #endif
    294 #ifdef VK_USE_PLATFORM_XLIB_KHR
    295     bool wsi_xlib_surface_enabled;
    296 #endif
    297 #ifdef VK_USE_PLATFORM_ANDROID_KHR
    298     bool wsi_android_surface_enabled;
    299 #endif
    300     bool wsi_display_enabled;
    301 };
    302 
    303 // VkPhysicalDevice requires special treatment by loader.  Firstly, terminator
    304 // code must be able to get the struct loader_icd_term to call into the proper
    305 // driver  (multiple ICD/gpu case). This can be accomplished by wrapping the
    306 // created VkPhysicalDevice in loader terminate_EnumeratePhysicalDevices().
    307 // Secondly, the loader must be able to handle wrapped by layer VkPhysicalDevice
    308 // in trampoline code.  This implies, that the loader trampoline code must also
    309 // wrap the VkPhysicalDevice object in trampoline code.  Thus, loader has to
    310 // wrap the VkPhysicalDevice created object twice. In trampoline code it can't
    311 // rely on the terminator object wrapping since a layer may also wrap. Since
    312 // trampoline code wraps the VkPhysicalDevice this means all loader trampoline
    313 // code that passes a VkPhysicalDevice should unwrap it.
    314 
    315 // Per enumerated PhysicalDevice structure, used to wrap in trampoline code and
    316 // also same structure used to wrap in terminator code
    317 struct loader_physical_device_tramp {
    318     struct loader_instance_dispatch_table *disp;  // must be first entry in structure
    319     struct loader_instance *this_instance;
    320     VkPhysicalDevice phys_dev;  // object from layers/loader terminator
    321 };
    322 
    323 // Per enumerated PhysicalDevice structure, used to wrap in terminator code
    324 struct loader_physical_device_term {
    325     struct loader_instance_dispatch_table *disp;  // must be first entry in structure
    326     struct loader_icd_term *this_icd_term;
    327     uint8_t icd_index;
    328     VkPhysicalDevice phys_dev;  // object from ICD
    329 };
    330 
    331 struct loader_struct {
    332     struct loader_instance *instances;
    333 };
    334 
    335 struct loader_scanned_icd {
    336     char *lib_name;
    337     loader_platform_dl_handle handle;
    338     uint32_t api_version;
    339     uint32_t interface_version;
    340     PFN_vkGetInstanceProcAddr GetInstanceProcAddr;
    341     PFN_GetPhysicalDeviceProcAddr GetPhysicalDeviceProcAddr;
    342     PFN_vkCreateInstance CreateInstance;
    343     PFN_vkEnumerateInstanceExtensionProperties EnumerateInstanceExtensionProperties;
    344 };
    345 
    346 static inline struct loader_instance *loader_instance(VkInstance instance) { return (struct loader_instance *)instance; }
    347 
    348 static inline VkPhysicalDevice loader_unwrap_physical_device(VkPhysicalDevice physicalDevice) {
    349     struct loader_physical_device_tramp *phys_dev = (struct loader_physical_device_tramp *)physicalDevice;
    350     return phys_dev->phys_dev;
    351 }
    352 
    353 static inline void loader_set_dispatch(void *obj, const void *data) { *((const void **)obj) = data; }
    354 
    355 static inline VkLayerDispatchTable *loader_get_dispatch(const void *obj) { return *((VkLayerDispatchTable **)obj); }
    356 
    357 static inline struct loader_dev_dispatch_table *loader_get_dev_dispatch(const void *obj) {
    358     return *((struct loader_dev_dispatch_table **)obj);
    359 }
    360 
    361 static inline VkLayerInstanceDispatchTable *loader_get_instance_layer_dispatch(const void *obj) {
    362     return *((VkLayerInstanceDispatchTable **)obj);
    363 }
    364 
    365 static inline struct loader_instance_dispatch_table *loader_get_instance_dispatch(const void *obj) {
    366     return *((struct loader_instance_dispatch_table **)obj);
    367 }
    368 
    369 static inline void loader_init_dispatch(void *obj, const void *data) {
    370 #ifdef DEBUG
    371     assert(valid_loader_magic_value(obj) &&
    372            "Incompatible ICD, first dword must be initialized to "
    373            "ICD_LOADER_MAGIC. See loader/README.md for details.");
    374 #endif
    375 
    376     loader_set_dispatch(obj, data);
    377 }
    378 
    379 // Global variables used across files
    380 extern struct loader_struct loader;
    381 extern THREAD_LOCAL_DECL struct loader_instance *tls_instance;
    382 #if defined(_WIN32) && !defined(LOADER_DYNAMIC_LIB)
    383 extern LOADER_PLATFORM_THREAD_ONCE_DEFINITION(once_init);
    384 #endif
    385 extern loader_platform_thread_mutex loader_lock;
    386 extern loader_platform_thread_mutex loader_json_lock;
    387 
    388 struct loader_msg_callback_map_entry {
    389     VkDebugReportCallbackEXT icd_obj;
    390     VkDebugReportCallbackEXT loader_obj;
    391 };
    392 
    393 // Helper function definitions
    394 void *loader_instance_heap_alloc(const struct loader_instance *instance, size_t size, VkSystemAllocationScope allocationScope);
    395 void loader_instance_heap_free(const struct loader_instance *instance, void *pMemory);
    396 void *loader_instance_heap_realloc(const struct loader_instance *instance, void *pMemory, size_t orig_size, size_t size,
    397                                    VkSystemAllocationScope alloc_scope);
    398 void *loader_instance_tls_heap_alloc(size_t size);
    399 void loader_instance_tls_heap_free(void *pMemory);
    400 void *loader_device_heap_alloc(const struct loader_device *device, size_t size, VkSystemAllocationScope allocationScope);
    401 void loader_device_heap_free(const struct loader_device *device, void *pMemory);
    402 void *loader_device_heap_realloc(const struct loader_device *device, void *pMemory, size_t orig_size, size_t size,
    403                                  VkSystemAllocationScope alloc_scope);
    404 
    405 void loader_log(const struct loader_instance *inst, VkFlags msg_type, int32_t msg_code, const char *format, ...);
    406 
    407 bool compare_vk_extension_properties(const VkExtensionProperties *op1, const VkExtensionProperties *op2);
    408 
    409 VkResult loader_validate_layers(const struct loader_instance *inst, const uint32_t layer_count,
    410                                 const char *const *ppEnabledLayerNames, const struct loader_layer_list *list);
    411 
    412 VkResult loader_validate_instance_extensions(const struct loader_instance *inst, const struct loader_extension_list *icd_exts,
    413                                              const struct loader_layer_list *instance_layer,
    414                                              const VkInstanceCreateInfo *pCreateInfo);
    415 
    416 void loader_initialize(void);
    417 VkResult loader_copy_layer_properties(const struct loader_instance *inst, struct loader_layer_properties *dst,
    418                                       struct loader_layer_properties *src);
    419 bool has_vk_extension_property_array(const VkExtensionProperties *vk_ext_prop, const uint32_t count,
    420                                      const VkExtensionProperties *ext_array);
    421 bool has_vk_extension_property(const VkExtensionProperties *vk_ext_prop, const struct loader_extension_list *ext_list);
    422 
    423 VkResult loader_add_to_ext_list(const struct loader_instance *inst, struct loader_extension_list *ext_list,
    424                                 uint32_t prop_list_count, const VkExtensionProperties *props);
    425 VkResult loader_add_to_dev_ext_list(const struct loader_instance *inst, struct loader_device_extension_list *ext_list,
    426                                     const VkExtensionProperties *props, uint32_t entry_count, char **entrys);
    427 VkResult loader_add_device_extensions(const struct loader_instance *inst,
    428                                       PFN_vkEnumerateDeviceExtensionProperties fpEnumerateDeviceExtensionProperties,
    429                                       VkPhysicalDevice physical_device, const char *lib_name,
    430                                       struct loader_extension_list *ext_list);
    431 VkResult loader_init_generic_list(const struct loader_instance *inst, struct loader_generic_list *list_info, size_t element_size);
    432 void loader_destroy_generic_list(const struct loader_instance *inst, struct loader_generic_list *list);
    433 void loader_destroy_layer_list(const struct loader_instance *inst, struct loader_device *device,
    434                                struct loader_layer_list *layer_list);
    435 void loader_delete_layer_properties(const struct loader_instance *inst, struct loader_layer_list *layer_list);
    436 bool loader_find_layer_name_array(const char *name, uint32_t layer_count, const char layer_list[][VK_MAX_EXTENSION_NAME_SIZE]);
    437 VkResult loader_add_to_layer_list(const struct loader_instance *inst, struct loader_layer_list *list, uint32_t prop_list_count,
    438                                   const struct loader_layer_properties *props);
    439 void loader_find_layer_name_add_list(const struct loader_instance *inst, const char *name, const enum layer_type_flags type_flags,
    440                                      const struct loader_layer_list *source_list, struct loader_layer_list *target_list,
    441                                      struct loader_layer_list *expanded_target_list);
    442 void loader_scanned_icd_clear(const struct loader_instance *inst, struct loader_icd_tramp_list *icd_tramp_list);
    443 VkResult loader_icd_scan(const struct loader_instance *inst, struct loader_icd_tramp_list *icd_tramp_list);
    444 void loader_layer_scan(const struct loader_instance *inst, struct loader_layer_list *instance_layers);
    445 void loader_implicit_layer_scan(const struct loader_instance *inst, struct loader_layer_list *instance_layers);
    446 bool loader_is_implicit_layer_enabled(const struct loader_instance *inst, const struct loader_layer_properties *prop);
    447 VkResult loader_get_icd_loader_instance_extensions(const struct loader_instance *inst, struct loader_icd_tramp_list *icd_tramp_list,
    448                                                    struct loader_extension_list *inst_exts);
    449 struct loader_icd_term *loader_get_icd_and_device(const VkDevice device, struct loader_device **found_dev, uint32_t *icd_index);
    450 void loader_init_dispatch_dev_ext(struct loader_instance *inst, struct loader_device *dev);
    451 void *loader_dev_ext_gpa(struct loader_instance *inst, const char *funcName);
    452 void *loader_get_dev_ext_trampoline(uint32_t index);
    453 bool loader_phys_dev_ext_gpa(struct loader_instance *inst, const char *funcName, bool perform_checking, void **tramp_addr,
    454                              void **term_addr);
    455 void *loader_get_phys_dev_ext_tramp(uint32_t index);
    456 void *loader_get_phys_dev_ext_termin(uint32_t index);
    457 struct loader_instance *loader_get_instance(const VkInstance instance);
    458 void loader_deactivate_layers(const struct loader_instance *instance, struct loader_device *device, struct loader_layer_list *list);
    459 struct loader_device *loader_create_logical_device(const struct loader_instance *inst, const VkAllocationCallbacks *pAllocator);
    460 void loader_add_logical_device(const struct loader_instance *inst, struct loader_icd_term *icd_term,
    461                                struct loader_device *found_dev);
    462 void loader_remove_logical_device(const struct loader_instance *inst, struct loader_icd_term *icd_term,
    463                                   struct loader_device *found_dev, const VkAllocationCallbacks *pAllocator);
    464 // NOTE: Outside of loader, this entry-point is only provided for error
    465 // cleanup.
    466 void loader_destroy_logical_device(const struct loader_instance *inst, struct loader_device *dev,
    467                                    const VkAllocationCallbacks *pAllocator);
    468 
    469 VkResult loader_enable_instance_layers(struct loader_instance *inst, const VkInstanceCreateInfo *pCreateInfo,
    470                                        const struct loader_layer_list *instance_layers);
    471 
    472 VkResult loader_create_instance_chain(const VkInstanceCreateInfo *pCreateInfo, const VkAllocationCallbacks *pAllocator,
    473                                       struct loader_instance *inst, VkInstance *created_instance);
    474 
    475 void loader_activate_instance_layer_extensions(struct loader_instance *inst, VkInstance created_inst);
    476 
    477 VkResult loader_create_device_chain(const struct loader_physical_device_tramp *pd, const VkDeviceCreateInfo *pCreateInfo,
    478                                     const VkAllocationCallbacks *pAllocator, const struct loader_instance *inst,
    479                                     struct loader_device *dev);
    480 
    481 VkResult loader_validate_device_extensions(struct loader_physical_device_tramp *phys_dev,
    482                                            const struct loader_layer_list *activated_device_layers,
    483                                            const struct loader_extension_list *icd_exts, const VkDeviceCreateInfo *pCreateInfo);
    484 
    485 VkResult setupLoaderTrampPhysDevs(VkInstance instance);
    486 VkResult setupLoaderTermPhysDevs(struct loader_instance *inst);
    487 
    488 VkStringErrorFlags vk_string_validate(const int max_length, const char *char_array);
    489 
    490 #endif  // LOADER_H
    491