/*
 * Vulkan
 *
 * Copyright (C) 2014 LunarG, Inc.
 *
 * 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.
 *
 * Authors:
 *   Chia-I Wu <olv@lunarg.com>
 *   Jon Ashburn <jon@lunarg.com>
 *   Courtney Goeltzenleuchter <courtney@lunarg.com>
 *   Ian Elliott <ian@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 "vk_icd.h"
#include "cJSON.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 PFN_vkVoidFunction VKAPI loader_GetInstanceProcAddr(
        VkInstance instance,
        const char * pName);
static bool loader_init_ext_list(
        const struct loader_instance *inst,
        struct loader_extension_list *ext_info);

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;

// 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 = loader_GetInstanceProcAddr,
    .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,
    .GetPhysicalDeviceExtensionProperties = loader_GetPhysicalDeviceExtensionProperties,
    .GetPhysicalDeviceLayerProperties = loader_GetPhysicalDeviceLayerProperties,
    .GetPhysicalDeviceSparseImageFormatProperties = loader_GetPhysicalDeviceSparseImageFormatProperties,
    .GetPhysicalDeviceSurfaceSupportKHR = loader_GetPhysicalDeviceSurfaceSupportKHR,
    .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,
    VkSystemAllocType                 alloc_type)
{
    if (instance && instance->alloc_callbacks.pfnAlloc) {
        /* TODO: What should default alignment be? 1, 4, 8, other? */
        return instance->alloc_callbacks.pfnAlloc(instance->alloc_callbacks.pUserData, size, 4, alloc_type);
    }
    return malloc(size);
}

void* loader_aligned_heap_alloc(
    const struct loader_instance *instance,
    size_t                        size,
    size_t                        alignment,
    VkSystemAllocType             alloc_type)
{
    if (instance && instance->alloc_callbacks.pfnAlloc) {
        return instance->alloc_callbacks.pfnAlloc(instance->alloc_callbacks.pUserData, size, alignment, alloc_type);
    }
#if defined(_WIN32)
    return _aligned_malloc(alignment, size);
#else
    return aligned_alloc(alignment, size);
#endif
}

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

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

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

void loader_tls_heap_free(void *pMem)
{
    return loader_heap_free(tls_instance, pMem);
}

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 = KEY_QUERY_VALUE;
    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;
        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_ALLOC_TYPE_INTERNAL);
                    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_ALLOC_TYPE_INTERNAL);
                    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

/**
 * 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, minor, patch;
    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->extName, op2->extName) == 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_ALLOC_TYPE_INTERNAL);
        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_ALLOC_TYPE_INTERNAL);
        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_vkGetGlobalExtensionProperties 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 GetGlobalExtensionProperties 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].extName, lib_name, spec_version);
        loader_add_to_ext_list(inst, ext_list, 1, &ext_props[i]);
    }

    return;
}

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

    if (!get_phys_dev_ext_props) {
        /* No GetPhysicalDeviceExtensionProperties defined */
        return;
    }

        res = get_phys_dev_ext_props(physical_device, NULL, &count, NULL);
        if (res == VK_SUCCESS && count > 0) {
            ext_props = loader_stack_alloc(count * sizeof(VkExtensionProperties));

            res = get_phys_dev_ext_props(physical_device, NULL, &count, ext_props);
            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].extName, lib_name, spec_version);
                loader_add_to_ext_list(inst, ext_list, 1, &ext_props[i]);
            }
        } else {
            loader_log(VK_DBG_REPORT_ERROR_BIT, 0, "Error getting physical device extension info count from library %s", lib_name);
        }

    return;
}

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_ALLOC_TYPE_INTERNAL);
    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.
 */
void 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;

    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_ALLOC_TYPE_INTERNAL);
            // double capacity
            ext_list->capacity *= 2;
        }

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

/**
 * 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_INVALID_LAYER;
            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_ALLOC_TYPE_INTERNAL);
    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_ALLOC_TYPE_INTERNAL);
    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_ALLOC_TYPE_INTERNAL);
            // 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_ALLOC_TYPE_INTERNAL);
            // 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)
{
    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);
        }
    }
}

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].extName) == 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].GetGlobalExtensionProperties,
                                     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_swapchain_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)
                if (dev->device == 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_ALLOC_TYPE_INTERNAL);
    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,
                            VkDevice device)
{
    struct loader_device *found_dev, *dev, *prev_dev;
    struct loader_icd *icd;
    icd = loader_get_icd_and_device(device, &found_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--;
    loader_heap_free(ptr_inst, icd->gpus);
    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_ALLOC_TYPE_INTERNAL);
    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_ALLOC_TYPE_INTERNAL);

}

static void loader_scanned_icd_add(
                            const struct loader_instance *inst,
                            struct loader_icd_libs *icd_libs,
                            const char *filename)
{
    loader_platform_dl_handle handle;
    PFN_vkCreateInstance fp_create_inst;
    PFN_vkGetGlobalExtensionProperties 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, GetGlobalExtensionProperties);

#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_ALLOC_TYPE_INTERNAL);
            // double capacity
            icd_libs->capacity *= 2;
    }
    new_node = &(icd_libs->list[icd_libs->count]);

    new_node->handle = handle;
    new_node->GetInstanceProcAddr = fp_get_proc_addr;
    new_node->CreateInstance = fp_create_inst;
    new_node->GetGlobalExtensionProperties = fp_get_global_ext_props;

    new_node->lib_name = (char *) loader_heap_alloc(inst,
                                            strlen(filename) + 1,
                                            VK_SYSTEM_ALLOC_TYPE_INTERNAL);
    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(GetPhysicalDeviceExtensionProperties, true);
    LOOKUP_GIPA(GetPhysicalDeviceSparseImageFormatProperties, true);
    LOOKUP_GIPA(DbgCreateMsgCallback, false);
    LOOKUP_GIPA(DbgDestroyMsgCallback, false);
    LOOKUP_GIPA(GetPhysicalDeviceSurfaceSupportKHR, false);

#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 a mutex
    loader_platform_thread_create_mutex(&loader_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 otherwise
 * leave the path unmodified if absolute. The path which is relative from is
 * given in rel_base and should include trailing directory seperator '/'
 *
 * \returns
 * A string in out_fullpath of the full absolute path
 * Side effect is that dir string maybe modified.
 */
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)) {
        strncpy(out_fullpath, path, out_size);
        out_fullpath[out_size - 1] = '\0';
    }
    else {
        // convert relative to absolute path based on rel_base
        size_t len = strlen(path);
        strncpy(out_fullpath, rel_base, out_size);
        out_fullpath[out_size - 1] = '\0';
        assert(out_size >= strlen(out_fullpath) + len + 1);
        strncat(out_fullpath, path, len);
    }
}

/**
 * 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.
 * Side effect is that dir string maybe modified.
 */
static void loader_get_fullpath(const char *file,
                                char *dir,
                                size_t out_size,
                                char *out_fullpath)
{
    char *next_dir;
    if (strchr(file,DIRECTORY_SYMBOL) == NULL) {
        //find file exists with prepending given path
        while (*dir) {
            next_dir = loader_get_next_path(dir);
            snprintf(out_fullpath, out_size, "%s%c%s",
                     dir, DIRECTORY_SYMBOL, file);
            if (loader_platform_file_exists(out_fullpath)) {
                return;
            }
            dir = next_dir;
        }
    }
    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_ALLOC_TYPE_INTERNAL);
    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_ALLOC_TYPE_INTERNAL);
    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) “abi_versions”
     * (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, *abi_versions;
    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, "\"0.9.0\"") != 0)
        loader_log(VK_DBG_REPORT_WARN_BIT, 0, "Unexpected manifest file version (expected 0.9.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, abi_versions)
        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;
        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;
        }

        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 (strchr(library_path, DIRECTORY_SYMBOL) == NULL) {
            // a filename which is assumed in the system directory
            char *def_path = loader_stack_alloc(strlen(DEFAULT_VK_LAYERS_PATH) + 1);
            strcpy(def_path, DEFAULT_VK_LAYERS_PATH);
            loader_get_fullpath(library_path, def_path, MAX_STRING_SIZE, fullpath);
        } else {
            // a relative or absolute path
            char *name_copy = loader_stack_alloc(strlen(filename) + 2);
            size_t len;
            strcpy(name_copy, filename);
            rel_base = loader_platform_dirname(name_copy);
            len = strlen(rel_base);
            rel_base[len] = DIRECTORY_SYMBOL;
            rel_base[len + 1] = '\0';
            loader_expand_path(library_path, rel_base, MAX_STRING_SIZE, fullpath);
        }
        props->info.specVersion = loader_make_version(abi_versions);
        props->info.implVersion = loader_make_version(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, *version;
        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, version)
                strncpy(ext_prop.extName, name, sizeof (ext_prop.extName));
                ext_prop.extName[sizeof (ext_prop.extName) - 1] = '\0';
                ext_prop.specVersion = loader_make_version(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, version);
                strncpy(ext_prop.extName, name, sizeof (ext_prop.extName));
                ext_prop.extName[sizeof (ext_prop.extName) - 1] = '\0';
                ext_prop.specVersion = loader_make_version(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(__linux__)
        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(__linux__)
    list_is_dirs = (override == NULL || is_layer) ? true : false;
#else //WIN32
    list_is_dirs = (is_layer && override != NULL) ? 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(__linux__)
            // only Linux has relative paths
            char *dir;
            // make a copy of location so it isn't modified
            dir = loader_stack_alloc(strlen(location) + 1);
            if (dir == NULL) {
                loader_log(VK_DBG_REPORT_ERROR_BIT, 0, "Out of memory can't get manifest files");
                return;
            }
            strcpy(dir, location);

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

            name = full_path;
#else  // WIN32
            name = file;
#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_ALLOC_TYPE_INTERNAL);
                    }
                    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_ALLOC_TYPE_INTERNAL);
                        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_ALLOC_TYPE_INTERNAL);
                    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;
    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;
        item = cJSON_GetObjectItem(json, "file_format_version");
        if (item == NULL)
            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);
        item = cJSON_GetObjectItem(json, "ICD");
        if (item != NULL) {
            item = cJSON_GetObjectItem(item, "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;
                uint32_t path_len;
                char *rel_base;
                // 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 (strchr(library_path, DIRECTORY_SYMBOL) == NULL) {
                    // a filename which is assumed in the system directory
                    char *def_path = loader_stack_alloc(strlen(DEFAULT_VK_DRIVERS_PATH) + 1);
                    strcpy(def_path, DEFAULT_VK_DRIVERS_PATH);
                    path_len = strlen(DEFAULT_VK_DRIVERS_PATH) + strlen(library_path) + 2;
                    fullpath = loader_stack_alloc(path_len);
#if defined(__linux__)
                    loader_get_fullpath(library_path, def_path, path_len, fullpath);
#else // WIN32
                    strncpy(fullpath, library_path, sizeof (fullpath));
                    fullpath[sizeof (fullpath) - 1] = '\0';
#endif
                } else {
                    // a relative or absolute path
                    char *name_copy = loader_stack_alloc(strlen(file_str) + 2);
                    size_t len;
                    strcpy(name_copy, file_str);
                    rel_base = loader_platform_dirname(name_copy);
                    len = strlen(rel_base);
                    rel_base[len] = DIRECTORY_SYMBOL;
                    rel_base[len + 1] = '\0';
                    path_len = strlen(rel_base) + strlen(library_path) + 2;
                    fullpath = loader_stack_alloc(path_len);
                    loader_expand_path(library_path, rel_base, path_len, fullpath);
                }
                loader_scanned_icd_add(inst, icds, fullpath);
            }

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

}


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);


    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);

}

static PFN_vkVoidFunction VKAPI 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);
}

struct loader_icd * loader_get_icd(const VkPhysicalDevice gpu, uint32_t *gpu_index)
{

    *gpu_index = 0;
    for (struct loader_instance *inst = loader.instances; inst; inst = inst->next) {
        for (struct loader_icd *icd = inst->icds; icd; icd = icd->next) {
            for (uint32_t i = 0; i < icd->gpu_count; i++)
                if (icd->gpus[i] == gpu) {
                    *gpu_index = i;
                    return icd;
                }
        }
    }
    return NULL;
}

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_ALLOC_TYPE_INTERNAL);
        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_ALLOC_TYPE_INTERNAL);
    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;

    if (inst == NULL)
        return VK_ERROR_UNKNOWN;

    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->layerCount,
                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) {
        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 intialize it's 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;

    if (dev == NULL)
        return VK_ERROR_UNKNOWN;

    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->layerCount,
                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 VkResult VKAPI scratch_vkCreateDevice(
    VkPhysicalDevice          gpu,
    const VkDeviceCreateInfo *pCreateInfo,
    VkDevice                 *pDevice)
{
    return VK_SUCCESS;
}

static PFN_vkVoidFunction VKAPI 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)
        return 0;

    wrappedGpus = loader_heap_alloc(inst,
                    sizeof (VkBaseLayerObject) * dev->activated_layer_list.count,
                    VK_SYSTEM_ALLOC_TYPE_INTERNAL);
    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_INVALID_LAYER;
        }
    }

    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->extensionCount; 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->layerCount; 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_INVALID_EXTENSION;
        }
    }
    return VK_SUCCESS;
}

VkResult loader_validate_device_extensions(
                                struct loader_icd *icd,
                                uint32_t gpu_index,
                                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->extensionCount; i++) {
        const char *extension_name = pCreateInfo->ppEnabledExtensionNames[i];
        extension_prop = get_extension_property(extension_name,
                                                &icd->device_extension_cache[gpu_index]);

        if (extension_prop) {
            continue;
        }

        /* Not in global list, search layer extension lists */
        for (uint32_t j = 0; j < pCreateInfo->layerCount; 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_INVALID_EXTENSION;
        }
    }
    return VK_SUCCESS;
}

VkResult VKAPI loader_CreateInstance(
        const VkInstanceCreateInfo*     pCreateInfo,
        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;

    icd_create_info.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO;
    icd_create_info.layerCount = 0;
    icd_create_info.ppEnabledLayerNames = NULL;
    icd_create_info.pAllocCb = pCreateInfo->pAllocCb;
    icd_create_info.pAppInfo = pCreateInfo->pAppInfo;
    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->extensionCount * 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.extensionCount = 0;
            for (uint32_t i = 0; i < pCreateInfo->extensionCount; i++) {
                prop = get_extension_property(pCreateInfo->ppEnabledExtensionNames[i],
                                              &ptr_instance->ext_list);
                if (prop) {
                    filtered_extension_names[icd_create_info.extensionCount] = (char *) pCreateInfo->ppEnabledExtensionNames[i];
                    icd_create_info.extensionCount++;
                }
            }

            res = ptr_instance->icd_libs.list[i].CreateInstance(&icd_create_info,
                                           &(icd->instance));
            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;
}

void VKAPI loader_DestroyInstance(
        VkInstance                                instance)
{
    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;
    }
    /* TODOVV: Move this test to validation layer */
//    if (next  == NULL) {
//        // This must be an invalid instance handle or empty list
//        return VK_ERROR_INVALID_HANDLE;
//    }

    while (icds) {
        if (icds->instance) {
            icds->DestroyInstance(icds->instance);
            /* TODOVV: Move this test to validation layer */
            //if (res != VK_SUCCESS)
            //    loader_log(VK_DBG_REPORT_WARN_BIT, 0,
            //                "ICD ignored: failed to DestroyInstance on device");
        }
        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);
}

VkResult loader_init_physical_device_info(
        struct loader_instance *ptr_instance)
{
    struct loader_icd *icd;
    uint32_t n, count = 0;
    VkResult res = VK_ERROR_UNKNOWN;

    icd = ptr_instance->icds;
    while (icd) {
        res = icd->EnumeratePhysicalDevices(icd->instance, &n, NULL);
        if (res != VK_SUCCESS)
            return res;
        icd->gpu_count = n;
        count += n;
        icd = icd->next;
    }

    ptr_instance->total_gpu_count = count;

    icd = ptr_instance->icds;
    while (icd) {

        n = icd->gpu_count;
        icd->gpus = (VkPhysicalDevice *) loader_heap_alloc(
                                                ptr_instance,
                                                n * sizeof(VkPhysicalDevice),
                                                VK_SYSTEM_ALLOC_TYPE_INTERNAL);
        if (!icd->gpus) {
            /* TODO: Add cleanup code here */
            return VK_ERROR_OUT_OF_HOST_MEMORY;
        }
        res = icd->EnumeratePhysicalDevices(
                                        icd->instance,
                                        &n,
                                        icd->gpus);
        if ((res == VK_SUCCESS) && (n == icd->gpu_count)) {

            for (unsigned int i = 0; i < n; i++) {

                loader_init_dispatch(icd->gpus[i], ptr_instance->disp);

                if (!loader_init_ext_list(ptr_instance, &icd->device_extension_cache[i])) {
                    /* TODO: Add cleanup code here */
                    res = VK_ERROR_OUT_OF_HOST_MEMORY;
                }
                if (res == VK_SUCCESS) {

                    loader_add_physical_device_extensions(
                                ptr_instance,
                                icd->GetPhysicalDeviceExtensionProperties,
                                icd->gpus[0],
                                icd->this_icd_lib->lib_name,
                                &icd->device_extension_cache[i]);

                }

                if (res != VK_SUCCESS) {
                    /* clean up any extension lists previously created before this request failed */
                    for (uint32_t j = 0; j < i; j++) {
                        loader_destroy_ext_list(
                                ptr_instance,
                                &icd->device_extension_cache[i]);
                    }

                    return res;
                }
            }

            count += n;
        }

        icd = icd->next;
    }

    return VK_SUCCESS;
}

VkResult VKAPI loader_EnumeratePhysicalDevices(
        VkInstance                              instance,
        uint32_t*                               pPhysicalDeviceCount,
        VkPhysicalDevice*                       pPhysicalDevices)
{
    uint32_t index = 0;
    struct loader_instance *ptr_instance = (struct loader_instance *) instance;
    struct loader_icd *icd = ptr_instance->icds;

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

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

    while (icd) {
        assert((index + icd->gpu_count) <= *pPhysicalDeviceCount);
        memcpy(&pPhysicalDevices[index], icd->gpus, icd->gpu_count * sizeof(VkPhysicalDevice));
        index += icd->gpu_count;
        icd = icd->next;
    }

    return VK_SUCCESS;
}

VkResult VKAPI loader_GetPhysicalDeviceProperties(
        VkPhysicalDevice                        gpu,
        VkPhysicalDeviceProperties*             pProperties)
{
    uint32_t gpu_index;
    struct loader_icd *icd = loader_get_icd(gpu, &gpu_index);
    VkResult res = VK_ERROR_INITIALIZATION_FAILED;

    if (icd->GetPhysicalDeviceProperties)
        res = icd->GetPhysicalDeviceProperties(gpu, pProperties);

    return res;
}

VkResult VKAPI loader_GetPhysicalDeviceQueueFamilyProperties (
        VkPhysicalDevice                        gpu,
        uint32_t*                               pCount,
        VkQueueFamilyProperties*                pProperties)
{
    uint32_t gpu_index;
    struct loader_icd *icd = loader_get_icd(gpu, &gpu_index);
    VkResult res = VK_ERROR_INITIALIZATION_FAILED;

    if (icd->GetPhysicalDeviceQueueFamilyProperties)
        res = icd->GetPhysicalDeviceQueueFamilyProperties(gpu, pCount, pProperties);

    return res;
}

VkResult VKAPI loader_GetPhysicalDeviceMemoryProperties (
        VkPhysicalDevice gpu,
        VkPhysicalDeviceMemoryProperties* pProperties)
{
    uint32_t gpu_index;
    struct loader_icd *icd = loader_get_icd(gpu, &gpu_index);
    VkResult res = VK_ERROR_INITIALIZATION_FAILED;

    if (icd->GetPhysicalDeviceMemoryProperties)
        res = icd->GetPhysicalDeviceMemoryProperties(gpu, pProperties);

    return res;
}

VkResult VKAPI loader_GetPhysicalDeviceFeatures(
        VkPhysicalDevice                        physicalDevice,
        VkPhysicalDeviceFeatures*               pFeatures)
{
    uint32_t gpu_index;
    struct loader_icd *icd = loader_get_icd(physicalDevice, &gpu_index);
    VkResult res = VK_ERROR_INITIALIZATION_FAILED;

    if (icd->GetPhysicalDeviceFeatures)
        res = icd->GetPhysicalDeviceFeatures(physicalDevice, pFeatures);

    return res;
}

VkResult VKAPI loader_GetPhysicalDeviceFormatProperties(
        VkPhysicalDevice                        physicalDevice,
        VkFormat                                format,
        VkFormatProperties*                     pFormatInfo)
{
    uint32_t gpu_index;
    struct loader_icd *icd = loader_get_icd(physicalDevice, &gpu_index);
    VkResult res = VK_ERROR_INITIALIZATION_FAILED;

    if (icd->GetPhysicalDeviceFormatProperties)
        res = icd->GetPhysicalDeviceFormatProperties(physicalDevice, format, pFormatInfo);

    return res;
}

VkResult VKAPI loader_GetPhysicalDeviceImageFormatProperties(
        VkPhysicalDevice                        physicalDevice,
        VkFormat                                format,
        VkImageType                             type,
        VkImageTiling                           tiling,
        VkImageUsageFlags                       usage,
        VkImageCreateFlags                      flags,
        VkImageFormatProperties*                pImageFormatProperties)
{
    uint32_t gpu_index;
    struct loader_icd *icd = loader_get_icd(physicalDevice, &gpu_index);
    VkResult res = VK_ERROR_INITIALIZATION_FAILED;

    if (icd->GetPhysicalDeviceImageFormatProperties)
        res = icd->GetPhysicalDeviceImageFormatProperties(physicalDevice, format,
                                type, tiling, usage, flags, pImageFormatProperties);

    return res;
}

VkResult VKAPI loader_GetPhysicalDeviceSparseImageFormatProperties(
        VkPhysicalDevice                        physicalDevice,
        VkFormat                                format,
        VkImageType                             type,
        uint32_t                                samples,
        VkImageUsageFlags                       usage,
        VkImageTiling                           tiling,
        uint32_t*                               pNumProperties,
        VkSparseImageFormatProperties*          pProperties)
{
    uint32_t gpu_index;
    struct loader_icd *icd = loader_get_icd(physicalDevice, &gpu_index);
    VkResult res = VK_ERROR_INITIALIZATION_FAILED;

    if (icd->GetPhysicalDeviceSparseImageFormatProperties)
        res = icd->GetPhysicalDeviceSparseImageFormatProperties(physicalDevice, format, type, samples, usage, tiling, pNumProperties, pProperties);

    return res;
}

VkResult VKAPI loader_CreateDevice(
        VkPhysicalDevice                        gpu,
        const VkDeviceCreateInfo*               pCreateInfo,
        VkDevice*                               pDevice)
{
    uint32_t gpu_index;
    struct loader_icd *icd = loader_get_icd(gpu, &gpu_index);
    struct loader_device *dev;
    const struct loader_instance *inst = icd->this_instance;
    VkDeviceCreateInfo device_create_info;
    char **filtered_extension_names = NULL;
    VkResult res;

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

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

    res = loader_validate_device_extensions(icd, gpu_index, &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->extensionCount * 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.layerCount = 0;
    device_create_info.ppEnabledLayerNames = NULL;

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

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

    res = icd->CreateDevice(gpu, pCreateInfo, 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;
    }
    PFN_vkGetDeviceProcAddr get_proc_addr = icd->GetDeviceProcAddr;
    loader_init_device_dispatch_table(&dev->loader_dispatch, get_proc_addr,
                                      *pDevice, *pDevice);

    dev->loader_dispatch.CreateDevice = scratch_vkCreateDevice;
    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);

    res = dev->loader_dispatch.CreateDevice(gpu, pCreateInfo, pDevice);

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

    return res;
}

static PFN_vkVoidFunction VKAPI loader_GetInstanceProcAddr(VkInstance instance, const char * pName)
{
    if (instance == VK_NULL_HANDLE)
        return NULL;

    void *addr;
    /* get entrypoint addresses that are global (in the loader)*/
    addr = globalGetProcAddr(pName);
    if (addr)
        return addr;

    struct loader_instance *ptr_instance = (struct loader_instance *) instance;

    /* return any extension global entrypoints */
    addr = debug_report_instance_gpa(ptr_instance, pName);
    if (addr) {
        return addr;
    }

    addr = wsi_swapchain_GetInstanceProcAddr(ptr_instance, pName);
    if (addr) {
        return addr;
    }

    /* return the instance dispatch table entrypoint for extensions */
    const VkLayerInstanceDispatchTable *disp_table = * (VkLayerInstanceDispatchTable **) instance;
    if (disp_table == NULL)
        return NULL;

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

    return NULL;
}

LOADER_EXPORT PFN_vkVoidFunction VKAPI vkGetInstanceProcAddr(VkInstance instance, const char * pName)
{
    return loader_GetInstanceProcAddr(instance, pName);
}

static PFN_vkVoidFunction VKAPI loader_GetDeviceProcAddr(VkDevice device, const char * pName)
{
    if (device == VK_NULL_HANDLE) {
        return NULL;
    }

    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_gpa(pName);
    if (addr) {
        return addr;
    }

    /* 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;
    else  {
        if (disp_table->GetDeviceProcAddr == NULL)
            return NULL;
        return disp_table->GetDeviceProcAddr(device, pName);
    }
}

LOADER_EXPORT PFN_vkVoidFunction VKAPI vkGetDeviceProcAddr(VkDevice device, const char * pName)
{
    return loader_GetDeviceProcAddr(device, pName);
}

LOADER_EXPORT VkResult VKAPI vkGetGlobalExtensionProperties(
    const char*                                 pLayerName,
    uint32_t*                                   pCount,
    VkExtensionProperties*                      pProperties)
{
    struct loader_extension_list *global_ext_list;
    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));
    loader_platform_thread_once(&once_init, loader_initialize);

    //TODO do we still need to lock? for loader.global_extensions
    loader_platform_thread_lock_mutex(&loader_lock);
    /* get layer libraries if needed */
    if (pLayerName && strlen(pLayerName) != 0) {
        memset(&instance_layers, 0, sizeof(instance_layers));
        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;
            }
        }
        loader_destroy_layer_list(NULL, &instance_layers);
    }
    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_platform_thread_unlock_mutex(&loader_lock);
        return VK_ERROR_INVALID_LAYER;
    }

    if (pProperties == NULL) {
        *pCount = global_ext_list->count;
        loader_destroy_ext_list(NULL, &icd_extensions);
        loader_platform_thread_unlock_mutex(&loader_lock);
        return VK_SUCCESS;
    }

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

    if (copy_size < global_ext_list->count) {
        return VK_INCOMPLETE;
    }

    return VK_SUCCESS;
}

LOADER_EXPORT VkResult VKAPI vkGetGlobalLayerProperties(
    uint32_t*                                   pCount,
    VkLayerProperties*                          pProperties)
{

    struct loader_layer_list instance_layer_list;
    tls_instance = NULL;

    loader_platform_thread_once(&once_init, loader_initialize);

    uint32_t copy_size;

    /* TODO: do we still need to lock */
    loader_platform_thread_lock_mutex(&loader_lock);

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

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

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

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

    return VK_SUCCESS;
}

VkResult VKAPI loader_GetPhysicalDeviceExtensionProperties(
        VkPhysicalDevice                        gpu,
        const char*                             pLayerName,
        uint32_t*                               pCount,
        VkExtensionProperties*                  pProperties)
{
    uint32_t gpu_index;
    struct loader_icd *icd = loader_get_icd(gpu, &gpu_index);
    uint32_t copy_size;

    uint32_t count;
    struct loader_extension_list *dev_ext_list;

    /* get layer libraries if needed */
    if (pLayerName && strlen(pLayerName) != 0) {
        for (uint32_t i = 0; i < icd->this_instance->device_layer_list.count; i++) {
            struct loader_layer_properties *props = &icd->this_instance->device_layer_list.list[i];
            if (strcmp(props->info.layerName, pLayerName) == 0) {
               dev_ext_list = &props->device_extension_list;
            }
        }
    }
    else {
        dev_ext_list = &icd->device_extension_cache[gpu_index];
    }

    count = dev_ext_list->count;
    if (pProperties == NULL) {
        *pCount = count;
        return VK_SUCCESS;
    }

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

    if (copy_size < count) {
        return VK_INCOMPLETE;
    }

    return VK_SUCCESS;
}

VkResult VKAPI loader_GetPhysicalDeviceLayerProperties(
        VkPhysicalDevice                        gpu,
        uint32_t*                               pCount,
        VkLayerProperties*                      pProperties)
{
    uint32_t copy_size;
    uint32_t gpu_index;
    struct loader_icd *icd = loader_get_icd(gpu, &gpu_index);

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

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

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

    if (copy_size < count) {
        return VK_INCOMPLETE;
    }

    return VK_SUCCESS;
}
