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