Home | History | Annotate | Download | only in tests
      1 /*
      2  * Copyright (c) 2015-2016 The Khronos Group Inc.
      3  * Copyright (c) 2015-2016 Valve Corporation
      4  * Copyright (c) 2015-2016 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  */
     27 
     28 #include <algorithm>
     29 #include <iostream>
     30 #include <memory>
     31 #include <string>
     32 #include <vector>
     33 
     34 #include "test_common.h"
     35 #include <vulkan/vulkan.h>
     36 
     37 namespace VK {
     38 
     39 struct InstanceCreateInfo {
     40     InstanceCreateInfo()
     41         : info // MSVC can't handle list initialization, thus explicit construction herein.
     42           (VkInstanceCreateInfo{
     43               VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO, // sType
     44               nullptr,                                // pNext
     45               0,                                      // flags
     46               nullptr,                                // pApplicationInfo
     47               0,                                      // enabledLayerCount
     48               nullptr,                                // ppEnabledLayerNames
     49               0,                                      // enabledExtensionCount
     50               nullptr                                 // ppEnabledExtensionNames
     51           }) {}
     52 
     53     InstanceCreateInfo &sType(VkStructureType const &sType) {
     54         info.sType = sType;
     55 
     56         return *this;
     57     }
     58 
     59     InstanceCreateInfo &pNext(void const *const pNext) {
     60         info.pNext = pNext;
     61 
     62         return *this;
     63     }
     64 
     65     InstanceCreateInfo &flags(VkInstanceCreateFlags const &flags) {
     66         info.flags = flags;
     67 
     68         return *this;
     69     }
     70 
     71     InstanceCreateInfo &pApplicationInfo(VkApplicationInfo const *const pApplicationInfo) {
     72         info.pApplicationInfo = pApplicationInfo;
     73 
     74         return *this;
     75     }
     76 
     77     InstanceCreateInfo &enabledLayerCount(uint32_t const &enabledLayerCount) {
     78         info.enabledLayerCount = enabledLayerCount;
     79 
     80         return *this;
     81     }
     82 
     83     InstanceCreateInfo &ppEnabledLayerNames(char const *const *const ppEnabledLayerNames) {
     84         info.ppEnabledLayerNames = ppEnabledLayerNames;
     85 
     86         return *this;
     87     }
     88 
     89     InstanceCreateInfo &enabledExtensionCount(uint32_t const &enabledExtensionCount) {
     90         info.enabledExtensionCount = enabledExtensionCount;
     91 
     92         return *this;
     93     }
     94 
     95     InstanceCreateInfo &ppEnabledExtensionNames(char const *const *const ppEnabledExtensionNames) {
     96         info.ppEnabledExtensionNames = ppEnabledExtensionNames;
     97 
     98         return *this;
     99     }
    100 
    101     operator VkInstanceCreateInfo const *() const { return &info; }
    102 
    103     operator VkInstanceCreateInfo *() { return &info; }
    104 
    105     VkInstanceCreateInfo info;
    106 };
    107 
    108 struct DeviceQueueCreateInfo {
    109     DeviceQueueCreateInfo()
    110         : info // MSVC can't handle list initialization, thus explicit construction herein.
    111           (VkDeviceQueueCreateInfo{
    112               VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO, // sType
    113               nullptr,                                    // pNext
    114               0,                                          // flags
    115               0,                                          // queueFamilyIndex
    116               0,                                          // queueCount
    117               nullptr                                     // pQueuePriorities
    118           }) {}
    119 
    120     DeviceQueueCreateInfo &sType(VkStructureType const &sType) {
    121         info.sType = sType;
    122 
    123         return *this;
    124     }
    125 
    126     DeviceQueueCreateInfo &pNext(void const *const pNext) {
    127         info.pNext = pNext;
    128 
    129         return *this;
    130     }
    131 
    132     DeviceQueueCreateInfo &flags(VkDeviceQueueCreateFlags const &flags) {
    133         info.flags = flags;
    134 
    135         return *this;
    136     }
    137 
    138     DeviceQueueCreateInfo &queueFamilyIndex(uint32_t const &queueFamilyIndex) {
    139         info.queueFamilyIndex = queueFamilyIndex;
    140 
    141         return *this;
    142     }
    143 
    144     DeviceQueueCreateInfo &queueCount(uint32_t const &queueCount) {
    145         info.queueCount = queueCount;
    146 
    147         return *this;
    148     }
    149 
    150     DeviceQueueCreateInfo &pQueuePriorities(float const *const pQueuePriorities) {
    151         info.pQueuePriorities = pQueuePriorities;
    152 
    153         return *this;
    154     }
    155 
    156     operator VkDeviceQueueCreateInfo() { return info; }
    157 
    158     VkDeviceQueueCreateInfo info;
    159 };
    160 
    161 struct DeviceCreateInfo {
    162     DeviceCreateInfo()
    163         : info // MSVC can't handle list initialization, thus explicit construction herein.
    164           (VkDeviceCreateInfo{
    165               VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO, // sType
    166               nullptr,                              // pNext
    167               0,                                    // flags
    168               0,                                    // queueCreateInfoCount
    169               nullptr,                              // pQueueCreateInfos
    170               0,                                    // enabledLayerCount
    171               nullptr,                              // ppEnabledLayerNames
    172               0,                                    // enabledExtensionCount
    173               nullptr,                              // ppEnabledExtensionNames
    174               nullptr                               // pEnabledFeatures
    175           }) {}
    176 
    177     DeviceCreateInfo &sType(VkStructureType const &sType) {
    178         info.sType = sType;
    179 
    180         return *this;
    181     }
    182 
    183     DeviceCreateInfo &pNext(void const *const pNext) {
    184         info.pNext = pNext;
    185 
    186         return *this;
    187     }
    188 
    189     DeviceCreateInfo &flags(VkDeviceQueueCreateFlags const &flags) {
    190         info.flags = flags;
    191 
    192         return *this;
    193     }
    194 
    195     DeviceCreateInfo &queueCreateInfoCount(uint32_t const &queueCreateInfoCount) {
    196         info.queueCreateInfoCount = queueCreateInfoCount;
    197 
    198         return *this;
    199     }
    200 
    201     DeviceCreateInfo &pQueueCreateInfos(VkDeviceQueueCreateInfo const *const pQueueCreateInfos) {
    202         info.pQueueCreateInfos = pQueueCreateInfos;
    203 
    204         return *this;
    205     }
    206 
    207     DeviceCreateInfo &enabledLayerCount(uint32_t const &enabledLayerCount) {
    208         info.enabledLayerCount = enabledLayerCount;
    209 
    210         return *this;
    211     }
    212 
    213     DeviceCreateInfo &ppEnabledLayerNames(char const *const *const ppEnabledLayerNames) {
    214         info.ppEnabledLayerNames = ppEnabledLayerNames;
    215 
    216         return *this;
    217     }
    218 
    219     DeviceCreateInfo &enabledExtensionCount(uint32_t const &enabledExtensionCount) {
    220         info.enabledExtensionCount = enabledExtensionCount;
    221 
    222         return *this;
    223     }
    224 
    225     DeviceCreateInfo &ppEnabledExtensionNames(char const *const *const ppEnabledExtensionNames) {
    226         info.ppEnabledExtensionNames = ppEnabledExtensionNames;
    227 
    228         return *this;
    229     }
    230 
    231     DeviceCreateInfo &pEnabledFeatures(VkPhysicalDeviceFeatures const *const pEnabledFeatures) {
    232         info.pEnabledFeatures = pEnabledFeatures;
    233 
    234         return *this;
    235     }
    236 
    237     operator VkDeviceCreateInfo const *() const { return &info; }
    238 
    239     operator VkDeviceCreateInfo *() { return &info; }
    240 
    241     VkDeviceCreateInfo info;
    242 };
    243 }
    244 
    245 struct CommandLine : public ::testing::Test {
    246     static void Initialize(int argc, char **argv) { arguments.assign(argv, argv + argc); };
    247 
    248     static void SetUpTestCase(){};
    249     static void TearDownTestCase(){};
    250 
    251     static std::vector<std::string> arguments;
    252 };
    253 std::vector<std::string> CommandLine::arguments;
    254 
    255 struct EnumerateInstanceLayerProperties : public CommandLine {};
    256 struct EnumerateInstanceExtensionProperties : public CommandLine {};
    257 struct ImplicitLayer : public CommandLine {};
    258 
    259 // Test groups:
    260 // LX = lunar exchange
    261 // LVLGH = loader and validation github
    262 // LVLGL = lodaer and validation gitlab
    263 
    264 TEST(LX435, InstanceCreateInfoConst) {
    265     VkInstanceCreateInfo const info = {VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO, nullptr, 0, nullptr, 0, nullptr, 0, nullptr};
    266 
    267     VkInstance instance = VK_NULL_HANDLE;
    268     VkResult result = vkCreateInstance(&info, VK_NULL_HANDLE, &instance);
    269     EXPECT_EQ(result, VK_SUCCESS);
    270 
    271     vkDestroyInstance(instance, nullptr);
    272 }
    273 
    274 TEST(LX475, DestroyInstanceNullHandle) { vkDestroyInstance(VK_NULL_HANDLE, nullptr); }
    275 
    276 TEST(LX475, DestroyDeviceNullHandle) { vkDestroyDevice(VK_NULL_HANDLE, nullptr); }
    277 
    278 TEST(CreateInstance, ExtensionNotPresent) {
    279     char const *const names[] = {"NotPresent"}; // Temporary required due to MSVC bug.
    280     auto const info = VK::InstanceCreateInfo().enabledExtensionCount(1).ppEnabledExtensionNames(names);
    281 
    282     VkInstance instance = VK_NULL_HANDLE;
    283     VkResult result = vkCreateInstance(info, VK_NULL_HANDLE, &instance);
    284     ASSERT_EQ(result, VK_ERROR_EXTENSION_NOT_PRESENT);
    285 
    286     // It's not necessary to destroy the instance because it will not be created successfully.
    287 }
    288 
    289 TEST(CreateInstance, LayerNotPresent) {
    290     char const *const names[] = {"NotPresent"}; // Temporary required due to MSVC bug.
    291     auto const info = VK::InstanceCreateInfo().enabledLayerCount(1).ppEnabledLayerNames(names);
    292 
    293     VkInstance instance = VK_NULL_HANDLE;
    294     VkResult result = vkCreateInstance(info, VK_NULL_HANDLE, &instance);
    295     ASSERT_EQ(result, VK_ERROR_LAYER_NOT_PRESENT);
    296 
    297     // It's not necessary to destroy the instance because it will not be created successfully.
    298 }
    299 
    300 // Used by run_loader_tests.sh to test for layer insertion.
    301 TEST(CreateInstance, LayerPresent) {
    302     char const *const names[] = {"VK_LAYER_LUNARG_parameter_validation"}; // Temporary required due to MSVC bug.
    303     auto const info = VK::InstanceCreateInfo().enabledLayerCount(1).ppEnabledLayerNames(names);
    304 
    305     VkInstance instance = VK_NULL_HANDLE;
    306     VkResult result = vkCreateInstance(info, VK_NULL_HANDLE, &instance);
    307     ASSERT_EQ(result, VK_SUCCESS);
    308 
    309     vkDestroyInstance(instance, nullptr);
    310 }
    311 
    312 TEST(CreateDevice, ExtensionNotPresent) {
    313     VkInstance instance = VK_NULL_HANDLE;
    314     VkResult result = vkCreateInstance(VK::InstanceCreateInfo(), VK_NULL_HANDLE, &instance);
    315     ASSERT_EQ(result, VK_SUCCESS);
    316 
    317     uint32_t physicalCount = 0;
    318     result = vkEnumeratePhysicalDevices(instance, &physicalCount, nullptr);
    319     ASSERT_EQ(result, VK_SUCCESS);
    320     ASSERT_GT(physicalCount, 0u);
    321 
    322     std::unique_ptr<VkPhysicalDevice[]> physical(new VkPhysicalDevice[physicalCount]);
    323     result = vkEnumeratePhysicalDevices(instance, &physicalCount, physical.get());
    324     ASSERT_EQ(result, VK_SUCCESS);
    325     ASSERT_GT(physicalCount, 0u);
    326 
    327     for (uint32_t p = 0; p < physicalCount; ++p) {
    328         uint32_t familyCount = 0;
    329         vkGetPhysicalDeviceQueueFamilyProperties(physical[p], &familyCount, nullptr);
    330         ASSERT_EQ(result, VK_SUCCESS);
    331         ASSERT_GT(familyCount, 0u);
    332 
    333         std::unique_ptr<VkQueueFamilyProperties[]> family(new VkQueueFamilyProperties[familyCount]);
    334         vkGetPhysicalDeviceQueueFamilyProperties(physical[p], &familyCount, family.get());
    335         ASSERT_EQ(result, VK_SUCCESS);
    336         ASSERT_GT(familyCount, 0u);
    337 
    338         for (uint32_t q = 0; q < familyCount; ++q) {
    339             if (~family[q].queueFlags & VK_QUEUE_GRAPHICS_BIT) {
    340                 continue;
    341             }
    342 
    343             float const priorities[] = {0.0f}; // Temporary required due to MSVC bug.
    344             VkDeviceQueueCreateInfo const queueInfo[1]{
    345                 VK::DeviceQueueCreateInfo().queueFamilyIndex(q).queueCount(1).pQueuePriorities(priorities)};
    346 
    347             char const *const names[] = {"NotPresent"}; // Temporary required due to MSVC bug.
    348             auto const deviceInfo = VK::DeviceCreateInfo()
    349                                         .queueCreateInfoCount(1)
    350                                         .pQueueCreateInfos(queueInfo)
    351                                         .enabledExtensionCount(1)
    352                                         .ppEnabledExtensionNames(names);
    353 
    354             VkDevice device;
    355             result = vkCreateDevice(physical[p], deviceInfo, nullptr, &device);
    356             ASSERT_EQ(result, VK_ERROR_EXTENSION_NOT_PRESENT);
    357 
    358             // It's not necessary to destroy the device because it will not be created successfully.
    359         }
    360     }
    361 
    362     vkDestroyInstance(instance, nullptr);
    363 }
    364 
    365 // LX535 / MI-76: Device layers are deprecated.
    366 // For backwards compatibility, they are allowed, but must be ignored.
    367 // Ensure that no errors occur if a bogus device layer list is passed to vkCreateDevice.
    368 TEST(CreateDevice, LayersNotPresent) {
    369     VkInstance instance = VK_NULL_HANDLE;
    370     VkResult result = vkCreateInstance(VK::InstanceCreateInfo(), VK_NULL_HANDLE, &instance);
    371     ASSERT_EQ(result, VK_SUCCESS);
    372 
    373     uint32_t physicalCount = 0;
    374     result = vkEnumeratePhysicalDevices(instance, &physicalCount, nullptr);
    375     ASSERT_EQ(result, VK_SUCCESS);
    376     ASSERT_GT(physicalCount, 0u);
    377 
    378     std::unique_ptr<VkPhysicalDevice[]> physical(new VkPhysicalDevice[physicalCount]);
    379     result = vkEnumeratePhysicalDevices(instance, &physicalCount, physical.get());
    380     ASSERT_EQ(result, VK_SUCCESS);
    381     ASSERT_GT(physicalCount, 0u);
    382 
    383     for (uint32_t p = 0; p < physicalCount; ++p) {
    384         uint32_t familyCount = 0;
    385         vkGetPhysicalDeviceQueueFamilyProperties(physical[p], &familyCount, nullptr);
    386         ASSERT_EQ(result, VK_SUCCESS);
    387         ASSERT_GT(familyCount, 0u);
    388 
    389         std::unique_ptr<VkQueueFamilyProperties[]> family(new VkQueueFamilyProperties[familyCount]);
    390         vkGetPhysicalDeviceQueueFamilyProperties(physical[p], &familyCount, family.get());
    391         ASSERT_EQ(result, VK_SUCCESS);
    392         ASSERT_GT(familyCount, 0u);
    393 
    394         for (uint32_t q = 0; q < familyCount; ++q) {
    395             if (~family[q].queueFlags & VK_QUEUE_GRAPHICS_BIT) {
    396                 continue;
    397             }
    398 
    399             float const priorities[] = {0.0f}; // Temporary required due to MSVC bug.
    400             VkDeviceQueueCreateInfo const queueInfo[1]{
    401                 VK::DeviceQueueCreateInfo().queueFamilyIndex(q).queueCount(1).pQueuePriorities(priorities)};
    402 
    403             char const *const names[] = {"NotPresent"}; // Temporary required due to MSVC bug.
    404             auto const deviceInfo = VK::DeviceCreateInfo()
    405                                         .queueCreateInfoCount(1)
    406                                         .pQueueCreateInfos(queueInfo)
    407                                         .enabledLayerCount(1)
    408                                         .ppEnabledLayerNames(names);
    409 
    410             VkDevice device;
    411             result = vkCreateDevice(physical[p], deviceInfo, nullptr, &device);
    412             ASSERT_EQ(result, VK_SUCCESS);
    413 
    414             vkDestroyDevice(device, nullptr);
    415         }
    416     }
    417 
    418     vkDestroyInstance(instance, nullptr);
    419 }
    420 
    421 TEST_F(EnumerateInstanceLayerProperties, PropertyCountLessThanAvailable) {
    422     uint32_t count = 0u;
    423     VkResult result = vkEnumerateInstanceLayerProperties(&count, nullptr);
    424     ASSERT_EQ(result, VK_SUCCESS);
    425 
    426     // We need atleast two for the test to be relevant.
    427     if (count < 2u) {
    428         return;
    429     }
    430 
    431     std::unique_ptr<VkLayerProperties[]> properties(new VkLayerProperties[count]);
    432     count = 1;
    433     result = vkEnumerateInstanceLayerProperties(&count, properties.get());
    434     ASSERT_EQ(result, VK_INCOMPLETE);
    435 }
    436 
    437 TEST(EnumerateDeviceLayerProperties, PropertyCountLessThanAvailable) {
    438     VkInstance instance = VK_NULL_HANDLE;
    439     VkResult result = vkCreateInstance(VK::InstanceCreateInfo(), VK_NULL_HANDLE, &instance);
    440     ASSERT_EQ(result, VK_SUCCESS);
    441 
    442     uint32_t physicalCount = 0;
    443     result = vkEnumeratePhysicalDevices(instance, &physicalCount, nullptr);
    444     ASSERT_EQ(result, VK_SUCCESS);
    445     ASSERT_GT(physicalCount, 0u);
    446 
    447     std::unique_ptr<VkPhysicalDevice[]> physical(new VkPhysicalDevice[physicalCount]);
    448     result = vkEnumeratePhysicalDevices(instance, &physicalCount, physical.get());
    449     ASSERT_EQ(result, VK_SUCCESS);
    450     ASSERT_GT(physicalCount, 0u);
    451 
    452     for (uint32_t p = 0; p < physicalCount; ++p) {
    453         uint32_t count = 0u;
    454         result = vkEnumerateDeviceLayerProperties(physical[p], &count, nullptr);
    455         ASSERT_EQ(result, VK_SUCCESS);
    456 
    457         // We need atleast two for the test to be relevant.
    458         if (count < 2u) {
    459             continue;
    460         }
    461 
    462         std::unique_ptr<VkLayerProperties[]> properties(new VkLayerProperties[count]);
    463         count = 1;
    464         result = vkEnumerateDeviceLayerProperties(physical[p], &count, properties.get());
    465         ASSERT_EQ(result, VK_INCOMPLETE);
    466     }
    467 
    468     vkDestroyInstance(instance, nullptr);
    469 }
    470 
    471 TEST_F(EnumerateInstanceLayerProperties, Count) {
    472     uint32_t count = 0u;
    473     VkResult result = vkEnumerateInstanceLayerProperties(&count, nullptr);
    474     ASSERT_EQ(result, VK_SUCCESS);
    475 
    476     if (std::find(arguments.begin(), arguments.end(), "count") != arguments.end()) {
    477         std::cout << "count=" << count << '\n';
    478     }
    479 }
    480 
    481 TEST_F(EnumerateInstanceLayerProperties, OnePass) {
    482     // Count required for this test.
    483     if (std::find(arguments.begin(), arguments.end(), "count") == arguments.end()) {
    484         return;
    485     }
    486 
    487     uint32_t count = std::stoul(arguments[2]);
    488 
    489     std::unique_ptr<VkLayerProperties[]> properties(new VkLayerProperties[count]);
    490     VkResult result = vkEnumerateInstanceLayerProperties(&count, properties.get());
    491     ASSERT_EQ(result, VK_SUCCESS);
    492 
    493     if (std::find(arguments.begin(), arguments.end(), "properties") != arguments.end()) {
    494         for (uint32_t p = 0; p < count; ++p) {
    495             std::cout << "properties[" << p << "] =" << ' ' << properties[p].layerName << ' ' << properties[p].specVersion << ' '
    496                       << properties[p].implementationVersion << ' ' << properties[p].description << '\n';
    497         }
    498     }
    499 }
    500 
    501 TEST_F(EnumerateInstanceLayerProperties, TwoPass) {
    502     uint32_t count = 0u;
    503     VkResult result = vkEnumerateInstanceLayerProperties(&count, nullptr);
    504     ASSERT_EQ(result, VK_SUCCESS);
    505 
    506     std::unique_ptr<VkLayerProperties[]> properties(new VkLayerProperties[count]);
    507     result = vkEnumerateInstanceLayerProperties(&count, properties.get());
    508     ASSERT_EQ(result, VK_SUCCESS);
    509 
    510     if (std::find(arguments.begin(), arguments.end(), "properties") != arguments.end()) {
    511         for (uint32_t p = 0; p < count; ++p) {
    512             std::cout << "properties[" << p << "] =" << ' ' << properties[p].layerName << ' ' << properties[p].specVersion << ' '
    513                       << properties[p].implementationVersion << ' ' << properties[p].description << '\n';
    514         }
    515     }
    516 }
    517 
    518 TEST_F(EnumerateInstanceExtensionProperties, PropertyCountLessThanAvailable) {
    519     uint32_t count = 0u;
    520     VkResult result = vkEnumerateInstanceExtensionProperties(nullptr, &count, nullptr);
    521     ASSERT_EQ(result, VK_SUCCESS);
    522 
    523     // We need atleast two for the test to be relevant.
    524     if (count < 2u) {
    525         return;
    526     }
    527 
    528     std::unique_ptr<VkExtensionProperties[]> properties(new VkExtensionProperties[count]);
    529     count = 1;
    530     result = vkEnumerateInstanceExtensionProperties(nullptr, &count, properties.get());
    531     ASSERT_EQ(result, VK_INCOMPLETE);
    532 }
    533 
    534 TEST(EnumerateDeviceExtensionProperties, PropertyCountLessThanAvailable) {
    535     VkInstance instance = VK_NULL_HANDLE;
    536     VkResult result = vkCreateInstance(VK::InstanceCreateInfo(), VK_NULL_HANDLE, &instance);
    537     ASSERT_EQ(result, VK_SUCCESS);
    538 
    539     uint32_t physicalCount = 0;
    540     result = vkEnumeratePhysicalDevices(instance, &physicalCount, nullptr);
    541     ASSERT_EQ(result, VK_SUCCESS);
    542     ASSERT_GT(physicalCount, 0u);
    543 
    544     std::unique_ptr<VkPhysicalDevice[]> physical(new VkPhysicalDevice[physicalCount]);
    545     result = vkEnumeratePhysicalDevices(instance, &physicalCount, physical.get());
    546     ASSERT_EQ(result, VK_SUCCESS);
    547     ASSERT_GT(physicalCount, 0u);
    548 
    549     for (uint32_t p = 0; p < physicalCount; ++p) {
    550         uint32_t count = 0u;
    551         result = vkEnumerateDeviceExtensionProperties(physical[p], nullptr, &count, nullptr);
    552         ASSERT_EQ(result, VK_SUCCESS);
    553 
    554         // We need atleast two for the test to be relevant.
    555         if (count < 2u) {
    556             continue;
    557         }
    558 
    559         std::unique_ptr<VkExtensionProperties[]> properties(new VkExtensionProperties[count]);
    560         count = 1;
    561         result = vkEnumerateDeviceExtensionProperties(physical[p], nullptr, &count, properties.get());
    562         ASSERT_EQ(result, VK_INCOMPLETE);
    563     }
    564 
    565     vkDestroyInstance(instance, nullptr);
    566 }
    567 
    568 TEST_F(EnumerateInstanceExtensionProperties, Count) {
    569     uint32_t count = 0u;
    570     VkResult result = vkEnumerateInstanceExtensionProperties(nullptr, &count, nullptr);
    571     ASSERT_EQ(result, VK_SUCCESS);
    572 
    573     if (std::find(arguments.begin(), arguments.end(), "count") != arguments.end()) {
    574         std::cout << "count=" << count << '\n';
    575     }
    576 }
    577 
    578 TEST_F(EnumerateInstanceExtensionProperties, OnePass) {
    579     // Count required for this test.
    580     if (std::find(arguments.begin(), arguments.end(), "count") == arguments.end()) {
    581         return;
    582     }
    583 
    584     uint32_t count = std::stoul(arguments[2]);
    585 
    586     std::unique_ptr<VkExtensionProperties[]> properties(new VkExtensionProperties[count]);
    587     VkResult result = vkEnumerateInstanceExtensionProperties(nullptr, &count, properties.get());
    588     ASSERT_EQ(result, VK_SUCCESS);
    589 
    590     if (std::find(arguments.begin(), arguments.end(), "properties") != arguments.end()) {
    591         for (uint32_t p = 0; p < count; ++p) {
    592             std::cout << "properties[" << p << "] =" << ' ' << properties[p].extensionName << ' ' << properties[p].specVersion
    593                       << '\n';
    594         }
    595     }
    596 }
    597 
    598 TEST_F(EnumerateInstanceExtensionProperties, TwoPass) {
    599     uint32_t count = 0u;
    600     VkResult result = vkEnumerateInstanceExtensionProperties(nullptr, &count, nullptr);
    601     ASSERT_EQ(result, VK_SUCCESS);
    602 
    603     std::unique_ptr<VkExtensionProperties[]> properties(new VkExtensionProperties[count]);
    604     result = vkEnumerateInstanceExtensionProperties(nullptr, &count, properties.get());
    605     ASSERT_EQ(result, VK_SUCCESS);
    606 
    607     if (std::find(arguments.begin(), arguments.end(), "properties") != arguments.end()) {
    608         for (uint32_t p = 0; p < count; ++p) {
    609             std::cout << "properties[" << p << "] =" << ' ' << properties[p].extensionName << ' ' << properties[p].specVersion
    610                       << '\n';
    611         }
    612     }
    613 }
    614 
    615 TEST_F(EnumerateInstanceExtensionProperties, InstanceExtensionEnumerated) {
    616     uint32_t count = 0u;
    617     VkResult result = vkEnumerateInstanceExtensionProperties(nullptr, &count, nullptr);
    618     ASSERT_EQ(result, VK_SUCCESS);
    619 
    620     std::unique_ptr<VkExtensionProperties[]> properties(new VkExtensionProperties[count]);
    621     result = vkEnumerateInstanceExtensionProperties(nullptr, &count, properties.get());
    622     ASSERT_EQ(result, VK_SUCCESS);
    623 
    624     ASSERT_NE(std::find_if(
    625                   &properties[0], &properties[count],
    626                   [](VkExtensionProperties const &properties) { return strcmp(properties.extensionName, "VK_KHR_surface") == 0; }),
    627               &properties[count]);
    628 }
    629 
    630 TEST(EnumerateDeviceExtensionProperties, DeviceExtensionEnumerated) {
    631     VkInstance instance = VK_NULL_HANDLE;
    632     VkResult result = vkCreateInstance(VK::InstanceCreateInfo(), VK_NULL_HANDLE, &instance);
    633     ASSERT_EQ(result, VK_SUCCESS);
    634 
    635     uint32_t physicalCount = 0;
    636     result = vkEnumeratePhysicalDevices(instance, &physicalCount, nullptr);
    637     ASSERT_EQ(result, VK_SUCCESS);
    638     ASSERT_GT(physicalCount, 0u);
    639 
    640     std::unique_ptr<VkPhysicalDevice[]> physical(new VkPhysicalDevice[physicalCount]);
    641     result = vkEnumeratePhysicalDevices(instance, &physicalCount, physical.get());
    642     ASSERT_EQ(result, VK_SUCCESS);
    643     ASSERT_GT(physicalCount, 0u);
    644 
    645     for (uint32_t p = 0; p < physicalCount; ++p) {
    646         uint32_t count = 0u;
    647         result = vkEnumerateDeviceExtensionProperties(physical[p], nullptr, &count, nullptr);
    648         ASSERT_EQ(result, VK_SUCCESS);
    649 
    650         std::unique_ptr<VkExtensionProperties[]> properties(new VkExtensionProperties[count]);
    651         result = vkEnumerateDeviceExtensionProperties(physical[p], nullptr, &count, properties.get());
    652         ASSERT_EQ(result, VK_SUCCESS);
    653 
    654         ASSERT_NE(std::find_if(&properties[0], &properties[count],
    655                                [](VkExtensionProperties const &properties) {
    656                                    return strcmp(properties.extensionName, "VK_KHR_swapchain") == 0;
    657                                }),
    658                   &properties[count]);
    659     }
    660 
    661     vkDestroyInstance(instance, nullptr);
    662 }
    663 
    664 TEST_F(ImplicitLayer, Present) {
    665     auto const info = VK::InstanceCreateInfo();
    666     VkInstance instance = VK_NULL_HANDLE;
    667     VkResult result = vkCreateInstance(info, VK_NULL_HANDLE, &instance);
    668     ASSERT_EQ(result, VK_SUCCESS);
    669 
    670     vkDestroyInstance(instance, nullptr);
    671 }
    672 
    673 TEST(WrapObjects, Insert) {
    674     VkInstance instance = VK_NULL_HANDLE;
    675     VkResult result = vkCreateInstance(VK::InstanceCreateInfo(), VK_NULL_HANDLE, &instance);
    676     ASSERT_EQ(result, VK_SUCCESS);
    677 
    678     uint32_t physicalCount = 0;
    679     result = vkEnumeratePhysicalDevices(instance, &physicalCount, nullptr);
    680     ASSERT_EQ(result, VK_SUCCESS);
    681     ASSERT_GT(physicalCount, 0u);
    682 
    683     std::unique_ptr<VkPhysicalDevice[]> physical(new VkPhysicalDevice[physicalCount]);
    684     result = vkEnumeratePhysicalDevices(instance, &physicalCount, physical.get());
    685     ASSERT_EQ(result, VK_SUCCESS);
    686     ASSERT_GT(physicalCount, 0u);
    687 
    688     for (uint32_t p = 0; p < physicalCount; ++p) {
    689         uint32_t familyCount = 0;
    690         vkGetPhysicalDeviceQueueFamilyProperties(physical[p], &familyCount, nullptr);
    691         ASSERT_EQ(result, VK_SUCCESS);
    692         ASSERT_GT(familyCount, 0u);
    693 
    694         std::unique_ptr<VkQueueFamilyProperties[]> family(new VkQueueFamilyProperties[familyCount]);
    695         vkGetPhysicalDeviceQueueFamilyProperties(physical[p], &familyCount, family.get());
    696         ASSERT_EQ(result, VK_SUCCESS);
    697         ASSERT_GT(familyCount, 0u);
    698 
    699         for (uint32_t q = 0; q < familyCount; ++q) {
    700             if (~family[q].queueFlags & VK_QUEUE_GRAPHICS_BIT) {
    701                 continue;
    702             }
    703 
    704             float const priorities[] = {0.0f}; // Temporary required due to MSVC bug.
    705             VkDeviceQueueCreateInfo const queueInfo[1]{
    706                 VK::DeviceQueueCreateInfo().queueFamilyIndex(q).queueCount(1).pQueuePriorities(priorities)};
    707 
    708             auto const deviceInfo = VK::DeviceCreateInfo().queueCreateInfoCount(1).pQueueCreateInfos(queueInfo);
    709 
    710             VkDevice device;
    711             result = vkCreateDevice(physical[p], deviceInfo, nullptr, &device);
    712             ASSERT_EQ(result, VK_SUCCESS);
    713 
    714             vkDestroyDevice(device, nullptr);
    715         }
    716     }
    717 
    718     vkDestroyInstance(instance, nullptr);
    719 }
    720 
    721 int main(int argc, char **argv) {
    722     int result;
    723 
    724     ::testing::InitGoogleTest(&argc, argv);
    725 
    726     if (argc > 0) {
    727         CommandLine::Initialize(argc, argv);
    728     }
    729 
    730     result = RUN_ALL_TESTS();
    731 
    732     return result;
    733 }
    734