/*
 *
 * Copyright (C) 2015 Valve Corporation
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included
 * in all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 * DEALINGS IN THE SOFTWARE.
 *
 * Author: Chia-I Wu <olvaffe@gmail.com>
 * Author: Courtney Goeltzenleuchter <courtney@LunarG.com>
 * Author: Ian Elliott <ian@LunarG.com>
 * Author: Jon Ashburn <jon@lunarg.com>
 *
 */
#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <stdbool.h>
#include <string.h>

#include <sys/types.h>
#if defined(_WIN32)
#include "dirent_on_windows.h"
#else // _WIN32
#include <dirent.h>
#endif // _WIN32
#include "vk_loader_platform.h"
#include "loader.h"
#include "gpa_helper.h"
#include "table_ops.h"
#include "debug_report.h"
#include "wsi.h"
#include "vulkan/vk_icd.h"
#include "cJSON.h"
#include "murmurhash.h"

static loader_platform_dl_handle loader_add_layer_lib(
        const struct loader_instance *inst,
        const char *chain_type,
        struct loader_layer_properties *layer_prop);

static void loader_remove_layer_lib(
        struct loader_instance *inst,
        struct loader_layer_properties *layer_prop);

struct loader_struct loader = {0};
// TLS for instance for alloc/free callbacks
THREAD_LOCAL_DECL struct loader_instance *tls_instance;

static bool loader_init_ext_list(
        const struct loader_instance *inst,
        struct loader_extension_list *ext_info);

static int loader_platform_combine_path(char *dest, int len, ...);

struct loader_phys_dev_per_icd {
    uint32_t count;
    VkPhysicalDevice *phys_devs;
};

enum loader_debug {
    LOADER_INFO_BIT       = 0x01,
    LOADER_WARN_BIT       = 0x02,
    LOADER_PERF_BIT       = 0x04,
    LOADER_ERROR_BIT      = 0x08,
    LOADER_DEBUG_BIT      = 0x10,
};

uint32_t g_loader_debug = 0;
uint32_t g_loader_log_msgs = 0;

//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_json_lock;

// This table contains the loader's instance dispatch table, which contains
// default functions if no instance layers are activated.  This contains
// pointers to "terminator functions".
const VkLayerInstanceDispatchTable instance_disp = {
    .GetInstanceProcAddr = vkGetInstanceProcAddr,
    .CreateInstance = loader_CreateInstance,
    .DestroyInstance = loader_DestroyInstance,
    .EnumeratePhysicalDevices = loader_EnumeratePhysicalDevices,
    .GetPhysicalDeviceFeatures = loader_GetPhysicalDeviceFeatures,
    .GetPhysicalDeviceFormatProperties = loader_GetPhysicalDeviceFormatProperties,
    .GetPhysicalDeviceImageFormatProperties = loader_GetPhysicalDeviceImageFormatProperties,
    .GetPhysicalDeviceProperties = loader_GetPhysicalDeviceProperties,
    .GetPhysicalDeviceQueueFamilyProperties = loader_GetPhysicalDeviceQueueFamilyProperties,
    .GetPhysicalDeviceMemoryProperties = loader_GetPhysicalDeviceMemoryProperties,
    .EnumerateDeviceExtensionProperties = loader_EnumerateDeviceExtensionProperties,
    .EnumerateDeviceLayerProperties = loader_EnumerateDeviceLayerProperties,
    .GetPhysicalDeviceSparseImageFormatProperties = loader_GetPhysicalDeviceSparseImageFormatProperties,
    .GetPhysicalDeviceSurfaceSupportKHR = loader_GetPhysicalDeviceSurfaceSupportKHR,
    .GetPhysicalDeviceSurfaceCapabilitiesKHR = loader_GetPhysicalDeviceSurfaceCapabilitiesKHR,
    .GetPhysicalDeviceSurfaceFormatsKHR = loader_GetPhysicalDeviceSurfaceFormatsKHR,
    .GetPhysicalDeviceSurfacePresentModesKHR = loader_GetPhysicalDeviceSurfacePresentModesKHR,
#ifdef VK_USE_PLATFORM_MIR_KHR
    .CreateMirSurfaceKHR = vkCreateMirSurfaceKHR,
    .GetPhysicalDeviceMirPresentationSupportKHR = loader_GetPhysicalDeviceMirPresentationSupportKHR,
#endif
#ifdef VK_USE_PLATFORM_WAYLAND_KHR
    .CreateWaylandSurfaceKHR = vkCreateWaylandSurfaceKHR,
    .GetPhysicalDeviceWaylandPresentationSupportKHR = loader_GetPhysicalDeviceWaylandPresentationSupportKHR,
#endif
#ifdef VK_USE_PLATFORM_WIN32_KHR
    .CreateWin32SurfaceKHR = vkCreateWin32SurfaceKHR,
    .GetPhysicalDeviceWin32PresentationSupportKHR = loader_GetPhysicalDeviceWin32PresentationSupportKHR,
#endif
#ifdef VK_USE_PLATFORM_XCB_KHR
    .CreateXcbSurfaceKHR = vkCreateXcbSurfaceKHR,
    .GetPhysicalDeviceXcbPresentationSupportKHR = loader_GetPhysicalDeviceXcbPresentationSupportKHR,
#endif
#ifdef VK_USE_PLATFORM_XLIB_KHR
    .CreateXlibSurfaceKHR = vkCreateXlibSurfaceKHR,
    .GetPhysicalDeviceXlibPresentationSupportKHR = loader_GetPhysicalDeviceXlibPresentationSupportKHR,
#endif
    .DbgCreateMsgCallback = loader_DbgCreateMsgCallback,
    .DbgDestroyMsgCallback = loader_DbgDestroyMsgCallback,
};

LOADER_PLATFORM_THREAD_ONCE_DECLARATION(once_init);

void* loader_heap_alloc(
    const struct loader_instance     *instance,
    size_t                            size,
    VkSystemAllocationScope                alloc_scope)
{
    if (instance && instance->alloc_callbacks.pfnAllocation) {
        /* TODO: What should default alignment be? 1, 4, 8, other? */
        return instance->alloc_callbacks.pfnAllocation(instance->alloc_callbacks.pUserData, size, 4, alloc_scope);
    }
    return malloc(size);
}

void loader_heap_free(
    const struct loader_instance   *instance,
    void                           *pMemory)
{
    if (pMemory == NULL) return;
    if (instance && instance->alloc_callbacks.pfnFree) {
        instance->alloc_callbacks.pfnFree(instance->alloc_callbacks.pUserData, pMemory);
        return;
    }
    free(pMemory);
}

void* loader_heap_realloc(
    const struct loader_instance *instance,
    void                       *pMemory,
    size_t                      orig_size,
    size_t                      size,
    VkSystemAllocationScope          alloc_scope)
{
    if (pMemory == NULL  || orig_size == 0)
        return loader_heap_alloc(instance, size, alloc_scope);
    if (size == 0) {
        loader_heap_free(instance, pMemory);
        return NULL;
    }
    if (instance && instance->alloc_callbacks.pfnAllocation) {
        if (size <= orig_size) {
            memset(((uint8_t *)pMemory) + size,  0, orig_size - size);
            return pMemory;
        }
        void *new_ptr = instance->alloc_callbacks.pfnAllocation(instance->alloc_callbacks.pUserData, size, 4, alloc_scope);
        if (!new_ptr)
            return NULL;
        memcpy(new_ptr, pMemory, orig_size);
        instance->alloc_callbacks.pfnFree(instance->alloc_callbacks.pUserData, pMemory);
	return new_ptr;
    }
    return realloc(pMemory, size);
}

void *loader_tls_heap_alloc(size_t size)
{
    return loader_heap_alloc(tls_instance, size, VK_SYSTEM_ALLOCATION_SCOPE_COMMAND);
}

void loader_tls_heap_free(void *pMemory)
{
    loader_heap_free(tls_instance, pMemory);
}

static void loader_log(VkFlags msg_type, int32_t msg_code,
    const char *format, ...)
{
    char msg[512];
    va_list ap;
    int ret;

    if (!(msg_type & g_loader_log_msgs)) {
        return;
    }

    va_start(ap, format);
    ret = vsnprintf(msg, sizeof(msg), format, ap);
    if ((ret >= (int) sizeof(msg)) || ret < 0) {
        msg[sizeof(msg)-1] = '\0';
    }
    va_end(ap);

#if defined(WIN32)
    OutputDebugString(msg);
    OutputDebugString("\n");
#endif
    fputs(msg, stderr);
    fputc('\n', stderr);
}

#if defined(WIN32)
static char *loader_get_next_path(char *path);
/**
* Find the list of registry files (names within a key) in key "location".
*
* This function looks in the registry (hive = DEFAULT_VK_REGISTRY_HIVE) key as given in "location"
* for a list or name/values which are added to a returned list (function return value).
* The DWORD values within the key must be 0 or they are skipped.
* Function return is a string with a ';'  separated list of filenames.
* Function return is NULL if no valid name/value pairs  are found in the key,
* or the key is not found.
*
* \returns
* A string list of filenames as pointer.
* When done using the returned string list, pointer should be freed.
*/
static char *loader_get_registry_files(const struct loader_instance *inst, char *location)
{
    LONG rtn_value;
    HKEY hive, key;
    DWORD access_flags;
    char name[2048];
    char *out = NULL;
    char *loc = location;
    char *next;
    DWORD idx = 0;
    DWORD name_size = sizeof(name);
    DWORD value;
    DWORD total_size = 4096;
    DWORD value_size = sizeof(value);

    while(*loc)
    {
        next = loader_get_next_path(loc);
        hive = DEFAULT_VK_REGISTRY_HIVE;
        access_flags = KEY_QUERY_VALUE;
        rtn_value = RegOpenKeyEx(hive, loc, 0, access_flags, &key);
        if (rtn_value != ERROR_SUCCESS) {
            // We didn't find the key.  Try the 32-bit hive (where we've seen the
            // key end up on some people's systems):
            access_flags |= KEY_WOW64_32KEY;
            rtn_value = RegOpenKeyEx(hive, loc, 0, access_flags, &key);
            if (rtn_value != ERROR_SUCCESS) {
                // We still couldn't find the key, so give up:
                loc = next;
                continue;
            }
        }

        while ((rtn_value = RegEnumValue(key, idx++, name, &name_size, NULL, NULL, (LPBYTE) &value, &value_size)) == ERROR_SUCCESS) {
            if (value_size == sizeof(value) && value == 0) {
                if (out == NULL) {
                    out = loader_heap_alloc(inst, total_size, VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE);
                    out[0] = '\0';
                }
                else if (strlen(out) + name_size + 1 > total_size) {
                    out = loader_heap_realloc(inst, out, total_size, total_size * 2, VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE);
                    total_size *= 2;
                }
                if (out == NULL) {
                    loader_log(VK_DBG_REPORT_ERROR_BIT, 0, "Out of memory, failed loader_get_registry_files");
                    return NULL;
                }
                if (strlen(out) == 0)
                     snprintf(out, name_size + 1, "%s", name);
                else
                     snprintf(out + strlen(out), name_size + 2, "%c%s", PATH_SEPERATOR, name);
            }
            name_size = 2048;
        }
        loc = next;
    }

    return out;
}

#endif // WIN32

/**
 * Combine path elements, separating each element with the platform-specific
 * directory separator, and save the combined string to a destination buffer,
 * not exceeding the given length. Path elements are given as variadic args,
 * with a NULL element terminating the list.
 *
 * \returns the total length of the combined string, not including an ASCII
 * NUL termination character. This length may exceed the available storage:
 * in this case, the written string will be truncated to avoid a buffer
 * overrun, and the return value will greater than or equal to the storage
 * size. A NULL argument may be provided as the destination buffer in order
 * to determine the required string length without actually writing a string.
 */

static int loader_platform_combine_path(char *dest, int len, ...)
{
    int required_len = 0;
    va_list ap;
    const char *component;

    va_start(ap, len);

    while((component = va_arg(ap, const char *))) {
        if (required_len > 0) {
            // This path element is not the first non-empty element; prepend
            // a directory separator if space allows
            if (dest && required_len + 1 < len) {
                snprintf(dest + required_len, len - required_len, "%c",
                         DIRECTORY_SYMBOL);
            }
            required_len++;
        }

        if (dest && required_len < len) {
            strncpy(dest + required_len, component, len - required_len);
        }
        required_len += strlen(component);
    }

    va_end(ap);

    // strncpy(3) won't add a NUL terminating byte in the event of truncation.
    if (dest && required_len >= len) {
        dest[len - 1] = '\0';
    }

    return required_len;
}


/**
 * Given string of three part form "maj.min.pat" convert to a vulkan version
 * number.
 */
static uint32_t loader_make_version(const char *vers_str)
{
    uint32_t vers = 0, major=0, minor=0, patch=0;
    char *minor_str= NULL;
    char *patch_str = NULL;
    char *cstr;
    char *str;

    if (!vers_str)
        return vers;
    cstr = loader_stack_alloc(strlen(vers_str) + 1);
    strcpy(cstr, vers_str);
    while ((str = strchr(cstr, '.')) != NULL) {
        if (minor_str == NULL) {
            minor_str = str + 1;
            *str = '\0';
            major = atoi(cstr);
        }
        else if (patch_str == NULL) {
            patch_str = str + 1;
            *str = '\0';
            minor = atoi(minor_str);
        }
        else {
            return vers;
        }
        cstr = str + 1;
    }
    patch = atoi(patch_str);

    return VK_MAKE_VERSION(major, minor, patch);

}

bool compare_vk_extension_properties(const VkExtensionProperties *op1, const VkExtensionProperties *op2)
{
    return strcmp(op1->extensionName, op2->extensionName) == 0 ? true : false;
}

/**
 * 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)
{
    for (uint32_t i = 0; i < count; i++) {
        if (compare_vk_extension_properties(vk_ext_prop, &ext_array[i]))
            return true;
    }
    return false;
}

/**
 * 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)
{
    for (uint32_t i = 0; i < ext_list->count; i++) {
        if (compare_vk_extension_properties(&ext_list->list[i], vk_ext_prop))
            return true;
    }
    return false;
}

static inline bool loader_is_layer_type_device(const enum layer_type type) {
    if ((type & VK_LAYER_TYPE_DEVICE_EXPLICIT) ||
                (type & VK_LAYER_TYPE_DEVICE_IMPLICIT))
        return true;
    return false;
}

/*
 * Search the given layer list for a layer matching the given layer name
 */
static struct loader_layer_properties *loader_get_layer_property(
        const char *name,
        const struct loader_layer_list *layer_list)
{
    for (uint32_t i = 0; i < layer_list->count; i++) {
        const VkLayerProperties *item = &layer_list->list[i].info;
        if (strcmp(name, item->layerName) == 0)
            return &layer_list->list[i];
    }
    return NULL;
}

/**
 * Get the next unused layer property in the list. Init the property to zero.
 */
static struct loader_layer_properties *loader_get_next_layer_property(
                                           const struct loader_instance *inst,
                                           struct loader_layer_list *layer_list)
{
    if (layer_list->capacity == 0) {
        layer_list->list = loader_heap_alloc(inst,
                                  sizeof(struct loader_layer_properties) * 64,
                                  VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE);
        if (layer_list->list == NULL) {
            loader_log(VK_DBG_REPORT_ERROR_BIT, 0, "Out of memory can't add any layer properties to list");
            return NULL;
        }
        memset(layer_list->list, 0, sizeof(struct loader_layer_properties) * 64);
        layer_list->capacity = sizeof(struct loader_layer_properties) * 64;
    }

    // ensure enough room to add an entry
    if ((layer_list->count + 1) * sizeof (struct loader_layer_properties)
            > layer_list->capacity) {
        layer_list->list = loader_heap_realloc(inst, layer_list->list,
                                            layer_list->capacity,
                                            layer_list->capacity * 2,
                                            VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE);
        if (layer_list->list == NULL) {
            loader_log(VK_DBG_REPORT_ERROR_BIT, 0,
                            "realloc failed for layer list");
        }
        layer_list->capacity *= 2;
    }

    layer_list->count++;
    return &(layer_list->list[layer_list->count - 1]);
}

/**
 * Remove all layer properties entrys from the list
 */
void loader_delete_layer_properties(
                        const struct loader_instance *inst,
                        struct loader_layer_list *layer_list)
{
    uint32_t i;

    if (!layer_list)
        return;

    for (i = 0; i < layer_list->count; i++) {
        loader_destroy_ext_list(inst, &layer_list->list[i].instance_extension_list);
        loader_destroy_ext_list(inst, &layer_list->list[i].device_extension_list);
    }
    layer_list->count = 0;

    if (layer_list->capacity > 0) {
        layer_list->capacity = 0;
        loader_heap_free(inst, layer_list->list);
    }

}

static void loader_add_global_extensions(
        const struct loader_instance *inst,
        const PFN_vkEnumerateInstanceExtensionProperties fp_get_props,
        const char *lib_name,
        struct loader_extension_list *ext_list)
{
    uint32_t i, count;
    VkExtensionProperties *ext_props;
    VkResult res;

    if (!fp_get_props) {
        /* No EnumerateInstanceExtensionProperties defined */
        return;
    }

    res = fp_get_props(NULL, &count, NULL);
    if (res != VK_SUCCESS) {
        loader_log(VK_DBG_REPORT_WARN_BIT, 0, "Error getting global extension count from %s", lib_name);
        return;
    }

    if (count == 0) {
        /* No ExtensionProperties to report */
        return;
    }

    ext_props = loader_stack_alloc(count * sizeof(VkExtensionProperties));

    res = fp_get_props(NULL, &count, ext_props);
    if (res != VK_SUCCESS) {
        loader_log(VK_DBG_REPORT_WARN_BIT, 0, "Error getting global extensions from %s", lib_name);
        return;
    }

    for (i = 0; i < count; i++) {
        char spec_version[64];

        snprintf(spec_version, sizeof(spec_version), "%d.%d.%d",
                 VK_MAJOR(ext_props[i].specVersion),
                 VK_MINOR(ext_props[i].specVersion),
                 VK_PATCH(ext_props[i].specVersion));
        loader_log(VK_DBG_REPORT_DEBUG_BIT, 0,
                   "Global Extension: %s (%s) version %s",
                   ext_props[i].extensionName, lib_name, spec_version);
        loader_add_to_ext_list(inst, ext_list, 1, &ext_props[i]);
    }

    return;
}

/*
 * Initialize ext_list with the physical device extensions.
 * The extension properties are passed as inputs in count and ext_props.
 */
static VkResult loader_init_physical_device_extensions(
        const struct loader_instance *inst,
        struct loader_physical_device *phys_dev,
        uint32_t count,
        VkExtensionProperties *ext_props,
        struct loader_extension_list *ext_list)
{
    VkResult res;
    uint32_t i;

    if (!loader_init_ext_list(inst, ext_list)) {
        return VK_ERROR_OUT_OF_HOST_MEMORY;
    }

    for (i = 0; i < count; i++) {
        char spec_version[64];

        snprintf(spec_version, sizeof (spec_version), "%d.%d.%d",
                VK_MAJOR(ext_props[i].specVersion),
                VK_MINOR(ext_props[i].specVersion),
                VK_PATCH(ext_props[i].specVersion));
        loader_log(VK_DBG_REPORT_DEBUG_BIT, 0,
                "PhysicalDevice Extension: %s (%s) version %s",
                ext_props[i].extensionName, phys_dev->this_icd->this_icd_lib->lib_name, spec_version);
        res = loader_add_to_ext_list(inst, ext_list, 1, &ext_props[i]);
        if (res != VK_SUCCESS)
            return res;
    }

    return VK_SUCCESS;
}

static VkResult loader_add_physical_device_extensions(
        const struct loader_instance *inst,
        VkPhysicalDevice physical_device,
        const char *lib_name,
        struct loader_extension_list *ext_list)
{
    uint32_t i, count;
    VkResult res;
    VkExtensionProperties *ext_props;

    res = loader_EnumerateDeviceExtensionProperties(physical_device, NULL, &count, NULL);
    if (res == VK_SUCCESS && count > 0) {
        ext_props = loader_stack_alloc(count * sizeof (VkExtensionProperties));
        if (!ext_props)
            return VK_ERROR_OUT_OF_HOST_MEMORY;
        res = loader_EnumerateDeviceExtensionProperties(physical_device, NULL, &count, ext_props);
        if (res != VK_SUCCESS)
            return res;
        for (i = 0; i < count; i++) {
            char spec_version[64];

            snprintf(spec_version, sizeof (spec_version), "%d.%d.%d",
                    VK_MAJOR(ext_props[i].specVersion),
                    VK_MINOR(ext_props[i].specVersion),
                    VK_PATCH(ext_props[i].specVersion));
            loader_log(VK_DBG_REPORT_DEBUG_BIT, 0,
                    "PhysicalDevice Extension: %s (%s) version %s",
                    ext_props[i].extensionName, lib_name, spec_version);
            res = loader_add_to_ext_list(inst, ext_list, 1, &ext_props[i]);
            if (res != VK_SUCCESS)
                return res;
        }
    } else {
        loader_log(VK_DBG_REPORT_ERROR_BIT, 0, "Error getting physical device extension info count from library %s", lib_name);
        return res;
    }

    return VK_SUCCESS;
}

static bool loader_init_ext_list(const struct loader_instance *inst,
                                 struct loader_extension_list *ext_info)
{
    ext_info->capacity = 32 * sizeof(VkExtensionProperties);
    ext_info->list = loader_heap_alloc(inst, ext_info->capacity, VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE);
    if (ext_info->list == NULL) {
        return false;
    }
    memset(ext_info->list, 0, ext_info->capacity);
    ext_info->count = 0;
    return true;
}

void loader_destroy_ext_list(const struct loader_instance *inst,
                             struct loader_extension_list *ext_info)
{
    loader_heap_free(inst, ext_info->list);
    ext_info->count = 0;
    ext_info->capacity = 0;
}

/*
 * 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)
{
    uint32_t i;
    const VkExtensionProperties *cur_ext;

    if (ext_list->list == NULL || ext_list->capacity == 0) {
        loader_init_ext_list(inst, ext_list);
    }

    if (ext_list->list == NULL)
        return VK_ERROR_OUT_OF_HOST_MEMORY;

    for (i = 0; i < prop_list_count; i++) {
        cur_ext = &props[i];

        // look for duplicates
        if (has_vk_extension_property(cur_ext, ext_list)) {
            continue;
        }

        // add to list at end
        // check for enough capacity
        if (ext_list->count * sizeof(VkExtensionProperties)
                        >= ext_list->capacity) {

            ext_list->list = loader_heap_realloc(inst,
                                                 ext_list->list,
                                                 ext_list->capacity,
                                                 ext_list->capacity * 2,
                                                 VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE);

            if (ext_list->list == NULL)
                return VK_ERROR_OUT_OF_HOST_MEMORY;

            // double capacity
            ext_list->capacity *= 2;
        }

        memcpy(&ext_list->list[ext_list->count], cur_ext, sizeof(VkExtensionProperties));
        ext_list->count++;
    }
    return VK_SUCCESS;
}

/**
 * Search the given search_list for any layers in the props list.
 * Add these to the output layer_list.  Don't add duplicates to the output layer_list.
 */
static VkResult loader_add_layer_names_to_list(
        const struct loader_instance *inst,
        struct loader_layer_list *output_list,
        uint32_t name_count,
        const char * const *names,
        const struct loader_layer_list *search_list)
{
    struct loader_layer_properties *layer_prop;
    VkResult err = VK_SUCCESS;

    for (uint32_t i = 0; i < name_count; i++) {
        const char *search_target = names[i];
        layer_prop = loader_get_layer_property(search_target, search_list);
        if (!layer_prop) {
            loader_log(VK_DBG_REPORT_ERROR_BIT, 0, "Unable to find layer %s", search_target);
            err = VK_ERROR_LAYER_NOT_PRESENT;
            continue;
        }

        loader_add_to_layer_list(inst, output_list, 1, layer_prop);
    }

    return err;
}


/*
 * Manage lists of VkLayerProperties
 */
static bool loader_init_layer_list(const struct loader_instance *inst,
                                   struct loader_layer_list *list)
{
    list->capacity = 32 * sizeof(struct loader_layer_properties);
    list->list = loader_heap_alloc(inst, list->capacity, VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE);
    if (list->list == NULL) {
        return false;
    }
    memset(list->list, 0, list->capacity);
    list->count = 0;
    return true;
}

void loader_destroy_layer_list(const struct loader_instance *inst,
                               struct loader_layer_list *layer_list)
{
    loader_heap_free(inst, layer_list->list);
    layer_list->count = 0;
    layer_list->capacity = 0;
}

/*
 * Manage list of layer libraries (loader_lib_info)
 */
static bool loader_init_layer_library_list(const struct loader_instance *inst,
                                           struct loader_layer_library_list *list)
{
    list->capacity = 32 * sizeof(struct loader_lib_info);
    list->list = loader_heap_alloc(inst, list->capacity, VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE);
    if (list->list == NULL) {
        return false;
    }
    memset(list->list, 0, list->capacity);
    list->count = 0;
    return true;
}

void loader_destroy_layer_library_list(const struct loader_instance *inst,
                                       struct loader_layer_library_list *list)
{
    for (uint32_t i = 0; i < list->count; i++) {
        loader_heap_free(inst, list->list[i].lib_name);
    }
    loader_heap_free(inst, list->list);
    list->count = 0;
    list->capacity = 0;
}

void loader_add_to_layer_library_list(
        const struct loader_instance *inst,
        struct loader_layer_library_list *list,
        uint32_t item_count,
        const struct loader_lib_info *new_items)
{
    uint32_t i;
    struct loader_lib_info *item;

    if (list->list == NULL || list->capacity == 0) {
        loader_init_layer_library_list(inst, list);
    }

    if (list->list == NULL)
        return;

    for (i = 0; i < item_count; i++) {
        item = (struct loader_lib_info *) &new_items[i];

        // look for duplicates
        for (uint32_t j = 0; j < list->count; j++) {
            if (strcmp(list->list[i].lib_name, new_items->lib_name) == 0) {
                continue;
            }
        }

        // add to list at end
        // check for enough capacity
        if (list->count * sizeof(struct loader_lib_info)
                        >= list->capacity) {

            list->list = loader_heap_realloc(inst,
                                             list->list,
                                             list->capacity,
                                             list->capacity * 2,
                                             VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE);
            // double capacity
            list->capacity *= 2;
        }

        memcpy(&list->list[list->count], item, sizeof(struct loader_lib_info));
        list->count++;
    }
}


/*
 * Search the given layer list for a list
 * matching the given VkLayerProperties
 */
bool has_vk_layer_property(
        const VkLayerProperties *vk_layer_prop,
        const struct loader_layer_list *list)
{
    for (uint32_t i = 0; i < list->count; i++) {
        if (strcmp(vk_layer_prop->layerName, list->list[i].info.layerName) == 0)
            return true;
    }
    return false;
}

/*
 * Search the given layer list for a layer
 * matching the given name
 */
bool has_layer_name(
        const char *name,
        const struct loader_layer_list *list)
{
    for (uint32_t i = 0; i < list->count; i++) {
        if (strcmp(name, list->list[i].info.layerName) == 0)
            return true;
    }
    return false;
}

/*
 * Append non-duplicate layer properties defined in prop_list
 * to the given layer_info list
 */
void loader_add_to_layer_list(
        const struct loader_instance *inst,
        struct loader_layer_list *list,
        uint32_t prop_list_count,
        const struct loader_layer_properties *props)
{
    uint32_t i;
    struct loader_layer_properties *layer;

    if (list->list == NULL || list->capacity == 0) {
        loader_init_layer_list(inst, list);
    }

    if (list->list == NULL)
        return;

    for (i = 0; i < prop_list_count; i++) {
        layer = (struct loader_layer_properties *) &props[i];

        // look for duplicates
        if (has_vk_layer_property(&layer->info, list)) {
            continue;
        }

        // add to list at end
        // check for enough capacity
        if (list->count * sizeof(struct loader_layer_properties)
                        >= list->capacity) {

            list->list = loader_heap_realloc(inst,
                                             list->list,
                                             list->capacity,
                                             list->capacity * 2,
                                             VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE);
            // double capacity
            list->capacity *= 2;
        }

        memcpy(&list->list[list->count], layer, sizeof(struct loader_layer_properties));
        list->count++;
    }
}

/**
 * Search the search_list for any layer with a name
 * that matches the given name and a type that matches the given type
 * Add all matching layers to the found_list
 * Do not add if found loader_layer_properties is already
 * on the found_list.
 */
static void loader_find_layer_name_add_list(
        const struct loader_instance *inst,
        const char *name,
        const enum layer_type type,
        const struct loader_layer_list *search_list,
        struct loader_layer_list *found_list)
{
    bool found = false;
    for (uint32_t i = 0; i < search_list->count; i++) {
        struct loader_layer_properties *layer_prop = &search_list->list[i];
        if (0 == strcmp(layer_prop->info.layerName, name) &&
                (layer_prop->type & type)) {
            /* Found a layer with the same name, add to found_list */
            loader_add_to_layer_list(inst, found_list, 1, layer_prop);
            found = true;
        }
    }
    if (!found) {
        loader_log(VK_DBG_REPORT_WARN_BIT, 0, "Warning, couldn't find layer name %s to activate", name);
    }
}

static VkExtensionProperties *get_extension_property(
        const char *name,
        const struct loader_extension_list *list)
{
    for (uint32_t i = 0; i < list->count; i++) {
        if (strcmp(name, list->list[i].extensionName) == 0)
            return &list->list[i];
    }
    return NULL;
}

/*
 * For global exenstions 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 logica 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.
 */

void loader_get_icd_loader_instance_extensions(
                                        const struct loader_instance *inst,
                                        struct loader_icd_libs *icd_libs,
                                        struct loader_extension_list *inst_exts)
{
    struct loader_extension_list icd_exts;
    loader_log(VK_DBG_REPORT_DEBUG_BIT, 0, "Build ICD instance extension list");
    // traverse scanned icd list adding non-duplicate extensions to the list
    for (uint32_t i = 0; i < icd_libs->count; i++) {
        loader_init_ext_list(inst, &icd_exts);
        loader_add_global_extensions(inst, icd_libs->list[i].EnumerateInstanceExtensionProperties,
                                     icd_libs->list[i].lib_name,
                                     &icd_exts);
        loader_add_to_ext_list(inst, inst_exts,
                               icd_exts.count,
                               icd_exts.list);
        loader_destroy_ext_list(inst, &icd_exts);
    };

    // Traverse loader's extensions, adding non-duplicate extensions to the list
    wsi_add_instance_extensions(inst, inst_exts);
    debug_report_add_instance_extensions(inst, inst_exts);
}

struct loader_icd *loader_get_icd_and_device(const VkDevice device,
                                             struct loader_device **found_dev)
{
    *found_dev = NULL;
    for (struct loader_instance *inst = loader.instances; inst; inst = inst->next) {
        for (struct loader_icd *icd = inst->icds; icd; icd = icd->next) {
            for (struct loader_device *dev = icd->logical_device_list; dev; dev = dev->next)
                /* Value comparison of device prevents object wrapping by layers */
                if (loader_get_dispatch(dev->device) == loader_get_dispatch(device)) {
                    *found_dev = dev;
                    return icd;
                }
        }
    }
    return NULL;
}

static void loader_destroy_logical_device(const struct loader_instance *inst,
                                          struct loader_device *dev)
{
    loader_heap_free(inst, dev->app_extension_props);
    if (dev->activated_layer_list.count)
        loader_destroy_layer_list(inst, &dev->activated_layer_list);
    loader_heap_free(inst, dev);
}

static struct loader_device *loader_add_logical_device(
                                        const struct loader_instance *inst,
                                        const VkDevice dev,
                                        struct loader_device **device_list)
{
    struct loader_device *new_dev;

    new_dev = loader_heap_alloc(inst, sizeof(struct loader_device), VK_SYSTEM_ALLOCATION_SCOPE_DEVICE);
    if (!new_dev) {
        loader_log(VK_DBG_REPORT_ERROR_BIT, 0, "Failed to alloc struct laoder-device");
        return NULL;
    }

    memset(new_dev, 0, sizeof(struct loader_device));

    new_dev->next = *device_list;
    new_dev->device = dev;
    *device_list = new_dev;
    return new_dev;
}

void loader_remove_logical_device(
                            const struct loader_instance *inst,
                            struct loader_icd *icd,
                            struct loader_device *found_dev)
{
    struct loader_device *dev, *prev_dev;

    if (!icd || !found_dev)
        return;

    prev_dev = NULL;
    dev = icd->logical_device_list;
    while (dev && dev != found_dev) {
        prev_dev = dev;
        dev = dev->next;
    }

    if (prev_dev)
        prev_dev->next = found_dev->next;
    else
        icd->logical_device_list = found_dev->next;
    loader_destroy_logical_device(inst, found_dev);
}


static void loader_icd_destroy(
        struct loader_instance *ptr_inst,
        struct loader_icd *icd)
{
    ptr_inst->total_icd_count--;
    for (struct loader_device *dev = icd->logical_device_list; dev; ) {
        struct loader_device *next_dev = dev->next;
        loader_destroy_logical_device(ptr_inst, dev);
        dev = next_dev;
    }

    loader_heap_free(ptr_inst, icd);
}

static struct loader_icd * loader_icd_create(const struct loader_instance *inst)
{
    struct loader_icd *icd;

    icd = loader_heap_alloc(inst, sizeof(*icd), VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE);
    if (!icd)
        return NULL;

    memset(icd, 0, sizeof(*icd));

    return icd;
}

static struct loader_icd *loader_icd_add(
        struct loader_instance *ptr_inst,
        const struct loader_scanned_icds *icd_lib)
{
    struct loader_icd *icd;

    icd = loader_icd_create(ptr_inst);
    if (!icd)
        return NULL;

    icd->this_icd_lib = icd_lib;
    icd->this_instance = ptr_inst;

    /* prepend to the list */
    icd->next = ptr_inst->icds;
    ptr_inst->icds = icd;
    ptr_inst->total_icd_count++;

    return icd;
}

void loader_scanned_icd_clear(
                            const struct loader_instance *inst,
                            struct loader_icd_libs *icd_libs)
{
    if (icd_libs->capacity == 0)
        return;
    for (uint32_t i = 0; i < icd_libs->count; i++) {
        loader_platform_close_library(icd_libs->list[i].handle);
        loader_heap_free(inst, icd_libs->list[i].lib_name);
    }
    loader_heap_free(inst, icd_libs->list);
    icd_libs->capacity = 0;
    icd_libs->count = 0;
    icd_libs->list = NULL;
}

static void loader_scanned_icd_init(const struct loader_instance *inst,
                                    struct loader_icd_libs *icd_libs)
{
    loader_scanned_icd_clear(inst, icd_libs);
    icd_libs->capacity = 8 * sizeof(struct loader_scanned_icds);
    icd_libs->list = loader_heap_alloc(inst, icd_libs->capacity, VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE);

}

static void loader_scanned_icd_add(
                            const struct loader_instance *inst,
                            struct loader_icd_libs *icd_libs,
                            const char *filename,
                            uint32_t api_version)
{
    loader_platform_dl_handle handle;
    PFN_vkCreateInstance fp_create_inst;
    PFN_vkEnumerateInstanceExtensionProperties fp_get_global_ext_props;
    PFN_vkGetInstanceProcAddr fp_get_proc_addr;
    struct loader_scanned_icds *new_node;

    /* TODO implement ref counting of libraries, for now this function leaves
       libraries open and the scanned_icd_clear closes them */
    // Used to call: dlopen(filename, RTLD_LAZY);
    handle = loader_platform_open_library(filename);
    if (!handle) {
        loader_log(VK_DBG_REPORT_WARN_BIT, 0, loader_platform_open_library_error(filename));
        return;
    }

#define LOOKUP_LD(func_ptr, func) do {                            \
    func_ptr = (PFN_vk ##func) loader_platform_get_proc_address(handle, "vk" #func); \
    if (!func_ptr) {                                           \
        loader_log(VK_DBG_REPORT_WARN_BIT, 0, loader_platform_get_proc_address_error("vk" #func)); \
        return;                                                \
    }                                                          \
} while (0)

    LOOKUP_LD(fp_get_proc_addr, GetInstanceProcAddr);
    LOOKUP_LD(fp_create_inst, CreateInstance);
    LOOKUP_LD(fp_get_global_ext_props, EnumerateInstanceExtensionProperties);

#undef LOOKUP_LD

    // check for enough capacity
    if ((icd_libs->count * sizeof(struct loader_scanned_icds)) >= icd_libs->capacity) {

            icd_libs->list = loader_heap_realloc(inst,
                                                 icd_libs->list,
                                                 icd_libs->capacity,
                                                 icd_libs->capacity * 2,
                                                 VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE);
            // double capacity
            icd_libs->capacity *= 2;
    }
    new_node = &(icd_libs->list[icd_libs->count]);

    new_node->handle = handle;
    new_node->api_version = api_version;
    new_node->GetInstanceProcAddr = fp_get_proc_addr;
    new_node->CreateInstance = fp_create_inst;
    new_node->EnumerateInstanceExtensionProperties = fp_get_global_ext_props;

    new_node->lib_name = (char *) loader_heap_alloc(inst,
                                            strlen(filename) + 1,
                                            VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE);
    if (!new_node->lib_name) {
        loader_log(VK_DBG_REPORT_WARN_BIT, 0, "Out of memory can't add icd");
        return;
    }
    strcpy(new_node->lib_name, filename);
    icd_libs->count++;
}

static bool loader_icd_init_entrys(struct loader_icd *icd,
                                   VkInstance inst,
                                   const PFN_vkGetInstanceProcAddr fp_gipa)
{
    /* initialize entrypoint function pointers */

    #define LOOKUP_GIPA(func, required) do {                       \
    icd->func = (PFN_vk ##func) fp_gipa(inst, "vk" #func);         \
    if (!icd->func && required) {                                  \
        loader_log(VK_DBG_REPORT_WARN_BIT, 0,                      \
              loader_platform_get_proc_address_error("vk" #func)); \
        return false;                                              \
    }                                                              \
    } while (0)

    LOOKUP_GIPA(GetDeviceProcAddr, true);
    LOOKUP_GIPA(DestroyInstance, true);
    LOOKUP_GIPA(EnumeratePhysicalDevices, true);
    LOOKUP_GIPA(GetPhysicalDeviceFeatures, true);
    LOOKUP_GIPA(GetPhysicalDeviceFormatProperties, true);
    LOOKUP_GIPA(GetPhysicalDeviceImageFormatProperties, true);
    LOOKUP_GIPA(CreateDevice, true);
    LOOKUP_GIPA(GetPhysicalDeviceProperties, true);
    LOOKUP_GIPA(GetPhysicalDeviceMemoryProperties, true);
    LOOKUP_GIPA(GetPhysicalDeviceQueueFamilyProperties, true);
    LOOKUP_GIPA(EnumerateDeviceExtensionProperties, true);
    LOOKUP_GIPA(GetPhysicalDeviceSparseImageFormatProperties, true);
    LOOKUP_GIPA(DbgCreateMsgCallback, false);
    LOOKUP_GIPA(DbgDestroyMsgCallback, false);
    LOOKUP_GIPA(GetPhysicalDeviceSurfaceSupportKHR, false);
    LOOKUP_GIPA(GetPhysicalDeviceSurfaceCapabilitiesKHR, false);
    LOOKUP_GIPA(GetPhysicalDeviceSurfaceFormatsKHR, false);
    LOOKUP_GIPA(GetPhysicalDeviceSurfacePresentModesKHR, false);
#ifdef VK_USE_PLATFORM_WIN32_KHR
    LOOKUP_GIPA(GetPhysicalDeviceWin32PresentationSupportKHR, false);
#endif
#ifdef VK_USE_PLATFORM_XCB_KHR
    LOOKUP_GIPA(GetPhysicalDeviceXcbPresentationSupportKHR, false);
#endif

#undef LOOKUP_GIPA

    return true;
}

static void loader_debug_init(void)
{
    const char *env;

    if (g_loader_debug > 0)
        return;

    g_loader_debug = 0;

    /* parse comma-separated debug options */
    env = getenv("VK_LOADER_DEBUG");
    while (env) {
        const char *p = strchr(env, ',');
        size_t len;

        if (p)
            len = p - env;
        else
            len = strlen(env);

        if (len > 0) {
            if (strncmp(env, "warn", len) == 0) {
                g_loader_debug |= LOADER_WARN_BIT;
                g_loader_log_msgs |= VK_DBG_REPORT_WARN_BIT;
            } else if (strncmp(env, "info", len) == 0) {
                g_loader_debug |= LOADER_INFO_BIT;
                g_loader_log_msgs |= VK_DBG_REPORT_INFO_BIT;
            } else if (strncmp(env, "perf", len) == 0) {
                g_loader_debug |= LOADER_PERF_BIT;
                g_loader_log_msgs |= VK_DBG_REPORT_PERF_WARN_BIT;
            } else if (strncmp(env, "error", len) == 0) {
                g_loader_debug |= LOADER_ERROR_BIT;
                g_loader_log_msgs |= VK_DBG_REPORT_ERROR_BIT;
            } else if (strncmp(env, "debug", len) == 0) {
                g_loader_debug |= LOADER_DEBUG_BIT;
                g_loader_log_msgs |= VK_DBG_REPORT_DEBUG_BIT;
            }
        }

        if (!p)
            break;

        env = p + 1;
    }
}

void loader_initialize(void)
{
    // initialize mutexs
    loader_platform_thread_create_mutex(&loader_lock);
    loader_platform_thread_create_mutex(&loader_json_lock);

    // initialize logging
    loader_debug_init();

    // initial cJSON to use alloc callbacks
    cJSON_Hooks alloc_fns = {
        .malloc_fn = loader_tls_heap_alloc,
        .free_fn = loader_tls_heap_free,
    };
    cJSON_InitHooks(&alloc_fns);
}

struct loader_manifest_files {
    uint32_t count;
    char **filename_list;
};

/**
 * 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!
 */
static char *loader_get_next_path(char *path)
{
    uint32_t len;
    char *next;

    if (path == NULL)
        return NULL;
    next = strchr(path, PATH_SEPERATOR);
    if (next == NULL) {
        len = (uint32_t) strlen(path);
        next = path + len;
    }
    else {
        *next = '\0';
        next++;
    }

    return next;
}

/**
 * Given a path which is absolute or relative, expand the path if relative or
 * leave the path unmodified if absolute. The base path to prepend to relative
 * paths is given in rel_base.
 *
 * \returns
 * A string in out_fullpath of the full absolute path
 */
static void loader_expand_path(const char *path,
                               const char *rel_base,
                               size_t out_size,
                               char *out_fullpath)
{
    if (loader_platform_is_path_absolute(path)) {
        // do not prepend a base to an absolute path
        rel_base = "";
    }

    loader_platform_combine_path(out_fullpath, out_size, rel_base, path, NULL);
}

/**
 * Given a filename (file)  and a list of paths (dir), try to find an existing
 * file in the paths.  If filename already is a path then no
 * searching in the given paths.
 *
 * \returns
 * A string in out_fullpath of either the full path or file.
 */
static void loader_get_fullpath(const char *file,
                                const char *dirs,
                                size_t out_size,
                                char *out_fullpath)
{
    if (!loader_platform_is_path(file) && *dirs) {
        char *dirs_copy, *dir, *next_dir;

        dirs_copy = loader_stack_alloc(strlen(dirs) + 1);
        strcpy(dirs_copy, dirs);

        //find if file exists after prepending paths in given list
        for (dir = dirs_copy;
             *dir && (next_dir = loader_get_next_path(dir));
             dir = next_dir) {
            loader_platform_combine_path(out_fullpath, out_size, dir, file, NULL);
            if (loader_platform_file_exists(out_fullpath)) {
                return;
            }
        }
    }

    snprintf(out_fullpath, out_size, "%s", file);
}

/**
 * Read a JSON file into a buffer.
 *
 * \returns
 * A pointer to a cJSON object representing the JSON parse tree.
 * This returned buffer should be freed by caller.
 */
static cJSON *loader_get_json(const char *filename)
{
    FILE *file;
    char *json_buf;
    cJSON *json;
    uint64_t len;
    file = fopen(filename,"rb");
    if (!file) {
        loader_log(VK_DBG_REPORT_ERROR_BIT, 0, "Couldn't open JSON file %s", filename);
        return NULL;
    }
    fseek(file, 0, SEEK_END);
    len = ftell(file);
    fseek(file, 0, SEEK_SET);
    json_buf = (char*) loader_stack_alloc(len+1);
    if (json_buf == NULL) {
        loader_log(VK_DBG_REPORT_ERROR_BIT, 0, "Out of memory can't get JSON file");
        fclose(file);
        return NULL;
    }
    if (fread(json_buf, sizeof(char), len, file) != len) {
        loader_log(VK_DBG_REPORT_ERROR_BIT, 0, "fread failed can't get JSON file");
        fclose(file);
        return NULL;
    }
    fclose(file);
    json_buf[len] = '\0';

    //parse text from file
    json = cJSON_Parse(json_buf);
    if (json == NULL)
        loader_log(VK_DBG_REPORT_ERROR_BIT, 0, "Can't parse JSON file %s", filename);
    return json;
}

/**
 * Do a deep copy of the loader_layer_properties structure.
 */
static void loader_copy_layer_properties(
                            const struct loader_instance *inst,
                            struct loader_layer_properties *dst,
                            struct loader_layer_properties *src)
{
    memcpy(dst, src, sizeof (*src));
    dst->instance_extension_list.list = loader_heap_alloc(
                                        inst,
                                        sizeof(VkExtensionProperties) *
                                        src->instance_extension_list.count,
                                        VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE);
    dst->instance_extension_list.capacity = sizeof(VkExtensionProperties) *
                                        src->instance_extension_list.count;
    memcpy(dst->instance_extension_list.list, src->instance_extension_list.list,
                                        dst->instance_extension_list.capacity);
    dst->device_extension_list.list = loader_heap_alloc(
                                        inst,
                                        sizeof(VkExtensionProperties) *
                                        src->device_extension_list.count,
                                        VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE);
    dst->device_extension_list.capacity = sizeof(VkExtensionProperties) *
                                        src->device_extension_list.count;
    memcpy(dst->device_extension_list.list, src->device_extension_list.list,
                                        dst->device_extension_list.capacity);
}

/**
 * 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.
 */
static void loader_add_layer_properties(const struct loader_instance *inst,
                                        struct loader_layer_list *layer_instance_list,
                                        struct loader_layer_list *layer_device_list,
                                        cJSON *json,
                                        bool is_implicit,
                                        char *filename)
{
    /* Fields in layer manifest file that are required:
     * (required) “file_format_version”
     * following are required in the "layer" object:
     * (required) "name"
     * (required) "type"
     * (required) “library_path”
     * (required) “api_version”
     * (required) “implementation_version”
     * (required) “description”
     * (required for implicit layers) “disable_environment”
     *
     * First get all required items and if any missing abort
     */

    cJSON *item, *layer_node, *ext_item;
    char *temp;
    char *name, *type, *library_path, *api_version;
    char *implementation_version, *description;
    cJSON *disable_environment;
    int i;
    VkExtensionProperties ext_prop;
    item = cJSON_GetObjectItem(json, "file_format_version");
    if (item == NULL) {
        return;
    }
    char *file_vers = cJSON_PrintUnformatted(item);
    loader_log(VK_DBG_REPORT_INFO_BIT, 0, "Found manifest file %s, version %s",
               filename, file_vers);
    if (strcmp(file_vers, "\"1.0.0\"") != 0)
        loader_log(VK_DBG_REPORT_WARN_BIT, 0, "Unexpected manifest file version (expected 1.0.0), may cause errors");
    loader_tls_heap_free(file_vers);

    layer_node = cJSON_GetObjectItem(json, "layer");
    if (layer_node == NULL) {
        loader_log(VK_DBG_REPORT_WARN_BIT, 0, "Can't find \"layer\" object in manifest JSON file, skipping");
        return;
    }

    // loop through all "layer" objects in the file
    do {
#define GET_JSON_OBJECT(node, var) {                  \
        var = cJSON_GetObjectItem(node, #var);        \
        if (var == NULL) {                            \
            layer_node = layer_node->next;            \
            continue;                                 \
        }                                             \
        }
#define GET_JSON_ITEM(node, var) {                    \
        item = cJSON_GetObjectItem(node, #var);       \
        if (item == NULL) {                           \
            layer_node = layer_node->next;            \
            continue;                                 \
        }                                             \
        temp = cJSON_Print(item);                     \
        temp[strlen(temp) - 1] = '\0';                \
        var = loader_stack_alloc(strlen(temp) + 1);   \
        strcpy(var, &temp[1]);                        \
        loader_tls_heap_free(temp);                   \
        }
        GET_JSON_ITEM(layer_node, name)
        GET_JSON_ITEM(layer_node, type)
        GET_JSON_ITEM(layer_node, library_path)
        GET_JSON_ITEM(layer_node, api_version)
        GET_JSON_ITEM(layer_node, implementation_version)
        GET_JSON_ITEM(layer_node, description)
        if (is_implicit) {
            GET_JSON_OBJECT(layer_node, disable_environment)
        }
#undef GET_JSON_ITEM
#undef GET_JSON_OBJECT

        // add list entry
        struct loader_layer_properties *props=NULL;
        if (!strcmp(type, "DEVICE")) {
            if (layer_device_list == NULL) {
                layer_node = layer_node->next;
                continue;
            }
            props = loader_get_next_layer_property(inst, layer_device_list);
            props->type = (is_implicit) ? VK_LAYER_TYPE_DEVICE_IMPLICIT : VK_LAYER_TYPE_DEVICE_EXPLICIT;
        }
        if (!strcmp(type, "INSTANCE")) {
            if (layer_instance_list == NULL) {
                layer_node = layer_node->next;
                continue;
            }
            props = loader_get_next_layer_property(inst, layer_instance_list);
            props->type = (is_implicit) ? VK_LAYER_TYPE_INSTANCE_IMPLICIT : VK_LAYER_TYPE_INSTANCE_EXPLICIT;
        }
        if (!strcmp(type, "GLOBAL")) {
            if (layer_instance_list != NULL)
                props = loader_get_next_layer_property(inst, layer_instance_list);
            else if (layer_device_list != NULL)
                props = loader_get_next_layer_property(inst, layer_device_list);
            else {
                layer_node = layer_node->next;
                continue;
            }
            props->type = (is_implicit) ? VK_LAYER_TYPE_GLOBAL_IMPLICIT : VK_LAYER_TYPE_GLOBAL_EXPLICIT;
        }

        if (props == NULL) {
            layer_node = layer_node->next;
            continue;
        }

        strncpy(props->info.layerName, name, sizeof (props->info.layerName));
        props->info.layerName[sizeof (props->info.layerName) - 1] = '\0';

        char *fullpath = props->lib_name;
        char *rel_base;
        if (loader_platform_is_path(filename)) {
            // a relative or absolute path
            char *name_copy = loader_stack_alloc(strlen(filename) + 1);
            strcpy(name_copy, filename);
            rel_base = loader_platform_dirname(name_copy);
            loader_expand_path(library_path, rel_base, MAX_STRING_SIZE, fullpath);
        } else {
            // a filename which is assumed in a system directory
            loader_get_fullpath(library_path, DEFAULT_VK_LAYERS_PATH, MAX_STRING_SIZE, fullpath);
        }
        props->info.specVersion = loader_make_version(api_version);
        props->info.implementationVersion = atoi(implementation_version);
        strncpy((char *) props->info.description, description, sizeof (props->info.description));
        props->info.description[sizeof (props->info.description) - 1] = '\0';
        if (is_implicit) {
            strncpy(props->disable_env_var.name, disable_environment->child->string, sizeof (props->disable_env_var.name));
            props->disable_env_var.name[sizeof (props->disable_env_var.name) - 1] = '\0';
            strncpy(props->disable_env_var.value, disable_environment->child->valuestring, sizeof (props->disable_env_var.value));
            props->disable_env_var.value[sizeof (props->disable_env_var.value) - 1] = '\0';
        }

        /**
         * Now get all optional items and objects and put in list:
         * functions
         * instance_extensions
         * device_extensions
         * enable_environment (implicit layers only)
         */
#define GET_JSON_OBJECT(node, var) {                  \
        var = cJSON_GetObjectItem(node, #var);        \
        }
#define GET_JSON_ITEM(node, var) {                    \
        item = cJSON_GetObjectItem(node, #var);       \
        if (item != NULL) {                           \
            temp = cJSON_Print(item);                 \
            temp[strlen(temp) - 1] = '\0';            \
            var = loader_stack_alloc(strlen(temp) + 1);\
            strcpy(var, &temp[1]);                    \
            loader_tls_heap_free(temp);               \
        }                                             \
        }

        cJSON *instance_extensions, *device_extensions, *functions, *enable_environment;
        char *vkGetInstanceProcAddr = NULL, *vkGetDeviceProcAddr = NULL, *spec_version=NULL;
        GET_JSON_OBJECT(layer_node, functions)
        if (functions != NULL) {
            GET_JSON_ITEM(functions, vkGetInstanceProcAddr)
            GET_JSON_ITEM(functions, vkGetDeviceProcAddr)
            if (vkGetInstanceProcAddr != NULL)
                strncpy(props->functions.str_gipa, vkGetInstanceProcAddr, sizeof (props->functions.str_gipa));
            props->functions.str_gipa[sizeof (props->functions.str_gipa) - 1] = '\0';
            if (vkGetDeviceProcAddr != NULL)
                strncpy(props->functions.str_gdpa, vkGetDeviceProcAddr, sizeof (props->functions.str_gdpa));
            props->functions.str_gdpa[sizeof (props->functions.str_gdpa) - 1] = '\0';
        }
        GET_JSON_OBJECT(layer_node, instance_extensions)
        if (instance_extensions != NULL) {
            int count = cJSON_GetArraySize(instance_extensions);
            for (i = 0; i < count; i++) {
                ext_item = cJSON_GetArrayItem(instance_extensions, i);
                GET_JSON_ITEM(ext_item, name)
                GET_JSON_ITEM(ext_item, spec_version)
                strncpy(ext_prop.extensionName, name, sizeof (ext_prop.extensionName));
                ext_prop.extensionName[sizeof (ext_prop.extensionName) - 1] = '\0';
                ext_prop.specVersion = atoi(spec_version);
                loader_add_to_ext_list(inst, &props->instance_extension_list, 1, &ext_prop);
            }
        }
        GET_JSON_OBJECT(layer_node, device_extensions)
        if (device_extensions != NULL) {
            int count = cJSON_GetArraySize(device_extensions);
            for (i = 0; i < count; i++) {
                ext_item = cJSON_GetArrayItem(device_extensions, i);
                GET_JSON_ITEM(ext_item, name);
                GET_JSON_ITEM(ext_item, spec_version);
                strncpy(ext_prop.extensionName, name, sizeof (ext_prop.extensionName));
                ext_prop.extensionName[sizeof (ext_prop.extensionName) - 1] = '\0';
                ext_prop.specVersion = atoi(spec_version);
                loader_add_to_ext_list(inst, &props->device_extension_list, 1, &ext_prop);
            }
        }
        if (is_implicit) {
            GET_JSON_OBJECT(layer_node, enable_environment)
            strncpy(props->enable_env_var.name, enable_environment->child->string, sizeof (props->enable_env_var.name));
            props->enable_env_var.name[sizeof (props->enable_env_var.name) - 1] = '\0';
            strncpy(props->enable_env_var.value, enable_environment->child->valuestring, sizeof (props->enable_env_var.value));
            props->enable_env_var.value[sizeof (props->enable_env_var.value) - 1] = '\0';
        }
#undef GET_JSON_ITEM
#undef GET_JSON_OBJECT
        // for global layers need to add them to both device and instance list
        if (!strcmp(type, "GLOBAL")) {
            struct loader_layer_properties *dev_props;
            if (layer_instance_list == NULL || layer_device_list == NULL) {
                layer_node = layer_node->next;
                continue;
            }
            dev_props = loader_get_next_layer_property(inst, layer_device_list);
            //copy into device layer list
            loader_copy_layer_properties(inst, dev_props, props);
        }
        layer_node = layer_node->next;
    } while (layer_node != NULL);
    return;
}

/**
 * Find the Vulkan library manifest files.
 *
 * This function scans the location or env_override directories/files
 * for a list of JSON manifest files.  If env_override is non-NULL
 * and has a valid value. Then the location is ignored.  Otherwise
 * location is used to look for manifest files. The location
 * is interpreted as  Registry path on Windows and a directory path(s)
 * on Linux.
 *
 * \returns
 * 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
 */
static void loader_get_manifest_files(const struct loader_instance *inst,
                                      const char *env_override,
                                      bool is_layer,
                                      const char *location,
                                      struct loader_manifest_files *out_files)
{
    char *override = NULL;
    char *loc;
    char *file, *next_file, *name;
    size_t alloced_count = 64;
    char full_path[2048];
    DIR *sysdir = NULL;
    bool list_is_dirs = false;
    struct dirent *dent;

    out_files->count = 0;
    out_files->filename_list = NULL;

    if (env_override != NULL && (override = getenv(env_override))) {
#if !defined(_WIN32)
        if (geteuid() != getuid()) {
            /* Don't allow setuid apps to use the env var: */
            override = NULL;
        }
#endif
    }

    if (location == NULL) {
        loader_log(VK_DBG_REPORT_ERROR_BIT, 0,
            "Can't get manifest files with NULL location, env_override=%s",
            env_override);
        return;
    }

#if defined(_WIN32)
    list_is_dirs = (is_layer && override != NULL) ? true : false;
#else
    list_is_dirs = (override == NULL || is_layer) ? true : false;
#endif
    // Make a copy of the input we are using so it is not modified
    // Also handle getting the location(s) from registry on Windows
    if (override == NULL) {
        loc = loader_stack_alloc(strlen(location) + 1);
        if (loc == NULL) {
            loader_log(VK_DBG_REPORT_ERROR_BIT, 0, "Out of memory can't get manifest files");
            return;
        }
        strcpy(loc, location);
#if defined(_WIN32)
        loc = loader_get_registry_files(inst, loc);
        if (loc == NULL) {
            loader_log(VK_DBG_REPORT_ERROR_BIT, 0, "Registry lookup failed can't get manifest files");
            return;
        }
#endif
    }
    else {
        loc = loader_stack_alloc(strlen(override) + 1);
        if (loc == NULL) {
            loader_log(VK_DBG_REPORT_ERROR_BIT, 0, "Out of memory can't get manifest files");
            return;
        }
        strcpy(loc, override);
    }

    // Print out the paths being searched if debugging is enabled
    loader_log(VK_DBG_REPORT_DEBUG_BIT, 0, "Searching the following paths for manifest files: %s\n", loc);

    file = loc;
    while (*file) {
        next_file = loader_get_next_path(file);
        if (list_is_dirs) {
            sysdir = opendir(file);
            name = NULL;
            if (sysdir) {
                dent = readdir(sysdir);
                if (dent == NULL)
                    break;
                name = &(dent->d_name[0]);
                loader_get_fullpath(name, file, sizeof(full_path), full_path);
                name = full_path;
            }
        }
        else {
#if defined(_WIN32)
            name = file;
#else
            // only Linux has relative paths
            char *dir;
            // make a copy of location so it isn't modified
            dir = loader_stack_alloc(strlen(loc) + 1);
            if (dir == NULL) {
                loader_log(VK_DBG_REPORT_ERROR_BIT, 0, "Out of memory can't get manifest files");
                return;
            }
            strcpy(dir, loc);

            loader_get_fullpath(file, dir, sizeof(full_path), full_path);

            name = full_path;
#endif
        }
        while (name) {
                /* Look for files ending with ".json" suffix */
                uint32_t nlen = (uint32_t) strlen(name);
                const char *suf = name + nlen - 5;
                if ((nlen > 5) && !strncmp(suf, ".json", 5)) {
                    if (out_files->count == 0) {
                        out_files->filename_list = loader_heap_alloc(inst,
                                              alloced_count * sizeof(char *),
                                              VK_SYSTEM_ALLOCATION_SCOPE_COMMAND);
                    }
                    else if (out_files->count == alloced_count) {
                        out_files->filename_list = loader_heap_realloc(inst,
                                        out_files->filename_list,
                                        alloced_count * sizeof(char *),
                                        alloced_count * sizeof(char *) * 2,
                                        VK_SYSTEM_ALLOCATION_SCOPE_COMMAND);
                        alloced_count *= 2;
                    }
                    if (out_files->filename_list == NULL) {
                        loader_log(VK_DBG_REPORT_ERROR_BIT, 0, "Out of memory can't alloc manifest file list");
                        return;
                    }
                    out_files->filename_list[out_files->count] = loader_heap_alloc(
                                                inst,
                                                strlen(name) + 1,
                                                VK_SYSTEM_ALLOCATION_SCOPE_COMMAND);
                    if (out_files->filename_list[out_files->count] == NULL) {
                        loader_log(VK_DBG_REPORT_ERROR_BIT, 0, "Out of memory can't get manifest files");
                        return;
                    }
                    strcpy(out_files->filename_list[out_files->count], name);
                    out_files->count++;
                } else if (!list_is_dirs) {
                    loader_log(VK_DBG_REPORT_WARN_BIT, 0, "Skipping manifest file %s, file name must end in .json", name);
                }
                if (list_is_dirs) {
                    dent = readdir(sysdir);
                    if (dent == NULL)
                        break;
                    name = &(dent->d_name[0]);
                    loader_get_fullpath(name, file, sizeof(full_path), full_path);
                    name = full_path;
                }
                else {
                    break;
                }
        }
        if (sysdir)
            closedir(sysdir);
        file = next_file;
    }
    return;
}

void loader_init_icd_lib_list()
{

}

void loader_destroy_icd_lib_list()
{

}
/**
 * Try to find the Vulkan ICD driver(s).
 *
 * This function scans the default system loader path(s) or path
 * specified by the \c VK_ICD_FILENAMES environment variable in
 * order to find loadable VK ICDs manifest files. From these
 * manifest files it finds the ICD libraries.
 *
 * \returns
 * a list of icds that were discovered
 */
void loader_icd_scan(
                     const struct loader_instance *inst,
                     struct loader_icd_libs *icds)
{
    char *file_str;
    struct loader_manifest_files manifest_files;

    loader_scanned_icd_init(inst, icds);
    // Get a list of manifest files for ICDs
    loader_get_manifest_files(inst, "VK_ICD_FILENAMES", false,
                              DEFAULT_VK_DRIVERS_INFO, &manifest_files);
    if (manifest_files.count == 0)
        return;
    loader_platform_thread_lock_mutex(&loader_json_lock);
    for (uint32_t i = 0; i < manifest_files.count; i++) {
        file_str = manifest_files.filename_list[i];
        if (file_str == NULL)
            continue;

        cJSON *json;
        json = loader_get_json(file_str);
        if (!json)
            continue;
        cJSON *item, *itemICD;
        item = cJSON_GetObjectItem(json, "file_format_version");
        if (item == NULL) {
            loader_platform_thread_unlock_mutex(&loader_json_lock);
            return;
        }
        char *file_vers = cJSON_Print(item);
        loader_log(VK_DBG_REPORT_INFO_BIT, 0, "Found manifest file %s, version %s",
                   file_str, file_vers);
        if (strcmp(file_vers, "\"1.0.0\"") != 0)
            loader_log(VK_DBG_REPORT_WARN_BIT, 0, "Unexpected manifest file version (expected 1.0.0), may cause errors");
        loader_tls_heap_free(file_vers);
        itemICD = cJSON_GetObjectItem(json, "ICD");
        if (itemICD != NULL) {
            item = cJSON_GetObjectItem(itemICD, "library_path");
            if (item != NULL) {
                char *temp= cJSON_Print(item);
                if (!temp || strlen(temp) == 0) {
                    loader_log(VK_DBG_REPORT_WARN_BIT, 0, "Can't find \"library_path\" in ICD JSON file %s, skipping", file_str);
                    loader_tls_heap_free(temp);
                    loader_heap_free(inst, file_str);
                    cJSON_Delete(json);
                    continue;
                }
                //strip out extra quotes
                temp[strlen(temp) - 1] = '\0';
                char *library_path = loader_stack_alloc(strlen(temp) + 1);
                strcpy(library_path, &temp[1]);
                loader_tls_heap_free(temp);
                if (!library_path || strlen(library_path) == 0) {
                    loader_log(VK_DBG_REPORT_WARN_BIT, 0, "Can't find \"library_path\" in ICD JSON file %s, skipping", file_str);
                    loader_heap_free(inst, file_str);
                    cJSON_Delete(json);
                    continue;
                }
                char fullpath[MAX_STRING_SIZE];
                // Print out the paths being searched if debugging is enabled
                loader_log(VK_DBG_REPORT_DEBUG_BIT, 0, "Searching for ICD drivers named %s default dir %s\n", library_path, DEFAULT_VK_DRIVERS_PATH);
                if (loader_platform_is_path(library_path)) {
                    // a relative or absolute path
                    char *name_copy = loader_stack_alloc(strlen(file_str) + 1);
                    char *rel_base;
                    strcpy(name_copy, file_str);
                    rel_base = loader_platform_dirname(name_copy);
                    loader_expand_path(library_path, rel_base, sizeof(fullpath), fullpath);
                } else {
                    // a filename which is assumed in a system directory
                    loader_get_fullpath(library_path, DEFAULT_VK_DRIVERS_PATH, sizeof(fullpath), fullpath);
                }

                uint32_t vers = 0;
                item = cJSON_GetObjectItem(itemICD, "api_version");
                if (item != NULL) {
                    temp= cJSON_Print(item);
                    vers = loader_make_version(temp);
                    loader_tls_heap_free(temp);
                }
                loader_scanned_icd_add(inst, icds, fullpath, vers);
            }
            else
                loader_log(VK_DBG_REPORT_WARN_BIT, 0, "Can't find \"library_path\" object in ICD JSON file %s, skipping", file_str);
        }
        else
            loader_log(VK_DBG_REPORT_WARN_BIT, 0, "Can't find \"ICD\" object in ICD JSON file %s, skipping", file_str);

        loader_heap_free(inst, file_str);
        cJSON_Delete(json);
    }
    loader_heap_free(inst, manifest_files.filename_list);
    loader_platform_thread_unlock_mutex(&loader_json_lock);
}


void loader_layer_scan(
                       const struct loader_instance *inst,
                       struct loader_layer_list *instance_layers,
                       struct loader_layer_list *device_layers)
{
    char *file_str;
    struct loader_manifest_files manifest_files;
    cJSON *json;
    uint32_t i;

    // Get a list of manifest files for layers
    loader_get_manifest_files(inst, LAYERS_PATH_ENV, true, DEFAULT_VK_LAYERS_INFO,
                              &manifest_files);
    if (manifest_files.count == 0)
        return;

#if 0 //TODO
    /**
     * We need a list of the layer libraries, not just a list of
     * the layer properties (a layer library could expose more than
     * one layer property). This list of scanned layers would be
     * used to check for global and physicaldevice layer properties.
     */
    if (!loader_init_layer_library_list(&loader.scanned_layer_libraries)) {
        loader_log(VK_DBG_REPORT_ERROR_BIT, 0,
                   "Alloc for layer list failed: %s line: %d", __FILE__, __LINE__);
        return;
    }
#endif

    /* cleanup any previously scanned libraries */
    loader_delete_layer_properties(inst, instance_layers);
    loader_delete_layer_properties(inst, device_layers);

    loader_platform_thread_lock_mutex(&loader_json_lock);
    for (i = 0; i < manifest_files.count; i++) {
        file_str = manifest_files.filename_list[i];
        if (file_str == NULL)
            continue;

        // parse file into JSON struct
        json = loader_get_json(file_str);
        if (!json) {
            continue;
        }

        //TODO pass in implicit versus explicit bool
        //TODO error if device layers expose instance_extensions
        //TODO error if instance layers expose device extensions
        loader_add_layer_properties(inst,
                                    instance_layers,
                                    device_layers,
                                    json,
                                    false,
                                    file_str);

        loader_heap_free(inst, file_str);
        cJSON_Delete(json);
    }
    loader_heap_free(inst, manifest_files.filename_list);
    loader_platform_thread_unlock_mutex(&loader_json_lock);
}

static VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL loader_gpa_instance_internal(VkInstance inst, const char * pName)
{
    // inst is not wrapped
    if (inst == VK_NULL_HANDLE) {
        return NULL;
    }
    VkLayerInstanceDispatchTable* disp_table = * (VkLayerInstanceDispatchTable **) inst;
    void *addr;

    if (!strcmp(pName, "vkGetInstanceProcAddr"))
        return (void *) loader_gpa_instance_internal;

    if (disp_table == NULL)
        return NULL;

    addr = loader_lookup_instance_dispatch_table(disp_table, pName);
    if (addr) {
        return addr;
    }

    if (disp_table->GetInstanceProcAddr == NULL) {
        return NULL;
    }
    return disp_table->GetInstanceProcAddr(inst, pName);
}

/**
 * Initialize device_ext dispatch table entry as follows:
 * If dev == NULL find all logical devices created within this instance and
 *  init the entry (given by idx) in the ext dispatch table.
 * If dev != NULL only initialize the entry in the given dev's dispatch table.
 * The initialization value is gotten by calling down the device chain with GDPA.
 * If GDPA returns NULL then don't initialize the dispatch table entry.
 */
static void loader_init_dispatch_dev_ext_entry(struct loader_instance *inst,
                                         struct loader_device *dev,
                                         uint32_t idx,
                                         const char *funcName)

 {
    void *gdpa_value;
    if (dev != NULL) {
        gdpa_value = dev->loader_dispatch.core_dispatch.GetDeviceProcAddr(
                                                    dev->device, funcName);
        if (gdpa_value != NULL)
            dev->loader_dispatch.ext_dispatch.DevExt[idx] = (PFN_vkDevExt) gdpa_value;
    } else {
        for (uint32_t i = 0; i < inst->total_icd_count; i++) {
            struct loader_icd *icd = &inst->icds[i];
            struct loader_device *dev = icd->logical_device_list;
            while (dev) {
                gdpa_value = dev->loader_dispatch.core_dispatch.GetDeviceProcAddr(
                                                    dev->device, funcName);
                if (gdpa_value != NULL)
                    dev->loader_dispatch.ext_dispatch.DevExt[idx] =
                                                    (PFN_vkDevExt) gdpa_value;
                dev = dev->next;
            }
        }
    }

}

/**
 * Find all dev extension in the hash table  and initialize the dispatch table
 * for dev  for each of those extension entrypoints found in hash table.

 */
static void loader_init_dispatch_dev_ext(struct loader_instance *inst,
                                         struct loader_device *dev)
{
    for (uint32_t i = 0; i < MAX_NUM_DEV_EXTS; i++) {
        if (inst->disp_hash[i].func_name != NULL)
            loader_init_dispatch_dev_ext_entry(inst, dev, i,
                                               inst->disp_hash[i].func_name);
    }
}

static bool loader_check_icds_for_address(struct loader_instance *inst,
                                          const char *funcName)
{
    struct loader_icd *icd;
    icd = inst->icds;
    while (icd) {
        if (icd->this_icd_lib->GetInstanceProcAddr(icd->instance, funcName))
            // this icd supports funcName
            return true;
        icd = icd->next;
    }

    return false;
}

static void loader_free_dev_ext_table(struct loader_instance *inst)
{
    for (uint32_t i = 0; i < MAX_NUM_DEV_EXTS; i++) {
        loader_heap_free(inst, inst->disp_hash[i].func_name);
        loader_heap_free(inst, inst->disp_hash[i].list.index);

    }
    memset(inst->disp_hash, 0, sizeof(inst->disp_hash));
}

static bool loader_add_dev_ext_table(struct loader_instance *inst,
                                     uint32_t *ptr_idx,
                                     const char *funcName)
{
    uint32_t i;
    uint32_t idx = *ptr_idx;
    struct loader_dispatch_hash_list *list = &inst->disp_hash[idx].list;

    if (!inst->disp_hash[idx].func_name) {
        // no entry here at this idx, so use it
        assert(list->capacity == 0);
        inst->disp_hash[idx].func_name = (char *) loader_heap_alloc(inst,
                                         strlen(funcName) + 1,
                                         VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE);
        if (inst->disp_hash[idx].func_name == NULL) {
            loader_log(VK_DBG_REPORT_ERROR_BIT, 0,
                       "loader_add_dev_ext_table() can't allocate memory for func_name");
            return false;
        }
        strncpy(inst->disp_hash[idx].func_name, funcName, strlen(funcName) + 1);
        return true;
    }

    // check for enough capacity
    if (list->capacity == 0) {
        list->index = loader_heap_alloc(inst, 8 * sizeof(*(list->index)),
                                        VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE);
        if (list->index == NULL) {
            loader_log(VK_DBG_REPORT_ERROR_BIT, 0,
                       "loader_add_dev_ext_table() can't allocate list memory");
            return false;
        }
        list->capacity = 8 * sizeof(*(list->index));
    } else if (list->capacity < (list->count + 1) * sizeof(*(list->index))) {
        list->index = loader_heap_realloc(inst, list->index, list->capacity,
                            list->capacity * 2,
                            VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE);
        if (list->index == NULL) {
            loader_log(VK_DBG_REPORT_ERROR_BIT, 0,
                       "loader_add_dev_ext_table() can't reallocate list memory");
            return false;
        }
        list->capacity *= 2;
    }

    //find an unused index in the hash table and use it
    i = (idx + 1) % MAX_NUM_DEV_EXTS;
    do {
        if (!inst->disp_hash[i].func_name) {
            assert(inst->disp_hash[i].list.capacity == 0);
            inst->disp_hash[i].func_name = (char *) loader_heap_alloc(inst,
                                            strlen(funcName) + 1,
                                            VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE);
            if (inst->disp_hash[i].func_name == NULL) {
                loader_log(VK_DBG_REPORT_ERROR_BIT, 0,
                       "loader_add_dev_ext_table() can't rallocate func_name memory");
                return false;
            }
            strncpy(inst->disp_hash[i].func_name, funcName, strlen(funcName) + 1);
            list->index[list->count] = i;
            list->count++;
            *ptr_idx = i;
            return true;
        }
        i = (i + 1) % MAX_NUM_DEV_EXTS;
    } while (i != idx);

    loader_log(VK_DBG_REPORT_ERROR_BIT, 0,
               "loader_add_dev_ext_table() couldn't insert into hash table; is it full?");
    return false;
}

static bool loader_name_in_dev_ext_table(struct loader_instance *inst,
                                         uint32_t *idx,
                                         const char *funcName)
{
    uint32_t alt_idx;
    if (inst->disp_hash[*idx].func_name && !strcmp(
                                                inst->disp_hash[*idx].func_name,
                                                funcName))
        return true;

    // funcName wasn't at the primary spot in the hash table
    // search the list of secondary locations (shallow search, not deep search)
    for (uint32_t i = 0; i < inst->disp_hash[*idx].list.count; i++) {
        alt_idx = inst->disp_hash[*idx].list.index[i];
        if (!strcmp(inst->disp_hash[*idx].func_name, funcName)) {
            *idx = alt_idx;
            return true;
        }
    }

    return false;
}

/**
 * This function returns generic trampoline code address for unknown entry points.
 * Presumably, these unknown entry points (as given by funcName) are device
 * extension entrypoints.  A hash table is used to keep a list of unknown entry
 * points and their mapping to the device extension dispatch table
 * (struct loader_dev_ext_dispatch_table).
 * \returns
 * For a given entry point string (funcName), if an existing mapping is found the
 * trampoline address for that mapping is returned. Otherwise, this unknown entry point
 * has not been seen yet. Next check if a layer or ICD supports it.  If so then a
 * new entry in the hash table is initialized and that trampoline address for
 * the new entry is returned. Null is returned if the hash table is full or
 * if no discovered layer or ICD returns a non-NULL GetProcAddr for it.
 */
void *loader_dev_ext_gpa(struct loader_instance *inst,
                         const char *funcName)
{
    uint32_t idx;
    uint32_t seed = 0;

    idx = murmurhash(funcName, strlen(funcName), seed) % MAX_NUM_DEV_EXTS;

    if (loader_name_in_dev_ext_table(inst, &idx, funcName))
        // found funcName already in hash
        return loader_get_dev_ext_trampoline(idx);

    // Check if funcName is supported in either ICDs or a layer library
    if (!loader_check_icds_for_address(inst, funcName)) {
        // TODO Add check in layer libraries for support of address
        // if support found in layers continue on
        return NULL;
    }

    if (loader_add_dev_ext_table(inst, &idx, funcName)) {
        // successfully added new table entry
        // init any dev dispatch table entrys as needed
        loader_init_dispatch_dev_ext_entry(inst, NULL, idx, funcName);
        return loader_get_dev_ext_trampoline(idx);
    }

    return NULL;
}

struct loader_instance *loader_get_instance(const VkInstance instance)
{
    /* look up the loader_instance in our list by comparing dispatch tables, as
     * there is no guarantee the instance is still a loader_instance* after any
     * layers which wrap the instance object.
     */
    const VkLayerInstanceDispatchTable *disp;
    struct loader_instance *ptr_instance = NULL;
    disp = loader_get_instance_dispatch(instance);
    for (struct loader_instance *inst = loader.instances; inst; inst = inst->next) {
        if (inst->disp == disp) {
            ptr_instance = inst;
            break;
        }
    }
    return ptr_instance;
}

static loader_platform_dl_handle loader_add_layer_lib(
        const struct loader_instance *inst,
        const char *chain_type,
        struct loader_layer_properties *layer_prop)
{
    struct loader_lib_info *new_layer_lib_list, *my_lib;
    size_t new_alloc_size;
    /*
     * TODO: We can now track this information in the
     * scanned_layer_libraries list.
     */
    for (uint32_t i = 0; i < loader.loaded_layer_lib_count; i++) {
        if (strcmp(loader.loaded_layer_lib_list[i].lib_name, layer_prop->lib_name) == 0) {
            /* Have already loaded this library, just increment ref count */
            loader.loaded_layer_lib_list[i].ref_count++;
            loader_log(VK_DBG_REPORT_DEBUG_BIT, 0,
                       "%s Chain: Increment layer reference count for layer library %s",
                       chain_type, layer_prop->lib_name);
            return loader.loaded_layer_lib_list[i].lib_handle;
        }
    }

    /* Haven't seen this library so load it */
    new_alloc_size = 0;
    if (loader.loaded_layer_lib_capacity == 0)
        new_alloc_size = 8 * sizeof(struct loader_lib_info);
    else if (loader.loaded_layer_lib_capacity <= loader.loaded_layer_lib_count *
                                            sizeof(struct loader_lib_info))
        new_alloc_size = loader.loaded_layer_lib_capacity * 2;

    if (new_alloc_size) {
        new_layer_lib_list = loader_heap_realloc(
                                            inst, loader.loaded_layer_lib_list,
                                            loader.loaded_layer_lib_capacity,
                                            new_alloc_size,
                                            VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE);
        if (!new_layer_lib_list) {
            loader_log(VK_DBG_REPORT_ERROR_BIT, 0, "loader: realloc failed in loader_add_layer_lib");
            return NULL;
        }
        loader.loaded_layer_lib_capacity = new_alloc_size;
    } else
        new_layer_lib_list = loader.loaded_layer_lib_list;
    my_lib = &new_layer_lib_list[loader.loaded_layer_lib_count];

    strncpy(my_lib->lib_name, layer_prop->lib_name, sizeof(my_lib->lib_name));
    my_lib->lib_name[sizeof(my_lib->lib_name) - 1] = '\0';
    my_lib->ref_count = 0;
    my_lib->lib_handle = NULL;

    if ((my_lib->lib_handle = loader_platform_open_library(my_lib->lib_name)) == NULL) {
        loader_log(VK_DBG_REPORT_ERROR_BIT, 0,
                   loader_platform_open_library_error(my_lib->lib_name));
        return NULL;
    } else {
        loader_log(VK_DBG_REPORT_DEBUG_BIT, 0,
                   "Chain: %s: Loading layer library %s",
                   chain_type, layer_prop->lib_name);
    }
    loader.loaded_layer_lib_count++;
    loader.loaded_layer_lib_list = new_layer_lib_list;
    my_lib->ref_count++;

    return my_lib->lib_handle;
}

static void loader_remove_layer_lib(
        struct loader_instance *inst,
        struct loader_layer_properties *layer_prop)
{
    uint32_t idx;
    struct loader_lib_info *new_layer_lib_list, *my_lib = NULL;

    for (uint32_t i = 0; i < loader.loaded_layer_lib_count; i++) {
        if (strcmp(loader.loaded_layer_lib_list[i].lib_name, layer_prop->lib_name) == 0) {
            /* found matching library */
            idx = i;
            my_lib = &loader.loaded_layer_lib_list[i];
            break;
        }
    }

    if (my_lib) {
        my_lib->ref_count--;
        if (my_lib->ref_count > 0) {
            loader_log(VK_DBG_REPORT_DEBUG_BIT, 0,
                       "Decrement reference count for layer library %s", layer_prop->lib_name);
            return;
        }
    }
    loader_platform_close_library(my_lib->lib_handle);
    loader_log(VK_DBG_REPORT_DEBUG_BIT, 0,
               "Unloading layer library %s", layer_prop->lib_name);

    /* Need to remove unused library from list */
    new_layer_lib_list = loader_heap_alloc(inst,
                                           loader.loaded_layer_lib_capacity,
                                           VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE);
    if (!new_layer_lib_list) {
        loader_log(VK_DBG_REPORT_ERROR_BIT, 0, "loader: heap alloc failed loader_remove_layer_library");
        return;
    }

    if (idx > 0) {
        /* Copy records before idx */
        memcpy(new_layer_lib_list, &loader.loaded_layer_lib_list[0],
               sizeof(struct loader_lib_info) * idx);
    }
    if (idx < (loader.loaded_layer_lib_count - 1)) {
        /* Copy records after idx */
        memcpy(&new_layer_lib_list[idx], &loader.loaded_layer_lib_list[idx+1],
                sizeof(struct loader_lib_info) * (loader.loaded_layer_lib_count - idx - 1));
    }

    loader_heap_free(inst, loader.loaded_layer_lib_list);
    loader.loaded_layer_lib_count--;
    loader.loaded_layer_lib_list = new_layer_lib_list;
}


/**
 * 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.
 */
//TODO need to handle implict layer enable env var and disable env var
static void loader_add_layer_implicit(
                const struct loader_instance *inst,
                const enum layer_type type,
                struct loader_layer_list *list,
                const struct loader_layer_list *search_list)
{
    uint32_t i;
    for (i = 0; i < search_list->count; i++) {
        const struct loader_layer_properties *prop = &search_list->list[i];
        if (prop->type & type) {
            /* Found an layer with the same type, add to layer_list */
            loader_add_to_layer_list(inst, list, 1, prop);
        }
    }

}

/**
 * Get the layer name(s) from the env_name environment variable. If layer
 * is found in search_list then add it to layer_list.  But only add it to
 * layer_list if type matches.
 */
static void loader_add_layer_env(
                const struct loader_instance *inst,
                const enum layer_type type,
                const char *env_name,
                struct loader_layer_list *layer_list,
                const struct loader_layer_list *search_list)
{
    char *layerEnv;
    char *next, *name;

    layerEnv = getenv(env_name);
    if (layerEnv == NULL) {
        return;
    }
    name = loader_stack_alloc(strlen(layerEnv) + 1);
    if (name == NULL) {
        return;
    }
    strcpy(name, layerEnv);

    while (name && *name ) {
        next = loader_get_next_path(name);
        loader_find_layer_name_add_list(inst, name, type, search_list, layer_list);
        name = next;
    }

    return;
}

void loader_deactivate_instance_layers(struct loader_instance *instance)
{
    if (!instance->activated_layer_list.count) {
        return;
    }

    /* Create instance chain of enabled layers */
    for (uint32_t i = 0; i < instance->activated_layer_list.count; i++) {
        struct loader_layer_properties *layer_prop = &instance->activated_layer_list.list[i];

        loader_remove_layer_lib(instance, layer_prop);
    }
    loader_destroy_layer_list(instance, &instance->activated_layer_list);
}

VkResult loader_enable_instance_layers(
                    struct loader_instance *inst,
                    const VkInstanceCreateInfo *pCreateInfo,
                    const struct loader_layer_list *instance_layers)
{
    VkResult err;

    assert(inst && "Cannot have null instance");

    if (!loader_init_layer_list(inst, &inst->activated_layer_list)) {
        loader_log(VK_DBG_REPORT_ERROR_BIT, 0, "Failed to alloc Instance activated layer list");
        return VK_ERROR_OUT_OF_HOST_MEMORY;
    }

    /* Add any implicit layers first */
    loader_add_layer_implicit(
                                inst,
                                VK_LAYER_TYPE_INSTANCE_IMPLICIT,
                                &inst->activated_layer_list,
                                instance_layers);

    /* Add any layers specified via environment variable next */
    loader_add_layer_env(
                            inst,
                            VK_LAYER_TYPE_INSTANCE_EXPLICIT,
                            "VK_INSTANCE_LAYERS",
                            &inst->activated_layer_list,
                            instance_layers);

    /* Add layers specified by the application */
    err = loader_add_layer_names_to_list(
                inst,
                &inst->activated_layer_list,
                pCreateInfo->enabledLayerNameCount,
                pCreateInfo->ppEnabledLayerNames,
                instance_layers);

    return err;
}

uint32_t loader_activate_instance_layers(struct loader_instance *inst)
{
    uint32_t layer_idx;
    VkBaseLayerObject *wrappedInstance;

    if (inst == NULL) {
        return 0;
    }

    // NOTE inst is unwrapped at this point in time
    void* baseObj = (void*) inst;
    void* nextObj = (void*) inst;
    VkBaseLayerObject *nextInstObj;
    PFN_vkGetInstanceProcAddr nextGPA = loader_gpa_instance_internal;

    if (!inst->activated_layer_list.count) {
        loader_init_instance_core_dispatch_table(inst->disp, nextGPA, (VkInstance) nextObj, (VkInstance) baseObj);
        return 0;
    }

    wrappedInstance = loader_stack_alloc(sizeof(VkBaseLayerObject)
                                   * inst->activated_layer_list.count);
    if (!wrappedInstance) {
        loader_log(VK_DBG_REPORT_ERROR_BIT, 0, "Failed to alloc Instance objects for layer");
        return 0;
    }

    /* Create instance chain of enabled layers */
    layer_idx = inst->activated_layer_list.count - 1;
    for (int32_t i = inst->activated_layer_list.count - 1; i >= 0; i--) {
        struct loader_layer_properties *layer_prop = &inst->activated_layer_list.list[i];
        loader_platform_dl_handle lib_handle;

         /*
         * Note: An extension's Get*ProcAddr should not return a function pointer for
         * any extension entry points until the extension has been enabled.
         * To do this requires a different behavior from Get*ProcAddr functions implemented
         * in layers.
         * The very first call to a layer will be it's Get*ProcAddr function requesting
         * the layer's vkGet*ProcAddr. The layer should initialize its internal dispatch table
         * with the wrapped object given (either Instance or Device) and return the layer's
         * Get*ProcAddr function. The layer should also use this opportunity to record the
         * baseObject so that it can find the correct local dispatch table on future calls.
         * Subsequent calls to Get*ProcAddr, CreateInstance, CreateDevice
         * will not use a wrapped object and must look up their local dispatch table from
         * the given baseObject.
         */
        nextInstObj = (wrappedInstance + layer_idx);
        nextInstObj->pGPA = (PFN_vkGPA) nextGPA;
        nextInstObj->baseObject = baseObj;
        nextInstObj->nextObject = nextObj;
        nextObj = (void*) nextInstObj;

        lib_handle = loader_add_layer_lib(inst, "instance", layer_prop);
        if ((nextGPA = layer_prop->functions.get_instance_proc_addr) == NULL) {
            if (layer_prop->functions.str_gipa == NULL || strlen(layer_prop->functions.str_gipa) == 0) {
                nextGPA = (PFN_vkGetInstanceProcAddr) loader_platform_get_proc_address(lib_handle, "vkGetInstanceProcAddr");
                layer_prop->functions.get_instance_proc_addr = nextGPA;
            } else
                nextGPA = (PFN_vkGetInstanceProcAddr) loader_platform_get_proc_address(lib_handle, layer_prop->functions.str_gipa);
            if (!nextGPA) {
                loader_log(VK_DBG_REPORT_ERROR_BIT, 0, "Failed to find vkGetInstanceProcAddr in layer %s", layer_prop->lib_name);

                /* TODO: Should we return nextObj, nextGPA to previous? or decrement layer_list count*/
                continue;
            }
        }

        loader_log(VK_DBG_REPORT_INFO_BIT, 0,
                   "Insert instance layer %s (%s)",
                   layer_prop->info.layerName,
                   layer_prop->lib_name);

        layer_idx--;
    }

    loader_init_instance_core_dispatch_table(inst->disp, nextGPA, (VkInstance) nextObj, (VkInstance) baseObj);

    return inst->activated_layer_list.count;
}

void loader_activate_instance_layer_extensions(struct loader_instance *inst)
{

    loader_init_instance_extension_dispatch_table(inst->disp,
                                                  inst->disp->GetInstanceProcAddr,
                                                  (VkInstance) inst);
}

static VkResult loader_enable_device_layers(
                        const struct loader_instance *inst,
                        struct loader_icd *icd,
                        struct loader_device *dev,
                        const VkDeviceCreateInfo *pCreateInfo,
                        const struct loader_layer_list *device_layers)

{
    VkResult err;

    assert(dev && "Cannot have null device");

    if (dev->activated_layer_list.list == NULL || dev->activated_layer_list.capacity == 0) {
        loader_init_layer_list(inst, &dev->activated_layer_list);
    }

    if (dev->activated_layer_list.list == NULL) {
        loader_log(VK_DBG_REPORT_ERROR_BIT, 0, "Failed to alloc device activated layer list");
        return VK_ERROR_OUT_OF_HOST_MEMORY;
    }

    /* Add any implicit layers first */
    loader_add_layer_implicit(
                inst,
                VK_LAYER_TYPE_DEVICE_IMPLICIT,
                &dev->activated_layer_list,
                device_layers);

    /* Add any layers specified via environment variable next */
    loader_add_layer_env(
                inst,
                VK_LAYER_TYPE_DEVICE_EXPLICIT,
                "VK_DEVICE_LAYERS",
                &dev->activated_layer_list,
                device_layers);

    /* Add layers specified by the application */
    err = loader_add_layer_names_to_list(
                inst,
                &dev->activated_layer_list,
                pCreateInfo->enabledLayerNameCount,
                pCreateInfo->ppEnabledLayerNames,
                device_layers);

    return err;
}

/*
 * This function terminates the device chain for CreateDevice.
 * CreateDevice is a special case and so the loader call's
 * the ICD's CreateDevice before creating the chain. Since
 * we can't call CreateDevice twice we must terminate the
 * device chain with something else.
 */
static VKAPI_ATTR VkResult VKAPI_CALL scratch_vkCreateDevice(
    VkPhysicalDevice          physicalDevice,
    const VkDeviceCreateInfo *pCreateInfo,
    const VkAllocationCallbacks*   pAllocator,
    VkDevice                 *pDevice)
{
    return VK_SUCCESS;
}

static VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL loader_GetDeviceChainProcAddr(VkDevice device, const char * name)
{
    if (!strcmp(name, "vkGetDeviceProcAddr"))
        return (PFN_vkVoidFunction) loader_GetDeviceChainProcAddr;
    if (!strcmp(name, "vkCreateDevice"))
        return (PFN_vkVoidFunction) scratch_vkCreateDevice;

    struct loader_device *found_dev;
    struct loader_icd *icd = loader_get_icd_and_device(device, &found_dev);
    return icd->GetDeviceProcAddr(device, name);
}

static uint32_t loader_activate_device_layers(
        const struct loader_instance *inst,
        struct loader_device *dev,
        VkDevice device)
{
    if (!dev) {
        return 0;
    }

    /* activate any layer libraries */
    void* nextObj = (void*) device;
    void* baseObj = nextObj;
    VkBaseLayerObject *nextGpuObj;
    PFN_vkGetDeviceProcAddr nextGPA = loader_GetDeviceChainProcAddr;
    VkBaseLayerObject *wrappedGpus;

    if (!dev->activated_layer_list.count) {
        loader_init_device_dispatch_table(&dev->loader_dispatch, nextGPA,
            (VkDevice) nextObj, (VkDevice) baseObj);
        return 0;
    }

    wrappedGpus = loader_heap_alloc(inst,
                    sizeof (VkBaseLayerObject) * dev->activated_layer_list.count,
                    VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE);
    if (!wrappedGpus) {
        loader_log(VK_DBG_REPORT_ERROR_BIT, 0, "Failed to alloc Gpu objects for layer");
        return 0;
    }

    for (int32_t i = dev->activated_layer_list.count - 1; i >= 0; i--) {

        struct loader_layer_properties *layer_prop = &dev->activated_layer_list.list[i];
        loader_platform_dl_handle lib_handle;

        nextGpuObj = (wrappedGpus + i);
        nextGpuObj->pGPA = (PFN_vkGPA)nextGPA;
        nextGpuObj->baseObject = baseObj;
        nextGpuObj->nextObject = nextObj;
        nextObj = (void*) nextGpuObj;

        lib_handle = loader_add_layer_lib(inst, "device", layer_prop);
        if ((nextGPA = layer_prop->functions.get_device_proc_addr) == NULL) {
            if (layer_prop->functions.str_gdpa == NULL || strlen(layer_prop->functions.str_gdpa) == 0) {
                nextGPA = (PFN_vkGetDeviceProcAddr) loader_platform_get_proc_address(lib_handle, "vkGetDeviceProcAddr");
                layer_prop->functions.get_device_proc_addr = nextGPA;
            } else
                nextGPA = (PFN_vkGetDeviceProcAddr) loader_platform_get_proc_address(lib_handle, layer_prop->functions.str_gdpa);
            if (!nextGPA) {
                loader_log(VK_DBG_REPORT_ERROR_BIT, 0, "Failed to find vkGetDeviceProcAddr in layer %s", layer_prop->lib_name);
                continue;
            }
        }

        loader_log(VK_DBG_REPORT_INFO_BIT, 0,
                   "Insert device layer library %s (%s)",
                   layer_prop->info.layerName,
                   layer_prop->lib_name);

    }

    loader_init_device_dispatch_table(&dev->loader_dispatch, nextGPA,
            (VkDevice) nextObj, (VkDevice) baseObj);
    loader_heap_free(inst, wrappedGpus);

    return dev->activated_layer_list.count;
}

VkResult loader_validate_layers(
        const uint32_t                  layer_count,
        const char * const             *ppEnabledLayerNames,
        const struct loader_layer_list *list)
{
    struct loader_layer_properties *prop;

    for (uint32_t i = 0; i < layer_count; i++) {
        prop = loader_get_layer_property(ppEnabledLayerNames[i],
                                  list);
        if (!prop) {
            return VK_ERROR_LAYER_NOT_PRESENT;
        }
    }

    return VK_SUCCESS;
}

VkResult loader_validate_instance_extensions(
                        const struct loader_extension_list *icd_exts,
                        const struct loader_layer_list *instance_layer,
                        const VkInstanceCreateInfo     *pCreateInfo)
{
    VkExtensionProperties *extension_prop;
    struct loader_layer_properties *layer_prop;

    for (uint32_t i = 0; i < pCreateInfo->enabledExtensionNameCount; i++) {
        extension_prop = get_extension_property(pCreateInfo->ppEnabledExtensionNames[i],
                                                icd_exts);

        if (extension_prop) {
            continue;
        }

        extension_prop = NULL;

        /* Not in global list, search layer extension lists */
        for (uint32_t j = 0; j < pCreateInfo->enabledLayerNameCount; j++) {
            layer_prop = loader_get_layer_property(pCreateInfo->ppEnabledLayerNames[i],
                                            instance_layer);
            if (!layer_prop) {
                /* Should NOT get here, loader_validate_layers
                 * should have already filtered this case out.
                 */
                continue;
            }

            extension_prop = get_extension_property(pCreateInfo->ppEnabledExtensionNames[i],
                                          &layer_prop->instance_extension_list);
            if (extension_prop) {
                /* Found the extension in one of the layers enabled by the app. */
                break;
            }
        }

        if (!extension_prop) {
            /* Didn't find extension name in any of the global layers, error out */
            return VK_ERROR_EXTENSION_NOT_PRESENT;
        }
    }
    return VK_SUCCESS;
}

VkResult loader_validate_device_extensions(
                                struct loader_physical_device *phys_dev,
                                const struct loader_layer_list *device_layer,
                                const VkDeviceCreateInfo *pCreateInfo)
{
    VkExtensionProperties *extension_prop;
    struct loader_layer_properties *layer_prop;

    for (uint32_t i = 0; i < pCreateInfo->enabledExtensionNameCount; i++) {
        const char *extension_name = pCreateInfo->ppEnabledExtensionNames[i];
        extension_prop = get_extension_property(extension_name,
                                                &phys_dev->device_extension_cache);

        if (extension_prop) {
            continue;
        }

        /* Not in global list, search layer extension lists */
        for (uint32_t j = 0; j < pCreateInfo->enabledLayerNameCount; j++) {
            const char *layer_name = pCreateInfo->ppEnabledLayerNames[j];
            layer_prop = loader_get_layer_property(layer_name,
                                  device_layer);

            if (!layer_prop) {
                /* Should NOT get here, loader_validate_instance_layers
                 * should have already filtered this case out.
                 */
                continue;
            }

            extension_prop = get_extension_property(extension_name,
                                          &layer_prop->device_extension_list);
            if (extension_prop) {
                /* Found the extension in one of the layers enabled by the app. */
                break;
            }
        }

        if (!extension_prop) {
            /* Didn't find extension name in any of the device layers, error out */
            return VK_ERROR_EXTENSION_NOT_PRESENT;
        }
    }
    return VK_SUCCESS;
}

VKAPI_ATTR VkResult VKAPI_CALL loader_CreateInstance(
        const VkInstanceCreateInfo*     pCreateInfo,
        const VkAllocationCallbacks*         pAllocator,
        VkInstance*                     pInstance)
{
    struct loader_instance *ptr_instance = *(struct loader_instance **) pInstance;
    struct loader_icd *icd;
    VkExtensionProperties *prop;
    char **filtered_extension_names = NULL;
    VkInstanceCreateInfo icd_create_info;
    VkResult res = VK_SUCCESS;
    bool success = false;

    icd_create_info.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO;
    icd_create_info.enabledLayerNameCount = 0;
    icd_create_info.ppEnabledLayerNames = NULL;
    icd_create_info.pApplicationInfo = pCreateInfo->pApplicationInfo;
    icd_create_info.pNext = pCreateInfo->pNext;

    /*
     * NOTE: Need to filter the extensions to only those
     * supported by the ICD.
     * No ICD will advertise support for layers. An ICD
     * library could support a layer, but it would be
     * independent of the actual ICD, just in the same library.
     */
    filtered_extension_names = loader_stack_alloc(pCreateInfo->enabledExtensionNameCount * sizeof(char *));
    if (!filtered_extension_names) {
        return VK_ERROR_OUT_OF_HOST_MEMORY;
    }
    icd_create_info.ppEnabledExtensionNames = (const char * const *) filtered_extension_names;

    for (uint32_t i = 0; i < ptr_instance->icd_libs.count; i++) {
        icd = loader_icd_add(ptr_instance, &ptr_instance->icd_libs.list[i]);
        if (icd) {
            icd_create_info.enabledExtensionNameCount = 0;
            for (uint32_t i = 0; i < pCreateInfo->enabledExtensionNameCount; i++) {
                prop = get_extension_property(pCreateInfo->ppEnabledExtensionNames[i],
                                              &ptr_instance->ext_list);
                if (prop) {
                    filtered_extension_names[icd_create_info.enabledExtensionNameCount] = (char *) pCreateInfo->ppEnabledExtensionNames[i];
                    icd_create_info.enabledExtensionNameCount++;
                }
            }

            res = ptr_instance->icd_libs.list[i].CreateInstance(&icd_create_info,
                                           pAllocator,
                                           &(icd->instance));
            if (res == VK_SUCCESS)
                success = loader_icd_init_entrys(
                                icd,
                                icd->instance,
                                ptr_instance->icd_libs.list[i].GetInstanceProcAddr);

            if (res != VK_SUCCESS || !success)
            {
                ptr_instance->icds = ptr_instance->icds->next;
                loader_icd_destroy(ptr_instance, icd);
                icd->instance = VK_NULL_HANDLE;
                loader_log(VK_DBG_REPORT_ERROR_BIT, 0,
                        "ICD ignored: failed to CreateInstance and find entrypoints with ICD");
            }
        }
    }

    /*
     * If no ICDs were added to instance list and res is unchanged
     * from it's initial value, the loader was unable to find
     * a suitable ICD.
     */
    if (ptr_instance->icds == NULL) {
        if (res == VK_SUCCESS) {
            return VK_ERROR_INCOMPATIBLE_DRIVER;
        } else {
            return res;
        }
    }

    return VK_SUCCESS;
}

VKAPI_ATTR void VKAPI_CALL loader_DestroyInstance(
        VkInstance                                instance,
        const VkAllocationCallbacks*                   pAllocator)
{
    struct loader_instance *ptr_instance = loader_instance(instance);
    struct loader_icd *icds = ptr_instance->icds;
    struct loader_icd *next_icd;

    // Remove this instance from the list of instances:
    struct loader_instance *prev = NULL;
    struct loader_instance *next = loader.instances;
    while (next != NULL) {
        if (next == ptr_instance) {
            // Remove this instance from the list:
            if (prev)
                prev->next = next->next;
            else
                loader.instances = next->next;
            break;
        }
        prev = next;
        next = next->next;
    }

    while (icds) {
        if (icds->instance) {
            icds->DestroyInstance(icds->instance, pAllocator);
        }
        next_icd = icds->next;
        icds->instance = VK_NULL_HANDLE;
        loader_icd_destroy(ptr_instance, icds);

        icds = next_icd;
    }
    loader_delete_layer_properties(ptr_instance, &ptr_instance->device_layer_list);
    loader_delete_layer_properties(ptr_instance, &ptr_instance->instance_layer_list);
    loader_scanned_icd_clear(ptr_instance, &ptr_instance->icd_libs);
    loader_destroy_ext_list(ptr_instance, &ptr_instance->ext_list);
    for (uint32_t i = 0; i < ptr_instance->total_gpu_count; i++)
        loader_destroy_ext_list(ptr_instance, &ptr_instance->phys_devs[i].device_extension_cache);
    loader_heap_free(ptr_instance, ptr_instance->phys_devs);
    loader_free_dev_ext_table(ptr_instance);
}

VkResult loader_init_physical_device_info(struct loader_instance *ptr_instance)
{
    struct loader_icd *icd;
    uint32_t i, j, idx, count = 0;
    VkResult res;
    struct loader_phys_dev_per_icd *phys_devs;

    ptr_instance->total_gpu_count = 0;
    phys_devs = (struct loader_phys_dev_per_icd *) loader_stack_alloc(
                            sizeof(struct loader_phys_dev_per_icd) *
                            ptr_instance->total_icd_count);
    if (!phys_devs)
        return VK_ERROR_OUT_OF_HOST_MEMORY;

    icd = ptr_instance->icds;
    for (i = 0; i < ptr_instance->total_icd_count; i++) {
        assert(icd);
        res = icd->EnumeratePhysicalDevices(icd->instance, &phys_devs[i].count, NULL);
        if (res != VK_SUCCESS)
            return res;
        count += phys_devs[i].count;
        icd = icd->next;
    }

    ptr_instance->phys_devs = (struct loader_physical_device *) loader_heap_alloc(
                                        ptr_instance,
                                        count * sizeof(struct loader_physical_device),
                                        VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE);
    if (!ptr_instance->phys_devs)
        return VK_ERROR_OUT_OF_HOST_MEMORY;

    icd = ptr_instance->icds;

    struct loader_physical_device *inst_phys_devs = ptr_instance->phys_devs;
    idx = 0;
    for (i = 0; i < ptr_instance->total_icd_count; i++) {
        assert(icd);

        phys_devs[i].phys_devs = (VkPhysicalDevice *) loader_stack_alloc(
                        phys_devs[i].count * sizeof(VkPhysicalDevice));
        if (!phys_devs[i].phys_devs) {
            loader_heap_free(ptr_instance, ptr_instance->phys_devs);
            ptr_instance->phys_devs = NULL;
            return VK_ERROR_OUT_OF_HOST_MEMORY;
        }
        res = icd->EnumeratePhysicalDevices(
                                        icd->instance,
                                        &(phys_devs[i].count),
                                        phys_devs[i].phys_devs);
        if ((res == VK_SUCCESS)) {
            ptr_instance->total_gpu_count += phys_devs[i].count;
            for (j = 0; j < phys_devs[i].count; j++) {

                // initialize the loader's physicalDevice object
                loader_set_dispatch((void *) &inst_phys_devs[idx], ptr_instance->disp);
                inst_phys_devs[idx].this_instance = ptr_instance;
                inst_phys_devs[idx].this_icd = icd;
                inst_phys_devs[idx].phys_dev = phys_devs[i].phys_devs[j];
                memset(&inst_phys_devs[idx].device_extension_cache, 0, sizeof(struct loader_extension_list));

                idx++;
            }
        } else {
            loader_heap_free(ptr_instance, ptr_instance->phys_devs);
            ptr_instance->phys_devs = NULL;
            return res;
        }

        icd = icd->next;
    }

    return VK_SUCCESS;
}

VKAPI_ATTR VkResult VKAPI_CALL loader_EnumeratePhysicalDevices(
        VkInstance                              instance,
        uint32_t*                               pPhysicalDeviceCount,
        VkPhysicalDevice*                       pPhysicalDevices)
{
    uint32_t i;
    struct loader_instance *ptr_instance = (struct loader_instance *) instance;
    VkResult res = VK_SUCCESS;

    if (ptr_instance->total_gpu_count == 0) {
        res = loader_init_physical_device_info(ptr_instance);
    }

    *pPhysicalDeviceCount = ptr_instance->total_gpu_count;
    if (!pPhysicalDevices) {
        return res;
    }

    for (i = 0; i < ptr_instance->total_gpu_count; i++) {
        pPhysicalDevices[i] = (VkPhysicalDevice) &ptr_instance->phys_devs[i];
    }

    return res;
}

VKAPI_ATTR void VKAPI_CALL loader_GetPhysicalDeviceProperties(
        VkPhysicalDevice                        physicalDevice,
        VkPhysicalDeviceProperties*             pProperties)
{
    struct loader_physical_device *phys_dev = (struct loader_physical_device *) physicalDevice;
    struct loader_icd *icd = phys_dev->this_icd;

    if (icd->GetPhysicalDeviceProperties)
        icd->GetPhysicalDeviceProperties(phys_dev->phys_dev, pProperties);
}

VKAPI_ATTR void VKAPI_CALL loader_GetPhysicalDeviceQueueFamilyProperties (
        VkPhysicalDevice                        physicalDevice,
        uint32_t*                               pQueueFamilyPropertyCount,
        VkQueueFamilyProperties*                pProperties)
{
    struct loader_physical_device *phys_dev = (struct loader_physical_device *) physicalDevice;
    struct loader_icd *icd = phys_dev->this_icd;

    if (icd->GetPhysicalDeviceQueueFamilyProperties)
        icd->GetPhysicalDeviceQueueFamilyProperties(phys_dev->phys_dev, pQueueFamilyPropertyCount, pProperties);
}

VKAPI_ATTR void VKAPI_CALL loader_GetPhysicalDeviceMemoryProperties (
        VkPhysicalDevice physicalDevice,
        VkPhysicalDeviceMemoryProperties* pProperties)
{
    struct loader_physical_device *phys_dev = (struct loader_physical_device *) physicalDevice;
    struct loader_icd *icd = phys_dev->this_icd;

    if (icd->GetPhysicalDeviceMemoryProperties)
        icd->GetPhysicalDeviceMemoryProperties(phys_dev->phys_dev, pProperties);
}

VKAPI_ATTR void VKAPI_CALL loader_GetPhysicalDeviceFeatures(
        VkPhysicalDevice                        physicalDevice,
        VkPhysicalDeviceFeatures*               pFeatures)
{
    struct loader_physical_device *phys_dev = (struct loader_physical_device *) physicalDevice;
    struct loader_icd *icd = phys_dev->this_icd;

    if (icd->GetPhysicalDeviceFeatures)
        icd->GetPhysicalDeviceFeatures(phys_dev->phys_dev, pFeatures);
}

VKAPI_ATTR void VKAPI_CALL loader_GetPhysicalDeviceFormatProperties(
        VkPhysicalDevice                        physicalDevice,
        VkFormat                                format,
        VkFormatProperties*                     pFormatInfo)
{
    struct loader_physical_device *phys_dev = (struct loader_physical_device *) physicalDevice;
    struct loader_icd *icd = phys_dev->this_icd;

    if (icd->GetPhysicalDeviceFormatProperties)
        icd->GetPhysicalDeviceFormatProperties(phys_dev->phys_dev, format, pFormatInfo);
}

VKAPI_ATTR VkResult VKAPI_CALL loader_GetPhysicalDeviceImageFormatProperties(
        VkPhysicalDevice                        physicalDevice,
        VkFormat                                format,
        VkImageType                             type,
        VkImageTiling                           tiling,
        VkImageUsageFlags                       usage,
        VkImageCreateFlags                      flags,
        VkImageFormatProperties*                pImageFormatProperties)
{
    struct loader_physical_device *phys_dev = (struct loader_physical_device *) physicalDevice;
    struct loader_icd *icd = phys_dev->this_icd;

    if (!icd->GetPhysicalDeviceImageFormatProperties)
        return VK_ERROR_INITIALIZATION_FAILED;

    return icd->GetPhysicalDeviceImageFormatProperties(phys_dev->phys_dev, format,
            type, tiling, usage, flags, pImageFormatProperties);
}

VKAPI_ATTR void VKAPI_CALL loader_GetPhysicalDeviceSparseImageFormatProperties(
        VkPhysicalDevice                        physicalDevice,
        VkFormat                                format,
        VkImageType                             type,
        VkSampleCountFlagBits                   samples,
        VkImageUsageFlags                       usage,
        VkImageTiling                           tiling,
        uint32_t*                               pNumProperties,
        VkSparseImageFormatProperties*          pProperties)
{
    struct loader_physical_device *phys_dev = (struct loader_physical_device *) physicalDevice;
    struct loader_icd *icd = phys_dev->this_icd;

    if (icd->GetPhysicalDeviceSparseImageFormatProperties)
        icd->GetPhysicalDeviceSparseImageFormatProperties(phys_dev->phys_dev, format, type, samples, usage, tiling, pNumProperties, pProperties);
}

VKAPI_ATTR VkResult VKAPI_CALL loader_CreateDevice(
        VkPhysicalDevice                        physicalDevice,
        const VkDeviceCreateInfo*               pCreateInfo,
        const VkAllocationCallbacks*                 pAllocator,
        VkDevice*                               pDevice)
{
    struct loader_physical_device *phys_dev = (struct loader_physical_device *) physicalDevice;
    struct loader_icd *icd = phys_dev->this_icd;
    struct loader_device *dev;
    struct loader_instance *inst;
    VkDeviceCreateInfo device_create_info;
    char **filtered_extension_names = NULL;
    VkResult res;

    assert(pCreateInfo->queueCreateInfoCount >= 1);

    if (!icd)
        return VK_ERROR_INITIALIZATION_FAILED;

    inst = phys_dev->this_instance;

    if (!icd->CreateDevice) {
        return VK_ERROR_INITIALIZATION_FAILED;
    }

    /* validate any app enabled layers are available */
    if (pCreateInfo->enabledLayerNameCount > 0) {
        res = loader_validate_layers(pCreateInfo->enabledLayerNameCount,
                pCreateInfo->ppEnabledLayerNames,
                &inst->device_layer_list);
        if (res != VK_SUCCESS) {
            return res;
        }
    }

    /* Get the physical device extensions if they haven't been retrieved yet */
    if (phys_dev->device_extension_cache.capacity == 0) {
        if (!loader_init_ext_list(inst, &phys_dev->device_extension_cache)) {
            return VK_ERROR_OUT_OF_HOST_MEMORY;
        }
        res = loader_add_physical_device_extensions(
                            inst, physicalDevice,
                            phys_dev->this_icd->this_icd_lib->lib_name,
                            &phys_dev->device_extension_cache);
        if (res != VK_SUCCESS) {
            return res;
        }
    }
    /* make sure requested extensions to be enabled are supported */
    res = loader_validate_device_extensions(phys_dev, &inst->device_layer_list, pCreateInfo);
    if (res != VK_SUCCESS) {
        return res;
    }

    /*
     * NOTE: Need to filter the extensions to only those
     * supported by the ICD.
     * No ICD will advertise support for layers. An ICD
     * library could support a layer, but it would be
     * independent of the actual ICD, just in the same library.
     */
    filtered_extension_names = loader_stack_alloc(pCreateInfo->enabledExtensionNameCount * sizeof(char *));
    if (!filtered_extension_names) {
        return VK_ERROR_OUT_OF_HOST_MEMORY;
    }

    /* Copy user's data */
    memcpy(&device_create_info, pCreateInfo, sizeof(VkDeviceCreateInfo));

    /* ICD's do not use layers */
    device_create_info.enabledLayerNameCount = 0;
    device_create_info.ppEnabledLayerNames = NULL;

    device_create_info.enabledExtensionNameCount = 0;
    device_create_info.ppEnabledExtensionNames = (const char * const *) filtered_extension_names;

    for (uint32_t i = 0; i < pCreateInfo->enabledExtensionNameCount; i++) {
        const char *extension_name = pCreateInfo->ppEnabledExtensionNames[i];
        VkExtensionProperties *prop = get_extension_property(extension_name,
                                      &phys_dev->device_extension_cache);
        if (prop) {
            filtered_extension_names[device_create_info.enabledExtensionNameCount] = (char *) extension_name;
            device_create_info.enabledExtensionNameCount++;
        }
    }

    // since physicalDevice object maybe wrapped by a layer need to get unwrapped version
    // we haven't yet called down the chain for the layer to unwrap the object
    res = icd->CreateDevice(phys_dev->phys_dev, pCreateInfo, pAllocator, pDevice);
    if (res != VK_SUCCESS) {
        return res;
    }

    dev = loader_add_logical_device(inst, *pDevice, &icd->logical_device_list);
    if (dev == NULL) {
        return VK_ERROR_OUT_OF_HOST_MEMORY;
    }

    loader_init_dispatch(*pDevice, &dev->loader_dispatch);

    /* activate any layers on device chain which terminates with device*/
    res = loader_enable_device_layers(inst, icd, dev, pCreateInfo, &inst->device_layer_list);
    if (res != VK_SUCCESS) {
        loader_destroy_logical_device(inst, dev);
        return res;
    }
    loader_activate_device_layers(inst, dev, *pDevice);

    /* initialize any device extension dispatch entry's from the instance list*/
    loader_init_dispatch_dev_ext(inst, dev);

    /* finally can call down the chain */
    res = dev->loader_dispatch.core_dispatch.CreateDevice(physicalDevice, pCreateInfo, pAllocator, pDevice);

    dev->loader_dispatch.core_dispatch.CreateDevice = icd->CreateDevice;

    return res;
}

/**
 * Get an instance level or global level entry point address.
 * @param instance
 * @param pName
 * @return
 *    If instance == NULL returns a global level functions only
 *    If instance is valid returns a trampoline entry point for all dispatchable Vulkan
 *    functions both core and extensions.
 */
LOADER_EXPORT VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL vkGetInstanceProcAddr(VkInstance instance, const char * pName)
{

    void *addr;

    addr = globalGetProcAddr(pName);
    if (instance == VK_NULL_HANDLE) {
        // get entrypoint addresses that are global (no dispatchable object)

        return addr;
    } else {
        // if a global entrypoint return NULL
        if (addr)
            return NULL;
    }

    struct loader_instance *ptr_instance = loader_get_instance(instance);
    if (ptr_instance == NULL)
        return NULL;
    // Return trampoline code for non-global entrypoints including any extensions.
    // Device extensions are returned if a layer or ICD supports the extension.
    // Instance extensions are returned if the extension is enabled and the loader
    // or someone else supports the extension
    return trampolineGetProcAddr(ptr_instance, pName);

}

/**
 * Get a device level or global level entry point address.
 * @param device
 * @param pName
 * @return
 *    If device is valid, returns a device relative entry point for device level
 *    entry points both core and extensions.
 *    Device relative means call down the device chain.
 */
LOADER_EXPORT VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL vkGetDeviceProcAddr(VkDevice device, const char * pName)
{
    void *addr;

    /* for entrypoints that loader must handle (ie non-dispatchable or create object)
       make sure the loader entrypoint is returned */
    addr = loader_non_passthrough_gdpa(pName);
    if (addr) {
        return addr;
    }

    /* Although CreateDevice is on device chain it's dispatchable object isn't
     * a VkDevice or child of VkDevice so return NULL.
     */
    if (!strcmp(pName, "CreateDevice"))
        return NULL;

    /* return the dispatch table entrypoint for the fastest case */
    const VkLayerDispatchTable *disp_table = * (VkLayerDispatchTable **) device;
    if (disp_table == NULL)
        return NULL;

    addr = loader_lookup_device_dispatch_table(disp_table, pName);
    if (addr)
        return addr;

    if (disp_table->GetDeviceProcAddr == NULL)
        return NULL;
    return disp_table->GetDeviceProcAddr(device, pName);
}

LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkEnumerateInstanceExtensionProperties(
    const char*                                 pLayerName,
    uint32_t*                                   pPropertyCount,
    VkExtensionProperties*                      pProperties)
{
    struct loader_extension_list *global_ext_list=NULL;
    struct loader_layer_list instance_layers;
    struct loader_extension_list icd_extensions;
    struct loader_icd_libs icd_libs;
    uint32_t copy_size;

    tls_instance = NULL;
    memset(&icd_extensions, 0, sizeof(icd_extensions));
    memset(&instance_layers, 0, sizeof(instance_layers));
    loader_platform_thread_once(&once_init, loader_initialize);

    /* get layer libraries if needed */
    if (pLayerName && strlen(pLayerName) != 0) {
        loader_layer_scan(NULL, &instance_layers, NULL);
        for (uint32_t i = 0; i < instance_layers.count; i++) {
            struct loader_layer_properties *props = &instance_layers.list[i];
            if (strcmp(props->info.layerName, pLayerName) == 0) {
               global_ext_list = &props->instance_extension_list;
            }
        }
    }
    else {
        /* Scan/discover all ICD libraries */
        memset(&icd_libs, 0 , sizeof(struct loader_icd_libs));
        loader_icd_scan(NULL, &icd_libs);
        /* get extensions from all ICD's, merge so no duplicates */
        loader_get_icd_loader_instance_extensions(NULL, &icd_libs, &icd_extensions);
        loader_scanned_icd_clear(NULL, &icd_libs);
        global_ext_list = &icd_extensions;
    }

    if (global_ext_list == NULL) {
	loader_destroy_layer_list(NULL, &instance_layers);
        return VK_ERROR_LAYER_NOT_PRESENT;
    }

    if (pProperties == NULL) {
	*pPropertyCount = global_ext_list->count;
	loader_destroy_layer_list(NULL, &instance_layers);
        loader_destroy_ext_list(NULL, &icd_extensions);
        return VK_SUCCESS;
    }

    copy_size = *pPropertyCount < global_ext_list->count ? *pPropertyCount : global_ext_list->count;
    for (uint32_t i = 0; i < copy_size; i++) {
        memcpy(&pProperties[i],
               &global_ext_list->list[i],
               sizeof(VkExtensionProperties));
    }
    *pPropertyCount = copy_size;
    loader_destroy_ext_list(NULL, &icd_extensions);

    if (copy_size < global_ext_list->count) {
	loader_destroy_layer_list(NULL, &instance_layers);
        return VK_INCOMPLETE;
    }

    loader_destroy_layer_list(NULL, &instance_layers);
    return VK_SUCCESS;
}

LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkEnumerateInstanceLayerProperties(
    uint32_t*                                   pPropertyCount,
    VkLayerProperties*                          pProperties)
{

    struct loader_layer_list instance_layer_list;
    tls_instance = NULL;

    loader_platform_thread_once(&once_init, loader_initialize);

    uint32_t copy_size;

    /* get layer libraries */
    memset(&instance_layer_list, 0, sizeof(instance_layer_list));
    loader_layer_scan(NULL, &instance_layer_list, NULL);

    if (pProperties == NULL) {
        *pPropertyCount = instance_layer_list.count;
        loader_destroy_layer_list(NULL, &instance_layer_list);
        return VK_SUCCESS;
    }

    copy_size = (*pPropertyCount < instance_layer_list.count) ? *pPropertyCount : instance_layer_list.count;
    for (uint32_t i = 0; i < copy_size; i++) {
        memcpy(&pProperties[i], &instance_layer_list.list[i].info, sizeof(VkLayerProperties));
    }
    *pPropertyCount = copy_size;
    loader_destroy_layer_list(NULL, &instance_layer_list);

    if (copy_size < instance_layer_list.count) {
        return VK_INCOMPLETE;
    }

    return VK_SUCCESS;
}

VKAPI_ATTR VkResult VKAPI_CALL loader_EnumerateDeviceExtensionProperties(
        VkPhysicalDevice                        physicalDevice,
        const char*                             pLayerName,
        uint32_t*                               pPropertyCount,
        VkExtensionProperties*                  pProperties)
{
    struct loader_physical_device *phys_dev = (struct loader_physical_device *) physicalDevice;
    uint32_t copy_size;

    uint32_t count;
    struct loader_extension_list *dev_ext_list=NULL;

    /* get layer libraries if needed */
    if (pLayerName && strlen(pLayerName) != 0) {
        for (uint32_t i = 0; i < phys_dev->this_instance->device_layer_list.count; i++) {
            struct loader_layer_properties *props = &phys_dev->this_instance->device_layer_list.list[i];
            if (strcmp(props->info.layerName, pLayerName) == 0) {
               dev_ext_list = &props->device_extension_list;
            }
        }
    }
    else {
        /* this case is during the call down the instance chain */
        struct loader_icd *icd = phys_dev->this_icd;
        VkResult res;
        res = icd->EnumerateDeviceExtensionProperties(phys_dev->phys_dev, NULL, pPropertyCount, pProperties);
        if (pProperties != NULL  && res == VK_SUCCESS) {
            /* initialize dev_extension list within the physicalDevice object */
            res = loader_init_physical_device_extensions(phys_dev->this_instance,
                               phys_dev, *pPropertyCount, pProperties,
                               &phys_dev->device_extension_cache);
        }
        return res;
    }

    count = (dev_ext_list == NULL) ? 0: dev_ext_list->count;
    if (pProperties == NULL) {
        *pPropertyCount = count;
        return VK_SUCCESS;
    }

    copy_size = *pPropertyCount < count ? *pPropertyCount : count;
    for (uint32_t i = 0; i < copy_size; i++) {
        memcpy(&pProperties[i],
               &dev_ext_list->list[i],
               sizeof(VkExtensionProperties));
    }
    *pPropertyCount = copy_size;

    if (copy_size < count) {
        return VK_INCOMPLETE;
    }

    return VK_SUCCESS;
}

VKAPI_ATTR VkResult VKAPI_CALL loader_EnumerateDeviceLayerProperties(
        VkPhysicalDevice                        physicalDevice,
        uint32_t*                               pPropertyCount,
        VkLayerProperties*                      pProperties)
{
    uint32_t copy_size;
    struct loader_physical_device *phys_dev = (struct loader_physical_device *) physicalDevice;

    uint32_t count = phys_dev->this_instance->device_layer_list.count;

    if (pProperties == NULL) {
        *pPropertyCount = count;
        return VK_SUCCESS;
    }

    copy_size = (*pPropertyCount < count) ? *pPropertyCount : count;
    for (uint32_t i = 0; i < copy_size; i++) {
        memcpy(&pProperties[i], &(phys_dev->this_instance->device_layer_list.list[i].info), sizeof(VkLayerProperties));
    }
    *pPropertyCount = copy_size;

    if (copy_size < count) {
        return VK_INCOMPLETE;
    }

    return VK_SUCCESS;
}
