/*
 * Copyright (c) 2015-2017 The Khronos Group Inc.
 * Copyright (c) 2015-2017 Valve Corporation
 * Copyright (c) 2015-2017 LunarG, Inc.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and/or associated documentation files (the "Materials"), to
 * deal in the Materials without restriction, including without limitation the
 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
 * sell copies of the Materials, and to permit persons to whom the Materials are
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice(s) and this permission notice shall be included in
 * all copies or substantial portions of the Materials.
 *
 * THE MATERIALS ARE 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 MATERIALS OR THE
 * USE OR OTHER DEALINGS IN THE MATERIALS.
 *
 * Author: Jeremy Hayes <jeremy@lunarG.com>
 * Author: Mark Young <marky@lunarG.com>
 */

// Following items are needed for C++ to work with PRIxLEAST64
#define __STDC_FORMAT_MACROS
#include <inttypes.h>

#include <stdint.h>  // For UINT32_MAX

#include <algorithm>
#include <iostream>
#include <memory>
#include <string>
#include <vector>

#include "test_common.h"
#include <vulkan/vulkan.h>

namespace VK {

struct InstanceCreateInfo {
    InstanceCreateInfo()
        : info  // MSVC can't handle list initialization, thus explicit construction herein.
          (VkInstanceCreateInfo{
              VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO,  // sType
              nullptr,                                 // pNext
              0,                                       // flags
              nullptr,                                 // pApplicationInfo
              0,                                       // enabledLayerCount
              nullptr,                                 // ppEnabledLayerNames
              0,                                       // enabledExtensionCount
              nullptr                                  // ppEnabledExtensionNames
          }) {}

    InstanceCreateInfo &sType(VkStructureType const &sType) {
        info.sType = sType;

        return *this;
    }

    InstanceCreateInfo &pNext(void const *const pNext) {
        info.pNext = pNext;

        return *this;
    }

    InstanceCreateInfo &flags(VkInstanceCreateFlags const &flags) {
        info.flags = flags;

        return *this;
    }

    InstanceCreateInfo &pApplicationInfo(VkApplicationInfo const *const pApplicationInfo) {
        info.pApplicationInfo = pApplicationInfo;

        return *this;
    }

    InstanceCreateInfo &enabledLayerCount(uint32_t const &enabledLayerCount) {
        info.enabledLayerCount = enabledLayerCount;

        return *this;
    }

    InstanceCreateInfo &ppEnabledLayerNames(char const *const *const ppEnabledLayerNames) {
        info.ppEnabledLayerNames = ppEnabledLayerNames;

        return *this;
    }

    InstanceCreateInfo &enabledExtensionCount(uint32_t const &enabledExtensionCount) {
        info.enabledExtensionCount = enabledExtensionCount;

        return *this;
    }

    InstanceCreateInfo &ppEnabledExtensionNames(char const *const *const ppEnabledExtensionNames) {
        info.ppEnabledExtensionNames = ppEnabledExtensionNames;

        return *this;
    }

    operator VkInstanceCreateInfo const *() const { return &info; }

    operator VkInstanceCreateInfo *() { return &info; }

    VkInstanceCreateInfo info;
};

struct DeviceQueueCreateInfo {
    DeviceQueueCreateInfo()
        : info  // MSVC can't handle list initialization, thus explicit construction herein.
          (VkDeviceQueueCreateInfo{
              VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO,  // sType
              nullptr,                                     // pNext
              0,                                           // flags
              0,                                           // queueFamilyIndex
              0,                                           // queueCount
              nullptr                                      // pQueuePriorities
          }) {}

    DeviceQueueCreateInfo &sType(VkStructureType const &sType) {
        info.sType = sType;

        return *this;
    }

    DeviceQueueCreateInfo &pNext(void const *const pNext) {
        info.pNext = pNext;

        return *this;
    }

    DeviceQueueCreateInfo &flags(VkDeviceQueueCreateFlags const &flags) {
        info.flags = flags;

        return *this;
    }

    DeviceQueueCreateInfo &queueFamilyIndex(uint32_t const &queueFamilyIndex) {
        info.queueFamilyIndex = queueFamilyIndex;

        return *this;
    }

    DeviceQueueCreateInfo &queueCount(uint32_t const &queueCount) {
        info.queueCount = queueCount;

        return *this;
    }

    DeviceQueueCreateInfo &pQueuePriorities(float const *const pQueuePriorities) {
        info.pQueuePriorities = pQueuePriorities;

        return *this;
    }

    operator VkDeviceQueueCreateInfo() { return info; }

    VkDeviceQueueCreateInfo info;
};

struct DeviceCreateInfo {
    DeviceCreateInfo()
        : info  // MSVC can't handle list initialization, thus explicit construction herein.
          (VkDeviceCreateInfo{
              VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO,  // sType
              nullptr,                               // pNext
              0,                                     // flags
              0,                                     // queueCreateInfoCount
              nullptr,                               // pQueueCreateInfos
              0,                                     // enabledLayerCount
              nullptr,                               // ppEnabledLayerNames
              0,                                     // enabledExtensionCount
              nullptr,                               // ppEnabledExtensionNames
              nullptr                                // pEnabledFeatures
          }) {}

    DeviceCreateInfo &sType(VkStructureType const &sType) {
        info.sType = sType;

        return *this;
    }

    DeviceCreateInfo &pNext(void const *const pNext) {
        info.pNext = pNext;

        return *this;
    }

    DeviceCreateInfo &flags(VkDeviceQueueCreateFlags const &flags) {
        info.flags = flags;

        return *this;
    }

    DeviceCreateInfo &queueCreateInfoCount(uint32_t const &queueCreateInfoCount) {
        info.queueCreateInfoCount = queueCreateInfoCount;

        return *this;
    }

    DeviceCreateInfo &pQueueCreateInfos(VkDeviceQueueCreateInfo const *const pQueueCreateInfos) {
        info.pQueueCreateInfos = pQueueCreateInfos;

        return *this;
    }

    DeviceCreateInfo &enabledLayerCount(uint32_t const &enabledLayerCount) {
        info.enabledLayerCount = enabledLayerCount;

        return *this;
    }

    DeviceCreateInfo &ppEnabledLayerNames(char const *const *const ppEnabledLayerNames) {
        info.ppEnabledLayerNames = ppEnabledLayerNames;

        return *this;
    }

    DeviceCreateInfo &enabledExtensionCount(uint32_t const &enabledExtensionCount) {
        info.enabledExtensionCount = enabledExtensionCount;

        return *this;
    }

    DeviceCreateInfo &ppEnabledExtensionNames(char const *const *const ppEnabledExtensionNames) {
        info.ppEnabledExtensionNames = ppEnabledExtensionNames;

        return *this;
    }

    DeviceCreateInfo &pEnabledFeatures(VkPhysicalDeviceFeatures const *const pEnabledFeatures) {
        info.pEnabledFeatures = pEnabledFeatures;

        return *this;
    }

    operator VkDeviceCreateInfo const *() const { return &info; }

    operator VkDeviceCreateInfo *() { return &info; }

    VkDeviceCreateInfo info;
};
}

struct CommandLine : public ::testing::Test {
    static void Initialize(int argc, char **argv) { arguments.assign(argv, argv + argc); };

    static void SetUpTestCase(){};
    static void TearDownTestCase(){};

    static std::vector<std::string> arguments;
};
std::vector<std::string> CommandLine::arguments;

struct EnumerateInstanceLayerProperties : public CommandLine {};
struct EnumerateInstanceExtensionProperties : public CommandLine {};
struct ImplicitLayer : public CommandLine {};

// Allocation tracking utilities
struct AllocTrack {
    bool active;
    bool was_allocated;
    void *aligned_start_addr;
    char *actual_start_addr;
    size_t requested_size_bytes;
    size_t actual_size_bytes;
    VkSystemAllocationScope alloc_scope;
    uint64_t user_data;

    AllocTrack()
        : active(false),
          was_allocated(false),
          aligned_start_addr(nullptr),
          actual_start_addr(nullptr),
          requested_size_bytes(0),
          actual_size_bytes(0),
          alloc_scope(VK_SYSTEM_ALLOCATION_SCOPE_COMMAND),
          user_data(0) {}
};

// Global vector to track allocations.  This will be resized before each test and emptied after.
// However, we have to globally define it so the allocation callback functions work properly.
std::vector<AllocTrack> g_allocated_vector;
bool g_intentional_fail_enabled = false;
uint32_t g_intenional_fail_index = 0;
uint32_t g_intenional_fail_count = 0;

void FreeAllocTracker() { g_allocated_vector.clear(); }

void InitAllocTracker(size_t size, uint32_t intentional_fail_index = UINT32_MAX) {
    if (g_allocated_vector.size() > 0) {
        FreeAllocTracker();
    }
    g_allocated_vector.resize(size);
    if (intentional_fail_index != UINT32_MAX) {
        g_intentional_fail_enabled = true;
        g_intenional_fail_index = intentional_fail_index;
        g_intenional_fail_count = 0;
    } else {
        g_intentional_fail_enabled = false;
        g_intenional_fail_index = 0;
        g_intenional_fail_count = 0;
    }
}

bool IsAllocTrackerEmpty() {
    bool success = true;
    bool was_allocated = false;
    char print_command[1024];
    sprintf(print_command, "\t%%04d\t%%p (%%p) : 0x%%%s (0x%%%s) : scope %%d : user_data 0x%%%s\n", PRIxLEAST64, PRIxLEAST64,
            PRIxLEAST64);
    for (uint32_t iii = 0; iii < g_allocated_vector.size(); iii++) {
        if (g_allocated_vector[iii].active) {
            if (success) {
                printf("ERROR: Allocations still remain!\n");
            }
            printf(print_command, iii, g_allocated_vector[iii].aligned_start_addr, g_allocated_vector[iii].actual_start_addr,
                   g_allocated_vector[iii].requested_size_bytes, g_allocated_vector[iii].actual_size_bytes,
                   g_allocated_vector[iii].alloc_scope, g_allocated_vector[iii].user_data);
            success = false;
        } else if (!was_allocated && g_allocated_vector[iii].was_allocated) {
            was_allocated = true;
        }
    }
    if (!g_intentional_fail_enabled && !was_allocated) {
        printf("No allocations ever generated!");
        success = false;
    }
    return success;
}

VKAPI_ATTR void *VKAPI_CALL AllocCallbackFunc(void *pUserData, size_t size, size_t alignment,
                                              VkSystemAllocationScope allocationScope) {
    if (g_intentional_fail_enabled) {
        if (++g_intenional_fail_count >= g_intenional_fail_index) {
            return nullptr;
        }
    }
    for (uint32_t iii = 0; iii < g_allocated_vector.size(); iii++) {
        if (!g_allocated_vector[iii].active) {
            g_allocated_vector[iii].requested_size_bytes = size;
            g_allocated_vector[iii].actual_size_bytes = size + (alignment - 1);
            g_allocated_vector[iii].aligned_start_addr = NULL;
            g_allocated_vector[iii].actual_start_addr = new char[g_allocated_vector[iii].actual_size_bytes];
            if (g_allocated_vector[iii].actual_start_addr != NULL) {
                uint64_t addr = (uint64_t)g_allocated_vector[iii].actual_start_addr;
                addr += (alignment - 1);
                addr &= ~(alignment - 1);
                g_allocated_vector[iii].aligned_start_addr = (void *)addr;
                g_allocated_vector[iii].alloc_scope = allocationScope;
                g_allocated_vector[iii].user_data = (uint64_t)pUserData;
                g_allocated_vector[iii].active = true;
                g_allocated_vector[iii].was_allocated = true;
            }
            return g_allocated_vector[iii].aligned_start_addr;
        }
    }
    return nullptr;
}

VKAPI_ATTR void VKAPI_CALL FreeCallbackFunc(void *pUserData, void *pMemory) {
    for (uint32_t iii = 0; iii < g_allocated_vector.size(); iii++) {
        if (g_allocated_vector[iii].active && g_allocated_vector[iii].aligned_start_addr == pMemory) {
            delete[] g_allocated_vector[iii].actual_start_addr;
            g_allocated_vector[iii].active = false;
            break;
        }
    }
}

VKAPI_ATTR void *VKAPI_CALL ReallocCallbackFunc(void *pUserData, void *pOriginal, size_t size, size_t alignment,
                                                VkSystemAllocationScope allocationScope) {
    if (pOriginal != NULL) {
        for (uint32_t iii = 0; iii < g_allocated_vector.size(); iii++) {
            if (g_allocated_vector[iii].active && g_allocated_vector[iii].aligned_start_addr == pOriginal) {
                if (size == 0) {
                    FreeCallbackFunc(pUserData, pOriginal);
                    return nullptr;
                } else if (size < g_allocated_vector[iii].requested_size_bytes) {
                    return pOriginal;
                } else {
                    void *pNew = AllocCallbackFunc(pUserData, size, alignment, allocationScope);
                    if (pNew != NULL) {
                        size_t copy_size = size;
                        if (g_allocated_vector[iii].requested_size_bytes < size) {
                            copy_size = g_allocated_vector[iii].requested_size_bytes;
                        }
                        memcpy(pNew, pOriginal, copy_size);
                        FreeCallbackFunc(pUserData, pOriginal);
                    }
                    return pNew;
                }
            }
        }
        return nullptr;
    } else {
        return AllocCallbackFunc(pUserData, size, alignment, allocationScope);
    }
}

// Test groups:
// LX = lunar exchange
// LVLGH = loader and validation github
// LVLGL = lodaer and validation gitlab

TEST(LX435, InstanceCreateInfoConst) {
    VkInstanceCreateInfo const info = {VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO, nullptr, 0, nullptr, 0, nullptr, 0, nullptr};

    VkInstance instance = VK_NULL_HANDLE;
    VkResult result = vkCreateInstance(&info, VK_NULL_HANDLE, &instance);
    EXPECT_EQ(result, VK_SUCCESS);

    vkDestroyInstance(instance, nullptr);
}

TEST(LX475, DestroyInstanceNullHandle) { vkDestroyInstance(VK_NULL_HANDLE, nullptr); }

TEST(LX475, DestroyDeviceNullHandle) { vkDestroyDevice(VK_NULL_HANDLE, nullptr); }

TEST(CreateInstance, ExtensionNotPresent) {
    char const *const names[] = {"NotPresent"};  // Temporary required due to MSVC bug.
    auto const info = VK::InstanceCreateInfo().enabledExtensionCount(1).ppEnabledExtensionNames(names);

    VkInstance instance = VK_NULL_HANDLE;
    VkResult result = vkCreateInstance(info, VK_NULL_HANDLE, &instance);
    ASSERT_EQ(result, VK_ERROR_EXTENSION_NOT_PRESENT);

    // It's not necessary to destroy the instance because it will not be created successfully.
}

TEST(CreateInstance, LayerNotPresent) {
    char const *const names[] = {"NotPresent"};  // Temporary required due to MSVC bug.
    auto const info = VK::InstanceCreateInfo().enabledLayerCount(1).ppEnabledLayerNames(names);

    VkInstance instance = VK_NULL_HANDLE;
    VkResult result = vkCreateInstance(info, VK_NULL_HANDLE, &instance);
    ASSERT_EQ(result, VK_ERROR_LAYER_NOT_PRESENT);

    // It's not necessary to destroy the instance because it will not be created successfully.
}

// Used by run_loader_tests.sh to test for layer insertion.
TEST(CreateInstance, LayerPresent) {
    char const *const names1[] = {"VK_LAYER_LUNARG_parameter_validation"};  // Temporary required due to MSVC bug.
    char const *const names2[] = {"VK_LAYER_LUNARG_standard_validation"};   // Temporary required due to MSVC bug.
    auto const info1 = VK::InstanceCreateInfo().enabledLayerCount(1).ppEnabledLayerNames(names1);
    VkInstance instance = VK_NULL_HANDLE;
    VkResult result = vkCreateInstance(info1, VK_NULL_HANDLE, &instance);
    ASSERT_EQ(result, VK_SUCCESS);
    vkDestroyInstance(instance, nullptr);

    auto const info2 = VK::InstanceCreateInfo().enabledLayerCount(1).ppEnabledLayerNames(names2);
    instance = VK_NULL_HANDLE;
    result = vkCreateInstance(info2, VK_NULL_HANDLE, &instance);
    ASSERT_EQ(result, VK_SUCCESS);
    vkDestroyInstance(instance, nullptr);
}

// Used by run_loader_tests.sh to test that calling vkEnumeratePhysicalDevices without first querying
// the count, works.
TEST(EnumeratePhysicalDevices, OneCall) {
    VkInstance instance = VK_NULL_HANDLE;
    VkResult result = vkCreateInstance(VK::InstanceCreateInfo(), VK_NULL_HANDLE, &instance);
    ASSERT_EQ(result, VK_SUCCESS);

    uint32_t physicalCount = 500;
    std::unique_ptr<VkPhysicalDevice[]> physical(new VkPhysicalDevice[physicalCount]);
    result = vkEnumeratePhysicalDevices(instance, &physicalCount, physical.get());
    ASSERT_EQ(result, VK_SUCCESS);
    ASSERT_GT(physicalCount, 0u);

    vkDestroyInstance(instance, nullptr);
}

// Used by run_loader_tests.sh to test for the expected usage of the vkEnumeratePhysicalDevices call.
TEST(EnumeratePhysicalDevices, TwoCall) {
    VkInstance instance = VK_NULL_HANDLE;
    VkResult result = vkCreateInstance(VK::InstanceCreateInfo(), VK_NULL_HANDLE, &instance);
    ASSERT_EQ(result, VK_SUCCESS);

    uint32_t physicalCount = 0;
    result = vkEnumeratePhysicalDevices(instance, &physicalCount, nullptr);
    ASSERT_EQ(result, VK_SUCCESS);
    ASSERT_GT(physicalCount, 0u);

    std::unique_ptr<VkPhysicalDevice[]> physical(new VkPhysicalDevice[physicalCount]);
    result = vkEnumeratePhysicalDevices(instance, &physicalCount, physical.get());
    ASSERT_EQ(result, VK_SUCCESS);
    ASSERT_GT(physicalCount, 0u);

    vkDestroyInstance(instance, nullptr);
}

// Used by run_loader_tests.sh to test that calling vkEnumeratePhysicalDevices without first querying
// the count, matches the count from the standard call.
TEST(EnumeratePhysicalDevices, MatchOneAndTwoCallNumbers) {
    VkInstance instance_one = VK_NULL_HANDLE;
    VkResult result = vkCreateInstance(VK::InstanceCreateInfo(), VK_NULL_HANDLE, &instance_one);
    ASSERT_EQ(result, VK_SUCCESS);

    uint32_t physicalCount_one = 500;
    std::unique_ptr<VkPhysicalDevice[]> physical_one(new VkPhysicalDevice[physicalCount_one]);
    result = vkEnumeratePhysicalDevices(instance_one, &physicalCount_one, physical_one.get());
    ASSERT_EQ(result, VK_SUCCESS);
    ASSERT_GT(physicalCount_one, 0u);

    VkInstance instance_two = VK_NULL_HANDLE;
    result = vkCreateInstance(VK::InstanceCreateInfo(), VK_NULL_HANDLE, &instance_two);
    ASSERT_EQ(result, VK_SUCCESS);

    uint32_t physicalCount_two = 0;
    result = vkEnumeratePhysicalDevices(instance_two, &physicalCount_two, nullptr);
    ASSERT_EQ(result, VK_SUCCESS);
    ASSERT_GT(physicalCount_two, 0u);

    std::unique_ptr<VkPhysicalDevice[]> physical_two(new VkPhysicalDevice[physicalCount_two]);
    result = vkEnumeratePhysicalDevices(instance_two, &physicalCount_two, physical_two.get());
    ASSERT_EQ(result, VK_SUCCESS);
    ASSERT_GT(physicalCount_two, 0u);

    ASSERT_EQ(physicalCount_one, physicalCount_two);

    vkDestroyInstance(instance_one, nullptr);
    vkDestroyInstance(instance_two, nullptr);
}

// Used by run_loader_tests.sh to test for the expected usage of the vkEnumeratePhysicalDevices
// call if not enough numbers are provided for the final list.
TEST(EnumeratePhysicalDevices, TwoCallIncomplete) {
    VkInstance instance = VK_NULL_HANDLE;
    VkResult result = vkCreateInstance(VK::InstanceCreateInfo(), VK_NULL_HANDLE, &instance);
    ASSERT_EQ(result, VK_SUCCESS);

    uint32_t physicalCount = 0;
    result = vkEnumeratePhysicalDevices(instance, &physicalCount, nullptr);
    ASSERT_EQ(result, VK_SUCCESS);
    ASSERT_GT(physicalCount, 0u);

    std::unique_ptr<VkPhysicalDevice[]> physical(new VkPhysicalDevice[physicalCount]);

    // Remove one from the physical device count so we can get the VK_INCOMPLETE message
    physicalCount -= 1;

    result = vkEnumeratePhysicalDevices(instance, &physicalCount, physical.get());
    ASSERT_EQ(result, VK_INCOMPLETE);

    vkDestroyInstance(instance, nullptr);
}

// Test to make sure that layers enabled in the instance show up in the list of device layers.
TEST(EnumerateDeviceLayers, LayersMatch) {
    char const *const names1[] = {"VK_LAYER_LUNARG_standard_validation"};
    char const *const names2[3] = {"VK_LAYER_LUNARG_parameter_validation", "VK_LAYER_LUNARG_core_validation",
                                   "VK_LAYER_LUNARG_object_tracker"};
    auto const info1 = VK::InstanceCreateInfo().enabledLayerCount(1).ppEnabledLayerNames(names1);
    VkInstance instance = VK_NULL_HANDLE;
    VkResult result = vkCreateInstance(info1, VK_NULL_HANDLE, &instance);
    ASSERT_EQ(result, VK_SUCCESS);

    uint32_t physicalCount = 0;
    result = vkEnumeratePhysicalDevices(instance, &physicalCount, nullptr);
    ASSERT_EQ(result, VK_SUCCESS);
    ASSERT_GT(physicalCount, 0u);

    std::unique_ptr<VkPhysicalDevice[]> physical(new VkPhysicalDevice[physicalCount]);
    result = vkEnumeratePhysicalDevices(instance, &physicalCount, physical.get());
    ASSERT_EQ(result, VK_SUCCESS);
    ASSERT_GT(physicalCount, 0u);
    uint32_t count = 24;
    VkLayerProperties layer_props[24];
    vkEnumerateDeviceLayerProperties(physical[0], &count, layer_props);
    ASSERT_GE(count, 1u);
    bool found = false;
    for (uint32_t iii = 0; iii < count; iii++) {
        if (!strcmp(layer_props[iii].layerName, names1[0])) {
            found = true;
            break;
        }
    }
    if (!found) {
        ASSERT_EQ(count, 0);
    }

    vkDestroyInstance(instance, nullptr);

    auto const info2 = VK::InstanceCreateInfo().enabledLayerCount(3).ppEnabledLayerNames(names2);
    instance = VK_NULL_HANDLE;
    result = vkCreateInstance(info2, VK_NULL_HANDLE, &instance);
    ASSERT_EQ(result, VK_SUCCESS);

    physicalCount = 0;
    result = vkEnumeratePhysicalDevices(instance, &physicalCount, nullptr);
    ASSERT_EQ(result, VK_SUCCESS);
    ASSERT_GT(physicalCount, 0u);

    std::unique_ptr<VkPhysicalDevice[]> physical2(new VkPhysicalDevice[physicalCount]);
    result = vkEnumeratePhysicalDevices(instance, &physicalCount, physical2.get());
    ASSERT_EQ(result, VK_SUCCESS);
    ASSERT_GT(physicalCount, 0u);

    count = 24;
    vkEnumerateDeviceLayerProperties(physical2[0], &count, layer_props);
    ASSERT_GE(count, 3u);
    for (uint32_t jjj = 0; jjj < 3; jjj++) {
        found = false;
        for (uint32_t iii = 0; iii < count; iii++) {
            if (!strcmp(layer_props[iii].layerName, names2[jjj])) {
                found = true;
                break;
            }
        }
        if (!found) {
            ASSERT_EQ(count, 0);
        }
    }

    vkDestroyInstance(instance, nullptr);
}

TEST(CreateDevice, ExtensionNotPresent) {
    VkInstance instance = VK_NULL_HANDLE;
    VkResult result = vkCreateInstance(VK::InstanceCreateInfo(), VK_NULL_HANDLE, &instance);
    ASSERT_EQ(result, VK_SUCCESS);

    uint32_t physicalCount = 0;
    result = vkEnumeratePhysicalDevices(instance, &physicalCount, nullptr);
    ASSERT_EQ(result, VK_SUCCESS);
    ASSERT_GT(physicalCount, 0u);

    std::unique_ptr<VkPhysicalDevice[]> physical(new VkPhysicalDevice[physicalCount]);
    result = vkEnumeratePhysicalDevices(instance, &physicalCount, physical.get());
    ASSERT_EQ(result, VK_SUCCESS);
    ASSERT_GT(physicalCount, 0u);

    for (uint32_t p = 0; p < physicalCount; ++p) {
        uint32_t familyCount = 0;
        vkGetPhysicalDeviceQueueFamilyProperties(physical[p], &familyCount, nullptr);
        ASSERT_GT(familyCount, 0u);

        std::unique_ptr<VkQueueFamilyProperties[]> family(new VkQueueFamilyProperties[familyCount]);
        vkGetPhysicalDeviceQueueFamilyProperties(physical[p], &familyCount, family.get());
        ASSERT_GT(familyCount, 0u);

        for (uint32_t q = 0; q < familyCount; ++q) {
            if (~family[q].queueFlags & VK_QUEUE_GRAPHICS_BIT) {
                continue;
            }

            float const priorities[] = {0.0f};  // Temporary required due to MSVC bug.
            VkDeviceQueueCreateInfo const queueInfo[1]{
                VK::DeviceQueueCreateInfo().queueFamilyIndex(q).queueCount(1).pQueuePriorities(priorities)};

            char const *const names[] = {"NotPresent"};  // Temporary required due to MSVC bug.
            auto const deviceInfo = VK::DeviceCreateInfo()
                                        .queueCreateInfoCount(1)
                                        .pQueueCreateInfos(queueInfo)
                                        .enabledExtensionCount(1)
                                        .ppEnabledExtensionNames(names);

            VkDevice device;
            result = vkCreateDevice(physical[p], deviceInfo, nullptr, &device);
            ASSERT_EQ(result, VK_ERROR_EXTENSION_NOT_PRESENT);

            // It's not necessary to destroy the device because it will not be created successfully.
        }
    }

    vkDestroyInstance(instance, nullptr);
}

// LX535 / MI-76: Device layers are deprecated.
// For backwards compatibility, they are allowed, but must be ignored.
// Ensure that no errors occur if a bogus device layer list is passed to vkCreateDevice.
TEST(CreateDevice, LayersNotPresent) {
    VkInstance instance = VK_NULL_HANDLE;
    VkResult result = vkCreateInstance(VK::InstanceCreateInfo(), VK_NULL_HANDLE, &instance);
    ASSERT_EQ(result, VK_SUCCESS);

    uint32_t physicalCount = 0;
    result = vkEnumeratePhysicalDevices(instance, &physicalCount, nullptr);
    ASSERT_EQ(result, VK_SUCCESS);
    ASSERT_GT(physicalCount, 0u);

    std::unique_ptr<VkPhysicalDevice[]> physical(new VkPhysicalDevice[physicalCount]);
    result = vkEnumeratePhysicalDevices(instance, &physicalCount, physical.get());
    ASSERT_EQ(result, VK_SUCCESS);
    ASSERT_GT(physicalCount, 0u);

    for (uint32_t p = 0; p < physicalCount; ++p) {
        uint32_t familyCount = 0;
        vkGetPhysicalDeviceQueueFamilyProperties(physical[p], &familyCount, nullptr);
        ASSERT_EQ(result, VK_SUCCESS);
        ASSERT_GT(familyCount, 0u);

        std::unique_ptr<VkQueueFamilyProperties[]> family(new VkQueueFamilyProperties[familyCount]);
        vkGetPhysicalDeviceQueueFamilyProperties(physical[p], &familyCount, family.get());
        ASSERT_EQ(result, VK_SUCCESS);
        ASSERT_GT(familyCount, 0u);

        for (uint32_t q = 0; q < familyCount; ++q) {
            if (~family[q].queueFlags & VK_QUEUE_GRAPHICS_BIT) {
                continue;
            }

            float const priorities[] = {0.0f};  // Temporary required due to MSVC bug.
            VkDeviceQueueCreateInfo const queueInfo[1]{
                VK::DeviceQueueCreateInfo().queueFamilyIndex(q).queueCount(1).pQueuePriorities(priorities)};

            char const *const names[] = {"NotPresent"};  // Temporary required due to MSVC bug.
            auto const deviceInfo = VK::DeviceCreateInfo()
                                        .queueCreateInfoCount(1)
                                        .pQueueCreateInfos(queueInfo)
                                        .enabledLayerCount(1)
                                        .ppEnabledLayerNames(names);

            VkDevice device;
            result = vkCreateDevice(physical[p], deviceInfo, nullptr, &device);
            ASSERT_EQ(result, VK_SUCCESS);

            vkDestroyDevice(device, nullptr);
        }
    }

    vkDestroyInstance(instance, nullptr);
}

TEST_F(EnumerateInstanceLayerProperties, PropertyCountLessThanAvailable) {
    uint32_t count = 0u;
    VkResult result = vkEnumerateInstanceLayerProperties(&count, nullptr);
    ASSERT_EQ(result, VK_SUCCESS);

    // We need atleast two for the test to be relevant.
    if (count < 2u) {
        return;
    }

    std::unique_ptr<VkLayerProperties[]> properties(new VkLayerProperties[count]);
    count = 1;
    result = vkEnumerateInstanceLayerProperties(&count, properties.get());
    ASSERT_EQ(result, VK_INCOMPLETE);
}

TEST(EnumerateDeviceLayerProperties, PropertyCountLessThanAvailable) {
    VkInstance instance = VK_NULL_HANDLE;
    VkResult result = vkCreateInstance(VK::InstanceCreateInfo(), VK_NULL_HANDLE, &instance);
    ASSERT_EQ(result, VK_SUCCESS);

    uint32_t physicalCount = 0;
    result = vkEnumeratePhysicalDevices(instance, &physicalCount, nullptr);
    ASSERT_EQ(result, VK_SUCCESS);
    ASSERT_GT(physicalCount, 0u);

    std::unique_ptr<VkPhysicalDevice[]> physical(new VkPhysicalDevice[physicalCount]);
    result = vkEnumeratePhysicalDevices(instance, &physicalCount, physical.get());
    ASSERT_EQ(result, VK_SUCCESS);
    ASSERT_GT(physicalCount, 0u);

    for (uint32_t p = 0; p < physicalCount; ++p) {
        uint32_t count = 0u;
        result = vkEnumerateDeviceLayerProperties(physical[p], &count, nullptr);
        ASSERT_EQ(result, VK_SUCCESS);

        // We need atleast two for the test to be relevant.
        if (count < 2u) {
            continue;
        }

        std::unique_ptr<VkLayerProperties[]> properties(new VkLayerProperties[count]);
        count = 1;
        result = vkEnumerateDeviceLayerProperties(physical[p], &count, properties.get());
        ASSERT_EQ(result, VK_INCOMPLETE);
    }

    vkDestroyInstance(instance, nullptr);
}

TEST_F(EnumerateInstanceLayerProperties, Count) {
    uint32_t count = 0u;
    VkResult result = vkEnumerateInstanceLayerProperties(&count, nullptr);
    ASSERT_EQ(result, VK_SUCCESS);

    if (std::find(arguments.begin(), arguments.end(), "count") != arguments.end()) {
        std::cout << "count=" << count << '\n';
    }
}

TEST_F(EnumerateInstanceLayerProperties, OnePass) {
    // Count required for this test.
    if (std::find(arguments.begin(), arguments.end(), "count") == arguments.end()) {
        return;
    }

    uint32_t count = std::stoul(arguments[2]);

    std::unique_ptr<VkLayerProperties[]> properties(new VkLayerProperties[count]);
    VkResult result = vkEnumerateInstanceLayerProperties(&count, properties.get());
    ASSERT_EQ(result, VK_SUCCESS);

    if (std::find(arguments.begin(), arguments.end(), "properties") != arguments.end()) {
        for (uint32_t p = 0; p < count; ++p) {
            std::cout << "properties[" << p << "] =" << ' ' << properties[p].layerName << ' ' << properties[p].specVersion << ' '
                      << properties[p].implementationVersion << ' ' << properties[p].description << '\n';
        }
    }
}

TEST_F(EnumerateInstanceLayerProperties, TwoPass) {
    uint32_t count = 0u;
    VkResult result = vkEnumerateInstanceLayerProperties(&count, nullptr);
    ASSERT_EQ(result, VK_SUCCESS);

    std::unique_ptr<VkLayerProperties[]> properties(new VkLayerProperties[count]);
    result = vkEnumerateInstanceLayerProperties(&count, properties.get());
    ASSERT_EQ(result, VK_SUCCESS);

    if (std::find(arguments.begin(), arguments.end(), "properties") != arguments.end()) {
        for (uint32_t p = 0; p < count; ++p) {
            std::cout << "properties[" << p << "] =" << ' ' << properties[p].layerName << ' ' << properties[p].specVersion << ' '
                      << properties[p].implementationVersion << ' ' << properties[p].description << '\n';
        }
    }
}

TEST_F(EnumerateInstanceExtensionProperties, PropertyCountLessThanAvailable) {
    uint32_t count = 0u;
    VkResult result = vkEnumerateInstanceExtensionProperties(nullptr, &count, nullptr);
    ASSERT_EQ(result, VK_SUCCESS);

    // We need atleast two for the test to be relevant.
    if (count < 2u) {
        return;
    }

    std::unique_ptr<VkExtensionProperties[]> properties(new VkExtensionProperties[count]);
    count = 1;
    result = vkEnumerateInstanceExtensionProperties(nullptr, &count, properties.get());
    ASSERT_EQ(result, VK_INCOMPLETE);
}

TEST(EnumerateDeviceExtensionProperties, PropertyCountLessThanAvailable) {
    VkInstance instance = VK_NULL_HANDLE;
    VkResult result = vkCreateInstance(VK::InstanceCreateInfo(), VK_NULL_HANDLE, &instance);
    ASSERT_EQ(result, VK_SUCCESS);

    uint32_t physicalCount = 0;
    result = vkEnumeratePhysicalDevices(instance, &physicalCount, nullptr);
    ASSERT_EQ(result, VK_SUCCESS);
    ASSERT_GT(physicalCount, 0u);

    std::unique_ptr<VkPhysicalDevice[]> physical(new VkPhysicalDevice[physicalCount]);
    result = vkEnumeratePhysicalDevices(instance, &physicalCount, physical.get());
    ASSERT_EQ(result, VK_SUCCESS);
    ASSERT_GT(physicalCount, 0u);

    for (uint32_t p = 0; p < physicalCount; ++p) {
        uint32_t count = 0u;
        result = vkEnumerateDeviceExtensionProperties(physical[p], nullptr, &count, nullptr);
        ASSERT_EQ(result, VK_SUCCESS);

        // We need atleast two for the test to be relevant.
        if (count < 2u) {
            continue;
        }

        std::unique_ptr<VkExtensionProperties[]> properties(new VkExtensionProperties[count]);
        count = 1;
        result = vkEnumerateDeviceExtensionProperties(physical[p], nullptr, &count, properties.get());
        ASSERT_EQ(result, VK_INCOMPLETE);
    }

    vkDestroyInstance(instance, nullptr);
}

TEST_F(EnumerateInstanceExtensionProperties, Count) {
    uint32_t count = 0u;
    VkResult result = vkEnumerateInstanceExtensionProperties(nullptr, &count, nullptr);
    ASSERT_EQ(result, VK_SUCCESS);

    if (std::find(arguments.begin(), arguments.end(), "count") != arguments.end()) {
        std::cout << "count=" << count << '\n';
    }
}

TEST_F(EnumerateInstanceExtensionProperties, OnePass) {
    // Count required for this test.
    if (std::find(arguments.begin(), arguments.end(), "count") == arguments.end()) {
        return;
    }

    uint32_t count = std::stoul(arguments[2]);

    std::unique_ptr<VkExtensionProperties[]> properties(new VkExtensionProperties[count]);
    VkResult result = vkEnumerateInstanceExtensionProperties(nullptr, &count, properties.get());
    ASSERT_EQ(result, VK_SUCCESS);

    if (std::find(arguments.begin(), arguments.end(), "properties") != arguments.end()) {
        for (uint32_t p = 0; p < count; ++p) {
            std::cout << "properties[" << p << "] =" << ' ' << properties[p].extensionName << ' ' << properties[p].specVersion
                      << '\n';
        }
    }
}

TEST_F(EnumerateInstanceExtensionProperties, TwoPass) {
    uint32_t count = 0u;
    VkResult result = vkEnumerateInstanceExtensionProperties(nullptr, &count, nullptr);
    ASSERT_EQ(result, VK_SUCCESS);

    std::unique_ptr<VkExtensionProperties[]> properties(new VkExtensionProperties[count]);
    result = vkEnumerateInstanceExtensionProperties(nullptr, &count, properties.get());
    ASSERT_EQ(result, VK_SUCCESS);

    if (std::find(arguments.begin(), arguments.end(), "properties") != arguments.end()) {
        for (uint32_t p = 0; p < count; ++p) {
            std::cout << "properties[" << p << "] =" << ' ' << properties[p].extensionName << ' ' << properties[p].specVersion
                      << '\n';
        }
    }
}

TEST_F(EnumerateInstanceExtensionProperties, InstanceExtensionEnumerated) {
    uint32_t count = 0u;
    VkResult result = vkEnumerateInstanceExtensionProperties(nullptr, &count, nullptr);
    ASSERT_EQ(result, VK_SUCCESS);

    std::unique_ptr<VkExtensionProperties[]> properties(new VkExtensionProperties[count]);
    result = vkEnumerateInstanceExtensionProperties(nullptr, &count, properties.get());
    ASSERT_EQ(result, VK_SUCCESS);

    ASSERT_NE(std::find_if(
                  &properties[0], &properties[count],
                  [](VkExtensionProperties const &properties) { return strcmp(properties.extensionName, "VK_KHR_surface") == 0; }),
              &properties[count]);
}

TEST(EnumerateDeviceExtensionProperties, DeviceExtensionEnumerated) {
    VkInstance instance = VK_NULL_HANDLE;
    VkResult result = vkCreateInstance(VK::InstanceCreateInfo(), VK_NULL_HANDLE, &instance);
    ASSERT_EQ(result, VK_SUCCESS);

    uint32_t physicalCount = 0;
    result = vkEnumeratePhysicalDevices(instance, &physicalCount, nullptr);
    ASSERT_EQ(result, VK_SUCCESS);
    ASSERT_GT(physicalCount, 0u);

    std::unique_ptr<VkPhysicalDevice[]> physical(new VkPhysicalDevice[physicalCount]);
    result = vkEnumeratePhysicalDevices(instance, &physicalCount, physical.get());
    ASSERT_EQ(result, VK_SUCCESS);
    ASSERT_GT(physicalCount, 0u);

    for (uint32_t p = 0; p < physicalCount; ++p) {
        uint32_t count = 0u;
        result = vkEnumerateDeviceExtensionProperties(physical[p], nullptr, &count, nullptr);
        ASSERT_EQ(result, VK_SUCCESS);

        std::unique_ptr<VkExtensionProperties[]> properties(new VkExtensionProperties[count]);
        result = vkEnumerateDeviceExtensionProperties(physical[p], nullptr, &count, properties.get());
        ASSERT_EQ(result, VK_SUCCESS);

        ASSERT_NE(std::find_if(&properties[0], &properties[count],
                               [](VkExtensionProperties const &properties) {
                                   return strcmp(properties.extensionName, "VK_KHR_swapchain") == 0;
                               }),
                  &properties[count]);
    }

    vkDestroyInstance(instance, nullptr);
}

TEST_F(ImplicitLayer, Present) {
    auto const info = VK::InstanceCreateInfo();
    VkInstance instance = VK_NULL_HANDLE;
    VkResult result = vkCreateInstance(info, VK_NULL_HANDLE, &instance);
    ASSERT_EQ(result, VK_SUCCESS);

    vkDestroyInstance(instance, nullptr);
}

TEST(WrapObjects, Insert) {
    VkInstance instance = VK_NULL_HANDLE;
    VkResult result = vkCreateInstance(VK::InstanceCreateInfo(), VK_NULL_HANDLE, &instance);
    ASSERT_EQ(result, VK_SUCCESS);

    uint32_t physicalCount = 0;
    result = vkEnumeratePhysicalDevices(instance, &physicalCount, nullptr);
    ASSERT_EQ(result, VK_SUCCESS);
    ASSERT_GT(physicalCount, 0u);

    std::unique_ptr<VkPhysicalDevice[]> physical(new VkPhysicalDevice[physicalCount]);
    result = vkEnumeratePhysicalDevices(instance, &physicalCount, physical.get());
    ASSERT_EQ(result, VK_SUCCESS);
    ASSERT_GT(physicalCount, 0u);

    for (uint32_t p = 0; p < physicalCount; ++p) {
        uint32_t familyCount = 0;
        vkGetPhysicalDeviceQueueFamilyProperties(physical[p], &familyCount, nullptr);
        ASSERT_EQ(result, VK_SUCCESS);
        ASSERT_GT(familyCount, 0u);

        std::unique_ptr<VkQueueFamilyProperties[]> family(new VkQueueFamilyProperties[familyCount]);
        vkGetPhysicalDeviceQueueFamilyProperties(physical[p], &familyCount, family.get());
        ASSERT_EQ(result, VK_SUCCESS);
        ASSERT_GT(familyCount, 0u);

        for (uint32_t q = 0; q < familyCount; ++q) {
            if (~family[q].queueFlags & VK_QUEUE_GRAPHICS_BIT) {
                continue;
            }

            float const priorities[] = {0.0f};  // Temporary required due to MSVC bug.
            VkDeviceQueueCreateInfo const queueInfo[1]{
                VK::DeviceQueueCreateInfo().queueFamilyIndex(q).queueCount(1).pQueuePriorities(priorities)};

            auto const deviceInfo = VK::DeviceCreateInfo().queueCreateInfoCount(1).pQueueCreateInfos(queueInfo);

            VkDevice device;
            result = vkCreateDevice(physical[p], deviceInfo, nullptr, &device);
            ASSERT_EQ(result, VK_SUCCESS);

            vkDestroyDevice(device, nullptr);
        }
    }

    vkDestroyInstance(instance, nullptr);
}

// Test making sure the allocation functions are called to allocate and cleanup everything during
// a CreateInstance/DestroyInstance call pair.
TEST(Allocation, Instance) {
    auto const info = VK::InstanceCreateInfo();
    VkInstance instance = VK_NULL_HANDLE;
    VkAllocationCallbacks alloc_callbacks = {};
    alloc_callbacks.pUserData = (void *)0x00000001;
    alloc_callbacks.pfnAllocation = AllocCallbackFunc;
    alloc_callbacks.pfnReallocation = ReallocCallbackFunc;
    alloc_callbacks.pfnFree = FreeCallbackFunc;

    InitAllocTracker(2048);

    VkResult result = vkCreateInstance(info, &alloc_callbacks, &instance);
    ASSERT_EQ(result, VK_SUCCESS);

    alloc_callbacks.pUserData = (void *)0x00000002;
    vkDestroyInstance(instance, &alloc_callbacks);

    // Make sure everything's been freed
    ASSERT_EQ(true, IsAllocTrackerEmpty());
    FreeAllocTracker();
}

// Test making sure the allocation functions are called to allocate and cleanup everything during
// a CreateInstance/DestroyInstance call pair with a call to GetInstanceProcAddr.
TEST(Allocation, GetInstanceProcAddr) {
    auto const info = VK::InstanceCreateInfo();
    VkInstance instance = VK_NULL_HANDLE;
    VkAllocationCallbacks alloc_callbacks = {};
    alloc_callbacks.pUserData = (void *)0x00000010;
    alloc_callbacks.pfnAllocation = AllocCallbackFunc;
    alloc_callbacks.pfnReallocation = ReallocCallbackFunc;
    alloc_callbacks.pfnFree = FreeCallbackFunc;

    InitAllocTracker(2048);

    VkResult result = vkCreateInstance(info, &alloc_callbacks, &instance);
    ASSERT_EQ(result, VK_SUCCESS);

    void *pfnCreateDevice = (void *)vkGetInstanceProcAddr(instance, "vkCreateDevice");
    void *pfnDestroyDevice = (void *)vkGetInstanceProcAddr(instance, "vkDestroyDevice");
    ASSERT_TRUE(pfnCreateDevice != NULL && pfnDestroyDevice != NULL);

    alloc_callbacks.pUserData = (void *)0x00000011;
    vkDestroyInstance(instance, &alloc_callbacks);

    // Make sure everything's been freed
    ASSERT_EQ(true, IsAllocTrackerEmpty());
    FreeAllocTracker();
}

// Test making sure the allocation functions are called to allocate and cleanup everything during
// a vkEnumeratePhysicalDevices call pair.
TEST(Allocation, EnumeratePhysicalDevices) {
    auto const info = VK::InstanceCreateInfo();
    VkInstance instance = VK_NULL_HANDLE;
    VkAllocationCallbacks alloc_callbacks = {};
    alloc_callbacks.pUserData = (void *)0x00000021;
    alloc_callbacks.pfnAllocation = AllocCallbackFunc;
    alloc_callbacks.pfnReallocation = ReallocCallbackFunc;
    alloc_callbacks.pfnFree = FreeCallbackFunc;

    InitAllocTracker(2048);

    VkResult result = vkCreateInstance(info, &alloc_callbacks, &instance);
    ASSERT_EQ(result, VK_SUCCESS);

    uint32_t physicalCount = 0;
    alloc_callbacks.pUserData = (void *)0x00000022;
    result = vkEnumeratePhysicalDevices(instance, &physicalCount, nullptr);
    ASSERT_EQ(result, VK_SUCCESS);
    ASSERT_GT(physicalCount, 0u);

    std::unique_ptr<VkPhysicalDevice[]> physical(new VkPhysicalDevice[physicalCount]);
    alloc_callbacks.pUserData = (void *)0x00000023;
    result = vkEnumeratePhysicalDevices(instance, &physicalCount, physical.get());
    ASSERT_EQ(result, VK_SUCCESS);
    ASSERT_GT(physicalCount, 0u);

    alloc_callbacks.pUserData = (void *)0x00000024;
    vkDestroyInstance(instance, &alloc_callbacks);

    // Make sure everything's been freed
    ASSERT_EQ(true, IsAllocTrackerEmpty());
    FreeAllocTracker();
}

// Test making sure the allocation functions are called to allocate and cleanup everything from
// vkCreateInstance, to vkCreateDevicce, and then through their destructors.  With special
// allocators used on both the instance and device.
TEST(Allocation, InstanceAndDevice) {
    auto const info = VK::InstanceCreateInfo();
    VkInstance instance = VK_NULL_HANDLE;
    VkAllocationCallbacks alloc_callbacks = {};
    alloc_callbacks.pUserData = (void *)0x00000031;
    alloc_callbacks.pfnAllocation = AllocCallbackFunc;
    alloc_callbacks.pfnReallocation = ReallocCallbackFunc;
    alloc_callbacks.pfnFree = FreeCallbackFunc;

    InitAllocTracker(2048);

    VkResult result = vkCreateInstance(info, &alloc_callbacks, &instance);
    ASSERT_EQ(result, VK_SUCCESS);

    uint32_t physicalCount = 0;
    result = vkEnumeratePhysicalDevices(instance, &physicalCount, nullptr);
    ASSERT_EQ(result, VK_SUCCESS);
    ASSERT_GT(physicalCount, 0u);

    std::unique_ptr<VkPhysicalDevice[]> physical(new VkPhysicalDevice[physicalCount]);
    result = vkEnumeratePhysicalDevices(instance, &physicalCount, physical.get());
    ASSERT_EQ(result, VK_SUCCESS);
    ASSERT_GT(physicalCount, 0u);

    for (uint32_t p = 0; p < physicalCount; ++p) {
        uint32_t familyCount = 0;
        vkGetPhysicalDeviceQueueFamilyProperties(physical[p], &familyCount, nullptr);
        ASSERT_GT(familyCount, 0u);

        std::unique_ptr<VkQueueFamilyProperties[]> family(new VkQueueFamilyProperties[familyCount]);
        vkGetPhysicalDeviceQueueFamilyProperties(physical[p], &familyCount, family.get());
        ASSERT_GT(familyCount, 0u);

        for (uint32_t q = 0; q < familyCount; ++q) {
            if (~family[q].queueFlags & VK_QUEUE_GRAPHICS_BIT) {
                continue;
            }

            float const priorities[] = {0.0f};  // Temporary required due to MSVC bug.
            VkDeviceQueueCreateInfo const queueInfo[1]{
                VK::DeviceQueueCreateInfo().queueFamilyIndex(q).queueCount(1).pQueuePriorities(priorities)};

            auto const deviceInfo = VK::DeviceCreateInfo().queueCreateInfoCount(1).pQueueCreateInfos(queueInfo);

            VkDevice device;
            alloc_callbacks.pUserData = (void *)0x00000032;
            result = vkCreateDevice(physical[p], deviceInfo, &alloc_callbacks, &device);
            ASSERT_EQ(result, VK_SUCCESS);

            alloc_callbacks.pUserData = (void *)0x00000033;
            vkDestroyDevice(device, &alloc_callbacks);
        }
    }

    alloc_callbacks.pUserData = (void *)0x00000034;
    vkDestroyInstance(instance, &alloc_callbacks);

    // Make sure everything's been freed
    ASSERT_EQ(true, IsAllocTrackerEmpty());
    FreeAllocTracker();
}

// Test making sure the allocation functions are called to allocate and cleanup everything from
// vkCreateInstance, to vkCreateDevicce, and then through their destructors.  With special
// allocators used on only the instance and not the device.
TEST(Allocation, InstanceButNotDevice) {
    auto const info = VK::InstanceCreateInfo();
    VkInstance instance = VK_NULL_HANDLE;
    VkAllocationCallbacks alloc_callbacks = {};
    alloc_callbacks.pUserData = (void *)0x00000041;
    alloc_callbacks.pfnAllocation = AllocCallbackFunc;
    alloc_callbacks.pfnReallocation = ReallocCallbackFunc;
    alloc_callbacks.pfnFree = FreeCallbackFunc;

    InitAllocTracker(2048);

    VkResult result = vkCreateInstance(info, &alloc_callbacks, &instance);
    ASSERT_EQ(result, VK_SUCCESS);

    uint32_t physicalCount = 0;
    result = vkEnumeratePhysicalDevices(instance, &physicalCount, nullptr);
    ASSERT_EQ(result, VK_SUCCESS);
    ASSERT_GT(physicalCount, 0u);

    std::unique_ptr<VkPhysicalDevice[]> physical(new VkPhysicalDevice[physicalCount]);
    result = vkEnumeratePhysicalDevices(instance, &physicalCount, physical.get());
    ASSERT_EQ(result, VK_SUCCESS);
    ASSERT_GT(physicalCount, 0u);

    for (uint32_t p = 0; p < physicalCount; ++p) {
        uint32_t familyCount = 0;
        vkGetPhysicalDeviceQueueFamilyProperties(physical[p], &familyCount, nullptr);
        ASSERT_GT(familyCount, 0u);

        std::unique_ptr<VkQueueFamilyProperties[]> family(new VkQueueFamilyProperties[familyCount]);
        vkGetPhysicalDeviceQueueFamilyProperties(physical[p], &familyCount, family.get());
        ASSERT_GT(familyCount, 0u);

        for (uint32_t q = 0; q < familyCount; ++q) {
            if (~family[q].queueFlags & VK_QUEUE_GRAPHICS_BIT) {
                continue;
            }

            float const priorities[] = {0.0f};  // Temporary required due to MSVC bug.
            VkDeviceQueueCreateInfo const queueInfo[1]{
                VK::DeviceQueueCreateInfo().queueFamilyIndex(q).queueCount(1).pQueuePriorities(priorities)};

            auto const deviceInfo = VK::DeviceCreateInfo().queueCreateInfoCount(1).pQueueCreateInfos(queueInfo);

            VkDevice device;
            result = vkCreateDevice(physical[p], deviceInfo, NULL, &device);
            ASSERT_EQ(result, VK_SUCCESS);

            vkDestroyDevice(device, NULL);
        }
    }

    alloc_callbacks.pUserData = (void *)0x00000042;
    vkDestroyInstance(instance, &alloc_callbacks);

    // Make sure everything's been freed
    ASSERT_EQ(true, IsAllocTrackerEmpty());
    FreeAllocTracker();
}

// Test making sure the allocation functions are called to allocate and cleanup everything from
// vkCreateInstance, to vkCreateDevicce, and then through their destructors.  With special
// allocators used on only the device and not the instance.
TEST(Allocation, DeviceButNotInstance) {
    auto const info = VK::InstanceCreateInfo();
    VkInstance instance = VK_NULL_HANDLE;
    VkAllocationCallbacks alloc_callbacks = {};
    alloc_callbacks.pfnAllocation = AllocCallbackFunc;
    alloc_callbacks.pfnReallocation = ReallocCallbackFunc;
    alloc_callbacks.pfnFree = FreeCallbackFunc;

    InitAllocTracker(2048);

    VkResult result = vkCreateInstance(info, NULL, &instance);
    ASSERT_EQ(result, VK_SUCCESS);

    uint32_t physicalCount = 0;
    result = vkEnumeratePhysicalDevices(instance, &physicalCount, nullptr);
    ASSERT_EQ(result, VK_SUCCESS);
    ASSERT_GT(physicalCount, 0u);

    std::unique_ptr<VkPhysicalDevice[]> physical(new VkPhysicalDevice[physicalCount]);
    result = vkEnumeratePhysicalDevices(instance, &physicalCount, physical.get());
    ASSERT_EQ(result, VK_SUCCESS);
    ASSERT_GT(physicalCount, 0u);

    for (uint32_t p = 0; p < physicalCount; ++p) {
        uint32_t familyCount = 0;
        vkGetPhysicalDeviceQueueFamilyProperties(physical[p], &familyCount, nullptr);
        ASSERT_GT(familyCount, 0u);

        std::unique_ptr<VkQueueFamilyProperties[]> family(new VkQueueFamilyProperties[familyCount]);
        vkGetPhysicalDeviceQueueFamilyProperties(physical[p], &familyCount, family.get());
        ASSERT_GT(familyCount, 0u);

        for (uint32_t q = 0; q < familyCount; ++q) {
            if (~family[q].queueFlags & VK_QUEUE_GRAPHICS_BIT) {
                continue;
            }

            float const priorities[] = {0.0f};  // Temporary required due to MSVC bug.
            VkDeviceQueueCreateInfo const queueInfo[1]{
                VK::DeviceQueueCreateInfo().queueFamilyIndex(q).queueCount(1).pQueuePriorities(priorities)};

            auto const deviceInfo = VK::DeviceCreateInfo().queueCreateInfoCount(1).pQueueCreateInfos(queueInfo);

            VkDevice device;
            alloc_callbacks.pUserData = (void *)0x00000051;
            result = vkCreateDevice(physical[p], deviceInfo, &alloc_callbacks, &device);
            ASSERT_EQ(result, VK_SUCCESS);

            alloc_callbacks.pUserData = (void *)0x00000052;
            vkDestroyDevice(device, &alloc_callbacks);
        }
    }

    vkDestroyInstance(instance, NULL);

    // Make sure everything's been freed
    ASSERT_EQ(true, IsAllocTrackerEmpty());
    FreeAllocTracker();
}

// Test failure during vkCreateInstance to make sure we don't leak memory if
// one of the out-of-memory conditions trigger.
TEST(Allocation, CreateInstanceIntentionalAllocFail) {
    auto const info = VK::InstanceCreateInfo();
    VkInstance instance = VK_NULL_HANDLE;
    VkAllocationCallbacks alloc_callbacks = {};
    alloc_callbacks.pfnAllocation = AllocCallbackFunc;
    alloc_callbacks.pfnReallocation = ReallocCallbackFunc;
    alloc_callbacks.pfnFree = FreeCallbackFunc;

    VkResult result;
    uint32_t fail_index = 1;
    do {
        InitAllocTracker(9999, fail_index);

        result = vkCreateInstance(info, &alloc_callbacks, &instance);
        if (result == VK_ERROR_OUT_OF_HOST_MEMORY) {
            if (!IsAllocTrackerEmpty()) {
                std::cout << "Failed on index " << fail_index << '\n';
                ASSERT_EQ(true, IsAllocTrackerEmpty());
            }
        }
        fail_index++;
        // Make sure we don't overrun the memory
        ASSERT_LT(fail_index, 9999u);

        FreeAllocTracker();
    } while (result == VK_ERROR_OUT_OF_HOST_MEMORY);

    vkDestroyInstance(instance, &alloc_callbacks);
}

// Test failure during vkCreateDevice to make sure we don't leak memory if
// one of the out-of-memory conditions trigger.
TEST(Allocation, CreateDeviceIntentionalAllocFail) {
    auto const info = VK::InstanceCreateInfo();
    VkInstance instance = VK_NULL_HANDLE;
    VkDevice device = VK_NULL_HANDLE;
    VkAllocationCallbacks alloc_callbacks = {};
    alloc_callbacks.pfnAllocation = AllocCallbackFunc;
    alloc_callbacks.pfnReallocation = ReallocCallbackFunc;
    alloc_callbacks.pfnFree = FreeCallbackFunc;

    VkResult result = vkCreateInstance(info, NULL, &instance);
    ASSERT_EQ(result, VK_SUCCESS);

    uint32_t physicalCount = 0;
    result = vkEnumeratePhysicalDevices(instance, &physicalCount, nullptr);
    ASSERT_EQ(result, VK_SUCCESS);
    ASSERT_GT(physicalCount, 0u);

    std::unique_ptr<VkPhysicalDevice[]> physical(new VkPhysicalDevice[physicalCount]);
    result = vkEnumeratePhysicalDevices(instance, &physicalCount, physical.get());
    ASSERT_EQ(result, VK_SUCCESS);
    ASSERT_GT(physicalCount, 0u);

    for (uint32_t p = 0; p < physicalCount; ++p) {
        uint32_t familyCount = 0;
        vkGetPhysicalDeviceQueueFamilyProperties(physical[p], &familyCount, nullptr);
        ASSERT_GT(familyCount, 0u);

        std::unique_ptr<VkQueueFamilyProperties[]> family(new VkQueueFamilyProperties[familyCount]);
        vkGetPhysicalDeviceQueueFamilyProperties(physical[p], &familyCount, family.get());
        ASSERT_GT(familyCount, 0u);

        for (uint32_t q = 0; q < familyCount; ++q) {
            if (~family[q].queueFlags & VK_QUEUE_GRAPHICS_BIT) {
                continue;
            }

            float const priorities[] = {0.0f};  // Temporary required due to MSVC bug.
            VkDeviceQueueCreateInfo const queueInfo[1]{
                VK::DeviceQueueCreateInfo().queueFamilyIndex(q).queueCount(1).pQueuePriorities(priorities)};

            auto const deviceInfo = VK::DeviceCreateInfo().queueCreateInfoCount(1).pQueueCreateInfos(queueInfo);

            uint32_t fail_index = 1;
            do {
                InitAllocTracker(9999, fail_index);

                result = vkCreateDevice(physical[p], deviceInfo, &alloc_callbacks, &device);
                if (result == VK_ERROR_OUT_OF_HOST_MEMORY) {
                    if (!IsAllocTrackerEmpty()) {
                        std::cout << "Failed on index " << fail_index << '\n';
                        ASSERT_EQ(true, IsAllocTrackerEmpty());
                    }
                }
                fail_index++;
                // Make sure we don't overrun the memory
                ASSERT_LT(fail_index, 9999u);

                FreeAllocTracker();
            } while (result == VK_ERROR_OUT_OF_HOST_MEMORY);
            vkDestroyDevice(device, &alloc_callbacks);
            break;
        }
    }

    vkDestroyInstance(instance, NULL);
}

// Test failure during vkCreateInstance and vkCreateDevice to make sure we don't
// leak memory if one of the out-of-memory conditions trigger.
TEST(Allocation, CreateInstanceDeviceIntentionalAllocFail) {
    auto const info = VK::InstanceCreateInfo();
    VkInstance instance = VK_NULL_HANDLE;
    VkDevice device = VK_NULL_HANDLE;
    VkAllocationCallbacks alloc_callbacks = {};
    alloc_callbacks.pfnAllocation = AllocCallbackFunc;
    alloc_callbacks.pfnReallocation = ReallocCallbackFunc;
    alloc_callbacks.pfnFree = FreeCallbackFunc;

    VkResult result = VK_ERROR_OUT_OF_HOST_MEMORY;
    uint32_t fail_index = 0;
    uint32_t physicalCount = 0;
    while (result == VK_ERROR_OUT_OF_HOST_MEMORY) {
        InitAllocTracker(9999, ++fail_index);
        ASSERT_LT(fail_index, 9999u);

        result = vkCreateInstance(info, &alloc_callbacks, &instance);
        if (result == VK_ERROR_OUT_OF_HOST_MEMORY) {
            if (!IsAllocTrackerEmpty()) {
                std::cout << "Failed on index " << fail_index << '\n';
                ASSERT_EQ(true, IsAllocTrackerEmpty());
            }
            FreeAllocTracker();
            continue;
        }
        ASSERT_EQ(result, VK_SUCCESS);

        physicalCount = 0;
        result = vkEnumeratePhysicalDevices(instance, &physicalCount, nullptr);
        if (result == VK_ERROR_OUT_OF_HOST_MEMORY) {
            vkDestroyInstance(instance, &alloc_callbacks);
            if (!IsAllocTrackerEmpty()) {
                std::cout << "Failed on index " << fail_index << '\n';
                ASSERT_EQ(true, IsAllocTrackerEmpty());
            }
            FreeAllocTracker();
            continue;
        }
        ASSERT_EQ(result, VK_SUCCESS);

        std::unique_ptr<VkPhysicalDevice[]> physical(new VkPhysicalDevice[physicalCount]);
        result = vkEnumeratePhysicalDevices(instance, &physicalCount, physical.get());
        if (result == VK_ERROR_OUT_OF_HOST_MEMORY) {
            vkDestroyInstance(instance, &alloc_callbacks);
            if (!IsAllocTrackerEmpty()) {
                std::cout << "Failed on index " << fail_index << '\n';
                ASSERT_EQ(true, IsAllocTrackerEmpty());
            }
            FreeAllocTracker();
            continue;
        }
        ASSERT_EQ(result, VK_SUCCESS);

        uint32_t familyCount = 0;
        vkGetPhysicalDeviceQueueFamilyProperties(physical[0], &familyCount, nullptr);
        ASSERT_GT(familyCount, 0u);

        std::unique_ptr<VkQueueFamilyProperties[]> family(new VkQueueFamilyProperties[familyCount]);
        vkGetPhysicalDeviceQueueFamilyProperties(physical[0], &familyCount, family.get());
        ASSERT_GT(familyCount, 0u);

        uint32_t queue_index = 0;
        for (uint32_t q = 0; q < familyCount; ++q) {
            if (family[q].queueFlags & VK_QUEUE_GRAPHICS_BIT) {
                queue_index = q;
                break;
            }
        }

        float const priorities[] = {0.0f};  // Temporary required due to MSVC bug.
        VkDeviceQueueCreateInfo const queueInfo[1]{
            VK::DeviceQueueCreateInfo().queueFamilyIndex(queue_index).queueCount(1).pQueuePriorities(priorities)};

        auto const deviceInfo = VK::DeviceCreateInfo().queueCreateInfoCount(1).pQueueCreateInfos(queueInfo);

        result = vkCreateDevice(physical[0], deviceInfo, &alloc_callbacks, &device);
        if (result == VK_ERROR_OUT_OF_HOST_MEMORY) {
            vkDestroyInstance(instance, &alloc_callbacks);
            if (!IsAllocTrackerEmpty()) {
                std::cout << "Failed on index " << fail_index << '\n';
                ASSERT_EQ(true, IsAllocTrackerEmpty());
            }
            FreeAllocTracker();
            continue;
        }
        vkDestroyDevice(device, &alloc_callbacks);
        vkDestroyInstance(instance, &alloc_callbacks);
        FreeAllocTracker();
    }
}

// Used by run_loader_tests.sh to test that calling vkEnumeratePhysicalDeviceGroupsKHX without first querying
// the count, works.  And, that it also returns only physical devices made available by the standard
// enumerate call
TEST(EnumeratePhysicalDeviceGroupsKHX, OneCall) {
    VkInstance instance = VK_NULL_HANDLE;
    char const *const names[] = {VK_KHX_DEVICE_GROUP_CREATION_EXTENSION_NAME};
    auto const info = VK::InstanceCreateInfo().enabledExtensionCount(1).ppEnabledExtensionNames(names);
    uint32_t group;
    uint32_t dev;
    std::vector<std::pair<VkPhysicalDevice, bool>> phys_dev_normal_found;
    std::vector<std::pair<VkPhysicalDevice, bool>> phys_dev_group_found;

    VkResult result = vkCreateInstance(info, VK_NULL_HANDLE, &instance);
    if (result == VK_ERROR_EXTENSION_NOT_PRESENT) {
        // Extension isn't present, just skip this test
        ASSERT_EQ(result, VK_ERROR_EXTENSION_NOT_PRESENT);
        std::cout << "Skipping EnumeratePhysicalDeviceGroupsKHX : OneCall due to Instance lacking support"
                  << " for " << VK_KHX_DEVICE_GROUP_CREATION_EXTENSION_NAME << " extension\n";
        return;
    }

    uint32_t phys_dev_count = 500;
    std::unique_ptr<VkPhysicalDevice[]> phys_devs(new VkPhysicalDevice[phys_dev_count]);
    result = vkEnumeratePhysicalDevices(instance, &phys_dev_count, phys_devs.get());
    ASSERT_EQ(result, VK_SUCCESS);
    ASSERT_GT(phys_dev_count, 0u);

    // Initialize the normal physical device boolean pair array
    for (dev = 0; dev < phys_dev_count; dev++) {
        phys_dev_normal_found.push_back(std::make_pair(phys_devs[dev], false));
    }

    // Get a pointer to the new vkEnumeratePhysicalDeviceGroupsKHX call
    PFN_vkEnumeratePhysicalDeviceGroupsKHX p_vkEnumeratePhysicalDeviceGroupsKHX =
        (PFN_vkEnumeratePhysicalDeviceGroupsKHX)vkGetInstanceProcAddr(instance, "vkEnumeratePhysicalDeviceGroupsKHX");

    // Setup the group information in preparation for the call
    uint32_t group_count = 30;
    std::unique_ptr<VkPhysicalDeviceGroupPropertiesKHX[]> phys_dev_groups(new VkPhysicalDeviceGroupPropertiesKHX[group_count]);
    for (group = 0; group < group_count; group++) {
        phys_dev_groups[group].sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_GROUP_PROPERTIES_KHX;
        phys_dev_groups[group].pNext = nullptr;
        phys_dev_groups[group].physicalDeviceCount = 0;
        memset(phys_dev_groups[group].physicalDevices, 0, sizeof(VkPhysicalDevice) * VK_MAX_DEVICE_GROUP_SIZE_KHX);
        phys_dev_groups[group].subsetAllocation = VK_FALSE;
    }

    result = p_vkEnumeratePhysicalDeviceGroupsKHX(instance, &group_count, phys_dev_groups.get());
    ASSERT_EQ(result, VK_SUCCESS);
    ASSERT_GT(group_count, 0u);

    // Initialize the group physical device boolean pair array
    for (group = 0; group < group_count; group++) {
        for (dev = 0; dev < phys_dev_groups[group].physicalDeviceCount; dev++) {
            phys_dev_group_found.push_back(std::make_pair(phys_dev_groups[group].physicalDevices[dev], false));
        }
    }

    // Now, make sure we can find each normal and group item in the other list
    for (dev = 0; dev < phys_dev_count; dev++) {
        for (group = 0; group < phys_dev_group_found.size(); group++) {
            if (phys_dev_normal_found[dev].first == phys_dev_group_found[group].first) {
                phys_dev_normal_found[dev].second = true;
                phys_dev_group_found[group].second = true;
                break;
            }
        }
    }

    for (dev = 0; dev < phys_dev_count; dev++) {
        ASSERT_EQ(phys_dev_normal_found[dev].second, true);
    }
    for (dev = 0; dev < phys_dev_group_found.size(); dev++) {
        ASSERT_EQ(phys_dev_group_found[dev].second, true);
    }

    vkDestroyInstance(instance, nullptr);
}

// Used by run_loader_tests.sh to test for the expected usage of the
// vkEnumeratePhysicalDeviceGroupsKHX call in a two call fasion (once with NULL data
// to get count, and then again with data).
TEST(EnumeratePhysicalDeviceGroupsKHX, TwoCall) {
    VkInstance instance = VK_NULL_HANDLE;
    char const *const names[] = {VK_KHX_DEVICE_GROUP_CREATION_EXTENSION_NAME};
    auto const info = VK::InstanceCreateInfo().enabledExtensionCount(1).ppEnabledExtensionNames(names);
    uint32_t group;
    uint32_t group_count;
    uint32_t dev;
    std::vector<std::pair<VkPhysicalDevice, bool>> phys_dev_normal_found;
    std::vector<std::pair<VkPhysicalDevice, bool>> phys_dev_group_found;

    VkResult result = vkCreateInstance(info, VK_NULL_HANDLE, &instance);
    if (result == VK_ERROR_EXTENSION_NOT_PRESENT) {
        // Extension isn't present, just skip this test
        ASSERT_EQ(result, VK_ERROR_EXTENSION_NOT_PRESENT);
        std::cout << "Skipping EnumeratePhysicalDeviceGroupsKHX : TwoCall due to Instance lacking support"
                  << " for " << VK_KHX_DEVICE_GROUP_CREATION_EXTENSION_NAME << " extension\n";
        return;
    }

    // Get a pointer to the new vkEnumeratePhysicalDeviceGroupsKHX call
    PFN_vkEnumeratePhysicalDeviceGroupsKHX p_vkEnumeratePhysicalDeviceGroupsKHX =
        (PFN_vkEnumeratePhysicalDeviceGroupsKHX)vkGetInstanceProcAddr(instance, "vkEnumeratePhysicalDeviceGroupsKHX");

    // Setup the group information in preparation for the call
    uint32_t array_group_count = 30;
    std::unique_ptr<VkPhysicalDeviceGroupPropertiesKHX[]> phys_dev_groups(
        new VkPhysicalDeviceGroupPropertiesKHX[array_group_count]);
    for (group = 0; group < array_group_count; group++) {
        phys_dev_groups[group].sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_GROUP_PROPERTIES_KHX;
        phys_dev_groups[group].pNext = nullptr;
        phys_dev_groups[group].physicalDeviceCount = 0;
        memset(phys_dev_groups[group].physicalDevices, 0, sizeof(VkPhysicalDevice) * VK_MAX_DEVICE_GROUP_SIZE_KHX);
        phys_dev_groups[group].subsetAllocation = VK_FALSE;
    }

    result = p_vkEnumeratePhysicalDeviceGroupsKHX(instance, &group_count, nullptr);
    ASSERT_EQ(result, VK_SUCCESS);
    ASSERT_GT(group_count, 0u);
    ASSERT_LT(group_count, array_group_count);

    result = p_vkEnumeratePhysicalDeviceGroupsKHX(instance, &group_count, phys_dev_groups.get());
    ASSERT_EQ(result, VK_SUCCESS);
    ASSERT_GT(group_count, 0u);
    ASSERT_LT(group_count, array_group_count);

    // Initialize the group physical device boolean pair array
    for (group = 0; group < group_count; group++) {
        for (dev = 0; dev < phys_dev_groups[group].physicalDeviceCount; dev++) {
            phys_dev_group_found.push_back(std::make_pair(phys_dev_groups[group].physicalDevices[dev], false));
        }
    }

    uint32_t phys_dev_count = 500;
    std::unique_ptr<VkPhysicalDevice[]> phys_devs(new VkPhysicalDevice[phys_dev_count]);
    result = vkEnumeratePhysicalDevices(instance, &phys_dev_count, phys_devs.get());
    ASSERT_EQ(result, VK_SUCCESS);
    ASSERT_GT(phys_dev_count, 0u);

    // Initialize the normal physical device boolean pair array
    for (dev = 0; dev < phys_dev_count; dev++) {
        phys_dev_normal_found.push_back(std::make_pair(phys_devs[dev], false));
    }

    // Now, make sure we can find each normal and group item in the other list
    for (dev = 0; dev < phys_dev_count; dev++) {
        for (group = 0; group < phys_dev_group_found.size(); group++) {
            if (phys_dev_normal_found[dev].first == phys_dev_group_found[group].first) {
                phys_dev_normal_found[dev].second = true;
                phys_dev_group_found[group].second = true;
                break;
            }
        }
    }

    for (dev = 0; dev < phys_dev_count; dev++) {
        ASSERT_EQ(phys_dev_normal_found[dev].second, true);
    }
    for (dev = 0; dev < phys_dev_group_found.size(); dev++) {
        ASSERT_EQ(phys_dev_group_found[dev].second, true);
    }

    vkDestroyInstance(instance, nullptr);
}

// Used by run_loader_tests.sh to test for the expected usage of the EnumeratePhysicalDeviceGroupsKHX
// call if not enough numbers are provided for the final list.
TEST(EnumeratePhysicalDeviceGroupsKHX, TwoCallIncomplete) {
    VkInstance instance = VK_NULL_HANDLE;
    char const *const names[] = {VK_KHX_DEVICE_GROUP_CREATION_EXTENSION_NAME};
    auto const info = VK::InstanceCreateInfo().enabledExtensionCount(1).ppEnabledExtensionNames(names);
    uint32_t group;
    uint32_t group_count;

    VkResult result = vkCreateInstance(info, VK_NULL_HANDLE, &instance);
    if (result == VK_ERROR_EXTENSION_NOT_PRESENT) {
        // Extension isn't present, just skip this test
        ASSERT_EQ(result, VK_ERROR_EXTENSION_NOT_PRESENT);
        std::cout << "Skipping EnumeratePhysicalDeviceGroupsKHX : TwoCallIncomplete due to Instance lacking support"
                  << " for " << VK_KHX_DEVICE_GROUP_CREATION_EXTENSION_NAME << " extension\n";
        return;
    }

    // Get a pointer to the new vkEnumeratePhysicalDeviceGroupsKHX call
    PFN_vkEnumeratePhysicalDeviceGroupsKHX p_vkEnumeratePhysicalDeviceGroupsKHX =
        (PFN_vkEnumeratePhysicalDeviceGroupsKHX)vkGetInstanceProcAddr(instance, "vkEnumeratePhysicalDeviceGroupsKHX");

    // Setup the group information in preparation for the call
    uint32_t array_group_count = 30;
    std::unique_ptr<VkPhysicalDeviceGroupPropertiesKHX[]> phys_dev_groups(
        new VkPhysicalDeviceGroupPropertiesKHX[array_group_count]);
    for (group = 0; group < array_group_count; group++) {
        phys_dev_groups[group].sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_GROUP_PROPERTIES_KHX;
        phys_dev_groups[group].pNext = nullptr;
        phys_dev_groups[group].physicalDeviceCount = 0;
        memset(phys_dev_groups[group].physicalDevices, 0, sizeof(VkPhysicalDevice) * VK_MAX_DEVICE_GROUP_SIZE_KHX);
        phys_dev_groups[group].subsetAllocation = VK_FALSE;
    }

    result = p_vkEnumeratePhysicalDeviceGroupsKHX(instance, &group_count, nullptr);
    ASSERT_EQ(result, VK_SUCCESS);
    ASSERT_GT(group_count, 0u);
    ASSERT_LT(group_count, array_group_count);

    group_count -= 1;

    result = p_vkEnumeratePhysicalDeviceGroupsKHX(instance, &group_count, phys_dev_groups.get());
    ASSERT_EQ(result, VK_INCOMPLETE);

    vkDestroyInstance(instance, nullptr);
}

int main(int argc, char **argv) {
    int result;

    ::testing::InitGoogleTest(&argc, argv);

    if (argc > 0) {
        CommandLine::Initialize(argc, argv);
    }

    result = RUN_ALL_TESTS();

    return result;
}
