#include "loader.h"
#include <ctype.h>
#include <inttypes.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <stdbool.h>
#include <string.h>
#include <stddef.h>
#if defined(__APPLE__)
#include <CoreFoundation/CoreFoundation.h>
#include <sys/param.h>
#endif
#include <sys/types.h>
#if defined(_WIN32)
#include "dirent_on_windows.h"
#elif COMMON_UNIX_PLATFORMS
#include <dirent.h>
#else
#warning dirent.h not available on this platform
#endif
#include "allocation.h"
#include "cJSON.h"
#include "debug_utils.h"
#include "loader_environment.h"
#include "gpa_helper.h"
#include "log.h"
#include "unknown_function_handling.h"
#include "vk_loader_platform.h"
#include "wsi.h"
#if defined(WIN32)
#include "loader_windows.h"
#endif
#if defined(LOADER_ENABLE_LINUX_SORT)
#include "loader_linux.h"
#endif
#include "vk_loader_extensions.c"
struct loader_struct loader = …;
struct activated_layer_info { … };
loader_platform_thread_mutex loader_lock;
loader_platform_thread_mutex loader_preload_icd_lock;
loader_platform_thread_mutex loader_global_instance_list_lock;
struct loader_icd_tramp_list preloaded_icds;
bool loader_disable_dynamic_library_unloading;
LOADER_PLATFORM_THREAD_ONCE_DECLARATION(once_init);
loader_api_version loader_make_version(uint32_t version) { … }
loader_api_version loader_make_full_version(uint32_t version) { … }
loader_api_version loader_combine_version(uint32_t major, uint32_t minor, uint32_t patch) { … }
bool loader_check_version_meets_required(loader_api_version required, loader_api_version version) { … }
DIR *loader_opendir(const struct loader_instance *instance, const char *name) { … }
int loader_closedir(const struct loader_instance *instance, DIR *dir) { … }
bool is_json(const char *path, size_t len) { … }
void loader_handle_load_library_error(const struct loader_instance *inst, const char *filename,
enum loader_layer_library_status *lib_status) { … }
VKAPI_ATTR VkResult VKAPI_CALL vkSetInstanceDispatch(VkInstance instance, void *object) { … }
VKAPI_ATTR VkResult VKAPI_CALL vkSetDeviceDispatch(VkDevice device, void *object) { … }
void loader_free_layer_properties(const struct loader_instance *inst, struct loader_layer_properties *layer_properties) { … }
VkResult loader_init_library_list(struct loader_layer_list *instance_layers, loader_platform_dl_handle **libs) { … }
VkResult loader_copy_to_new_str(const struct loader_instance *inst, const char *source_str, char **dest_str) { … }
VkResult create_string_list(const struct loader_instance *inst, uint32_t allocated_count, struct loader_string_list *string_list) { … }
VkResult append_str_to_string_list(const struct loader_instance *inst, struct loader_string_list *string_list, char *str) { … }
VkResult copy_str_to_string_list(const struct loader_instance *inst, struct loader_string_list *string_list, const char *str,
size_t str_len) { … }
void free_string_list(const struct loader_instance *inst, struct loader_string_list *string_list) { … }
uint32_t loader_parse_version_string(char *vers_str) { … }
bool compare_vk_extension_properties(const VkExtensionProperties *op1, const VkExtensionProperties *op2) { … }
bool has_vk_extension_property_array(const VkExtensionProperties *vk_ext_prop, const uint32_t count,
const VkExtensionProperties *ext_array) { … }
bool has_vk_extension_property(const VkExtensionProperties *vk_ext_prop, const struct loader_extension_list *ext_list) { … }
bool has_vk_dev_ext_property(const VkExtensionProperties *ext_prop, const struct loader_device_extension_list *ext_list) { … }
VkResult loader_append_layer_property(const struct loader_instance *inst, struct loader_layer_list *layer_list,
struct loader_layer_properties *layer_property) { … }
struct loader_layer_properties *loader_find_layer_property(const char *name, const struct loader_layer_list *layer_list) { … }
struct loader_layer_properties *loader_find_pointer_layer_property(const char *name,
const struct loader_pointer_layer_list *layer_list) { … }
bool loader_find_layer_name_in_list(const char *name, const struct loader_pointer_layer_list *layer_list) { … }
bool loader_find_layer_name_in_meta_layer(const struct loader_instance *inst, const char *layer_name,
struct loader_layer_list *layer_list, struct loader_layer_properties *meta_layer_props) { … }
bool loader_find_layer_name_in_blacklist(const char *layer_name, struct loader_layer_properties *meta_layer_props) { … }
void loader_delete_layer_list_and_properties(const struct loader_instance *inst, struct loader_layer_list *layer_list) { … }
void loader_remove_layer_in_list(const struct loader_instance *inst, struct loader_layer_list *layer_list,
uint32_t layer_to_remove) { … }
void loader_remove_layers_in_blacklist(const struct loader_instance *inst, struct loader_layer_list *layer_list) { … }
void loader_remove_layers_not_in_implicit_meta_layers(const struct loader_instance *inst, struct loader_layer_list *layer_list) { … }
VkResult loader_add_instance_extensions(const struct loader_instance *inst,
const PFN_vkEnumerateInstanceExtensionProperties fp_get_props, const char *lib_name,
struct loader_extension_list *ext_list) { … }
VkResult loader_add_device_extensions(const struct loader_instance *inst,
PFN_vkEnumerateDeviceExtensionProperties fpEnumerateDeviceExtensionProperties,
VkPhysicalDevice physical_device, const char *lib_name,
struct loader_extension_list *ext_list) { … }
VkResult loader_init_generic_list(const struct loader_instance *inst, struct loader_generic_list *list_info, size_t element_size) { … }
VkResult loader_resize_generic_list(const struct loader_instance *inst, struct loader_generic_list *list_info) { … }
void loader_destroy_generic_list(const struct loader_instance *inst, struct loader_generic_list *list) { … }
VkResult loader_get_next_available_entry(const struct loader_instance *inst, struct loader_used_object_list *list_info,
uint32_t *free_index, const VkAllocationCallbacks *pAllocator) { … }
void loader_release_object_from_list(struct loader_used_object_list *list_info, uint32_t index_to_free) { … }
VkResult loader_add_to_ext_list(const struct loader_instance *inst, struct loader_extension_list *ext_list,
uint32_t prop_list_count, const VkExtensionProperties *props) { … }
VkResult loader_add_to_dev_ext_list(const struct loader_instance *inst, struct loader_device_extension_list *ext_list,
const VkExtensionProperties *props, struct loader_string_list *entrys) { … }
bool loader_init_pointer_layer_list(const struct loader_instance *inst, struct loader_pointer_layer_list *list) { … }
bool loader_names_array_has_layer_property(const VkLayerProperties *vk_layer_prop, uint32_t layer_info_count,
struct activated_layer_info *layer_info) { … }
void loader_destroy_pointer_layer_list(const struct loader_instance *inst, struct loader_pointer_layer_list *layer_list) { … }
VkResult loader_add_layer_properties_to_list(const struct loader_instance *inst, struct loader_pointer_layer_list *list,
struct loader_layer_properties *props) { … }
bool loader_layer_is_available(const struct loader_instance *inst, const struct loader_envvar_all_filters *filters,
const struct loader_layer_properties *prop) { … }
VkResult loader_add_layer_names_to_list(const struct loader_instance *inst, const struct loader_envvar_all_filters *filters,
struct loader_pointer_layer_list *output_list,
struct loader_pointer_layer_list *expanded_output_list, uint32_t name_count,
const char *const *names, const struct loader_layer_list *source_list) { … }
bool loader_implicit_layer_is_enabled(const struct loader_instance *inst, const struct loader_envvar_all_filters *filters,
const struct loader_layer_properties *prop) { … }
VkResult loader_add_implicit_layer(const struct loader_instance *inst, struct loader_layer_properties *prop,
const struct loader_envvar_all_filters *filters, struct loader_pointer_layer_list *target_list,
struct loader_pointer_layer_list *expanded_target_list,
const struct loader_layer_list *source_list) { … }
VkResult loader_add_meta_layer(const struct loader_instance *inst, const struct loader_envvar_all_filters *filters,
struct loader_layer_properties *prop, struct loader_pointer_layer_list *target_list,
struct loader_pointer_layer_list *expanded_target_list, const struct loader_layer_list *source_list,
bool *out_found_all_component_layers) { … }
VkExtensionProperties *get_extension_property(const char *name, const struct loader_extension_list *list) { … }
VkExtensionProperties *get_dev_extension_property(const char *name, const struct loader_device_extension_list *list) { … }
VkResult loader_get_icd_loader_instance_extensions(const struct loader_instance *inst, struct loader_icd_tramp_list *icd_tramp_list,
struct loader_extension_list *inst_exts) { … }
struct loader_icd_term *loader_get_icd_and_device(const void *device, struct loader_device **found_dev) { … }
void loader_destroy_logical_device(struct loader_device *dev, const VkAllocationCallbacks *pAllocator) { … }
struct loader_device *loader_create_logical_device(const struct loader_instance *inst, const VkAllocationCallbacks *pAllocator) { … }
void loader_add_logical_device(struct loader_icd_term *icd_term, struct loader_device *dev) { … }
void loader_remove_logical_device(struct loader_icd_term *icd_term, struct loader_device *found_dev,
const VkAllocationCallbacks *pAllocator) { … }
const VkAllocationCallbacks *ignore_null_callback(const VkAllocationCallbacks *callbacks) { … }
void loader_icd_close_objects(struct loader_instance *ptr_inst, struct loader_icd_term *icd_term) { … }
void loader_icd_destroy(struct loader_instance *ptr_inst, struct loader_icd_term *icd_term,
const VkAllocationCallbacks *pAllocator) { … }
struct loader_icd_term *loader_icd_add(struct loader_instance *ptr_inst, const struct loader_scanned_icd *scanned_icd) { … }
void loader_unload_scanned_icd(struct loader_instance *inst, struct loader_scanned_icd *scanned_icd) { … }
bool loader_get_icd_interface_version(PFN_vkNegotiateLoaderICDInterfaceVersion fp_negotiate_icd_version, uint32_t *pVersion) { … }
void loader_clear_scanned_icd_list(const struct loader_instance *inst, struct loader_icd_tramp_list *icd_tramp_list) { … }
VkResult loader_init_scanned_icd_list(const struct loader_instance *inst, struct loader_icd_tramp_list *icd_tramp_list) { … }
VkResult loader_add_direct_driver(const struct loader_instance *inst, uint32_t index,
const VkDirectDriverLoadingInfoLUNARG *pDriver, struct loader_icd_tramp_list *icd_tramp_list) { … }
VkResult loader_scan_for_direct_drivers(const struct loader_instance *inst, const VkInstanceCreateInfo *pCreateInfo,
struct loader_icd_tramp_list *icd_tramp_list, bool *direct_driver_loading_exclusive_mode) { … }
VkResult loader_scanned_icd_add(const struct loader_instance *inst, struct loader_icd_tramp_list *icd_tramp_list,
const char *filename, uint32_t api_version, enum loader_layer_library_status *lib_status) { … }
void loader_initialize(void) { … }
void loader_release() { … }
void loader_preload_icds(void) { … }
void loader_unload_preloaded_icds(void) { … }
#if !defined(_WIN32)
__attribute__((constructor)) void loader_init_library(void) { … }
__attribute__((destructor)) void loader_free_library(void) { … }
#endif
char *loader_get_next_path(char *path) { … }
VkResult combine_manifest_directory_and_library_path(const struct loader_instance *inst, char *library_path,
const char *manifest_file_path, char **out_fullpath) { … }
void loader_get_fullpath(const char *file, const char *in_dirs, size_t out_size, char *out_fullpath) { … }
bool verify_meta_layer_component_layers(const struct loader_instance *inst, struct loader_layer_properties *prop,
struct loader_layer_list *instance_layers) { … }
bool update_meta_layer_extensions_from_component_layers(const struct loader_instance *inst, struct loader_layer_properties *prop,
struct loader_layer_list *instance_layers) { … }
VkResult verify_all_meta_layers(struct loader_instance *inst, const struct loader_envvar_all_filters *filters,
struct loader_layer_list *instance_layers, bool *override_layer_present) { … }
void remove_all_non_valid_override_layers(struct loader_instance *inst, struct loader_layer_list *instance_layers) { … }
VkResult loader_read_layer_json(const struct loader_instance *inst, struct loader_layer_list *layer_instance_list,
cJSON *layer_node, loader_api_version version, bool is_implicit, char *filename) { … }
bool is_valid_layer_json_version(const loader_api_version *layer_json) { … }
VkResult loader_add_layer_properties(const struct loader_instance *inst, struct loader_layer_list *layer_instance_list, cJSON *json,
bool is_implicit, char *filename) { … }
size_t determine_data_file_path_size(const char *cur_path, size_t relative_path_size) { … }
void copy_data_file_info(const char *cur_path, const char *relative_path, size_t relative_path_size, char **output_path) { … }
VkResult add_if_manifest_file(const struct loader_instance *inst, const char *file_name, struct loader_string_list *out_files) { … }
VkResult add_data_files(const struct loader_instance *inst, char *search_path, struct loader_string_list *out_files,
bool use_first_found_manifest) { … }
VkResult read_data_files_in_search_paths(const struct loader_instance *inst, enum loader_data_files_type manifest_type,
const char *path_override, bool *override_active, struct loader_string_list *out_files) { … }
VkResult loader_get_data_files(const struct loader_instance *inst, enum loader_data_files_type manifest_type,
const char *path_override, struct loader_string_list *out_files) { … }
struct ICDManifestInfo { … };
VkResult loader_parse_icd_manifest(const struct loader_instance *inst, char *file_str, struct ICDManifestInfo *icd,
bool *skipped_portability_drivers) { … }
VkResult loader_icd_scan(const struct loader_instance *inst, struct loader_icd_tramp_list *icd_tramp_list,
const VkInstanceCreateInfo *pCreateInfo, bool *skipped_portability_drivers) { … }
VkResult loader_parse_instance_layers(struct loader_instance *inst, enum loader_data_files_type manifest_type,
const char *path_override, struct loader_layer_list *instance_layers) { … }
VkResult get_override_layer_override_paths(struct loader_instance *inst, struct loader_layer_properties *prop,
char **override_paths) { … }
VkResult loader_scan_for_layers(struct loader_instance *inst, struct loader_layer_list *instance_layers,
const struct loader_envvar_all_filters *filters) { … }
VkResult loader_scan_for_implicit_layers(struct loader_instance *inst, struct loader_layer_list *instance_layers,
const struct loader_envvar_all_filters *layer_filters) { … }
VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL loader_gpdpa_instance_terminator(VkInstance inst, const char *pName) { … }
VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL loader_gpa_instance_terminator(VkInstance inst, const char *pName) { … }
VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL loader_gpa_device_terminator(VkDevice device, const char *pName) { … }
struct loader_instance *loader_get_instance(const VkInstance instance) { … }
loader_platform_dl_handle loader_open_layer_file(const struct loader_instance *inst, struct loader_layer_properties *prop) { … }
VkResult loader_add_implicit_layers(const struct loader_instance *inst, const struct loader_envvar_all_filters *filters,
struct loader_pointer_layer_list *target_list,
struct loader_pointer_layer_list *expanded_target_list,
const struct loader_layer_list *source_list) { … }
void warn_if_layers_are_older_than_application(struct loader_instance *inst) { … }
VkResult loader_enable_instance_layers(struct loader_instance *inst, const VkInstanceCreateInfo *pCreateInfo,
const struct loader_layer_list *instance_layers,
const struct loader_envvar_all_filters *layer_filters) { … }
bool loader_get_layer_interface_version(PFN_vkNegotiateLoaderLayerInterfaceVersion fp_negotiate_layer_version,
VkNegotiateLayerInterface *interface_struct) { … }
void setup_logical_device_enabled_layer_extensions(const struct loader_instance *inst, struct loader_device *dev,
const struct loader_extension_list *icd_exts,
const VkDeviceCreateInfo *pCreateInfo) { … }
VKAPI_ATTR VkResult VKAPI_CALL loader_layer_create_device(VkInstance instance, VkPhysicalDevice physicalDevice,
const VkDeviceCreateInfo *pCreateInfo,
const VkAllocationCallbacks *pAllocator, VkDevice *pDevice,
PFN_vkGetInstanceProcAddr layerGIPA, PFN_vkGetDeviceProcAddr *nextGDPA) { … }
VKAPI_ATTR void VKAPI_CALL loader_layer_destroy_device(VkDevice device, const VkAllocationCallbacks *pAllocator,
PFN_vkDestroyDevice destroyFunction) { … }
VkResult loader_create_instance_chain(const VkInstanceCreateInfo *pCreateInfo, const VkAllocationCallbacks *pAllocator,
struct loader_instance *inst, VkInstance *created_instance) { … }
void loader_activate_instance_layer_extensions(struct loader_instance *inst, VkInstance created_inst) { … }
#if defined(__APPLE__)
VkResult loader_create_device_chain(const VkPhysicalDevice pd, const VkDeviceCreateInfo *pCreateInfo,
const VkAllocationCallbacks *pAllocator, const struct loader_instance *inst,
struct loader_device *dev, PFN_vkGetInstanceProcAddr callingLayer,
PFN_vkGetDeviceProcAddr *layerNextGDPA) __attribute__((optnone)) {
#else
VkResult loader_create_device_chain(const VkPhysicalDevice pd, const VkDeviceCreateInfo *pCreateInfo,
const VkAllocationCallbacks *pAllocator, const struct loader_instance *inst,
struct loader_device *dev, PFN_vkGetInstanceProcAddr callingLayer,
PFN_vkGetDeviceProcAddr *layerNextGDPA) { … }
VkResult loader_validate_layers(const struct loader_instance *inst, const uint32_t layer_count,
const char *const *ppEnabledLayerNames, const struct loader_layer_list *list) { … }
VkResult loader_validate_instance_extensions(struct loader_instance *inst, const struct loader_extension_list *icd_exts,
const struct loader_layer_list *instance_layers,
const struct loader_envvar_all_filters *layer_filters,
const VkInstanceCreateInfo *pCreateInfo) { … }
VkResult loader_validate_device_extensions(struct loader_instance *this_instance,
const struct loader_pointer_layer_list *activated_device_layers,
const struct loader_extension_list *icd_exts, const VkDeviceCreateInfo *pCreateInfo) { … }
VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateInstance(const VkInstanceCreateInfo *pCreateInfo,
const VkAllocationCallbacks *pAllocator, VkInstance *pInstance) { … }
VKAPI_ATTR void VKAPI_CALL terminator_DestroyInstance(VkInstance instance, const VkAllocationCallbacks *pAllocator) { … }
VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateDevice(VkPhysicalDevice physicalDevice, const VkDeviceCreateInfo *pCreateInfo,
const VkAllocationCallbacks *pAllocator, VkDevice *pDevice) { … }
VkResult setup_loader_tramp_phys_devs(struct loader_instance *inst, uint32_t phys_dev_count, VkPhysicalDevice *phys_devs) { … }
#if defined(LOADER_ENABLE_LINUX_SORT)
bool is_linux_sort_enabled(struct loader_instance *inst) { … }
#endif
bool find_phys_dev(VkPhysicalDevice physical_device, uint32_t phys_devs_count, struct loader_physical_device_term **phys_devs,
uint32_t *out_idx) { … }
VkResult check_and_add_to_new_phys_devs(struct loader_instance *inst, VkPhysicalDevice physical_device,
struct loader_icd_physical_devices *dev_array, uint32_t *cur_new_phys_dev_count,
struct loader_physical_device_term **new_phys_devs) { … }
VkResult setup_loader_term_phys_devs(struct loader_instance *inst) { … }
void unload_drivers_without_physical_devices(struct loader_instance *inst) { … }
VkResult setup_loader_tramp_phys_dev_groups(struct loader_instance *inst, uint32_t group_count,
VkPhysicalDeviceGroupProperties *groups) { … }
VKAPI_ATTR VkResult VKAPI_CALL terminator_EnumeratePhysicalDevices(VkInstance instance, uint32_t *pPhysicalDeviceCount,
VkPhysicalDevice *pPhysicalDevices) { … }
VKAPI_ATTR VkResult VKAPI_CALL terminator_EnumerateDeviceExtensionProperties(VkPhysicalDevice physicalDevice,
const char *pLayerName, uint32_t *pPropertyCount,
VkExtensionProperties *pProperties) { … }
VkStringErrorFlags vk_string_validate(const int max_length, const char *utf8) { … }
VKAPI_ATTR VkResult VKAPI_CALL terminator_EnumerateInstanceVersion(uint32_t *pApiVersion) { … }
VKAPI_ATTR VkResult VKAPI_CALL terminator_pre_instance_EnumerateInstanceVersion(const VkEnumerateInstanceVersionChain *chain,
uint32_t *pApiVersion) { … }
VKAPI_ATTR VkResult VKAPI_CALL terminator_EnumerateInstanceExtensionProperties(const char *pLayerName, uint32_t *pPropertyCount,
VkExtensionProperties *pProperties) { … }
VKAPI_ATTR VkResult VKAPI_CALL terminator_pre_instance_EnumerateInstanceExtensionProperties(
const VkEnumerateInstanceExtensionPropertiesChain *chain, const char *pLayerName, uint32_t *pPropertyCount,
VkExtensionProperties *pProperties) { … }
VKAPI_ATTR VkResult VKAPI_CALL terminator_EnumerateInstanceLayerProperties(uint32_t *pPropertyCount,
VkLayerProperties *pProperties) { … }
VKAPI_ATTR VkResult VKAPI_CALL terminator_pre_instance_EnumerateInstanceLayerProperties(
const VkEnumerateInstanceLayerPropertiesChain *chain, uint32_t *pPropertyCount, VkLayerProperties *pProperties) { … }
VKAPI_ATTR VkResult VKAPI_CALL terminator_EnumeratePhysicalDeviceGroups(
VkInstance instance, uint32_t *pPhysicalDeviceGroupCount, VkPhysicalDeviceGroupProperties *pPhysicalDeviceGroupProperties) { … }