• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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@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 {
InstanceCreateInfoVK::InstanceCreateInfo40     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 
sTypeVK::InstanceCreateInfo53     InstanceCreateInfo &sType(VkStructureType const &sType) {
54         info.sType = sType;
55 
56         return *this;
57     }
58 
pNextVK::InstanceCreateInfo59     InstanceCreateInfo &pNext(void const *const pNext) {
60         info.pNext = pNext;
61 
62         return *this;
63     }
64 
flagsVK::InstanceCreateInfo65     InstanceCreateInfo &flags(VkInstanceCreateFlags const &flags) {
66         info.flags = flags;
67 
68         return *this;
69     }
70 
pApplicationInfoVK::InstanceCreateInfo71     InstanceCreateInfo &pApplicationInfo(VkApplicationInfo const *const pApplicationInfo) {
72         info.pApplicationInfo = pApplicationInfo;
73 
74         return *this;
75     }
76 
enabledLayerCountVK::InstanceCreateInfo77     InstanceCreateInfo &enabledLayerCount(uint32_t const &enabledLayerCount) {
78         info.enabledLayerCount = enabledLayerCount;
79 
80         return *this;
81     }
82 
ppEnabledLayerNamesVK::InstanceCreateInfo83     InstanceCreateInfo &ppEnabledLayerNames(char const *const *const ppEnabledLayerNames) {
84         info.ppEnabledLayerNames = ppEnabledLayerNames;
85 
86         return *this;
87     }
88 
enabledExtensionCountVK::InstanceCreateInfo89     InstanceCreateInfo &enabledExtensionCount(uint32_t const &enabledExtensionCount) {
90         info.enabledExtensionCount = enabledExtensionCount;
91 
92         return *this;
93     }
94 
ppEnabledExtensionNamesVK::InstanceCreateInfo95     InstanceCreateInfo &ppEnabledExtensionNames(char const *const *const ppEnabledExtensionNames) {
96         info.ppEnabledExtensionNames = ppEnabledExtensionNames;
97 
98         return *this;
99     }
100 
operator VkInstanceCreateInfo const*VK::InstanceCreateInfo101     operator VkInstanceCreateInfo const *() const { return &info; }
102 
operator VkInstanceCreateInfo*VK::InstanceCreateInfo103     operator VkInstanceCreateInfo *() { return &info; }
104 
105     VkInstanceCreateInfo info;
106 };
107 
108 struct DeviceQueueCreateInfo {
DeviceQueueCreateInfoVK::DeviceQueueCreateInfo109     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 
sTypeVK::DeviceQueueCreateInfo120     DeviceQueueCreateInfo &sType(VkStructureType const &sType) {
121         info.sType = sType;
122 
123         return *this;
124     }
125 
pNextVK::DeviceQueueCreateInfo126     DeviceQueueCreateInfo &pNext(void const *const pNext) {
127         info.pNext = pNext;
128 
129         return *this;
130     }
131 
flagsVK::DeviceQueueCreateInfo132     DeviceQueueCreateInfo &flags(VkDeviceQueueCreateFlags const &flags) {
133         info.flags = flags;
134 
135         return *this;
136     }
137 
queueFamilyIndexVK::DeviceQueueCreateInfo138     DeviceQueueCreateInfo &queueFamilyIndex(uint32_t const &queueFamilyIndex) {
139         info.queueFamilyIndex = queueFamilyIndex;
140 
141         return *this;
142     }
143 
queueCountVK::DeviceQueueCreateInfo144     DeviceQueueCreateInfo &queueCount(uint32_t const &queueCount) {
145         info.queueCount = queueCount;
146 
147         return *this;
148     }
149 
pQueuePrioritiesVK::DeviceQueueCreateInfo150     DeviceQueueCreateInfo &pQueuePriorities(float const *const pQueuePriorities) {
151         info.pQueuePriorities = pQueuePriorities;
152 
153         return *this;
154     }
155 
operator VkDeviceQueueCreateInfoVK::DeviceQueueCreateInfo156     operator VkDeviceQueueCreateInfo() { return info; }
157 
158     VkDeviceQueueCreateInfo info;
159 };
160 
161 struct DeviceCreateInfo {
DeviceCreateInfoVK::DeviceCreateInfo162     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 
sTypeVK::DeviceCreateInfo177     DeviceCreateInfo &sType(VkStructureType const &sType) {
178         info.sType = sType;
179 
180         return *this;
181     }
182 
pNextVK::DeviceCreateInfo183     DeviceCreateInfo &pNext(void const *const pNext) {
184         info.pNext = pNext;
185 
186         return *this;
187     }
188 
flagsVK::DeviceCreateInfo189     DeviceCreateInfo &flags(VkDeviceQueueCreateFlags const &flags) {
190         info.flags = flags;
191 
192         return *this;
193     }
194 
queueCreateInfoCountVK::DeviceCreateInfo195     DeviceCreateInfo &queueCreateInfoCount(uint32_t const &queueCreateInfoCount) {
196         info.queueCreateInfoCount = queueCreateInfoCount;
197 
198         return *this;
199     }
200 
pQueueCreateInfosVK::DeviceCreateInfo201     DeviceCreateInfo &pQueueCreateInfos(VkDeviceQueueCreateInfo const *const pQueueCreateInfos) {
202         info.pQueueCreateInfos = pQueueCreateInfos;
203 
204         return *this;
205     }
206 
enabledLayerCountVK::DeviceCreateInfo207     DeviceCreateInfo &enabledLayerCount(uint32_t const &enabledLayerCount) {
208         info.enabledLayerCount = enabledLayerCount;
209 
210         return *this;
211     }
212 
ppEnabledLayerNamesVK::DeviceCreateInfo213     DeviceCreateInfo &ppEnabledLayerNames(char const *const *const ppEnabledLayerNames) {
214         info.ppEnabledLayerNames = ppEnabledLayerNames;
215 
216         return *this;
217     }
218 
enabledExtensionCountVK::DeviceCreateInfo219     DeviceCreateInfo &enabledExtensionCount(uint32_t const &enabledExtensionCount) {
220         info.enabledExtensionCount = enabledExtensionCount;
221 
222         return *this;
223     }
224 
ppEnabledExtensionNamesVK::DeviceCreateInfo225     DeviceCreateInfo &ppEnabledExtensionNames(char const *const *const ppEnabledExtensionNames) {
226         info.ppEnabledExtensionNames = ppEnabledExtensionNames;
227 
228         return *this;
229     }
230 
pEnabledFeaturesVK::DeviceCreateInfo231     DeviceCreateInfo &pEnabledFeatures(VkPhysicalDeviceFeatures const *const pEnabledFeatures) {
232         info.pEnabledFeatures = pEnabledFeatures;
233 
234         return *this;
235     }
236 
operator VkDeviceCreateInfo const*VK::DeviceCreateInfo237     operator VkDeviceCreateInfo const *() const { return &info; }
238 
operator VkDeviceCreateInfo*VK::DeviceCreateInfo239     operator VkDeviceCreateInfo *() { return &info; }
240 
241     VkDeviceCreateInfo info;
242 };
243 }
244 
245 struct CommandLine : public ::testing::Test {
InitializeCommandLine246     static void Initialize(int argc, char **argv) { arguments.assign(argv, argv + argc); };
247 
SetUpTestCaseCommandLine248     static void SetUpTestCase(){};
TearDownTestCaseCommandLine249     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 
TEST(LX435,InstanceCreateInfoConst)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 
TEST(LX475,DestroyInstanceNullHandle)274 TEST(LX475, DestroyInstanceNullHandle) { vkDestroyInstance(VK_NULL_HANDLE, nullptr); }
275 
TEST(LX475,DestroyDeviceNullHandle)276 TEST(LX475, DestroyDeviceNullHandle) { vkDestroyDevice(VK_NULL_HANDLE, nullptr); }
277 
TEST(CreateInstance,ExtensionNotPresent)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 
TEST(CreateInstance,LayerNotPresent)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.
TEST(CreateInstance,LayerPresent)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 
TEST(CreateDevice,ExtensionNotPresent)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.
TEST(CreateDevice,LayersNotPresent)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 
TEST_F(EnumerateInstanceLayerProperties,PropertyCountLessThanAvailable)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 
TEST(EnumerateDeviceLayerProperties,PropertyCountLessThanAvailable)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 
TEST_F(EnumerateInstanceLayerProperties,Count)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 
TEST_F(EnumerateInstanceLayerProperties,OnePass)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 
TEST_F(EnumerateInstanceLayerProperties,TwoPass)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 
TEST_F(EnumerateInstanceExtensionProperties,PropertyCountLessThanAvailable)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 
TEST(EnumerateDeviceExtensionProperties,PropertyCountLessThanAvailable)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 
TEST_F(EnumerateInstanceExtensionProperties,Count)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 
TEST_F(EnumerateInstanceExtensionProperties,OnePass)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 
TEST_F(EnumerateInstanceExtensionProperties,TwoPass)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 
TEST_F(EnumerateInstanceExtensionProperties,InstanceExtensionEnumerated)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 
TEST(EnumerateDeviceExtensionProperties,DeviceExtensionEnumerated)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 
TEST_F(ImplicitLayer,Present)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 
TEST(WrapObjects,Insert)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 
main(int argc,char ** argv)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