Home | History | Annotate | Download | only in tests
      1 /*
      2  * Copyright (c) 2015-2017 The Khronos Group Inc.
      3  * Copyright (c) 2015-2017 Valve Corporation
      4  * Copyright (c) 2015-2017 LunarG, Inc.
      5  *
      6  * Permission is hereby granted, free of charge, to any person obtaining a copy
      7  * of this software and/or associated documentation files (the "Materials"), to
      8  * deal in the Materials without restriction, including without limitation the
      9  * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
     10  * sell copies of the Materials, and to permit persons to whom the Materials are
     11  * furnished to do so, subject to the following conditions:
     12  *
     13  * The above copyright notice(s) and this permission notice shall be included in
     14  * all copies or substantial portions of the Materials.
     15  *
     16  * THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
     17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     18  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
     19  *
     20  * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
     21  * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
     22  * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE MATERIALS OR THE
     23  * USE OR OTHER DEALINGS IN THE MATERIALS.
     24  *
     25  * Author: Jeremy Hayes <jeremy (at) lunarG.com>
     26  * Author: Mark Young <marky (at) lunarG.com>
     27  */
     28 
     29 // Following items are needed for C++ to work with PRIxLEAST64
     30 #define __STDC_FORMAT_MACROS
     31 #include <inttypes.h>
     32 
     33 #include <stdint.h>  // For UINT32_MAX
     34 
     35 #include <algorithm>
     36 #include <iostream>
     37 #include <memory>
     38 #include <string>
     39 #include <vector>
     40 
     41 #include "test_common.h"
     42 #include <vulkan/vulkan.h>
     43 
     44 namespace VK {
     45 
     46 struct InstanceCreateInfo {
     47     InstanceCreateInfo()
     48         : info  // MSVC can't handle list initialization, thus explicit construction herein.
     49           (VkInstanceCreateInfo{
     50               VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO,  // sType
     51               nullptr,                                 // pNext
     52               0,                                       // flags
     53               nullptr,                                 // pApplicationInfo
     54               0,                                       // enabledLayerCount
     55               nullptr,                                 // ppEnabledLayerNames
     56               0,                                       // enabledExtensionCount
     57               nullptr                                  // ppEnabledExtensionNames
     58           }) {}
     59 
     60     InstanceCreateInfo &sType(VkStructureType const &sType) {
     61         info.sType = sType;
     62 
     63         return *this;
     64     }
     65 
     66     InstanceCreateInfo &pNext(void const *const pNext) {
     67         info.pNext = pNext;
     68 
     69         return *this;
     70     }
     71 
     72     InstanceCreateInfo &flags(VkInstanceCreateFlags const &flags) {
     73         info.flags = flags;
     74 
     75         return *this;
     76     }
     77 
     78     InstanceCreateInfo &pApplicationInfo(VkApplicationInfo const *const pApplicationInfo) {
     79         info.pApplicationInfo = pApplicationInfo;
     80 
     81         return *this;
     82     }
     83 
     84     InstanceCreateInfo &enabledLayerCount(uint32_t const &enabledLayerCount) {
     85         info.enabledLayerCount = enabledLayerCount;
     86 
     87         return *this;
     88     }
     89 
     90     InstanceCreateInfo &ppEnabledLayerNames(char const *const *const ppEnabledLayerNames) {
     91         info.ppEnabledLayerNames = ppEnabledLayerNames;
     92 
     93         return *this;
     94     }
     95 
     96     InstanceCreateInfo &enabledExtensionCount(uint32_t const &enabledExtensionCount) {
     97         info.enabledExtensionCount = enabledExtensionCount;
     98 
     99         return *this;
    100     }
    101 
    102     InstanceCreateInfo &ppEnabledExtensionNames(char const *const *const ppEnabledExtensionNames) {
    103         info.ppEnabledExtensionNames = ppEnabledExtensionNames;
    104 
    105         return *this;
    106     }
    107 
    108     operator VkInstanceCreateInfo const *() const { return &info; }
    109 
    110     operator VkInstanceCreateInfo *() { return &info; }
    111 
    112     VkInstanceCreateInfo info;
    113 };
    114 
    115 struct DeviceQueueCreateInfo {
    116     DeviceQueueCreateInfo()
    117         : info  // MSVC can't handle list initialization, thus explicit construction herein.
    118           (VkDeviceQueueCreateInfo{
    119               VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO,  // sType
    120               nullptr,                                     // pNext
    121               0,                                           // flags
    122               0,                                           // queueFamilyIndex
    123               0,                                           // queueCount
    124               nullptr                                      // pQueuePriorities
    125           }) {}
    126 
    127     DeviceQueueCreateInfo &sType(VkStructureType const &sType) {
    128         info.sType = sType;
    129 
    130         return *this;
    131     }
    132 
    133     DeviceQueueCreateInfo &pNext(void const *const pNext) {
    134         info.pNext = pNext;
    135 
    136         return *this;
    137     }
    138 
    139     DeviceQueueCreateInfo &flags(VkDeviceQueueCreateFlags const &flags) {
    140         info.flags = flags;
    141 
    142         return *this;
    143     }
    144 
    145     DeviceQueueCreateInfo &queueFamilyIndex(uint32_t const &queueFamilyIndex) {
    146         info.queueFamilyIndex = queueFamilyIndex;
    147 
    148         return *this;
    149     }
    150 
    151     DeviceQueueCreateInfo &queueCount(uint32_t const &queueCount) {
    152         info.queueCount = queueCount;
    153 
    154         return *this;
    155     }
    156 
    157     DeviceQueueCreateInfo &pQueuePriorities(float const *const pQueuePriorities) {
    158         info.pQueuePriorities = pQueuePriorities;
    159 
    160         return *this;
    161     }
    162 
    163     operator VkDeviceQueueCreateInfo() { return info; }
    164 
    165     VkDeviceQueueCreateInfo info;
    166 };
    167 
    168 struct DeviceCreateInfo {
    169     DeviceCreateInfo()
    170         : info  // MSVC can't handle list initialization, thus explicit construction herein.
    171           (VkDeviceCreateInfo{
    172               VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO,  // sType
    173               nullptr,                               // pNext
    174               0,                                     // flags
    175               0,                                     // queueCreateInfoCount
    176               nullptr,                               // pQueueCreateInfos
    177               0,                                     // enabledLayerCount
    178               nullptr,                               // ppEnabledLayerNames
    179               0,                                     // enabledExtensionCount
    180               nullptr,                               // ppEnabledExtensionNames
    181               nullptr                                // pEnabledFeatures
    182           }) {}
    183 
    184     DeviceCreateInfo &sType(VkStructureType const &sType) {
    185         info.sType = sType;
    186 
    187         return *this;
    188     }
    189 
    190     DeviceCreateInfo &pNext(void const *const pNext) {
    191         info.pNext = pNext;
    192 
    193         return *this;
    194     }
    195 
    196     DeviceCreateInfo &flags(VkDeviceQueueCreateFlags const &flags) {
    197         info.flags = flags;
    198 
    199         return *this;
    200     }
    201 
    202     DeviceCreateInfo &queueCreateInfoCount(uint32_t const &queueCreateInfoCount) {
    203         info.queueCreateInfoCount = queueCreateInfoCount;
    204 
    205         return *this;
    206     }
    207 
    208     DeviceCreateInfo &pQueueCreateInfos(VkDeviceQueueCreateInfo const *const pQueueCreateInfos) {
    209         info.pQueueCreateInfos = pQueueCreateInfos;
    210 
    211         return *this;
    212     }
    213 
    214     DeviceCreateInfo &enabledLayerCount(uint32_t const &enabledLayerCount) {
    215         info.enabledLayerCount = enabledLayerCount;
    216 
    217         return *this;
    218     }
    219 
    220     DeviceCreateInfo &ppEnabledLayerNames(char const *const *const ppEnabledLayerNames) {
    221         info.ppEnabledLayerNames = ppEnabledLayerNames;
    222 
    223         return *this;
    224     }
    225 
    226     DeviceCreateInfo &enabledExtensionCount(uint32_t const &enabledExtensionCount) {
    227         info.enabledExtensionCount = enabledExtensionCount;
    228 
    229         return *this;
    230     }
    231 
    232     DeviceCreateInfo &ppEnabledExtensionNames(char const *const *const ppEnabledExtensionNames) {
    233         info.ppEnabledExtensionNames = ppEnabledExtensionNames;
    234 
    235         return *this;
    236     }
    237 
    238     DeviceCreateInfo &pEnabledFeatures(VkPhysicalDeviceFeatures const *const pEnabledFeatures) {
    239         info.pEnabledFeatures = pEnabledFeatures;
    240 
    241         return *this;
    242     }
    243 
    244     operator VkDeviceCreateInfo const *() const { return &info; }
    245 
    246     operator VkDeviceCreateInfo *() { return &info; }
    247 
    248     VkDeviceCreateInfo info;
    249 };
    250 }  // namespace VK
    251 
    252 struct CommandLine : public ::testing::Test {
    253     static void Initialize(int argc, char **argv) { arguments.assign(argv, argv + argc); };
    254 
    255     static void SetUpTestCase(){};
    256     static void TearDownTestCase(){};
    257 
    258     static std::vector<std::string> arguments;
    259 };
    260 std::vector<std::string> CommandLine::arguments;
    261 
    262 struct EnumerateInstanceLayerProperties : public CommandLine {};
    263 struct EnumerateInstanceExtensionProperties : public CommandLine {};
    264 struct ImplicitLayer : public CommandLine {};
    265 
    266 // Allocation tracking utilities
    267 struct AllocTrack {
    268     bool active;
    269     bool was_allocated;
    270     void *aligned_start_addr;
    271     char *actual_start_addr;
    272     size_t requested_size_bytes;
    273     size_t actual_size_bytes;
    274     VkSystemAllocationScope alloc_scope;
    275     uint64_t user_data;
    276 
    277     AllocTrack()
    278         : active(false),
    279           was_allocated(false),
    280           aligned_start_addr(nullptr),
    281           actual_start_addr(nullptr),
    282           requested_size_bytes(0),
    283           actual_size_bytes(0),
    284           alloc_scope(VK_SYSTEM_ALLOCATION_SCOPE_COMMAND),
    285           user_data(0) {}
    286 };
    287 
    288 // Global vector to track allocations.  This will be resized before each test and emptied after.
    289 // However, we have to globally define it so the allocation callback functions work properly.
    290 std::vector<AllocTrack> g_allocated_vector;
    291 bool g_intentional_fail_enabled = false;
    292 uint32_t g_intenional_fail_index = 0;
    293 uint32_t g_intenional_fail_count = 0;
    294 
    295 void FreeAllocTracker() { g_allocated_vector.clear(); }
    296 
    297 void InitAllocTracker(size_t size, uint32_t intentional_fail_index = UINT32_MAX) {
    298     if (g_allocated_vector.size() > 0) {
    299         FreeAllocTracker();
    300     }
    301     g_allocated_vector.resize(size);
    302     if (intentional_fail_index != UINT32_MAX) {
    303         g_intentional_fail_enabled = true;
    304         g_intenional_fail_index = intentional_fail_index;
    305         g_intenional_fail_count = 0;
    306     } else {
    307         g_intentional_fail_enabled = false;
    308         g_intenional_fail_index = 0;
    309         g_intenional_fail_count = 0;
    310     }
    311 }
    312 
    313 bool IsAllocTrackerEmpty() {
    314     bool success = true;
    315     bool was_allocated = false;
    316     char print_command[1024];
    317     sprintf(print_command, "\t%%04d\t%%p (%%p) : 0x%%%s (0x%%%s) : scope %%d : user_data 0x%%%s\n", PRIxLEAST64, PRIxLEAST64,
    318             PRIxLEAST64);
    319     for (uint32_t iii = 0; iii < g_allocated_vector.size(); iii++) {
    320         if (g_allocated_vector[iii].active) {
    321             if (success) {
    322                 printf("ERROR: Allocations still remain!\n");
    323             }
    324             printf(print_command, iii, g_allocated_vector[iii].aligned_start_addr, g_allocated_vector[iii].actual_start_addr,
    325                    g_allocated_vector[iii].requested_size_bytes, g_allocated_vector[iii].actual_size_bytes,
    326                    g_allocated_vector[iii].alloc_scope, g_allocated_vector[iii].user_data);
    327             success = false;
    328         } else if (!was_allocated && g_allocated_vector[iii].was_allocated) {
    329             was_allocated = true;
    330         }
    331     }
    332     if (!g_intentional_fail_enabled && !was_allocated) {
    333         printf("No allocations ever generated!");
    334         success = false;
    335     }
    336     return success;
    337 }
    338 
    339 VKAPI_ATTR void *VKAPI_CALL AllocCallbackFunc(void *pUserData, size_t size, size_t alignment,
    340                                               VkSystemAllocationScope allocationScope) {
    341     if (g_intentional_fail_enabled) {
    342         if (++g_intenional_fail_count >= g_intenional_fail_index) {
    343             return nullptr;
    344         }
    345     }
    346     for (uint32_t iii = 0; iii < g_allocated_vector.size(); iii++) {
    347         if (!g_allocated_vector[iii].active) {
    348             g_allocated_vector[iii].requested_size_bytes = size;
    349             g_allocated_vector[iii].actual_size_bytes = size + (alignment - 1);
    350             g_allocated_vector[iii].aligned_start_addr = NULL;
    351             g_allocated_vector[iii].actual_start_addr = new char[g_allocated_vector[iii].actual_size_bytes];
    352             if (g_allocated_vector[iii].actual_start_addr != NULL) {
    353                 uint64_t addr = (uint64_t)g_allocated_vector[iii].actual_start_addr;
    354                 addr += (alignment - 1);
    355                 addr &= ~(alignment - 1);
    356                 g_allocated_vector[iii].aligned_start_addr = (void *)addr;
    357                 g_allocated_vector[iii].alloc_scope = allocationScope;
    358                 g_allocated_vector[iii].user_data = (uint64_t)pUserData;
    359                 g_allocated_vector[iii].active = true;
    360                 g_allocated_vector[iii].was_allocated = true;
    361             }
    362             return g_allocated_vector[iii].aligned_start_addr;
    363         }
    364     }
    365     return nullptr;
    366 }
    367 
    368 VKAPI_ATTR void VKAPI_CALL FreeCallbackFunc(void *pUserData, void *pMemory) {
    369     for (uint32_t iii = 0; iii < g_allocated_vector.size(); iii++) {
    370         if (g_allocated_vector[iii].active && g_allocated_vector[iii].aligned_start_addr == pMemory) {
    371             delete[] g_allocated_vector[iii].actual_start_addr;
    372             g_allocated_vector[iii].active = false;
    373             break;
    374         }
    375     }
    376 }
    377 
    378 VKAPI_ATTR void *VKAPI_CALL ReallocCallbackFunc(void *pUserData, void *pOriginal, size_t size, size_t alignment,
    379                                                 VkSystemAllocationScope allocationScope) {
    380     if (pOriginal != NULL) {
    381         for (uint32_t iii = 0; iii < g_allocated_vector.size(); iii++) {
    382             if (g_allocated_vector[iii].active && g_allocated_vector[iii].aligned_start_addr == pOriginal) {
    383                 if (size == 0) {
    384                     FreeCallbackFunc(pUserData, pOriginal);
    385                     return nullptr;
    386                 } else if (size < g_allocated_vector[iii].requested_size_bytes) {
    387                     return pOriginal;
    388                 } else {
    389                     void *pNew = AllocCallbackFunc(pUserData, size, alignment, allocationScope);
    390                     if (pNew != NULL) {
    391                         size_t copy_size = size;
    392                         if (g_allocated_vector[iii].requested_size_bytes < size) {
    393                             copy_size = g_allocated_vector[iii].requested_size_bytes;
    394                         }
    395                         memcpy(pNew, pOriginal, copy_size);
    396                         FreeCallbackFunc(pUserData, pOriginal);
    397                     }
    398                     return pNew;
    399                 }
    400             }
    401         }
    402         return nullptr;
    403     } else {
    404         return AllocCallbackFunc(pUserData, size, alignment, allocationScope);
    405     }
    406 }
    407 
    408 // Test groups:
    409 // LX = lunar exchange
    410 // LVLGH = loader and validation github
    411 // LVLGL = lodaer and validation gitlab
    412 
    413 TEST(LX435, InstanceCreateInfoConst) {
    414     VkInstanceCreateInfo const info = {VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO, nullptr, 0, nullptr, 0, nullptr, 0, nullptr};
    415 
    416     VkInstance instance = VK_NULL_HANDLE;
    417     VkResult result = vkCreateInstance(&info, VK_NULL_HANDLE, &instance);
    418     EXPECT_EQ(result, VK_SUCCESS);
    419 
    420     vkDestroyInstance(instance, nullptr);
    421 }
    422 
    423 TEST(LX475, DestroyInstanceNullHandle) { vkDestroyInstance(VK_NULL_HANDLE, nullptr); }
    424 
    425 TEST(LX475, DestroyDeviceNullHandle) { vkDestroyDevice(VK_NULL_HANDLE, nullptr); }
    426 
    427 TEST(CreateInstance, ExtensionNotPresent) {
    428     char const *const names[] = {"NotPresent"};  // Temporary required due to MSVC bug.
    429     auto const info = VK::InstanceCreateInfo().enabledExtensionCount(1).ppEnabledExtensionNames(names);
    430 
    431     VkInstance instance = VK_NULL_HANDLE;
    432     VkResult result = vkCreateInstance(info, VK_NULL_HANDLE, &instance);
    433     ASSERT_EQ(result, VK_ERROR_EXTENSION_NOT_PRESENT);
    434 
    435     // It's not necessary to destroy the instance because it will not be created successfully.
    436 }
    437 
    438 TEST(CreateInstance, LayerNotPresent) {
    439     char const *const names[] = {"NotPresent"};  // Temporary required due to MSVC bug.
    440     auto const info = VK::InstanceCreateInfo().enabledLayerCount(1).ppEnabledLayerNames(names);
    441 
    442     VkInstance instance = VK_NULL_HANDLE;
    443     VkResult result = vkCreateInstance(info, VK_NULL_HANDLE, &instance);
    444     ASSERT_EQ(result, VK_ERROR_LAYER_NOT_PRESENT);
    445 
    446     // It's not necessary to destroy the instance because it will not be created successfully.
    447 }
    448 
    449 // Used by run_loader_tests.sh to test for layer insertion.
    450 TEST(CreateInstance, LayerPresent) {
    451     char const *const names1[] = {"VK_LAYER_LUNARG_parameter_validation"};  // Temporary required due to MSVC bug.
    452     char const *const names2[] = {"VK_LAYER_LUNARG_standard_validation"};   // Temporary required due to MSVC bug.
    453     auto const info1 = VK::InstanceCreateInfo().enabledLayerCount(1).ppEnabledLayerNames(names1);
    454     VkInstance instance = VK_NULL_HANDLE;
    455     VkResult result = vkCreateInstance(info1, VK_NULL_HANDLE, &instance);
    456     ASSERT_EQ(result, VK_SUCCESS);
    457     vkDestroyInstance(instance, nullptr);
    458 
    459     auto const info2 = VK::InstanceCreateInfo().enabledLayerCount(1).ppEnabledLayerNames(names2);
    460     instance = VK_NULL_HANDLE;
    461     result = vkCreateInstance(info2, VK_NULL_HANDLE, &instance);
    462     ASSERT_EQ(result, VK_SUCCESS);
    463     vkDestroyInstance(instance, nullptr);
    464 }
    465 
    466 // Used by run_loader_tests.sh to test that calling vkEnumeratePhysicalDevices without first querying
    467 // the count, works.
    468 TEST(EnumeratePhysicalDevices, OneCall) {
    469     VkInstance instance = VK_NULL_HANDLE;
    470     VkResult result = vkCreateInstance(VK::InstanceCreateInfo(), VK_NULL_HANDLE, &instance);
    471     ASSERT_EQ(result, VK_SUCCESS);
    472 
    473     uint32_t physicalCount = 500;
    474     std::unique_ptr<VkPhysicalDevice[]> physical(new VkPhysicalDevice[physicalCount]);
    475     result = vkEnumeratePhysicalDevices(instance, &physicalCount, physical.get());
    476     ASSERT_EQ(result, VK_SUCCESS);
    477     ASSERT_GT(physicalCount, 0u);
    478 
    479     vkDestroyInstance(instance, nullptr);
    480 }
    481 
    482 // Used by run_loader_tests.sh to test for the expected usage of the vkEnumeratePhysicalDevices call.
    483 TEST(EnumeratePhysicalDevices, TwoCall) {
    484     VkInstance instance = VK_NULL_HANDLE;
    485     VkResult result = vkCreateInstance(VK::InstanceCreateInfo(), VK_NULL_HANDLE, &instance);
    486     ASSERT_EQ(result, VK_SUCCESS);
    487 
    488     uint32_t physicalCount = 0;
    489     result = vkEnumeratePhysicalDevices(instance, &physicalCount, nullptr);
    490     ASSERT_EQ(result, VK_SUCCESS);
    491     ASSERT_GT(physicalCount, 0u);
    492 
    493     std::unique_ptr<VkPhysicalDevice[]> physical(new VkPhysicalDevice[physicalCount]);
    494     result = vkEnumeratePhysicalDevices(instance, &physicalCount, physical.get());
    495     ASSERT_EQ(result, VK_SUCCESS);
    496     ASSERT_GT(physicalCount, 0u);
    497 
    498     vkDestroyInstance(instance, nullptr);
    499 }
    500 
    501 // Used by run_loader_tests.sh to test that calling vkEnumeratePhysicalDevices without first querying
    502 // the count, matches the count from the standard call.
    503 TEST(EnumeratePhysicalDevices, MatchOneAndTwoCallNumbers) {
    504     VkInstance instance_one = VK_NULL_HANDLE;
    505     VkResult result = vkCreateInstance(VK::InstanceCreateInfo(), VK_NULL_HANDLE, &instance_one);
    506     ASSERT_EQ(result, VK_SUCCESS);
    507 
    508     uint32_t physicalCount_one = 500;
    509     std::unique_ptr<VkPhysicalDevice[]> physical_one(new VkPhysicalDevice[physicalCount_one]);
    510     result = vkEnumeratePhysicalDevices(instance_one, &physicalCount_one, physical_one.get());
    511     ASSERT_EQ(result, VK_SUCCESS);
    512     ASSERT_GT(physicalCount_one, 0u);
    513 
    514     VkInstance instance_two = VK_NULL_HANDLE;
    515     result = vkCreateInstance(VK::InstanceCreateInfo(), VK_NULL_HANDLE, &instance_two);
    516     ASSERT_EQ(result, VK_SUCCESS);
    517 
    518     uint32_t physicalCount_two = 0;
    519     result = vkEnumeratePhysicalDevices(instance_two, &physicalCount_two, nullptr);
    520     ASSERT_EQ(result, VK_SUCCESS);
    521     ASSERT_GT(physicalCount_two, 0u);
    522 
    523     std::unique_ptr<VkPhysicalDevice[]> physical_two(new VkPhysicalDevice[physicalCount_two]);
    524     result = vkEnumeratePhysicalDevices(instance_two, &physicalCount_two, physical_two.get());
    525     ASSERT_EQ(result, VK_SUCCESS);
    526     ASSERT_GT(physicalCount_two, 0u);
    527 
    528     ASSERT_EQ(physicalCount_one, physicalCount_two);
    529 
    530     vkDestroyInstance(instance_one, nullptr);
    531     vkDestroyInstance(instance_two, nullptr);
    532 }
    533 
    534 // Used by run_loader_tests.sh to test for the expected usage of the vkEnumeratePhysicalDevices
    535 // call if not enough numbers are provided for the final list.
    536 TEST(EnumeratePhysicalDevices, TwoCallIncomplete) {
    537     VkInstance instance = VK_NULL_HANDLE;
    538     VkResult result = vkCreateInstance(VK::InstanceCreateInfo(), VK_NULL_HANDLE, &instance);
    539     ASSERT_EQ(result, VK_SUCCESS);
    540 
    541     uint32_t physicalCount = 0;
    542     result = vkEnumeratePhysicalDevices(instance, &physicalCount, nullptr);
    543     ASSERT_EQ(result, VK_SUCCESS);
    544     ASSERT_GT(physicalCount, 0u);
    545 
    546     std::unique_ptr<VkPhysicalDevice[]> physical(new VkPhysicalDevice[physicalCount]);
    547 
    548     // Remove one from the physical device count so we can get the VK_INCOMPLETE message
    549     physicalCount -= 1;
    550 
    551     result = vkEnumeratePhysicalDevices(instance, &physicalCount, physical.get());
    552     ASSERT_EQ(result, VK_INCOMPLETE);
    553 
    554     vkDestroyInstance(instance, nullptr);
    555 }
    556 
    557 // Test to make sure that layers enabled in the instance show up in the list of device layers.
    558 TEST(EnumerateDeviceLayers, LayersMatch) {
    559     char const *const names1[] = {"VK_LAYER_LUNARG_standard_validation"};
    560     char const *const names2[3] = {"VK_LAYER_LUNARG_parameter_validation", "VK_LAYER_LUNARG_core_validation",
    561                                    "VK_LAYER_LUNARG_object_tracker"};
    562     auto const info1 = VK::InstanceCreateInfo().enabledLayerCount(1).ppEnabledLayerNames(names1);
    563     VkInstance instance = VK_NULL_HANDLE;
    564     VkResult result = vkCreateInstance(info1, VK_NULL_HANDLE, &instance);
    565     ASSERT_EQ(result, VK_SUCCESS);
    566 
    567     uint32_t physicalCount = 0;
    568     result = vkEnumeratePhysicalDevices(instance, &physicalCount, nullptr);
    569     ASSERT_EQ(result, VK_SUCCESS);
    570     ASSERT_GT(physicalCount, 0u);
    571 
    572     std::unique_ptr<VkPhysicalDevice[]> physical(new VkPhysicalDevice[physicalCount]);
    573     result = vkEnumeratePhysicalDevices(instance, &physicalCount, physical.get());
    574     ASSERT_EQ(result, VK_SUCCESS);
    575     ASSERT_GT(physicalCount, 0u);
    576     uint32_t count = 24;
    577     VkLayerProperties layer_props[24];
    578     vkEnumerateDeviceLayerProperties(physical[0], &count, layer_props);
    579     ASSERT_GE(count, 1u);
    580     bool found = false;
    581     for (uint32_t iii = 0; iii < count; iii++) {
    582         if (!strcmp(layer_props[iii].layerName, names1[0])) {
    583             found = true;
    584             break;
    585         }
    586     }
    587     if (!found) {
    588         ASSERT_EQ(count, 0);
    589     }
    590 
    591     vkDestroyInstance(instance, nullptr);
    592 
    593     auto const info2 = VK::InstanceCreateInfo().enabledLayerCount(3).ppEnabledLayerNames(names2);
    594     instance = VK_NULL_HANDLE;
    595     result = vkCreateInstance(info2, VK_NULL_HANDLE, &instance);
    596     ASSERT_EQ(result, VK_SUCCESS);
    597 
    598     physicalCount = 0;
    599     result = vkEnumeratePhysicalDevices(instance, &physicalCount, nullptr);
    600     ASSERT_EQ(result, VK_SUCCESS);
    601     ASSERT_GT(physicalCount, 0u);
    602 
    603     std::unique_ptr<VkPhysicalDevice[]> physical2(new VkPhysicalDevice[physicalCount]);
    604     result = vkEnumeratePhysicalDevices(instance, &physicalCount, physical2.get());
    605     ASSERT_EQ(result, VK_SUCCESS);
    606     ASSERT_GT(physicalCount, 0u);
    607 
    608     count = 24;
    609     vkEnumerateDeviceLayerProperties(physical2[0], &count, layer_props);
    610     ASSERT_GE(count, 3u);
    611     for (uint32_t jjj = 0; jjj < 3; jjj++) {
    612         found = false;
    613         for (uint32_t iii = 0; iii < count; iii++) {
    614             if (!strcmp(layer_props[iii].layerName, names2[jjj])) {
    615                 found = true;
    616                 break;
    617             }
    618         }
    619         if (!found) {
    620             ASSERT_EQ(count, 0);
    621         }
    622     }
    623 
    624     vkDestroyInstance(instance, nullptr);
    625 }
    626 
    627 TEST(CreateDevice, ExtensionNotPresent) {
    628     VkInstance instance = VK_NULL_HANDLE;
    629     VkResult result = vkCreateInstance(VK::InstanceCreateInfo(), VK_NULL_HANDLE, &instance);
    630     ASSERT_EQ(result, VK_SUCCESS);
    631 
    632     uint32_t physicalCount = 0;
    633     result = vkEnumeratePhysicalDevices(instance, &physicalCount, nullptr);
    634     ASSERT_EQ(result, VK_SUCCESS);
    635     ASSERT_GT(physicalCount, 0u);
    636 
    637     std::unique_ptr<VkPhysicalDevice[]> physical(new VkPhysicalDevice[physicalCount]);
    638     result = vkEnumeratePhysicalDevices(instance, &physicalCount, physical.get());
    639     ASSERT_EQ(result, VK_SUCCESS);
    640     ASSERT_GT(physicalCount, 0u);
    641 
    642     for (uint32_t p = 0; p < physicalCount; ++p) {
    643         uint32_t familyCount = 0;
    644         vkGetPhysicalDeviceQueueFamilyProperties(physical[p], &familyCount, nullptr);
    645         ASSERT_GT(familyCount, 0u);
    646 
    647         std::unique_ptr<VkQueueFamilyProperties[]> family(new VkQueueFamilyProperties[familyCount]);
    648         vkGetPhysicalDeviceQueueFamilyProperties(physical[p], &familyCount, family.get());
    649         ASSERT_GT(familyCount, 0u);
    650 
    651         for (uint32_t q = 0; q < familyCount; ++q) {
    652             if (~family[q].queueFlags & VK_QUEUE_GRAPHICS_BIT) {
    653                 continue;
    654             }
    655 
    656             float const priorities[] = {0.0f};  // Temporary required due to MSVC bug.
    657             VkDeviceQueueCreateInfo const queueInfo[1]{
    658                 VK::DeviceQueueCreateInfo().queueFamilyIndex(q).queueCount(1).pQueuePriorities(priorities)};
    659 
    660             char const *const names[] = {"NotPresent"};  // Temporary required due to MSVC bug.
    661             auto const deviceInfo = VK::DeviceCreateInfo()
    662                                         .queueCreateInfoCount(1)
    663                                         .pQueueCreateInfos(queueInfo)
    664                                         .enabledExtensionCount(1)
    665                                         .ppEnabledExtensionNames(names);
    666 
    667             VkDevice device;
    668             result = vkCreateDevice(physical[p], deviceInfo, nullptr, &device);
    669             ASSERT_EQ(result, VK_ERROR_EXTENSION_NOT_PRESENT);
    670 
    671             // It's not necessary to destroy the device because it will not be created successfully.
    672         }
    673     }
    674 
    675     vkDestroyInstance(instance, nullptr);
    676 }
    677 
    678 // LX535 / MI-76: Device layers are deprecated.
    679 // For backwards compatibility, they are allowed, but must be ignored.
    680 // Ensure that no errors occur if a bogus device layer list is passed to vkCreateDevice.
    681 TEST(CreateDevice, LayersNotPresent) {
    682     VkInstance instance = VK_NULL_HANDLE;
    683     VkResult result = vkCreateInstance(VK::InstanceCreateInfo(), VK_NULL_HANDLE, &instance);
    684     ASSERT_EQ(result, VK_SUCCESS);
    685 
    686     uint32_t physicalCount = 0;
    687     result = vkEnumeratePhysicalDevices(instance, &physicalCount, nullptr);
    688     ASSERT_EQ(result, VK_SUCCESS);
    689     ASSERT_GT(physicalCount, 0u);
    690 
    691     std::unique_ptr<VkPhysicalDevice[]> physical(new VkPhysicalDevice[physicalCount]);
    692     result = vkEnumeratePhysicalDevices(instance, &physicalCount, physical.get());
    693     ASSERT_EQ(result, VK_SUCCESS);
    694     ASSERT_GT(physicalCount, 0u);
    695 
    696     for (uint32_t p = 0; p < physicalCount; ++p) {
    697         uint32_t familyCount = 0;
    698         vkGetPhysicalDeviceQueueFamilyProperties(physical[p], &familyCount, nullptr);
    699         ASSERT_EQ(result, VK_SUCCESS);
    700         ASSERT_GT(familyCount, 0u);
    701 
    702         std::unique_ptr<VkQueueFamilyProperties[]> family(new VkQueueFamilyProperties[familyCount]);
    703         vkGetPhysicalDeviceQueueFamilyProperties(physical[p], &familyCount, family.get());
    704         ASSERT_EQ(result, VK_SUCCESS);
    705         ASSERT_GT(familyCount, 0u);
    706 
    707         for (uint32_t q = 0; q < familyCount; ++q) {
    708             if (~family[q].queueFlags & VK_QUEUE_GRAPHICS_BIT) {
    709                 continue;
    710             }
    711 
    712             float const priorities[] = {0.0f};  // Temporary required due to MSVC bug.
    713             VkDeviceQueueCreateInfo const queueInfo[1]{
    714                 VK::DeviceQueueCreateInfo().queueFamilyIndex(q).queueCount(1).pQueuePriorities(priorities)};
    715 
    716             char const *const names[] = {"NotPresent"};  // Temporary required due to MSVC bug.
    717             auto const deviceInfo = VK::DeviceCreateInfo()
    718                                         .queueCreateInfoCount(1)
    719                                         .pQueueCreateInfos(queueInfo)
    720                                         .enabledLayerCount(1)
    721                                         .ppEnabledLayerNames(names);
    722 
    723             VkDevice device;
    724             result = vkCreateDevice(physical[p], deviceInfo, nullptr, &device);
    725             ASSERT_EQ(result, VK_SUCCESS);
    726 
    727             vkDestroyDevice(device, nullptr);
    728         }
    729     }
    730 
    731     vkDestroyInstance(instance, nullptr);
    732 }
    733 
    734 TEST_F(EnumerateInstanceLayerProperties, PropertyCountLessThanAvailable) {
    735     uint32_t count = 0u;
    736     VkResult result = vkEnumerateInstanceLayerProperties(&count, nullptr);
    737     ASSERT_EQ(result, VK_SUCCESS);
    738 
    739     // We need atleast two for the test to be relevant.
    740     if (count < 2u) {
    741         return;
    742     }
    743 
    744     std::unique_ptr<VkLayerProperties[]> properties(new VkLayerProperties[count]);
    745     count = 1;
    746     result = vkEnumerateInstanceLayerProperties(&count, properties.get());
    747     ASSERT_EQ(result, VK_INCOMPLETE);
    748 }
    749 
    750 TEST(EnumerateDeviceLayerProperties, PropertyCountLessThanAvailable) {
    751     VkInstance instance = VK_NULL_HANDLE;
    752     VkResult result = vkCreateInstance(VK::InstanceCreateInfo(), VK_NULL_HANDLE, &instance);
    753     ASSERT_EQ(result, VK_SUCCESS);
    754 
    755     uint32_t physicalCount = 0;
    756     result = vkEnumeratePhysicalDevices(instance, &physicalCount, nullptr);
    757     ASSERT_EQ(result, VK_SUCCESS);
    758     ASSERT_GT(physicalCount, 0u);
    759 
    760     std::unique_ptr<VkPhysicalDevice[]> physical(new VkPhysicalDevice[physicalCount]);
    761     result = vkEnumeratePhysicalDevices(instance, &physicalCount, physical.get());
    762     ASSERT_EQ(result, VK_SUCCESS);
    763     ASSERT_GT(physicalCount, 0u);
    764 
    765     for (uint32_t p = 0; p < physicalCount; ++p) {
    766         uint32_t count = 0u;
    767         result = vkEnumerateDeviceLayerProperties(physical[p], &count, nullptr);
    768         ASSERT_EQ(result, VK_SUCCESS);
    769 
    770         // We need atleast two for the test to be relevant.
    771         if (count < 2u) {
    772             continue;
    773         }
    774 
    775         std::unique_ptr<VkLayerProperties[]> properties(new VkLayerProperties[count]);
    776         count = 1;
    777         result = vkEnumerateDeviceLayerProperties(physical[p], &count, properties.get());
    778         ASSERT_EQ(result, VK_INCOMPLETE);
    779     }
    780 
    781     vkDestroyInstance(instance, nullptr);
    782 }
    783 
    784 TEST_F(EnumerateInstanceLayerProperties, Count) {
    785     uint32_t count = 0u;
    786     VkResult result = vkEnumerateInstanceLayerProperties(&count, nullptr);
    787     ASSERT_EQ(result, VK_SUCCESS);
    788 
    789     if (std::find(arguments.begin(), arguments.end(), "count") != arguments.end()) {
    790         std::cout << "count=" << count << '\n';
    791     }
    792 }
    793 
    794 TEST_F(EnumerateInstanceLayerProperties, OnePass) {
    795     // Count required for this test.
    796     if (std::find(arguments.begin(), arguments.end(), "count") == arguments.end()) {
    797         return;
    798     }
    799 
    800     uint32_t count = std::stoul(arguments[2]);
    801 
    802     std::unique_ptr<VkLayerProperties[]> properties(new VkLayerProperties[count]);
    803     VkResult result = vkEnumerateInstanceLayerProperties(&count, properties.get());
    804     ASSERT_EQ(result, VK_SUCCESS);
    805 
    806     if (std::find(arguments.begin(), arguments.end(), "properties") != arguments.end()) {
    807         for (uint32_t p = 0; p < count; ++p) {
    808             std::cout << "properties[" << p << "] =" << ' ' << properties[p].layerName << ' ' << properties[p].specVersion << ' '
    809                       << properties[p].implementationVersion << ' ' << properties[p].description << '\n';
    810         }
    811     }
    812 }
    813 
    814 TEST_F(EnumerateInstanceLayerProperties, TwoPass) {
    815     uint32_t count = 0u;
    816     VkResult result = vkEnumerateInstanceLayerProperties(&count, nullptr);
    817     ASSERT_EQ(result, VK_SUCCESS);
    818 
    819     std::unique_ptr<VkLayerProperties[]> properties(new VkLayerProperties[count]);
    820     result = vkEnumerateInstanceLayerProperties(&count, properties.get());
    821     ASSERT_EQ(result, VK_SUCCESS);
    822 
    823     if (std::find(arguments.begin(), arguments.end(), "properties") != arguments.end()) {
    824         for (uint32_t p = 0; p < count; ++p) {
    825             std::cout << "properties[" << p << "] =" << ' ' << properties[p].layerName << ' ' << properties[p].specVersion << ' '
    826                       << properties[p].implementationVersion << ' ' << properties[p].description << '\n';
    827         }
    828     }
    829 }
    830 
    831 TEST_F(EnumerateInstanceExtensionProperties, PropertyCountLessThanAvailable) {
    832     uint32_t count = 0u;
    833     VkResult result = vkEnumerateInstanceExtensionProperties(nullptr, &count, nullptr);
    834     ASSERT_EQ(result, VK_SUCCESS);
    835 
    836     // We need atleast two for the test to be relevant.
    837     if (count < 2u) {
    838         return;
    839     }
    840 
    841     std::unique_ptr<VkExtensionProperties[]> properties(new VkExtensionProperties[count]);
    842     count = 1;
    843     result = vkEnumerateInstanceExtensionProperties(nullptr, &count, properties.get());
    844     ASSERT_EQ(result, VK_INCOMPLETE);
    845 }
    846 
    847 TEST(EnumerateDeviceExtensionProperties, PropertyCountLessThanAvailable) {
    848     VkInstance instance = VK_NULL_HANDLE;
    849     VkResult result = vkCreateInstance(VK::InstanceCreateInfo(), VK_NULL_HANDLE, &instance);
    850     ASSERT_EQ(result, VK_SUCCESS);
    851 
    852     uint32_t physicalCount = 0;
    853     result = vkEnumeratePhysicalDevices(instance, &physicalCount, nullptr);
    854     ASSERT_EQ(result, VK_SUCCESS);
    855     ASSERT_GT(physicalCount, 0u);
    856 
    857     std::unique_ptr<VkPhysicalDevice[]> physical(new VkPhysicalDevice[physicalCount]);
    858     result = vkEnumeratePhysicalDevices(instance, &physicalCount, physical.get());
    859     ASSERT_EQ(result, VK_SUCCESS);
    860     ASSERT_GT(physicalCount, 0u);
    861 
    862     for (uint32_t p = 0; p < physicalCount; ++p) {
    863         uint32_t count = 0u;
    864         result = vkEnumerateDeviceExtensionProperties(physical[p], nullptr, &count, nullptr);
    865         ASSERT_EQ(result, VK_SUCCESS);
    866 
    867         // We need atleast two for the test to be relevant.
    868         if (count < 2u) {
    869             continue;
    870         }
    871 
    872         std::unique_ptr<VkExtensionProperties[]> properties(new VkExtensionProperties[count]);
    873         count = 1;
    874         result = vkEnumerateDeviceExtensionProperties(physical[p], nullptr, &count, properties.get());
    875         ASSERT_EQ(result, VK_INCOMPLETE);
    876     }
    877 
    878     vkDestroyInstance(instance, nullptr);
    879 }
    880 
    881 TEST_F(EnumerateInstanceExtensionProperties, Count) {
    882     uint32_t count = 0u;
    883     VkResult result = vkEnumerateInstanceExtensionProperties(nullptr, &count, nullptr);
    884     ASSERT_EQ(result, VK_SUCCESS);
    885 
    886     if (std::find(arguments.begin(), arguments.end(), "count") != arguments.end()) {
    887         std::cout << "count=" << count << '\n';
    888     }
    889 }
    890 
    891 TEST_F(EnumerateInstanceExtensionProperties, OnePass) {
    892     // Count required for this test.
    893     if (std::find(arguments.begin(), arguments.end(), "count") == arguments.end()) {
    894         return;
    895     }
    896 
    897     uint32_t count = std::stoul(arguments[2]);
    898 
    899     std::unique_ptr<VkExtensionProperties[]> properties(new VkExtensionProperties[count]);
    900     VkResult result = vkEnumerateInstanceExtensionProperties(nullptr, &count, properties.get());
    901     ASSERT_EQ(result, VK_SUCCESS);
    902 
    903     if (std::find(arguments.begin(), arguments.end(), "properties") != arguments.end()) {
    904         for (uint32_t p = 0; p < count; ++p) {
    905             std::cout << "properties[" << p << "] =" << ' ' << properties[p].extensionName << ' ' << properties[p].specVersion
    906                       << '\n';
    907         }
    908     }
    909 }
    910 
    911 TEST_F(EnumerateInstanceExtensionProperties, TwoPass) {
    912     uint32_t count = 0u;
    913     VkResult result = vkEnumerateInstanceExtensionProperties(nullptr, &count, nullptr);
    914     ASSERT_EQ(result, VK_SUCCESS);
    915 
    916     std::unique_ptr<VkExtensionProperties[]> properties(new VkExtensionProperties[count]);
    917     result = vkEnumerateInstanceExtensionProperties(nullptr, &count, properties.get());
    918     ASSERT_EQ(result, VK_SUCCESS);
    919 
    920     if (std::find(arguments.begin(), arguments.end(), "properties") != arguments.end()) {
    921         for (uint32_t p = 0; p < count; ++p) {
    922             std::cout << "properties[" << p << "] =" << ' ' << properties[p].extensionName << ' ' << properties[p].specVersion
    923                       << '\n';
    924         }
    925     }
    926 }
    927 
    928 TEST_F(EnumerateInstanceExtensionProperties, InstanceExtensionEnumerated) {
    929     uint32_t count = 0u;
    930     VkResult result = vkEnumerateInstanceExtensionProperties(nullptr, &count, nullptr);
    931     ASSERT_EQ(result, VK_SUCCESS);
    932 
    933     std::unique_ptr<VkExtensionProperties[]> properties(new VkExtensionProperties[count]);
    934     result = vkEnumerateInstanceExtensionProperties(nullptr, &count, properties.get());
    935     ASSERT_EQ(result, VK_SUCCESS);
    936 
    937     ASSERT_NE(std::find_if(
    938                   &properties[0], &properties[count],
    939                   [](VkExtensionProperties const &properties) { return strcmp(properties.extensionName, "VK_KHR_surface") == 0; }),
    940               &properties[count]);
    941 }
    942 
    943 TEST(EnumerateDeviceExtensionProperties, DeviceExtensionEnumerated) {
    944     VkInstance instance = VK_NULL_HANDLE;
    945     VkResult result = vkCreateInstance(VK::InstanceCreateInfo(), VK_NULL_HANDLE, &instance);
    946     ASSERT_EQ(result, VK_SUCCESS);
    947 
    948     uint32_t physicalCount = 0;
    949     result = vkEnumeratePhysicalDevices(instance, &physicalCount, nullptr);
    950     ASSERT_EQ(result, VK_SUCCESS);
    951     ASSERT_GT(physicalCount, 0u);
    952 
    953     std::unique_ptr<VkPhysicalDevice[]> physical(new VkPhysicalDevice[physicalCount]);
    954     result = vkEnumeratePhysicalDevices(instance, &physicalCount, physical.get());
    955     ASSERT_EQ(result, VK_SUCCESS);
    956     ASSERT_GT(physicalCount, 0u);
    957 
    958     for (uint32_t p = 0; p < physicalCount; ++p) {
    959         uint32_t count = 0u;
    960         result = vkEnumerateDeviceExtensionProperties(physical[p], nullptr, &count, nullptr);
    961         ASSERT_EQ(result, VK_SUCCESS);
    962 
    963         std::unique_ptr<VkExtensionProperties[]> properties(new VkExtensionProperties[count]);
    964         result = vkEnumerateDeviceExtensionProperties(physical[p], nullptr, &count, properties.get());
    965         ASSERT_EQ(result, VK_SUCCESS);
    966 
    967         ASSERT_NE(std::find_if(&properties[0], &properties[count],
    968                                [](VkExtensionProperties const &properties) {
    969                                    return strcmp(properties.extensionName, "VK_KHR_swapchain") == 0;
    970                                }),
    971                   &properties[count]);
    972     }
    973 
    974     vkDestroyInstance(instance, nullptr);
    975 }
    976 
    977 TEST_F(ImplicitLayer, Present) {
    978     auto const info = VK::InstanceCreateInfo();
    979     VkInstance instance = VK_NULL_HANDLE;
    980     VkResult result = vkCreateInstance(info, VK_NULL_HANDLE, &instance);
    981     ASSERT_EQ(result, VK_SUCCESS);
    982 
    983     vkDestroyInstance(instance, nullptr);
    984 }
    985 
    986 TEST(WrapObjects, Insert) {
    987     VkInstance instance = VK_NULL_HANDLE;
    988     VkResult result = vkCreateInstance(VK::InstanceCreateInfo(), VK_NULL_HANDLE, &instance);
    989     ASSERT_EQ(result, VK_SUCCESS);
    990 
    991     uint32_t physicalCount = 0;
    992     result = vkEnumeratePhysicalDevices(instance, &physicalCount, nullptr);
    993     ASSERT_EQ(result, VK_SUCCESS);
    994     ASSERT_GT(physicalCount, 0u);
    995 
    996     std::unique_ptr<VkPhysicalDevice[]> physical(new VkPhysicalDevice[physicalCount]);
    997     result = vkEnumeratePhysicalDevices(instance, &physicalCount, physical.get());
    998     ASSERT_EQ(result, VK_SUCCESS);
    999     ASSERT_GT(physicalCount, 0u);
   1000 
   1001     for (uint32_t p = 0; p < physicalCount; ++p) {
   1002         uint32_t familyCount = 0;
   1003         vkGetPhysicalDeviceQueueFamilyProperties(physical[p], &familyCount, nullptr);
   1004         ASSERT_EQ(result, VK_SUCCESS);
   1005         ASSERT_GT(familyCount, 0u);
   1006 
   1007         std::unique_ptr<VkQueueFamilyProperties[]> family(new VkQueueFamilyProperties[familyCount]);
   1008         vkGetPhysicalDeviceQueueFamilyProperties(physical[p], &familyCount, family.get());
   1009         ASSERT_EQ(result, VK_SUCCESS);
   1010         ASSERT_GT(familyCount, 0u);
   1011 
   1012         for (uint32_t q = 0; q < familyCount; ++q) {
   1013             if (~family[q].queueFlags & VK_QUEUE_GRAPHICS_BIT) {
   1014                 continue;
   1015             }
   1016 
   1017             float const priorities[] = {0.0f};  // Temporary required due to MSVC bug.
   1018             VkDeviceQueueCreateInfo const queueInfo[1]{
   1019                 VK::DeviceQueueCreateInfo().queueFamilyIndex(q).queueCount(1).pQueuePriorities(priorities)};
   1020 
   1021             auto const deviceInfo = VK::DeviceCreateInfo().queueCreateInfoCount(1).pQueueCreateInfos(queueInfo);
   1022 
   1023             VkDevice device;
   1024             result = vkCreateDevice(physical[p], deviceInfo, nullptr, &device);
   1025             ASSERT_EQ(result, VK_SUCCESS);
   1026 
   1027             vkDestroyDevice(device, nullptr);
   1028         }
   1029     }
   1030 
   1031     vkDestroyInstance(instance, nullptr);
   1032 }
   1033 
   1034 // Test making sure the allocation functions are called to allocate and cleanup everything during
   1035 // a CreateInstance/DestroyInstance call pair.
   1036 TEST(Allocation, Instance) {
   1037     auto const info = VK::InstanceCreateInfo();
   1038     VkInstance instance = VK_NULL_HANDLE;
   1039     VkAllocationCallbacks alloc_callbacks = {};
   1040     alloc_callbacks.pUserData = (void *)0x00000001;
   1041     alloc_callbacks.pfnAllocation = AllocCallbackFunc;
   1042     alloc_callbacks.pfnReallocation = ReallocCallbackFunc;
   1043     alloc_callbacks.pfnFree = FreeCallbackFunc;
   1044 
   1045     InitAllocTracker(2048);
   1046 
   1047     VkResult result = vkCreateInstance(info, &alloc_callbacks, &instance);
   1048     ASSERT_EQ(result, VK_SUCCESS);
   1049 
   1050     alloc_callbacks.pUserData = (void *)0x00000002;
   1051     vkDestroyInstance(instance, &alloc_callbacks);
   1052 
   1053     // Make sure everything's been freed
   1054     ASSERT_EQ(true, IsAllocTrackerEmpty());
   1055     FreeAllocTracker();
   1056 }
   1057 
   1058 // Test making sure the allocation functions are called to allocate and cleanup everything during
   1059 // a CreateInstance/DestroyInstance call pair with a call to GetInstanceProcAddr.
   1060 TEST(Allocation, GetInstanceProcAddr) {
   1061     auto const info = VK::InstanceCreateInfo();
   1062     VkInstance instance = VK_NULL_HANDLE;
   1063     VkAllocationCallbacks alloc_callbacks = {};
   1064     alloc_callbacks.pUserData = (void *)0x00000010;
   1065     alloc_callbacks.pfnAllocation = AllocCallbackFunc;
   1066     alloc_callbacks.pfnReallocation = ReallocCallbackFunc;
   1067     alloc_callbacks.pfnFree = FreeCallbackFunc;
   1068 
   1069     InitAllocTracker(2048);
   1070 
   1071     VkResult result = vkCreateInstance(info, &alloc_callbacks, &instance);
   1072     ASSERT_EQ(result, VK_SUCCESS);
   1073 
   1074     void *pfnCreateDevice = (void *)vkGetInstanceProcAddr(instance, "vkCreateDevice");
   1075     void *pfnDestroyDevice = (void *)vkGetInstanceProcAddr(instance, "vkDestroyDevice");
   1076     ASSERT_TRUE(pfnCreateDevice != NULL && pfnDestroyDevice != NULL);
   1077 
   1078     alloc_callbacks.pUserData = (void *)0x00000011;
   1079     vkDestroyInstance(instance, &alloc_callbacks);
   1080 
   1081     // Make sure everything's been freed
   1082     ASSERT_EQ(true, IsAllocTrackerEmpty());
   1083     FreeAllocTracker();
   1084 }
   1085 
   1086 // Test making sure the allocation functions are called to allocate and cleanup everything during
   1087 // a vkEnumeratePhysicalDevices call pair.
   1088 TEST(Allocation, EnumeratePhysicalDevices) {
   1089     auto const info = VK::InstanceCreateInfo();
   1090     VkInstance instance = VK_NULL_HANDLE;
   1091     VkAllocationCallbacks alloc_callbacks = {};
   1092     alloc_callbacks.pUserData = (void *)0x00000021;
   1093     alloc_callbacks.pfnAllocation = AllocCallbackFunc;
   1094     alloc_callbacks.pfnReallocation = ReallocCallbackFunc;
   1095     alloc_callbacks.pfnFree = FreeCallbackFunc;
   1096 
   1097     InitAllocTracker(2048);
   1098 
   1099     VkResult result = vkCreateInstance(info, &alloc_callbacks, &instance);
   1100     ASSERT_EQ(result, VK_SUCCESS);
   1101 
   1102     uint32_t physicalCount = 0;
   1103     alloc_callbacks.pUserData = (void *)0x00000022;
   1104     result = vkEnumeratePhysicalDevices(instance, &physicalCount, nullptr);
   1105     ASSERT_EQ(result, VK_SUCCESS);
   1106     ASSERT_GT(physicalCount, 0u);
   1107 
   1108     std::unique_ptr<VkPhysicalDevice[]> physical(new VkPhysicalDevice[physicalCount]);
   1109     alloc_callbacks.pUserData = (void *)0x00000023;
   1110     result = vkEnumeratePhysicalDevices(instance, &physicalCount, physical.get());
   1111     ASSERT_EQ(result, VK_SUCCESS);
   1112     ASSERT_GT(physicalCount, 0u);
   1113 
   1114     alloc_callbacks.pUserData = (void *)0x00000024;
   1115     vkDestroyInstance(instance, &alloc_callbacks);
   1116 
   1117     // Make sure everything's been freed
   1118     ASSERT_EQ(true, IsAllocTrackerEmpty());
   1119     FreeAllocTracker();
   1120 }
   1121 
   1122 // Test making sure the allocation functions are called to allocate and cleanup everything from
   1123 // vkCreateInstance, to vkCreateDevicce, and then through their destructors.  With special
   1124 // allocators used on both the instance and device.
   1125 TEST(Allocation, InstanceAndDevice) {
   1126     auto const info = VK::InstanceCreateInfo();
   1127     VkInstance instance = VK_NULL_HANDLE;
   1128     VkAllocationCallbacks alloc_callbacks = {};
   1129     alloc_callbacks.pUserData = (void *)0x00000031;
   1130     alloc_callbacks.pfnAllocation = AllocCallbackFunc;
   1131     alloc_callbacks.pfnReallocation = ReallocCallbackFunc;
   1132     alloc_callbacks.pfnFree = FreeCallbackFunc;
   1133 
   1134     InitAllocTracker(2048);
   1135 
   1136     VkResult result = vkCreateInstance(info, &alloc_callbacks, &instance);
   1137     ASSERT_EQ(result, VK_SUCCESS);
   1138 
   1139     uint32_t physicalCount = 0;
   1140     result = vkEnumeratePhysicalDevices(instance, &physicalCount, nullptr);
   1141     ASSERT_EQ(result, VK_SUCCESS);
   1142     ASSERT_GT(physicalCount, 0u);
   1143 
   1144     std::unique_ptr<VkPhysicalDevice[]> physical(new VkPhysicalDevice[physicalCount]);
   1145     result = vkEnumeratePhysicalDevices(instance, &physicalCount, physical.get());
   1146     ASSERT_EQ(result, VK_SUCCESS);
   1147     ASSERT_GT(physicalCount, 0u);
   1148 
   1149     for (uint32_t p = 0; p < physicalCount; ++p) {
   1150         uint32_t familyCount = 0;
   1151         vkGetPhysicalDeviceQueueFamilyProperties(physical[p], &familyCount, nullptr);
   1152         ASSERT_GT(familyCount, 0u);
   1153 
   1154         std::unique_ptr<VkQueueFamilyProperties[]> family(new VkQueueFamilyProperties[familyCount]);
   1155         vkGetPhysicalDeviceQueueFamilyProperties(physical[p], &familyCount, family.get());
   1156         ASSERT_GT(familyCount, 0u);
   1157 
   1158         for (uint32_t q = 0; q < familyCount; ++q) {
   1159             if (~family[q].queueFlags & VK_QUEUE_GRAPHICS_BIT) {
   1160                 continue;
   1161             }
   1162 
   1163             float const priorities[] = {0.0f};  // Temporary required due to MSVC bug.
   1164             VkDeviceQueueCreateInfo const queueInfo[1]{
   1165                 VK::DeviceQueueCreateInfo().queueFamilyIndex(q).queueCount(1).pQueuePriorities(priorities)};
   1166 
   1167             auto const deviceInfo = VK::DeviceCreateInfo().queueCreateInfoCount(1).pQueueCreateInfos(queueInfo);
   1168 
   1169             VkDevice device;
   1170             alloc_callbacks.pUserData = (void *)0x00000032;
   1171             result = vkCreateDevice(physical[p], deviceInfo, &alloc_callbacks, &device);
   1172             ASSERT_EQ(result, VK_SUCCESS);
   1173 
   1174             alloc_callbacks.pUserData = (void *)0x00000033;
   1175             vkDestroyDevice(device, &alloc_callbacks);
   1176         }
   1177     }
   1178 
   1179     alloc_callbacks.pUserData = (void *)0x00000034;
   1180     vkDestroyInstance(instance, &alloc_callbacks);
   1181 
   1182     // Make sure everything's been freed
   1183     ASSERT_EQ(true, IsAllocTrackerEmpty());
   1184     FreeAllocTracker();
   1185 }
   1186 
   1187 // Test making sure the allocation functions are called to allocate and cleanup everything from
   1188 // vkCreateInstance, to vkCreateDevicce, and then through their destructors.  With special
   1189 // allocators used on only the instance and not the device.
   1190 TEST(Allocation, InstanceButNotDevice) {
   1191     auto const info = VK::InstanceCreateInfo();
   1192     VkInstance instance = VK_NULL_HANDLE;
   1193     VkAllocationCallbacks alloc_callbacks = {};
   1194     alloc_callbacks.pUserData = (void *)0x00000041;
   1195     alloc_callbacks.pfnAllocation = AllocCallbackFunc;
   1196     alloc_callbacks.pfnReallocation = ReallocCallbackFunc;
   1197     alloc_callbacks.pfnFree = FreeCallbackFunc;
   1198 
   1199     InitAllocTracker(2048);
   1200 
   1201     VkResult result = vkCreateInstance(info, &alloc_callbacks, &instance);
   1202     ASSERT_EQ(result, VK_SUCCESS);
   1203 
   1204     uint32_t physicalCount = 0;
   1205     result = vkEnumeratePhysicalDevices(instance, &physicalCount, nullptr);
   1206     ASSERT_EQ(result, VK_SUCCESS);
   1207     ASSERT_GT(physicalCount, 0u);
   1208 
   1209     std::unique_ptr<VkPhysicalDevice[]> physical(new VkPhysicalDevice[physicalCount]);
   1210     result = vkEnumeratePhysicalDevices(instance, &physicalCount, physical.get());
   1211     ASSERT_EQ(result, VK_SUCCESS);
   1212     ASSERT_GT(physicalCount, 0u);
   1213 
   1214     for (uint32_t p = 0; p < physicalCount; ++p) {
   1215         uint32_t familyCount = 0;
   1216         vkGetPhysicalDeviceQueueFamilyProperties(physical[p], &familyCount, nullptr);
   1217         ASSERT_GT(familyCount, 0u);
   1218 
   1219         std::unique_ptr<VkQueueFamilyProperties[]> family(new VkQueueFamilyProperties[familyCount]);
   1220         vkGetPhysicalDeviceQueueFamilyProperties(physical[p], &familyCount, family.get());
   1221         ASSERT_GT(familyCount, 0u);
   1222 
   1223         for (uint32_t q = 0; q < familyCount; ++q) {
   1224             if (~family[q].queueFlags & VK_QUEUE_GRAPHICS_BIT) {
   1225                 continue;
   1226             }
   1227 
   1228             float const priorities[] = {0.0f};  // Temporary required due to MSVC bug.
   1229             VkDeviceQueueCreateInfo const queueInfo[1]{
   1230                 VK::DeviceQueueCreateInfo().queueFamilyIndex(q).queueCount(1).pQueuePriorities(priorities)};
   1231 
   1232             auto const deviceInfo = VK::DeviceCreateInfo().queueCreateInfoCount(1).pQueueCreateInfos(queueInfo);
   1233 
   1234             VkDevice device;
   1235             result = vkCreateDevice(physical[p], deviceInfo, NULL, &device);
   1236             ASSERT_EQ(result, VK_SUCCESS);
   1237 
   1238             vkDestroyDevice(device, NULL);
   1239         }
   1240     }
   1241 
   1242     alloc_callbacks.pUserData = (void *)0x00000042;
   1243     vkDestroyInstance(instance, &alloc_callbacks);
   1244 
   1245     // Make sure everything's been freed
   1246     ASSERT_EQ(true, IsAllocTrackerEmpty());
   1247     FreeAllocTracker();
   1248 }
   1249 
   1250 // Test making sure the allocation functions are called to allocate and cleanup everything from
   1251 // vkCreateInstance, to vkCreateDevicce, and then through their destructors.  With special
   1252 // allocators used on only the device and not the instance.
   1253 TEST(Allocation, DeviceButNotInstance) {
   1254     auto const info = VK::InstanceCreateInfo();
   1255     VkInstance instance = VK_NULL_HANDLE;
   1256     VkAllocationCallbacks alloc_callbacks = {};
   1257     alloc_callbacks.pfnAllocation = AllocCallbackFunc;
   1258     alloc_callbacks.pfnReallocation = ReallocCallbackFunc;
   1259     alloc_callbacks.pfnFree = FreeCallbackFunc;
   1260 
   1261     InitAllocTracker(2048);
   1262 
   1263     VkResult result = vkCreateInstance(info, NULL, &instance);
   1264     ASSERT_EQ(result, VK_SUCCESS);
   1265 
   1266     uint32_t physicalCount = 0;
   1267     result = vkEnumeratePhysicalDevices(instance, &physicalCount, nullptr);
   1268     ASSERT_EQ(result, VK_SUCCESS);
   1269     ASSERT_GT(physicalCount, 0u);
   1270 
   1271     std::unique_ptr<VkPhysicalDevice[]> physical(new VkPhysicalDevice[physicalCount]);
   1272     result = vkEnumeratePhysicalDevices(instance, &physicalCount, physical.get());
   1273     ASSERT_EQ(result, VK_SUCCESS);
   1274     ASSERT_GT(physicalCount, 0u);
   1275 
   1276     for (uint32_t p = 0; p < physicalCount; ++p) {
   1277         uint32_t familyCount = 0;
   1278         vkGetPhysicalDeviceQueueFamilyProperties(physical[p], &familyCount, nullptr);
   1279         ASSERT_GT(familyCount, 0u);
   1280 
   1281         std::unique_ptr<VkQueueFamilyProperties[]> family(new VkQueueFamilyProperties[familyCount]);
   1282         vkGetPhysicalDeviceQueueFamilyProperties(physical[p], &familyCount, family.get());
   1283         ASSERT_GT(familyCount, 0u);
   1284 
   1285         for (uint32_t q = 0; q < familyCount; ++q) {
   1286             if (~family[q].queueFlags & VK_QUEUE_GRAPHICS_BIT) {
   1287                 continue;
   1288             }
   1289 
   1290             float const priorities[] = {0.0f};  // Temporary required due to MSVC bug.
   1291             VkDeviceQueueCreateInfo const queueInfo[1]{
   1292                 VK::DeviceQueueCreateInfo().queueFamilyIndex(q).queueCount(1).pQueuePriorities(priorities)};
   1293 
   1294             auto const deviceInfo = VK::DeviceCreateInfo().queueCreateInfoCount(1).pQueueCreateInfos(queueInfo);
   1295 
   1296             VkDevice device;
   1297             alloc_callbacks.pUserData = (void *)0x00000051;
   1298             result = vkCreateDevice(physical[p], deviceInfo, &alloc_callbacks, &device);
   1299             ASSERT_EQ(result, VK_SUCCESS);
   1300 
   1301             alloc_callbacks.pUserData = (void *)0x00000052;
   1302             vkDestroyDevice(device, &alloc_callbacks);
   1303         }
   1304     }
   1305 
   1306     vkDestroyInstance(instance, NULL);
   1307 
   1308     // Make sure everything's been freed
   1309     ASSERT_EQ(true, IsAllocTrackerEmpty());
   1310     FreeAllocTracker();
   1311 }
   1312 
   1313 // Test failure during vkCreateInstance to make sure we don't leak memory if
   1314 // one of the out-of-memory conditions trigger.
   1315 TEST(Allocation, CreateInstanceIntentionalAllocFail) {
   1316     auto const info = VK::InstanceCreateInfo();
   1317     VkInstance instance = VK_NULL_HANDLE;
   1318     VkAllocationCallbacks alloc_callbacks = {};
   1319     alloc_callbacks.pfnAllocation = AllocCallbackFunc;
   1320     alloc_callbacks.pfnReallocation = ReallocCallbackFunc;
   1321     alloc_callbacks.pfnFree = FreeCallbackFunc;
   1322 
   1323     VkResult result;
   1324     uint32_t fail_index = 1;
   1325     do {
   1326         InitAllocTracker(9999, fail_index);
   1327 
   1328         result = vkCreateInstance(info, &alloc_callbacks, &instance);
   1329         if (result == VK_ERROR_OUT_OF_HOST_MEMORY) {
   1330             if (!IsAllocTrackerEmpty()) {
   1331                 std::cout << "Failed on index " << fail_index << '\n';
   1332                 ASSERT_EQ(true, IsAllocTrackerEmpty());
   1333             }
   1334         }
   1335         fail_index++;
   1336         // Make sure we don't overrun the memory
   1337         ASSERT_LT(fail_index, 9999u);
   1338 
   1339         FreeAllocTracker();
   1340     } while (result == VK_ERROR_OUT_OF_HOST_MEMORY);
   1341 
   1342     vkDestroyInstance(instance, &alloc_callbacks);
   1343 }
   1344 
   1345 // Test failure during vkCreateDevice to make sure we don't leak memory if
   1346 // one of the out-of-memory conditions trigger.
   1347 TEST(Allocation, CreateDeviceIntentionalAllocFail) {
   1348     auto const info = VK::InstanceCreateInfo();
   1349     VkInstance instance = VK_NULL_HANDLE;
   1350     VkDevice device = VK_NULL_HANDLE;
   1351     VkAllocationCallbacks alloc_callbacks = {};
   1352     alloc_callbacks.pfnAllocation = AllocCallbackFunc;
   1353     alloc_callbacks.pfnReallocation = ReallocCallbackFunc;
   1354     alloc_callbacks.pfnFree = FreeCallbackFunc;
   1355 
   1356     VkResult result = vkCreateInstance(info, NULL, &instance);
   1357     ASSERT_EQ(result, VK_SUCCESS);
   1358 
   1359     uint32_t physicalCount = 0;
   1360     result = vkEnumeratePhysicalDevices(instance, &physicalCount, nullptr);
   1361     ASSERT_EQ(result, VK_SUCCESS);
   1362     ASSERT_GT(physicalCount, 0u);
   1363 
   1364     std::unique_ptr<VkPhysicalDevice[]> physical(new VkPhysicalDevice[physicalCount]);
   1365     result = vkEnumeratePhysicalDevices(instance, &physicalCount, physical.get());
   1366     ASSERT_EQ(result, VK_SUCCESS);
   1367     ASSERT_GT(physicalCount, 0u);
   1368 
   1369     for (uint32_t p = 0; p < physicalCount; ++p) {
   1370         uint32_t familyCount = 0;
   1371         vkGetPhysicalDeviceQueueFamilyProperties(physical[p], &familyCount, nullptr);
   1372         ASSERT_GT(familyCount, 0u);
   1373 
   1374         std::unique_ptr<VkQueueFamilyProperties[]> family(new VkQueueFamilyProperties[familyCount]);
   1375         vkGetPhysicalDeviceQueueFamilyProperties(physical[p], &familyCount, family.get());
   1376         ASSERT_GT(familyCount, 0u);
   1377 
   1378         for (uint32_t q = 0; q < familyCount; ++q) {
   1379             if (~family[q].queueFlags & VK_QUEUE_GRAPHICS_BIT) {
   1380                 continue;
   1381             }
   1382 
   1383             float const priorities[] = {0.0f};  // Temporary required due to MSVC bug.
   1384             VkDeviceQueueCreateInfo const queueInfo[1]{
   1385                 VK::DeviceQueueCreateInfo().queueFamilyIndex(q).queueCount(1).pQueuePriorities(priorities)};
   1386 
   1387             auto const deviceInfo = VK::DeviceCreateInfo().queueCreateInfoCount(1).pQueueCreateInfos(queueInfo);
   1388 
   1389             uint32_t fail_index = 1;
   1390             do {
   1391                 InitAllocTracker(9999, fail_index);
   1392 
   1393                 result = vkCreateDevice(physical[p], deviceInfo, &alloc_callbacks, &device);
   1394                 if (result == VK_ERROR_OUT_OF_HOST_MEMORY) {
   1395                     if (!IsAllocTrackerEmpty()) {
   1396                         std::cout << "Failed on index " << fail_index << '\n';
   1397                         ASSERT_EQ(true, IsAllocTrackerEmpty());
   1398                     }
   1399                 }
   1400                 fail_index++;
   1401                 // Make sure we don't overrun the memory
   1402                 ASSERT_LT(fail_index, 9999u);
   1403 
   1404                 FreeAllocTracker();
   1405             } while (result == VK_ERROR_OUT_OF_HOST_MEMORY);
   1406             vkDestroyDevice(device, &alloc_callbacks);
   1407             break;
   1408         }
   1409     }
   1410 
   1411     vkDestroyInstance(instance, NULL);
   1412 }
   1413 
   1414 // Test failure during vkCreateInstance and vkCreateDevice to make sure we don't
   1415 // leak memory if one of the out-of-memory conditions trigger.
   1416 TEST(Allocation, CreateInstanceDeviceIntentionalAllocFail) {
   1417     auto const info = VK::InstanceCreateInfo();
   1418     VkInstance instance = VK_NULL_HANDLE;
   1419     VkDevice device = VK_NULL_HANDLE;
   1420     VkAllocationCallbacks alloc_callbacks = {};
   1421     alloc_callbacks.pfnAllocation = AllocCallbackFunc;
   1422     alloc_callbacks.pfnReallocation = ReallocCallbackFunc;
   1423     alloc_callbacks.pfnFree = FreeCallbackFunc;
   1424 
   1425     VkResult result = VK_ERROR_OUT_OF_HOST_MEMORY;
   1426     uint32_t fail_index = 0;
   1427     uint32_t physicalCount = 0;
   1428     while (result == VK_ERROR_OUT_OF_HOST_MEMORY) {
   1429         InitAllocTracker(9999, ++fail_index);
   1430         ASSERT_LT(fail_index, 9999u);
   1431 
   1432         result = vkCreateInstance(info, &alloc_callbacks, &instance);
   1433         if (result == VK_ERROR_OUT_OF_HOST_MEMORY) {
   1434             if (!IsAllocTrackerEmpty()) {
   1435                 std::cout << "Failed on index " << fail_index << '\n';
   1436                 ASSERT_EQ(true, IsAllocTrackerEmpty());
   1437             }
   1438             FreeAllocTracker();
   1439             continue;
   1440         }
   1441         ASSERT_EQ(result, VK_SUCCESS);
   1442 
   1443         physicalCount = 0;
   1444         result = vkEnumeratePhysicalDevices(instance, &physicalCount, nullptr);
   1445         if (result == VK_ERROR_OUT_OF_HOST_MEMORY) {
   1446             vkDestroyInstance(instance, &alloc_callbacks);
   1447             if (!IsAllocTrackerEmpty()) {
   1448                 std::cout << "Failed on index " << fail_index << '\n';
   1449                 ASSERT_EQ(true, IsAllocTrackerEmpty());
   1450             }
   1451             FreeAllocTracker();
   1452             continue;
   1453         }
   1454         ASSERT_EQ(result, VK_SUCCESS);
   1455 
   1456         std::unique_ptr<VkPhysicalDevice[]> physical(new VkPhysicalDevice[physicalCount]);
   1457         result = vkEnumeratePhysicalDevices(instance, &physicalCount, physical.get());
   1458         if (result == VK_ERROR_OUT_OF_HOST_MEMORY) {
   1459             vkDestroyInstance(instance, &alloc_callbacks);
   1460             if (!IsAllocTrackerEmpty()) {
   1461                 std::cout << "Failed on index " << fail_index << '\n';
   1462                 ASSERT_EQ(true, IsAllocTrackerEmpty());
   1463             }
   1464             FreeAllocTracker();
   1465             continue;
   1466         }
   1467         ASSERT_EQ(result, VK_SUCCESS);
   1468 
   1469         uint32_t familyCount = 0;
   1470         vkGetPhysicalDeviceQueueFamilyProperties(physical[0], &familyCount, nullptr);
   1471         ASSERT_GT(familyCount, 0u);
   1472 
   1473         std::unique_ptr<VkQueueFamilyProperties[]> family(new VkQueueFamilyProperties[familyCount]);
   1474         vkGetPhysicalDeviceQueueFamilyProperties(physical[0], &familyCount, family.get());
   1475         ASSERT_GT(familyCount, 0u);
   1476 
   1477         uint32_t queue_index = 0;
   1478         for (uint32_t q = 0; q < familyCount; ++q) {
   1479             if (family[q].queueFlags & VK_QUEUE_GRAPHICS_BIT) {
   1480                 queue_index = q;
   1481                 break;
   1482             }
   1483         }
   1484 
   1485         float const priorities[] = {0.0f};  // Temporary required due to MSVC bug.
   1486         VkDeviceQueueCreateInfo const queueInfo[1]{
   1487             VK::DeviceQueueCreateInfo().queueFamilyIndex(queue_index).queueCount(1).pQueuePriorities(priorities)};
   1488 
   1489         auto const deviceInfo = VK::DeviceCreateInfo().queueCreateInfoCount(1).pQueueCreateInfos(queueInfo);
   1490 
   1491         result = vkCreateDevice(physical[0], deviceInfo, &alloc_callbacks, &device);
   1492         if (result == VK_ERROR_OUT_OF_HOST_MEMORY) {
   1493             vkDestroyInstance(instance, &alloc_callbacks);
   1494             if (!IsAllocTrackerEmpty()) {
   1495                 std::cout << "Failed on index " << fail_index << '\n';
   1496                 ASSERT_EQ(true, IsAllocTrackerEmpty());
   1497             }
   1498             FreeAllocTracker();
   1499             continue;
   1500         }
   1501         vkDestroyDevice(device, &alloc_callbacks);
   1502         vkDestroyInstance(instance, &alloc_callbacks);
   1503         FreeAllocTracker();
   1504     }
   1505 }
   1506 
   1507 // Used by run_loader_tests.sh to test that calling vkEnumeratePhysicalDeviceGroupsKHX without first querying
   1508 // the count, works.  And, that it also returns only physical devices made available by the standard
   1509 // enumerate call
   1510 TEST(EnumeratePhysicalDeviceGroupsKHX, OneCall) {
   1511     VkInstance instance = VK_NULL_HANDLE;
   1512     char const *const names[] = {VK_KHX_DEVICE_GROUP_CREATION_EXTENSION_NAME};
   1513     auto const info = VK::InstanceCreateInfo().enabledExtensionCount(1).ppEnabledExtensionNames(names);
   1514     uint32_t group;
   1515     uint32_t dev;
   1516     std::vector<std::pair<VkPhysicalDevice, bool>> phys_dev_normal_found;
   1517     std::vector<std::pair<VkPhysicalDevice, bool>> phys_dev_group_found;
   1518 
   1519     VkResult result = vkCreateInstance(info, VK_NULL_HANDLE, &instance);
   1520     if (result == VK_ERROR_EXTENSION_NOT_PRESENT) {
   1521         // Extension isn't present, just skip this test
   1522         ASSERT_EQ(result, VK_ERROR_EXTENSION_NOT_PRESENT);
   1523         std::cout << "Skipping EnumeratePhysicalDeviceGroupsKHX : OneCall due to Instance lacking support"
   1524                   << " for " << VK_KHX_DEVICE_GROUP_CREATION_EXTENSION_NAME << " extension\n";
   1525         return;
   1526     }
   1527 
   1528     uint32_t phys_dev_count = 500;
   1529     std::unique_ptr<VkPhysicalDevice[]> phys_devs(new VkPhysicalDevice[phys_dev_count]);
   1530     result = vkEnumeratePhysicalDevices(instance, &phys_dev_count, phys_devs.get());
   1531     ASSERT_EQ(result, VK_SUCCESS);
   1532     ASSERT_GT(phys_dev_count, 0u);
   1533 
   1534     // Initialize the normal physical device boolean pair array
   1535     for (dev = 0; dev < phys_dev_count; dev++) {
   1536         phys_dev_normal_found.push_back(std::make_pair(phys_devs[dev], false));
   1537     }
   1538 
   1539     // Get a pointer to the new vkEnumeratePhysicalDeviceGroupsKHX call
   1540     PFN_vkEnumeratePhysicalDeviceGroupsKHX p_vkEnumeratePhysicalDeviceGroupsKHX =
   1541         (PFN_vkEnumeratePhysicalDeviceGroupsKHX)vkGetInstanceProcAddr(instance, "vkEnumeratePhysicalDeviceGroupsKHX");
   1542 
   1543     // Setup the group information in preparation for the call
   1544     uint32_t group_count = 30;
   1545     std::unique_ptr<VkPhysicalDeviceGroupPropertiesKHX[]> phys_dev_groups(new VkPhysicalDeviceGroupPropertiesKHX[group_count]);
   1546     for (group = 0; group < group_count; group++) {
   1547         phys_dev_groups[group].sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_GROUP_PROPERTIES_KHX;
   1548         phys_dev_groups[group].pNext = nullptr;
   1549         phys_dev_groups[group].physicalDeviceCount = 0;
   1550         memset(phys_dev_groups[group].physicalDevices, 0, sizeof(VkPhysicalDevice) * VK_MAX_DEVICE_GROUP_SIZE_KHX);
   1551         phys_dev_groups[group].subsetAllocation = VK_FALSE;
   1552     }
   1553 
   1554     result = p_vkEnumeratePhysicalDeviceGroupsKHX(instance, &group_count, phys_dev_groups.get());
   1555     ASSERT_EQ(result, VK_SUCCESS);
   1556     ASSERT_GT(group_count, 0u);
   1557 
   1558     // Initialize the group physical device boolean pair array
   1559     for (group = 0; group < group_count; group++) {
   1560         for (dev = 0; dev < phys_dev_groups[group].physicalDeviceCount; dev++) {
   1561             phys_dev_group_found.push_back(std::make_pair(phys_dev_groups[group].physicalDevices[dev], false));
   1562         }
   1563     }
   1564 
   1565     // Now, make sure we can find each normal and group item in the other list
   1566     for (dev = 0; dev < phys_dev_count; dev++) {
   1567         for (group = 0; group < phys_dev_group_found.size(); group++) {
   1568             if (phys_dev_normal_found[dev].first == phys_dev_group_found[group].first) {
   1569                 phys_dev_normal_found[dev].second = true;
   1570                 phys_dev_group_found[group].second = true;
   1571                 break;
   1572             }
   1573         }
   1574     }
   1575 
   1576     for (dev = 0; dev < phys_dev_count; dev++) {
   1577         ASSERT_EQ(phys_dev_normal_found[dev].second, true);
   1578     }
   1579     for (dev = 0; dev < phys_dev_group_found.size(); dev++) {
   1580         ASSERT_EQ(phys_dev_group_found[dev].second, true);
   1581     }
   1582 
   1583     vkDestroyInstance(instance, nullptr);
   1584 }
   1585 
   1586 // Used by run_loader_tests.sh to test for the expected usage of the
   1587 // vkEnumeratePhysicalDeviceGroupsKHX call in a two call fasion (once with NULL data
   1588 // to get count, and then again with data).
   1589 TEST(EnumeratePhysicalDeviceGroupsKHX, TwoCall) {
   1590     VkInstance instance = VK_NULL_HANDLE;
   1591     char const *const names[] = {VK_KHX_DEVICE_GROUP_CREATION_EXTENSION_NAME};
   1592     auto const info = VK::InstanceCreateInfo().enabledExtensionCount(1).ppEnabledExtensionNames(names);
   1593     uint32_t group;
   1594     uint32_t group_count;
   1595     uint32_t dev;
   1596     std::vector<std::pair<VkPhysicalDevice, bool>> phys_dev_normal_found;
   1597     std::vector<std::pair<VkPhysicalDevice, bool>> phys_dev_group_found;
   1598 
   1599     VkResult result = vkCreateInstance(info, VK_NULL_HANDLE, &instance);
   1600     if (result == VK_ERROR_EXTENSION_NOT_PRESENT) {
   1601         // Extension isn't present, just skip this test
   1602         ASSERT_EQ(result, VK_ERROR_EXTENSION_NOT_PRESENT);
   1603         std::cout << "Skipping EnumeratePhysicalDeviceGroupsKHX : TwoCall due to Instance lacking support"
   1604                   << " for " << VK_KHX_DEVICE_GROUP_CREATION_EXTENSION_NAME << " extension\n";
   1605         return;
   1606     }
   1607 
   1608     // Get a pointer to the new vkEnumeratePhysicalDeviceGroupsKHX call
   1609     PFN_vkEnumeratePhysicalDeviceGroupsKHX p_vkEnumeratePhysicalDeviceGroupsKHX =
   1610         (PFN_vkEnumeratePhysicalDeviceGroupsKHX)vkGetInstanceProcAddr(instance, "vkEnumeratePhysicalDeviceGroupsKHX");
   1611 
   1612     // Setup the group information in preparation for the call
   1613     uint32_t array_group_count = 30;
   1614     std::unique_ptr<VkPhysicalDeviceGroupPropertiesKHX[]> phys_dev_groups(
   1615         new VkPhysicalDeviceGroupPropertiesKHX[array_group_count]);
   1616     for (group = 0; group < array_group_count; group++) {
   1617         phys_dev_groups[group].sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_GROUP_PROPERTIES_KHX;
   1618         phys_dev_groups[group].pNext = nullptr;
   1619         phys_dev_groups[group].physicalDeviceCount = 0;
   1620         memset(phys_dev_groups[group].physicalDevices, 0, sizeof(VkPhysicalDevice) * VK_MAX_DEVICE_GROUP_SIZE_KHX);
   1621         phys_dev_groups[group].subsetAllocation = VK_FALSE;
   1622     }
   1623 
   1624     result = p_vkEnumeratePhysicalDeviceGroupsKHX(instance, &group_count, nullptr);
   1625     ASSERT_EQ(result, VK_SUCCESS);
   1626     ASSERT_GT(group_count, 0u);
   1627     ASSERT_LT(group_count, array_group_count);
   1628 
   1629     result = p_vkEnumeratePhysicalDeviceGroupsKHX(instance, &group_count, phys_dev_groups.get());
   1630     ASSERT_EQ(result, VK_SUCCESS);
   1631     ASSERT_GT(group_count, 0u);
   1632     ASSERT_LT(group_count, array_group_count);
   1633 
   1634     // Initialize the group physical device boolean pair array
   1635     for (group = 0; group < group_count; group++) {
   1636         for (dev = 0; dev < phys_dev_groups[group].physicalDeviceCount; dev++) {
   1637             phys_dev_group_found.push_back(std::make_pair(phys_dev_groups[group].physicalDevices[dev], false));
   1638         }
   1639     }
   1640 
   1641     uint32_t phys_dev_count = 500;
   1642     std::unique_ptr<VkPhysicalDevice[]> phys_devs(new VkPhysicalDevice[phys_dev_count]);
   1643     result = vkEnumeratePhysicalDevices(instance, &phys_dev_count, phys_devs.get());
   1644     ASSERT_EQ(result, VK_SUCCESS);
   1645     ASSERT_GT(phys_dev_count, 0u);
   1646 
   1647     // Initialize the normal physical device boolean pair array
   1648     for (dev = 0; dev < phys_dev_count; dev++) {
   1649         phys_dev_normal_found.push_back(std::make_pair(phys_devs[dev], false));
   1650     }
   1651 
   1652     // Now, make sure we can find each normal and group item in the other list
   1653     for (dev = 0; dev < phys_dev_count; dev++) {
   1654         for (group = 0; group < phys_dev_group_found.size(); group++) {
   1655             if (phys_dev_normal_found[dev].first == phys_dev_group_found[group].first) {
   1656                 phys_dev_normal_found[dev].second = true;
   1657                 phys_dev_group_found[group].second = true;
   1658                 break;
   1659             }
   1660         }
   1661     }
   1662 
   1663     for (dev = 0; dev < phys_dev_count; dev++) {
   1664         ASSERT_EQ(phys_dev_normal_found[dev].second, true);
   1665     }
   1666     for (dev = 0; dev < phys_dev_group_found.size(); dev++) {
   1667         ASSERT_EQ(phys_dev_group_found[dev].second, true);
   1668     }
   1669 
   1670     vkDestroyInstance(instance, nullptr);
   1671 }
   1672 
   1673 // Used by run_loader_tests.sh to test for the expected usage of the EnumeratePhysicalDeviceGroupsKHX
   1674 // call if not enough numbers are provided for the final list.
   1675 TEST(EnumeratePhysicalDeviceGroupsKHX, TwoCallIncomplete) {
   1676     VkInstance instance = VK_NULL_HANDLE;
   1677     char const *const names[] = {VK_KHX_DEVICE_GROUP_CREATION_EXTENSION_NAME};
   1678     auto const info = VK::InstanceCreateInfo().enabledExtensionCount(1).ppEnabledExtensionNames(names);
   1679     uint32_t group;
   1680     uint32_t group_count;
   1681 
   1682     VkResult result = vkCreateInstance(info, VK_NULL_HANDLE, &instance);
   1683     if (result == VK_ERROR_EXTENSION_NOT_PRESENT) {
   1684         // Extension isn't present, just skip this test
   1685         ASSERT_EQ(result, VK_ERROR_EXTENSION_NOT_PRESENT);
   1686         std::cout << "Skipping EnumeratePhysicalDeviceGroupsKHX : TwoCallIncomplete due to Instance lacking support"
   1687                   << " for " << VK_KHX_DEVICE_GROUP_CREATION_EXTENSION_NAME << " extension\n";
   1688         return;
   1689     }
   1690 
   1691     // Get a pointer to the new vkEnumeratePhysicalDeviceGroupsKHX call
   1692     PFN_vkEnumeratePhysicalDeviceGroupsKHX p_vkEnumeratePhysicalDeviceGroupsKHX =
   1693         (PFN_vkEnumeratePhysicalDeviceGroupsKHX)vkGetInstanceProcAddr(instance, "vkEnumeratePhysicalDeviceGroupsKHX");
   1694 
   1695     // Setup the group information in preparation for the call
   1696     uint32_t array_group_count = 30;
   1697     std::unique_ptr<VkPhysicalDeviceGroupPropertiesKHX[]> phys_dev_groups(
   1698         new VkPhysicalDeviceGroupPropertiesKHX[array_group_count]);
   1699     for (group = 0; group < array_group_count; group++) {
   1700         phys_dev_groups[group].sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_GROUP_PROPERTIES_KHX;
   1701         phys_dev_groups[group].pNext = nullptr;
   1702         phys_dev_groups[group].physicalDeviceCount = 0;
   1703         memset(phys_dev_groups[group].physicalDevices, 0, sizeof(VkPhysicalDevice) * VK_MAX_DEVICE_GROUP_SIZE_KHX);
   1704         phys_dev_groups[group].subsetAllocation = VK_FALSE;
   1705     }
   1706 
   1707     result = p_vkEnumeratePhysicalDeviceGroupsKHX(instance, &group_count, nullptr);
   1708     ASSERT_EQ(result, VK_SUCCESS);
   1709     ASSERT_GT(group_count, 0u);
   1710     ASSERT_LT(group_count, array_group_count);
   1711 
   1712     group_count -= 1;
   1713 
   1714     result = p_vkEnumeratePhysicalDeviceGroupsKHX(instance, &group_count, phys_dev_groups.get());
   1715     ASSERT_EQ(result, VK_INCOMPLETE);
   1716 
   1717     vkDestroyInstance(instance, nullptr);
   1718 }
   1719 
   1720 int main(int argc, char **argv) {
   1721     int result;
   1722 
   1723     ::testing::InitGoogleTest(&argc, argv);
   1724 
   1725     if (argc > 0) {
   1726         CommandLine::Initialize(argc, argv);
   1727     }
   1728 
   1729     result = RUN_ALL_TESTS();
   1730 
   1731     return result;
   1732 }
   1733