chromium/third_party/vulkan-loader/src/loader/loader.c

/*
 *
 * Copyright (c) 2014-2023 The Khronos Group Inc.
 * Copyright (c) 2014-2023 Valve Corporation
 * Copyright (c) 2014-2023 LunarG, Inc.
 * Copyright (C) 2015 Google Inc.
 * Copyright (c) 2021-2022 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
 * Copyright (c) 2023-2023 RasterGrid Kft.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.

 *
 * Author: Jon Ashburn <[email protected]>
 * Author: Courtney Goeltzenleuchter <[email protected]>
 * Author: Mark Young <[email protected]>
 * Author: Lenny Komow <[email protected]>
 * Author: Charles Giessen <[email protected]>
 *
 */

#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  // _WIN32

#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)
// This header is currently only used when sorting Linux devices, so don't include it otherwise.
#include "loader_linux.h"
#endif  // LOADER_ENABLE_LINUX_SORT

// Generated file containing all the extension data
#include "vk_loader_extensions.c"

struct loader_struct loader =;

struct activated_layer_info {};

// thread safety lock for accessing global data structures such as "loader"
// all entrypoints on the instance chain need to be locked except GPA
// additionally CreateDevice and DestroyDevice needs to be locked
loader_platform_thread_mutex loader_lock;
loader_platform_thread_mutex loader_preload_icd_lock;
loader_platform_thread_mutex loader_global_instance_list_lock;

// A list of ICDs that gets initialized when the loader does its global initialization. This list should never be used by anything
// other than EnumerateInstanceExtensionProperties(), vkDestroyInstance, and loader_release(). This list does not change
// functionality, but the fact that the libraries already been loaded causes any call that needs to load ICD libraries to speed up
// significantly. This can have a huge impact when making repeated calls to vkEnumerateInstanceExtensionProperties and
// vkCreateInstance.
struct loader_icd_tramp_list preloaded_icds;

// controls whether loader_platform_close_library() closes the libraries or not - controlled by an environment
// variables - this is just the definition of the variable, usage is in vk_loader_platform.h
bool loader_disable_dynamic_library_unloading;

LOADER_PLATFORM_THREAD_ONCE_DECLARATION(once_init);

// Creates loader_api_version struct that contains the major and minor fields, setting patch to 0
loader_api_version loader_make_version(uint32_t version) {}

// Creates loader_api_version struct containing the major, minor, and patch fields
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) {}

// Helper macros for determining if a version is valid or not
bool loader_check_version_meets_required(loader_api_version required, loader_api_version version) {}

// Wrapper around opendir so that the dirent_on_windows gets the instance it needs
// while linux opendir & readdir does not
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) {}

// Handle error from to library loading
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) {}

// Given string of three part form "maj.min.pat" convert to a vulkan version number.
// Also can understand four part form "variant.major.minor.patch" if provided.
uint32_t loader_parse_version_string(char *vers_str) {}

bool compare_vk_extension_properties(const VkExtensionProperties *op1, const VkExtensionProperties *op2) {}

// Search the given ext_array for an extension matching the given vk_ext_prop
bool has_vk_extension_property_array(const VkExtensionProperties *vk_ext_prop, const uint32_t count,
                                     const VkExtensionProperties *ext_array) {}

// Search the given ext_list for an extension matching the given vk_ext_prop
bool has_vk_extension_property(const VkExtensionProperties *vk_ext_prop, const struct loader_extension_list *ext_list) {}

// Search the given ext_list for a device extension matching the given ext_prop
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) {}

// Search the given layer list for a layer property matching the given layer name
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) {}

// Search the given layer list for a layer matching the given layer name
bool loader_find_layer_name_in_list(const char *name, const struct loader_pointer_layer_list *layer_list) {}

// Search the given meta-layer's component list for a layer matching the given layer name
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) {}

// Search the override layer's blacklist for a layer matching the given layer name
bool loader_find_layer_name_in_blacklist(const char *layer_name, struct loader_layer_properties *meta_layer_props) {}

// Remove all layer properties entries from the list
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) {}

// Remove all layers in the layer list that are blacklisted by the override layer.
// NOTE: This should only be called if an override layer is found and not expired.
void loader_remove_layers_in_blacklist(const struct loader_instance *inst, struct loader_layer_list *layer_list) {}

// Remove all layers in the layer list that are not found inside any implicit meta-layers.
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) {}

// Append non-duplicate extension properties defined in props to the given ext_list.
// Return - Vk_SUCCESS on success
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) {}

// Append one extension property defined in props with entrypoints defined in entries to the given
// ext_list. Do not append if a duplicate.
// If this is a duplicate, this function free's the passed in entries - as in it takes ownership over that list (if it is not
// NULL) Return - Vk_SUCCESS on success
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) {}

// Create storage for pointers to loader_layer_properties
bool loader_init_pointer_layer_list(const struct loader_instance *inst, struct loader_pointer_layer_list *list) {}

// Search the given array of layer names for an entry matching the given VkLayerProperties
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) {}

// Append layer properties defined in prop_list to the given layer_info list
VkResult loader_add_layer_properties_to_list(const struct loader_instance *inst, struct loader_pointer_layer_list *list,
                                             struct loader_layer_properties *props) {}

// Determine if the provided explicit layer should be available by querying the appropriate environmental variables.
bool loader_layer_is_available(const struct loader_instance *inst, const struct loader_envvar_all_filters *filters,
                               const struct loader_layer_properties *prop) {}

// Search the given search_list for any layers in the props list.  Add these to the
// output layer_list.
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) {}

// Determine if the provided implicit layer should be enabled by querying the appropriate environmental variables.
// For an implicit layer, at least a disable environment variable is required.
bool loader_implicit_layer_is_enabled(const struct loader_instance *inst, const struct loader_envvar_all_filters *filters,
                                      const struct loader_layer_properties *prop) {}

// Check the individual implicit layer for the enable/disable environment variable settings.  Only add it after
// every check has passed indicating it should be used, including making sure a layer of the same name hasn't already been
// added.
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) {}

// Add the component layers of a meta-layer to the active list of layers
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) {}

// For Instance extensions implemented within the loader (i.e. DEBUG_REPORT
// the extension must provide two entry points for the loader to use:
// - "trampoline" entry point - this is the address returned by GetProcAddr
//                              and will always do what's necessary to support a
//                              global call.
// - "terminator" function    - this function will be put at the end of the
//                              instance chain and will contain the necessary logic
//                              to call / process the extension for the appropriate
//                              ICDs that are available.
// There is no generic mechanism for including these functions, the references
// must be placed into the appropriate loader entry points.
// GetInstanceProcAddr: call extension GetInstanceProcAddr to check for GetProcAddr
// requests
// loader_coalesce_extensions(void) - add extension records to the list of global
//                                    extension available to the app.
// instance_disp                    - add function pointer for terminator function
//                                    to this array.
// The extension itself should be in a separate file that will be linked directly
// with the loader.
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) {}

// Try to close any open objects on the loader_icd_term - this must be done before destroying the instance
void loader_icd_close_objects(struct loader_instance *ptr_inst, struct loader_icd_term *icd_term) {}
// Free resources allocated inside the loader_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) {}
// Closes the library handle in the scanned ICD, free the lib_name string, and zeros out all data
void loader_unload_scanned_icd(struct loader_instance *inst, struct loader_scanned_icd *scanned_icd) {}

// Determine the ICD interface version to use.
//     @param icd
//     @param pVersion Output parameter indicating which version to use or 0 if
//            the negotiation API is not supported by the ICD
//     @return  bool indicating true if the selected interface version is supported
//            by the loader, false indicates the version is not supported
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) {}

// Search through VkInstanceCreateInfo's pNext chain for any drivers from the direct driver loading extension and load them.
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() {}

// Preload the ICD libraries that are likely to be needed so we don't repeatedly load/unload them later
void loader_preload_icds(void) {}

// Release the ICD libraries that were preloaded
void loader_unload_preloaded_icds(void) {}

#if !defined(_WIN32)
__attribute__((constructor)) void loader_init_library(void) {}

__attribute__((destructor)) void loader_free_library(void) {}
#endif

// Get next file or dirname given a string list or registry key path
//
// \returns
// A pointer to first char in the next path.
// The next path (or NULL) in the list is returned in next_path.
// Note: input string is modified in some cases. PASS IN A COPY!
char *loader_get_next_path(char *path) {}

/* Processes a json manifest's library_path and the location of the json manifest to create the path of the library
 * The output is stored in out_fullpath by allocating a string - so its the caller's responsibility to free it
 * The output is the combination of the base path of manifest_file_path concatenated with library path
 * If library_path is an absolute path, we do not prepend the base path of manifest_file_path
 *
 * This function takes ownership of library_path - caller does not need to worry about freeing it.
 */
VkResult combine_manifest_directory_and_library_path(const struct loader_instance *inst, char *library_path,
                                                     const char *manifest_file_path, char **out_fullpath) {}

// Given a filename (file)  and a list of paths (in_dirs), try to find an existing
// file in the paths.  If filename already is a path then no searching in the given paths.
//
// @return - A string in out_fullpath of either the full path or file.
void loader_get_fullpath(const char *file, const char *in_dirs, size_t out_size, char *out_fullpath) {}

// Verify that all component layers in a meta-layer are valid.
bool verify_meta_layer_component_layers(const struct loader_instance *inst, struct loader_layer_properties *prop,
                                        struct loader_layer_list *instance_layers) {}

// Add any instance and device extensions from component layers to this layer
// list, so that anyone querying extensions will only need to look at the meta-layer
bool update_meta_layer_extensions_from_component_layers(const struct loader_instance *inst, struct loader_layer_properties *prop,
                                                        struct loader_layer_list *instance_layers) {}

// Verify that all meta-layers in a layer list are valid.
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) {}

// If the current working directory matches any app_key_path of the layers, remove all other override layers.
// Otherwise if no matching app_key was found, remove all but the global override layer, which has no app_key_path.
void remove_all_non_valid_override_layers(struct loader_instance *inst, struct loader_layer_list *instance_layers) {}

/* The following are required in the "layer" object:
 * "name"
 * "type"
 * (for non-meta layers) "library_path"
 * (for meta layers) "component_layers"
 * "api_version"
 * "implementation_version"
 * "description"
 * (for implicit layers) "disable_environment"
 */

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) {}

// Given a cJSON struct (json) of the top level JSON object from layer manifest
// file, add entry to the layer_list. Fill out the layer_properties in this list
// entry from the input cJSON object.
//
// \returns
// void
// layer_list has a new entry and initialized accordingly.
// If the json input object does not have all the required fields no entry
// is added to the list.
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) {}

// If the file found is a manifest file name, add it to the out_files manifest list.
VkResult add_if_manifest_file(const struct loader_instance *inst, const char *file_name, struct loader_string_list *out_files) {}

// Add any files found in the search_path.  If any path in the search path points to a specific JSON, attempt to
// only open that one JSON.  Otherwise, if the path is a folder, search the folder for JSON files.
VkResult add_data_files(const struct loader_instance *inst, char *search_path, struct loader_string_list *out_files,
                        bool use_first_found_manifest) {}

// Look for data files in the provided paths, but first check the environment override to determine if we should use that
// instead.
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) {}

// Find the Vulkan library manifest files.
//
// This function scans the appropriate locations for a list of JSON manifest files based on the
// "manifest_type".  The location is interpreted as Registry path on Windows and a directory path(s)
// on Linux.
// "home_location" is an additional directory in the users home directory to look at. It is
// expanded into the dir path $XDG_DATA_HOME/home_location or $HOME/.local/share/home_location
// depending on environment variables. This "home_location" is only used on Linux.
//
// \returns
// VKResult
// A string list of manifest files to be opened in out_files param.
// List has a pointer to string for each manifest filename.
// When done using the list in out_files, pointers should be freed.
// Location or override  string lists can be either files or directories as
// follows:
//            | location | override
// --------------------------------
// Win ICD    | files    | files
// Win Layer  | files    | dirs
// Linux ICD  | dirs     | files
// Linux Layer| dirs     | dirs

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 {};

// Takes a json file, opens, reads, and parses an ICD Manifest out of it.
// Should only return VK_SUCCESS, VK_ERROR_INCOMPATIBLE_DRIVER, or VK_ERROR_OUT_OF_HOST_MEMORY
VkResult loader_parse_icd_manifest(const struct loader_instance *inst, char *file_str, struct ICDManifestInfo *icd,
                                   bool *skipped_portability_drivers) {}

// Try to find the Vulkan ICD driver(s).
//
// This function scans the default system loader path(s) or path specified by either the
// VK_DRIVER_FILES or VK_ICD_FILENAMES environment variable in order to find loadable
// VK ICDs manifest files.
// From these manifest files it finds the ICD libraries.
//
// skipped_portability_drivers is used to report whether the loader found drivers which report
// portability but the application didn't enable the bit to enumerate them
// Can be NULL
//
// \returns
// Vulkan result
// (on result == VK_SUCCESS) a list of icds that were discovered
VkResult loader_icd_scan(const struct loader_instance *inst, struct loader_icd_tramp_list *icd_tramp_list,
                         const VkInstanceCreateInfo *pCreateInfo, bool *skipped_portability_drivers) {}

// Gets the layer data files corresponding to manifest_type & path_override, then parses the resulting json objects
// into instance_layers
// Manifest type must be either implicit or explicit
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) {}

// Given a loader_layer_properties struct that is a valid override layer, concatenate the properties override paths and put them
// into the output parameter override_paths
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) {}

// Go through the search_list and find any layers which match type. If layer
// type match is found in then add it to ext_list.
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) {}

// Determine the layer interface version to use.
bool loader_get_layer_interface_version(PFN_vkNegotiateLoaderLayerInterfaceVersion fp_negotiate_layer_version,
                                        VkNegotiateLayerInterface *interface_struct) {}

// Every extension that has a loader-defined trampoline needs to be marked as enabled or disabled so that we know whether or
// not to return that trampoline when vkGetDeviceProcAddr is called
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) {}

// Given the list of layers to activate in the loader_instance
// structure. This function will add a VkLayerInstanceCreateInfo
// structure to the VkInstanceCreateInfo.pNext pointer.
// Each activated layer will have it's own VkLayerInstanceLink
// structure that tells the layer what Get*ProcAddr to call to
// get function pointers to the next layer down.
// Once the chain info has been created this function will
// execute the CreateInstance call chain. Each layer will
// then have an opportunity in it's CreateInstance function
// to setup it's dispatch table when the lower layer returns
// successfully.
// Each layer can wrap or not-wrap the returned VkInstance object
// as it sees fit.
// The instance chain is terminated by a loader function
// that will call CreateInstance on all available ICD's and
// cache those VkInstance objects for future use.
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) {}

// Terminator functions for the Instance chain
// All named terminator_<Vulkan API name>
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) {}

// Update the trampoline physical devices with the wrapped version.
// We always want to re-use previous physical device pointers since they may be used by an application
// after returning previously.
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  // LOADER_ENABLE_LINUX_SORT

// Look for physical_device in the provided phys_devs list, return true if found and put the index into out_idx, otherwise
// return false
bool find_phys_dev(VkPhysicalDevice physical_device, uint32_t phys_devs_count, struct loader_physical_device_term **phys_devs,
                   uint32_t *out_idx) {}

// Add physical_device to new_phys_devs
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) {}

/* Enumerate all physical devices from ICDs and add them to inst->phys_devs_term
 *
 * There are two methods to find VkPhysicalDevices - vkEnumeratePhysicalDevices and vkEnumerateAdapterPhysicalDevices
 * The latter is supported on windows only and on devices supporting ICD Interface Version 6 and greater.
 *
 * Once all physical devices are acquired, they need to be pulled into a single list of `loader_physical_device_term`'s.
 * They also need to be setup - the icd_term, icd_index, phys_dev, and disp (dispatch table) all need the correct data.
 * Additionally, we need to keep using already setup physical devices as they may be in use, thus anything enumerated
 * that is already in inst->phys_devs_term will be carried over.
 */

VkResult setup_loader_term_phys_devs(struct loader_instance *inst) {}
/**
 * Iterates through all drivers and unloads any which do not contain physical devices.
 * This saves address space, which for 32 bit applications is scarce.
 * This must only be called after a call to vkEnumeratePhysicalDevices that isn't just querying the count
 */
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) {}

// ---- Vulkan Core 1.1 terminators

VKAPI_ATTR VkResult VKAPI_CALL terminator_EnumeratePhysicalDeviceGroups(
    VkInstance instance, uint32_t *pPhysicalDeviceGroupCount, VkPhysicalDeviceGroupProperties *pPhysicalDeviceGroupProperties) {}