blob: bc6723e28ea267a7d3fb1ce37d316e61e736632e [file] [log] [blame]
Jeremy Hayes6650d1f2016-04-20 09:00:39 -06001/*
Mark Youngb9835412017-01-25 12:25:10 -08002 * Copyright (c) 2015-2017 The Khronos Group Inc.
3 * Copyright (c) 2015-2017 Valve Corporation
4 * Copyright (c) 2015-2017 LunarG, Inc.
Jeremy Hayes6650d1f2016-04-20 09:00:39 -06005 *
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>
Mark Youngb9835412017-01-25 12:25:10 -080026 * Author: Mark Young <marky@lunarG.com>
Jeremy Hayes6650d1f2016-04-20 09:00:39 -060027 */
28
Mark Youngaf0eaaa2017-04-27 01:30:14 -060029// Following items are needed for C++ to work with PRIxLEAST64
30#define __STDC_FORMAT_MACROS
31#include <inttypes.h>
32
Mark Youngc8b807a2017-07-14 17:11:31 -060033#include <stdint.h> // For UINT32_MAX
Mark Youngc146fc22017-02-02 18:14:21 -070034
Jeremy Hayes10357562016-07-06 11:56:44 -060035#include <algorithm>
36#include <iostream>
Jeremy Hayesd8726c22016-04-21 13:19:41 -060037#include <memory>
Jeremy Hayes10357562016-07-06 11:56:44 -060038#include <string>
39#include <vector>
Jeremy Hayesd8726c22016-04-21 13:19:41 -060040
Jeremy Hayes6650d1f2016-04-20 09:00:39 -060041#include "test_common.h"
Mark Lobodzinski51414032016-09-07 16:29:11 -060042#include <vulkan/vulkan.h>
Jeremy Hayes6650d1f2016-04-20 09:00:39 -060043
Mark Lobodzinski51414032016-09-07 16:29:11 -060044namespace VK {
Jeremy Hayesc5587182016-06-28 11:29:05 -060045
Mark Lobodzinski51414032016-09-07 16:29:11 -060046struct InstanceCreateInfo {
47 InstanceCreateInfo()
Mark Lobodzinski64318ba2017-01-26 13:34:13 -070048 : info // MSVC can't handle list initialization, thus explicit construction herein.
Mark Lobodzinski51414032016-09-07 16:29:11 -060049 (VkInstanceCreateInfo{
Mark Lobodzinski64318ba2017-01-26 13:34:13 -070050 VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO, // sType
51 nullptr, // pNext
52 0, // flags
53 nullptr, // pApplicationInfo
54 0, // enabledLayerCount
55 nullptr, // ppEnabledLayerNames
56 0, // enabledExtensionCount
57 nullptr // ppEnabledExtensionNames
Mark Lobodzinski51414032016-09-07 16:29:11 -060058 }) {}
Jeremy Hayesc5587182016-06-28 11:29:05 -060059
Mark Lobodzinski51414032016-09-07 16:29:11 -060060 InstanceCreateInfo &sType(VkStructureType const &sType) {
Jeremy Hayesc5587182016-06-28 11:29:05 -060061 info.sType = sType;
62
63 return *this;
64 }
65
Mark Lobodzinski51414032016-09-07 16:29:11 -060066 InstanceCreateInfo &pNext(void const *const pNext) {
Jeremy Hayesc5587182016-06-28 11:29:05 -060067 info.pNext = pNext;
68
69 return *this;
70 }
71
Mark Lobodzinski51414032016-09-07 16:29:11 -060072 InstanceCreateInfo &flags(VkInstanceCreateFlags const &flags) {
Jeremy Hayesc5587182016-06-28 11:29:05 -060073 info.flags = flags;
74
75 return *this;
76 }
77
Mark Lobodzinski51414032016-09-07 16:29:11 -060078 InstanceCreateInfo &pApplicationInfo(VkApplicationInfo const *const pApplicationInfo) {
Jeremy Hayesc5587182016-06-28 11:29:05 -060079 info.pApplicationInfo = pApplicationInfo;
80
81 return *this;
82 }
83
Mark Lobodzinski51414032016-09-07 16:29:11 -060084 InstanceCreateInfo &enabledLayerCount(uint32_t const &enabledLayerCount) {
Jeremy Hayesc5587182016-06-28 11:29:05 -060085 info.enabledLayerCount = enabledLayerCount;
86
87 return *this;
88 }
89
Mark Lobodzinski51414032016-09-07 16:29:11 -060090 InstanceCreateInfo &ppEnabledLayerNames(char const *const *const ppEnabledLayerNames) {
Jeremy Hayesc5587182016-06-28 11:29:05 -060091 info.ppEnabledLayerNames = ppEnabledLayerNames;
92
93 return *this;
94 }
95
Mark Lobodzinski51414032016-09-07 16:29:11 -060096 InstanceCreateInfo &enabledExtensionCount(uint32_t const &enabledExtensionCount) {
Jeremy Hayesc5587182016-06-28 11:29:05 -060097 info.enabledExtensionCount = enabledExtensionCount;
98
99 return *this;
100 }
101
Mark Lobodzinski51414032016-09-07 16:29:11 -0600102 InstanceCreateInfo &ppEnabledExtensionNames(char const *const *const ppEnabledExtensionNames) {
Jeremy Hayesc5587182016-06-28 11:29:05 -0600103 info.ppEnabledExtensionNames = ppEnabledExtensionNames;
104
105 return *this;
106 }
107
Mark Lobodzinski51414032016-09-07 16:29:11 -0600108 operator VkInstanceCreateInfo const *() const { return &info; }
Jeremy Hayesc5587182016-06-28 11:29:05 -0600109
Mark Lobodzinski51414032016-09-07 16:29:11 -0600110 operator VkInstanceCreateInfo *() { return &info; }
Jeremy Hayesc5587182016-06-28 11:29:05 -0600111
112 VkInstanceCreateInfo info;
113};
114
Mark Lobodzinski51414032016-09-07 16:29:11 -0600115struct DeviceQueueCreateInfo {
116 DeviceQueueCreateInfo()
Mark Lobodzinski64318ba2017-01-26 13:34:13 -0700117 : info // MSVC can't handle list initialization, thus explicit construction herein.
Mark Lobodzinski51414032016-09-07 16:29:11 -0600118 (VkDeviceQueueCreateInfo{
Mark Lobodzinski64318ba2017-01-26 13:34:13 -0700119 VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO, // sType
120 nullptr, // pNext
121 0, // flags
122 0, // queueFamilyIndex
123 0, // queueCount
124 nullptr // pQueuePriorities
Mark Lobodzinski51414032016-09-07 16:29:11 -0600125 }) {}
Jeremy Hayesc5587182016-06-28 11:29:05 -0600126
Mark Lobodzinski51414032016-09-07 16:29:11 -0600127 DeviceQueueCreateInfo &sType(VkStructureType const &sType) {
Jeremy Hayesc5587182016-06-28 11:29:05 -0600128 info.sType = sType;
129
130 return *this;
131 }
132
Mark Lobodzinski51414032016-09-07 16:29:11 -0600133 DeviceQueueCreateInfo &pNext(void const *const pNext) {
Jeremy Hayesc5587182016-06-28 11:29:05 -0600134 info.pNext = pNext;
135
136 return *this;
137 }
138
Mark Lobodzinski51414032016-09-07 16:29:11 -0600139 DeviceQueueCreateInfo &flags(VkDeviceQueueCreateFlags const &flags) {
Jeremy Hayesc5587182016-06-28 11:29:05 -0600140 info.flags = flags;
141
142 return *this;
143 }
144
Mark Lobodzinski51414032016-09-07 16:29:11 -0600145 DeviceQueueCreateInfo &queueFamilyIndex(uint32_t const &queueFamilyIndex) {
Jeremy Hayesc5587182016-06-28 11:29:05 -0600146 info.queueFamilyIndex = queueFamilyIndex;
147
148 return *this;
149 }
150
Mark Lobodzinski51414032016-09-07 16:29:11 -0600151 DeviceQueueCreateInfo &queueCount(uint32_t const &queueCount) {
Jeremy Hayesc5587182016-06-28 11:29:05 -0600152 info.queueCount = queueCount;
153
154 return *this;
155 }
156
Mark Lobodzinski51414032016-09-07 16:29:11 -0600157 DeviceQueueCreateInfo &pQueuePriorities(float const *const pQueuePriorities) {
Jeremy Hayesc5587182016-06-28 11:29:05 -0600158 info.pQueuePriorities = pQueuePriorities;
159
160 return *this;
161 }
162
Mark Lobodzinski51414032016-09-07 16:29:11 -0600163 operator VkDeviceQueueCreateInfo() { return info; }
Jeremy Hayesc5587182016-06-28 11:29:05 -0600164
165 VkDeviceQueueCreateInfo info;
166};
167
Mark Lobodzinski51414032016-09-07 16:29:11 -0600168struct DeviceCreateInfo {
169 DeviceCreateInfo()
Mark Lobodzinski64318ba2017-01-26 13:34:13 -0700170 : info // MSVC can't handle list initialization, thus explicit construction herein.
Mark Lobodzinski51414032016-09-07 16:29:11 -0600171 (VkDeviceCreateInfo{
Mark Lobodzinski64318ba2017-01-26 13:34:13 -0700172 VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO, // sType
173 nullptr, // pNext
174 0, // flags
175 0, // queueCreateInfoCount
176 nullptr, // pQueueCreateInfos
177 0, // enabledLayerCount
178 nullptr, // ppEnabledLayerNames
179 0, // enabledExtensionCount
180 nullptr, // ppEnabledExtensionNames
181 nullptr // pEnabledFeatures
Mark Lobodzinski51414032016-09-07 16:29:11 -0600182 }) {}
Jeremy Hayesc5587182016-06-28 11:29:05 -0600183
Mark Lobodzinski51414032016-09-07 16:29:11 -0600184 DeviceCreateInfo &sType(VkStructureType const &sType) {
Jeremy Hayesc5587182016-06-28 11:29:05 -0600185 info.sType = sType;
186
187 return *this;
188 }
189
Mark Lobodzinski51414032016-09-07 16:29:11 -0600190 DeviceCreateInfo &pNext(void const *const pNext) {
Jeremy Hayesc5587182016-06-28 11:29:05 -0600191 info.pNext = pNext;
192
193 return *this;
194 }
195
Mark Lobodzinski51414032016-09-07 16:29:11 -0600196 DeviceCreateInfo &flags(VkDeviceQueueCreateFlags const &flags) {
Jeremy Hayesc5587182016-06-28 11:29:05 -0600197 info.flags = flags;
198
199 return *this;
200 }
201
Mark Lobodzinski51414032016-09-07 16:29:11 -0600202 DeviceCreateInfo &queueCreateInfoCount(uint32_t const &queueCreateInfoCount) {
Jeremy Hayesc5587182016-06-28 11:29:05 -0600203 info.queueCreateInfoCount = queueCreateInfoCount;
204
205 return *this;
206 }
207
Mark Lobodzinski51414032016-09-07 16:29:11 -0600208 DeviceCreateInfo &pQueueCreateInfos(VkDeviceQueueCreateInfo const *const pQueueCreateInfos) {
Jeremy Hayesc5587182016-06-28 11:29:05 -0600209 info.pQueueCreateInfos = pQueueCreateInfos;
210
211 return *this;
212 }
213
Mark Lobodzinski51414032016-09-07 16:29:11 -0600214 DeviceCreateInfo &enabledLayerCount(uint32_t const &enabledLayerCount) {
Jeremy Hayesc5587182016-06-28 11:29:05 -0600215 info.enabledLayerCount = enabledLayerCount;
216
217 return *this;
218 }
219
Mark Lobodzinski51414032016-09-07 16:29:11 -0600220 DeviceCreateInfo &ppEnabledLayerNames(char const *const *const ppEnabledLayerNames) {
Jeremy Hayesc5587182016-06-28 11:29:05 -0600221 info.ppEnabledLayerNames = ppEnabledLayerNames;
222
223 return *this;
224 }
225
Mark Lobodzinski51414032016-09-07 16:29:11 -0600226 DeviceCreateInfo &enabledExtensionCount(uint32_t const &enabledExtensionCount) {
Jeremy Hayesc5587182016-06-28 11:29:05 -0600227 info.enabledExtensionCount = enabledExtensionCount;
228
229 return *this;
230 }
231
Mark Lobodzinski51414032016-09-07 16:29:11 -0600232 DeviceCreateInfo &ppEnabledExtensionNames(char const *const *const ppEnabledExtensionNames) {
Jeremy Hayesc5587182016-06-28 11:29:05 -0600233 info.ppEnabledExtensionNames = ppEnabledExtensionNames;
234
235 return *this;
236 }
237
Mark Lobodzinski51414032016-09-07 16:29:11 -0600238 DeviceCreateInfo &pEnabledFeatures(VkPhysicalDeviceFeatures const *const pEnabledFeatures) {
Jeremy Hayesc5587182016-06-28 11:29:05 -0600239 info.pEnabledFeatures = pEnabledFeatures;
240
241 return *this;
242 }
243
Mark Lobodzinski51414032016-09-07 16:29:11 -0600244 operator VkDeviceCreateInfo const *() const { return &info; }
Jeremy Hayesc5587182016-06-28 11:29:05 -0600245
Mark Lobodzinski51414032016-09-07 16:29:11 -0600246 operator VkDeviceCreateInfo *() { return &info; }
Jeremy Hayesc5587182016-06-28 11:29:05 -0600247
248 VkDeviceCreateInfo info;
249};
Jeremy Hayesc5587182016-06-28 11:29:05 -0600250}
251
Mark Lobodzinski51414032016-09-07 16:29:11 -0600252struct CommandLine : public ::testing::Test {
253 static void Initialize(int argc, char **argv) { arguments.assign(argv, argv + argc); };
Jeremy Hayes10357562016-07-06 11:56:44 -0600254
Mark Lobodzinski51414032016-09-07 16:29:11 -0600255 static void SetUpTestCase(){};
256 static void TearDownTestCase(){};
Jeremy Hayes10357562016-07-06 11:56:44 -0600257
258 static std::vector<std::string> arguments;
259};
260std::vector<std::string> CommandLine::arguments;
261
262struct EnumerateInstanceLayerProperties : public CommandLine {};
263struct EnumerateInstanceExtensionProperties : public CommandLine {};
Jeremy Hayes52261802016-08-15 10:37:24 -0600264struct ImplicitLayer : public CommandLine {};
Jeremy Hayes10357562016-07-06 11:56:44 -0600265
Mark Youngc146fc22017-02-02 18:14:21 -0700266// Allocation tracking utilities
267struct AllocTrack {
268 bool active;
269 bool was_allocated;
270 void *aligned_start_addr;
271 char *actual_start_addr;
272 size_t requested_size_bytes;
273 size_t actual_size_bytes;
274 VkSystemAllocationScope alloc_scope;
275 uint64_t user_data;
276
277 AllocTrack()
278 : active(false),
279 was_allocated(false),
280 aligned_start_addr(nullptr),
281 actual_start_addr(nullptr),
282 requested_size_bytes(0),
283 actual_size_bytes(0),
284 alloc_scope(VK_SYSTEM_ALLOCATION_SCOPE_COMMAND),
285 user_data(0) {}
286};
287
288// Global vector to track allocations. This will be resized before each test and emptied after.
289// However, we have to globally define it so the allocation callback functions work properly.
290std::vector<AllocTrack> g_allocated_vector;
Mark Young05e4f6a2017-03-15 10:36:03 -0600291bool g_intentional_fail_enabled = false;
292uint32_t g_intenional_fail_index = 0;
293uint32_t g_intenional_fail_count = 0;
Mark Youngc146fc22017-02-02 18:14:21 -0700294
295void FreeAllocTracker() { g_allocated_vector.clear(); }
296
Mark Young05e4f6a2017-03-15 10:36:03 -0600297void InitAllocTracker(size_t size, uint32_t intentional_fail_index = UINT32_MAX) {
Mark Youngc146fc22017-02-02 18:14:21 -0700298 if (g_allocated_vector.size() > 0) {
299 FreeAllocTracker();
300 }
301 g_allocated_vector.resize(size);
Mark Young05e4f6a2017-03-15 10:36:03 -0600302 if (intentional_fail_index != UINT32_MAX) {
303 g_intentional_fail_enabled = true;
304 g_intenional_fail_index = intentional_fail_index;
305 g_intenional_fail_count = 0;
306 } else {
307 g_intentional_fail_enabled = false;
308 g_intenional_fail_index = 0;
309 g_intenional_fail_count = 0;
310 }
Mark Youngc146fc22017-02-02 18:14:21 -0700311}
312
313bool IsAllocTrackerEmpty() {
314 bool success = true;
315 bool was_allocated = false;
316 char print_command[1024];
317 sprintf(print_command, "\t%%04d\t%%p (%%p) : 0x%%%s (0x%%%s) : scope %%d : user_data 0x%%%s\n", PRIxLEAST64, PRIxLEAST64,
318 PRIxLEAST64);
319 for (uint32_t iii = 0; iii < g_allocated_vector.size(); iii++) {
320 if (g_allocated_vector[iii].active) {
321 if (success) {
322 printf("ERROR: Allocations still remain!\n");
323 }
324 printf(print_command, iii, g_allocated_vector[iii].aligned_start_addr, g_allocated_vector[iii].actual_start_addr,
325 g_allocated_vector[iii].requested_size_bytes, g_allocated_vector[iii].actual_size_bytes,
326 g_allocated_vector[iii].alloc_scope, g_allocated_vector[iii].user_data);
327 success = false;
328 } else if (!was_allocated && g_allocated_vector[iii].was_allocated) {
329 was_allocated = true;
330 }
331 }
Mark Young05e4f6a2017-03-15 10:36:03 -0600332 if (!g_intentional_fail_enabled && !was_allocated) {
Mark Youngc146fc22017-02-02 18:14:21 -0700333 printf("No allocations ever generated!");
334 success = false;
335 }
336 return success;
337}
338
339VKAPI_ATTR void *VKAPI_CALL AllocCallbackFunc(void *pUserData, size_t size, size_t alignment,
340 VkSystemAllocationScope allocationScope) {
Mark Young05e4f6a2017-03-15 10:36:03 -0600341 if (g_intentional_fail_enabled) {
342 if (++g_intenional_fail_count >= g_intenional_fail_index) {
343 return nullptr;
344 }
345 }
Mark Youngc146fc22017-02-02 18:14:21 -0700346 for (uint32_t iii = 0; iii < g_allocated_vector.size(); iii++) {
347 if (!g_allocated_vector[iii].active) {
348 g_allocated_vector[iii].requested_size_bytes = size;
349 g_allocated_vector[iii].actual_size_bytes = size + (alignment - 1);
350 g_allocated_vector[iii].aligned_start_addr = NULL;
351 g_allocated_vector[iii].actual_start_addr = new char[g_allocated_vector[iii].actual_size_bytes];
352 if (g_allocated_vector[iii].actual_start_addr != NULL) {
353 uint64_t addr = (uint64_t)g_allocated_vector[iii].actual_start_addr;
354 addr += (alignment - 1);
355 addr &= ~(alignment - 1);
356 g_allocated_vector[iii].aligned_start_addr = (void *)addr;
357 g_allocated_vector[iii].alloc_scope = allocationScope;
358 g_allocated_vector[iii].user_data = (uint64_t)pUserData;
359 g_allocated_vector[iii].active = true;
360 g_allocated_vector[iii].was_allocated = true;
361 }
362 return g_allocated_vector[iii].aligned_start_addr;
363 }
364 }
365 return nullptr;
366}
367
368VKAPI_ATTR void VKAPI_CALL FreeCallbackFunc(void *pUserData, void *pMemory) {
369 for (uint32_t iii = 0; iii < g_allocated_vector.size(); iii++) {
370 if (g_allocated_vector[iii].active && g_allocated_vector[iii].aligned_start_addr == pMemory) {
371 delete[] g_allocated_vector[iii].actual_start_addr;
372 g_allocated_vector[iii].active = false;
373 break;
374 }
375 }
376}
377
378VKAPI_ATTR void *VKAPI_CALL ReallocCallbackFunc(void *pUserData, void *pOriginal, size_t size, size_t alignment,
379 VkSystemAllocationScope allocationScope) {
380 if (pOriginal != NULL) {
381 for (uint32_t iii = 0; iii < g_allocated_vector.size(); iii++) {
382 if (g_allocated_vector[iii].active && g_allocated_vector[iii].aligned_start_addr == pOriginal) {
383 if (size == 0) {
384 FreeCallbackFunc(pUserData, pOriginal);
385 return nullptr;
386 } else if (size < g_allocated_vector[iii].requested_size_bytes) {
387 return pOriginal;
388 } else {
389 void *pNew = AllocCallbackFunc(pUserData, size, alignment, allocationScope);
Mark Youngbb3a29c2017-05-19 12:29:43 -0600390 if (pNew != NULL) {
391 size_t copy_size = size;
392 if (g_allocated_vector[iii].requested_size_bytes < size) {
393 copy_size = g_allocated_vector[iii].requested_size_bytes;
394 }
395 memcpy(pNew, pOriginal, copy_size);
396 FreeCallbackFunc(pUserData, pOriginal);
Mark Youngc146fc22017-02-02 18:14:21 -0700397 }
Mark Youngc146fc22017-02-02 18:14:21 -0700398 return pNew;
399 }
400 }
401 }
402 return nullptr;
403 } else {
404 return AllocCallbackFunc(pUserData, size, alignment, allocationScope);
405 }
406}
407
Jeremy Hayesd8726c22016-04-21 13:19:41 -0600408// Test groups:
409// LX = lunar exchange
410// LVLGH = loader and validation github
411// LVLGL = lodaer and validation gitlab
412
Mark Lobodzinski51414032016-09-07 16:29:11 -0600413TEST(LX435, InstanceCreateInfoConst) {
414 VkInstanceCreateInfo const info = {VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO, nullptr, 0, nullptr, 0, nullptr, 0, nullptr};
Jeremy Hayes6650d1f2016-04-20 09:00:39 -0600415
416 VkInstance instance = VK_NULL_HANDLE;
417 VkResult result = vkCreateInstance(&info, VK_NULL_HANDLE, &instance);
418 EXPECT_EQ(result, VK_SUCCESS);
Jeremy Hayes10357562016-07-06 11:56:44 -0600419
420 vkDestroyInstance(instance, nullptr);
Jeremy Hayes6650d1f2016-04-20 09:00:39 -0600421}
422
Mark Lobodzinski51414032016-09-07 16:29:11 -0600423TEST(LX475, DestroyInstanceNullHandle) { vkDestroyInstance(VK_NULL_HANDLE, nullptr); }
Jeremy Hayesd8726c22016-04-21 13:19:41 -0600424
Mark Lobodzinski51414032016-09-07 16:29:11 -0600425TEST(LX475, DestroyDeviceNullHandle) { vkDestroyDevice(VK_NULL_HANDLE, nullptr); }
Jeremy Hayesd8726c22016-04-21 13:19:41 -0600426
Mark Lobodzinski51414032016-09-07 16:29:11 -0600427TEST(CreateInstance, ExtensionNotPresent) {
Mark Lobodzinski64318ba2017-01-26 13:34:13 -0700428 char const *const names[] = {"NotPresent"}; // Temporary required due to MSVC bug.
Mark Lobodzinski51414032016-09-07 16:29:11 -0600429 auto const info = VK::InstanceCreateInfo().enabledExtensionCount(1).ppEnabledExtensionNames(names);
Jeremy Hayes097188a2016-06-15 16:37:17 -0600430
431 VkInstance instance = VK_NULL_HANDLE;
Jeremy Hayesc5587182016-06-28 11:29:05 -0600432 VkResult result = vkCreateInstance(info, VK_NULL_HANDLE, &instance);
Jeremy Hayes097188a2016-06-15 16:37:17 -0600433 ASSERT_EQ(result, VK_ERROR_EXTENSION_NOT_PRESENT);
Jeremy Hayes10357562016-07-06 11:56:44 -0600434
435 // It's not necessary to destroy the instance because it will not be created successfully.
Jeremy Hayes097188a2016-06-15 16:37:17 -0600436}
437
Mark Lobodzinski51414032016-09-07 16:29:11 -0600438TEST(CreateInstance, LayerNotPresent) {
Mark Lobodzinski64318ba2017-01-26 13:34:13 -0700439 char const *const names[] = {"NotPresent"}; // Temporary required due to MSVC bug.
Mark Lobodzinski51414032016-09-07 16:29:11 -0600440 auto const info = VK::InstanceCreateInfo().enabledLayerCount(1).ppEnabledLayerNames(names);
Jeremy Hayes097188a2016-06-15 16:37:17 -0600441
442 VkInstance instance = VK_NULL_HANDLE;
Jeremy Hayesc5587182016-06-28 11:29:05 -0600443 VkResult result = vkCreateInstance(info, VK_NULL_HANDLE, &instance);
Jeremy Hayes097188a2016-06-15 16:37:17 -0600444 ASSERT_EQ(result, VK_ERROR_LAYER_NOT_PRESENT);
Jeremy Hayes10357562016-07-06 11:56:44 -0600445
446 // It's not necessary to destroy the instance because it will not be created successfully.
Jeremy Hayes097188a2016-06-15 16:37:17 -0600447}
448
Jeremy Hayesab9804d2016-06-30 10:13:35 -0600449// Used by run_loader_tests.sh to test for layer insertion.
Mark Lobodzinski51414032016-09-07 16:29:11 -0600450TEST(CreateInstance, LayerPresent) {
Mark Youngc8b807a2017-07-14 17:11:31 -0600451 char const *const names1[] = {"VK_LAYER_LUNARG_parameter_validation"}; // Temporary required due to MSVC bug.
452 char const *const names2[] = {"VK_LAYER_LUNARG_standard_validation"}; // Temporary required due to MSVC bug.
453 auto const info1 = VK::InstanceCreateInfo().enabledLayerCount(1).ppEnabledLayerNames(names1);
Jeremy Hayesab9804d2016-06-30 10:13:35 -0600454 VkInstance instance = VK_NULL_HANDLE;
Mark Youngc8b807a2017-07-14 17:11:31 -0600455 VkResult result = vkCreateInstance(info1, VK_NULL_HANDLE, &instance);
Jeremy Hayesab9804d2016-06-30 10:13:35 -0600456 ASSERT_EQ(result, VK_SUCCESS);
Mark Youngc8b807a2017-07-14 17:11:31 -0600457 vkDestroyInstance(instance, nullptr);
Jeremy Hayes10357562016-07-06 11:56:44 -0600458
Mark Youngc8b807a2017-07-14 17:11:31 -0600459 auto const info2 = VK::InstanceCreateInfo().enabledLayerCount(1).ppEnabledLayerNames(names2);
460 instance = VK_NULL_HANDLE;
461 result = vkCreateInstance(info2, VK_NULL_HANDLE, &instance);
462 ASSERT_EQ(result, VK_SUCCESS);
Jeremy Hayes10357562016-07-06 11:56:44 -0600463 vkDestroyInstance(instance, nullptr);
Jeremy Hayesab9804d2016-06-30 10:13:35 -0600464}
465
Mark Youngb9835412017-01-25 12:25:10 -0800466// Used by run_loader_tests.sh to test that calling vkEnumeratePhysicalDevices without first querying
467// the count, works.
Mark Youngab2c5352017-03-16 13:56:32 -0600468TEST(EnumeratePhysicalDevices, OneCall) {
Mark Youngb9835412017-01-25 12:25:10 -0800469 VkInstance instance = VK_NULL_HANDLE;
470 VkResult result = vkCreateInstance(VK::InstanceCreateInfo(), VK_NULL_HANDLE, &instance);
471 ASSERT_EQ(result, VK_SUCCESS);
472
473 uint32_t physicalCount = 500;
474 std::unique_ptr<VkPhysicalDevice[]> physical(new VkPhysicalDevice[physicalCount]);
475 result = vkEnumeratePhysicalDevices(instance, &physicalCount, physical.get());
476 ASSERT_EQ(result, VK_SUCCESS);
477 ASSERT_GT(physicalCount, 0u);
478
479 vkDestroyInstance(instance, nullptr);
480}
481
482// Used by run_loader_tests.sh to test for the expected usage of the vkEnumeratePhysicalDevices call.
Mark Youngab2c5352017-03-16 13:56:32 -0600483TEST(EnumeratePhysicalDevices, TwoCall) {
Mark Youngb9835412017-01-25 12:25:10 -0800484 VkInstance instance = VK_NULL_HANDLE;
485 VkResult result = vkCreateInstance(VK::InstanceCreateInfo(), VK_NULL_HANDLE, &instance);
486 ASSERT_EQ(result, VK_SUCCESS);
487
488 uint32_t physicalCount = 0;
489 result = vkEnumeratePhysicalDevices(instance, &physicalCount, nullptr);
490 ASSERT_EQ(result, VK_SUCCESS);
491 ASSERT_GT(physicalCount, 0u);
492
493 std::unique_ptr<VkPhysicalDevice[]> physical(new VkPhysicalDevice[physicalCount]);
494 result = vkEnumeratePhysicalDevices(instance, &physicalCount, physical.get());
495 ASSERT_EQ(result, VK_SUCCESS);
496 ASSERT_GT(physicalCount, 0u);
497
498 vkDestroyInstance(instance, nullptr);
499}
500
501// Used by run_loader_tests.sh to test that calling vkEnumeratePhysicalDevices without first querying
502// the count, matches the count from the standard call.
Mark Youngab2c5352017-03-16 13:56:32 -0600503TEST(EnumeratePhysicalDevices, MatchOneAndTwoCallNumbers) {
Mark Youngb9835412017-01-25 12:25:10 -0800504 VkInstance instance_one = VK_NULL_HANDLE;
505 VkResult result = vkCreateInstance(VK::InstanceCreateInfo(), VK_NULL_HANDLE, &instance_one);
506 ASSERT_EQ(result, VK_SUCCESS);
507
508 uint32_t physicalCount_one = 500;
509 std::unique_ptr<VkPhysicalDevice[]> physical_one(new VkPhysicalDevice[physicalCount_one]);
510 result = vkEnumeratePhysicalDevices(instance_one, &physicalCount_one, physical_one.get());
511 ASSERT_EQ(result, VK_SUCCESS);
512 ASSERT_GT(physicalCount_one, 0u);
513
514 VkInstance instance_two = VK_NULL_HANDLE;
515 result = vkCreateInstance(VK::InstanceCreateInfo(), VK_NULL_HANDLE, &instance_two);
516 ASSERT_EQ(result, VK_SUCCESS);
517
518 uint32_t physicalCount_two = 0;
519 result = vkEnumeratePhysicalDevices(instance_two, &physicalCount_two, nullptr);
520 ASSERT_EQ(result, VK_SUCCESS);
521 ASSERT_GT(physicalCount_two, 0u);
522
523 std::unique_ptr<VkPhysicalDevice[]> physical_two(new VkPhysicalDevice[physicalCount_two]);
524 result = vkEnumeratePhysicalDevices(instance_two, &physicalCount_two, physical_two.get());
525 ASSERT_EQ(result, VK_SUCCESS);
526 ASSERT_GT(physicalCount_two, 0u);
527
528 ASSERT_EQ(physicalCount_one, physicalCount_two);
529
530 vkDestroyInstance(instance_one, nullptr);
531 vkDestroyInstance(instance_two, nullptr);
532}
533
534// Used by run_loader_tests.sh to test for the expected usage of the vkEnumeratePhysicalDevices
535// call if not enough numbers are provided for the final list.
Mark Youngab2c5352017-03-16 13:56:32 -0600536TEST(EnumeratePhysicalDevices, TwoCallIncomplete) {
Mark Youngb9835412017-01-25 12:25:10 -0800537 VkInstance instance = VK_NULL_HANDLE;
538 VkResult result = vkCreateInstance(VK::InstanceCreateInfo(), VK_NULL_HANDLE, &instance);
539 ASSERT_EQ(result, VK_SUCCESS);
540
541 uint32_t physicalCount = 0;
542 result = vkEnumeratePhysicalDevices(instance, &physicalCount, nullptr);
543 ASSERT_EQ(result, VK_SUCCESS);
544 ASSERT_GT(physicalCount, 0u);
545
546 std::unique_ptr<VkPhysicalDevice[]> physical(new VkPhysicalDevice[physicalCount]);
547
548 // Remove one from the physical device count so we can get the VK_INCOMPLETE message
549 physicalCount -= 1;
550
551 result = vkEnumeratePhysicalDevices(instance, &physicalCount, physical.get());
552 ASSERT_EQ(result, VK_INCOMPLETE);
553
554 vkDestroyInstance(instance, nullptr);
555}
556
Mark Youngc8b807a2017-07-14 17:11:31 -0600557// Test to make sure that layers enabled in the instance show up in the list of device layers.
558TEST(EnumerateDeviceLayers, LayersMatch) {
559 char const *const names1[] = {"VK_LAYER_LUNARG_standard_validation"};
560 char const *const names2[3] = {"VK_LAYER_LUNARG_parameter_validation", "VK_LAYER_LUNARG_core_validation",
561 "VK_LAYER_LUNARG_object_tracker"};
562 auto const info1 = VK::InstanceCreateInfo().enabledLayerCount(1).ppEnabledLayerNames(names1);
563 VkInstance instance = VK_NULL_HANDLE;
564 VkResult result = vkCreateInstance(info1, VK_NULL_HANDLE, &instance);
565 ASSERT_EQ(result, VK_SUCCESS);
566
567 uint32_t physicalCount = 0;
568 result = vkEnumeratePhysicalDevices(instance, &physicalCount, nullptr);
569 ASSERT_EQ(result, VK_SUCCESS);
570 ASSERT_GT(physicalCount, 0u);
571
572 std::unique_ptr<VkPhysicalDevice[]> physical(new VkPhysicalDevice[physicalCount]);
573 result = vkEnumeratePhysicalDevices(instance, &physicalCount, physical.get());
574 ASSERT_EQ(result, VK_SUCCESS);
575 ASSERT_GT(physicalCount, 0u);
576 uint32_t count = 24;
577 VkLayerProperties layer_props[24];
578 vkEnumerateDeviceLayerProperties(physical[0], &count, layer_props);
579 ASSERT_GE(count, 1u);
580 bool found = false;
581 for (uint32_t iii = 0; iii < count; iii++) {
582 if (!strcmp(layer_props[iii].layerName, names1[0])) {
583 found = true;
584 break;
585 }
586 }
587 if (!found) {
588 ASSERT_EQ(count, 0);
589 }
590
591 vkDestroyInstance(instance, nullptr);
592
593 auto const info2 = VK::InstanceCreateInfo().enabledLayerCount(3).ppEnabledLayerNames(names2);
594 instance = VK_NULL_HANDLE;
595 result = vkCreateInstance(info2, VK_NULL_HANDLE, &instance);
596 ASSERT_EQ(result, VK_SUCCESS);
597
598 physicalCount = 0;
599 result = vkEnumeratePhysicalDevices(instance, &physicalCount, nullptr);
600 ASSERT_EQ(result, VK_SUCCESS);
601 ASSERT_GT(physicalCount, 0u);
602
603 std::unique_ptr<VkPhysicalDevice[]> physical2(new VkPhysicalDevice[physicalCount]);
604 result = vkEnumeratePhysicalDevices(instance, &physicalCount, physical2.get());
605 ASSERT_EQ(result, VK_SUCCESS);
606 ASSERT_GT(physicalCount, 0u);
607
608 count = 24;
609 vkEnumerateDeviceLayerProperties(physical2[0], &count, layer_props);
610 ASSERT_GE(count, 3u);
611 for (uint32_t jjj = 0; jjj < 3; jjj++) {
612 found = false;
613 for (uint32_t iii = 0; iii < count; iii++) {
614 if (!strcmp(layer_props[iii].layerName, names2[jjj])) {
615 found = true;
616 break;
617 }
618 }
619 if (!found) {
620 ASSERT_EQ(count, 0);
621 }
622 }
623
624 vkDestroyInstance(instance, nullptr);
625}
626
Mark Lobodzinski51414032016-09-07 16:29:11 -0600627TEST(CreateDevice, ExtensionNotPresent) {
Jeremy Hayes097188a2016-06-15 16:37:17 -0600628 VkInstance instance = VK_NULL_HANDLE;
Jeremy Hayesc5587182016-06-28 11:29:05 -0600629 VkResult result = vkCreateInstance(VK::InstanceCreateInfo(), VK_NULL_HANDLE, &instance);
Jeremy Hayes097188a2016-06-15 16:37:17 -0600630 ASSERT_EQ(result, VK_SUCCESS);
631
632 uint32_t physicalCount = 0;
633 result = vkEnumeratePhysicalDevices(instance, &physicalCount, nullptr);
634 ASSERT_EQ(result, VK_SUCCESS);
Jeremy Hayesa6fb5b42016-06-21 10:54:01 -0600635 ASSERT_GT(physicalCount, 0u);
Jeremy Hayes097188a2016-06-15 16:37:17 -0600636
637 std::unique_ptr<VkPhysicalDevice[]> physical(new VkPhysicalDevice[physicalCount]);
638 result = vkEnumeratePhysicalDevices(instance, &physicalCount, physical.get());
639 ASSERT_EQ(result, VK_SUCCESS);
Jeremy Hayesa6fb5b42016-06-21 10:54:01 -0600640 ASSERT_GT(physicalCount, 0u);
Jeremy Hayes097188a2016-06-15 16:37:17 -0600641
Mark Lobodzinski51414032016-09-07 16:29:11 -0600642 for (uint32_t p = 0; p < physicalCount; ++p) {
Jeremy Hayes097188a2016-06-15 16:37:17 -0600643 uint32_t familyCount = 0;
644 vkGetPhysicalDeviceQueueFamilyProperties(physical[p], &familyCount, nullptr);
Jeremy Hayesa6fb5b42016-06-21 10:54:01 -0600645 ASSERT_GT(familyCount, 0u);
Jeremy Hayes097188a2016-06-15 16:37:17 -0600646
647 std::unique_ptr<VkQueueFamilyProperties[]> family(new VkQueueFamilyProperties[familyCount]);
648 vkGetPhysicalDeviceQueueFamilyProperties(physical[p], &familyCount, family.get());
Jeremy Hayesa6fb5b42016-06-21 10:54:01 -0600649 ASSERT_GT(familyCount, 0u);
Jeremy Hayes097188a2016-06-15 16:37:17 -0600650
Mark Lobodzinski51414032016-09-07 16:29:11 -0600651 for (uint32_t q = 0; q < familyCount; ++q) {
652 if (~family[q].queueFlags & VK_QUEUE_GRAPHICS_BIT) {
Jeremy Hayes097188a2016-06-15 16:37:17 -0600653 continue;
654 }
655
Mark Lobodzinski64318ba2017-01-26 13:34:13 -0700656 float const priorities[] = {0.0f}; // Temporary required due to MSVC bug.
Mark Lobodzinski51414032016-09-07 16:29:11 -0600657 VkDeviceQueueCreateInfo const queueInfo[1]{
658 VK::DeviceQueueCreateInfo().queueFamilyIndex(q).queueCount(1).pQueuePriorities(priorities)};
Jeremy Hayes097188a2016-06-15 16:37:17 -0600659
Mark Lobodzinski64318ba2017-01-26 13:34:13 -0700660 char const *const names[] = {"NotPresent"}; // Temporary required due to MSVC bug.
Mark Lobodzinski51414032016-09-07 16:29:11 -0600661 auto const deviceInfo = VK::DeviceCreateInfo()
662 .queueCreateInfoCount(1)
663 .pQueueCreateInfos(queueInfo)
664 .enabledExtensionCount(1)
665 .ppEnabledExtensionNames(names);
Jeremy Hayes097188a2016-06-15 16:37:17 -0600666
667 VkDevice device;
Jeremy Hayesc5587182016-06-28 11:29:05 -0600668 result = vkCreateDevice(physical[p], deviceInfo, nullptr, &device);
Jeremy Hayes097188a2016-06-15 16:37:17 -0600669 ASSERT_EQ(result, VK_ERROR_EXTENSION_NOT_PRESENT);
Jeremy Hayes10357562016-07-06 11:56:44 -0600670
671 // It's not necessary to destroy the device because it will not be created successfully.
Jeremy Hayes097188a2016-06-15 16:37:17 -0600672 }
673 }
Jeremy Hayes10357562016-07-06 11:56:44 -0600674
675 vkDestroyInstance(instance, nullptr);
Jeremy Hayes097188a2016-06-15 16:37:17 -0600676}
677
Rene Lindsaye7ec3de2016-06-28 10:36:01 -0600678// LX535 / MI-76: Device layers are deprecated.
679// For backwards compatibility, they are allowed, but must be ignored.
680// Ensure that no errors occur if a bogus device layer list is passed to vkCreateDevice.
Mark Lobodzinski51414032016-09-07 16:29:11 -0600681TEST(CreateDevice, LayersNotPresent) {
Rene Lindsaye7ec3de2016-06-28 10:36:01 -0600682 VkInstance instance = VK_NULL_HANDLE;
Jeremy Hayesc5587182016-06-28 11:29:05 -0600683 VkResult result = vkCreateInstance(VK::InstanceCreateInfo(), VK_NULL_HANDLE, &instance);
Rene Lindsaye7ec3de2016-06-28 10:36:01 -0600684 ASSERT_EQ(result, VK_SUCCESS);
685
686 uint32_t physicalCount = 0;
687 result = vkEnumeratePhysicalDevices(instance, &physicalCount, nullptr);
688 ASSERT_EQ(result, VK_SUCCESS);
689 ASSERT_GT(physicalCount, 0u);
690
691 std::unique_ptr<VkPhysicalDevice[]> physical(new VkPhysicalDevice[physicalCount]);
692 result = vkEnumeratePhysicalDevices(instance, &physicalCount, physical.get());
693 ASSERT_EQ(result, VK_SUCCESS);
694 ASSERT_GT(physicalCount, 0u);
695
Mark Lobodzinski51414032016-09-07 16:29:11 -0600696 for (uint32_t p = 0; p < physicalCount; ++p) {
Rene Lindsaye7ec3de2016-06-28 10:36:01 -0600697 uint32_t familyCount = 0;
698 vkGetPhysicalDeviceQueueFamilyProperties(physical[p], &familyCount, nullptr);
699 ASSERT_EQ(result, VK_SUCCESS);
700 ASSERT_GT(familyCount, 0u);
701
702 std::unique_ptr<VkQueueFamilyProperties[]> family(new VkQueueFamilyProperties[familyCount]);
703 vkGetPhysicalDeviceQueueFamilyProperties(physical[p], &familyCount, family.get());
704 ASSERT_EQ(result, VK_SUCCESS);
705 ASSERT_GT(familyCount, 0u);
706
Mark Lobodzinski51414032016-09-07 16:29:11 -0600707 for (uint32_t q = 0; q < familyCount; ++q) {
708 if (~family[q].queueFlags & VK_QUEUE_GRAPHICS_BIT) {
Rene Lindsaye7ec3de2016-06-28 10:36:01 -0600709 continue;
710 }
711
Mark Lobodzinski64318ba2017-01-26 13:34:13 -0700712 float const priorities[] = {0.0f}; // Temporary required due to MSVC bug.
Mark Lobodzinski51414032016-09-07 16:29:11 -0600713 VkDeviceQueueCreateInfo const queueInfo[1]{
714 VK::DeviceQueueCreateInfo().queueFamilyIndex(q).queueCount(1).pQueuePriorities(priorities)};
Rene Lindsaye7ec3de2016-06-28 10:36:01 -0600715
Mark Lobodzinski64318ba2017-01-26 13:34:13 -0700716 char const *const names[] = {"NotPresent"}; // Temporary required due to MSVC bug.
Mark Lobodzinski51414032016-09-07 16:29:11 -0600717 auto const deviceInfo = VK::DeviceCreateInfo()
718 .queueCreateInfoCount(1)
719 .pQueueCreateInfos(queueInfo)
720 .enabledLayerCount(1)
721 .ppEnabledLayerNames(names);
Rene Lindsaye7ec3de2016-06-28 10:36:01 -0600722
723 VkDevice device;
Jeremy Hayesc5587182016-06-28 11:29:05 -0600724 result = vkCreateDevice(physical[p], deviceInfo, nullptr, &device);
725 ASSERT_EQ(result, VK_SUCCESS);
Jeremy Hayes10357562016-07-06 11:56:44 -0600726
727 vkDestroyDevice(device, nullptr);
Jeremy Hayesc5587182016-06-28 11:29:05 -0600728 }
729 }
Jeremy Hayes10357562016-07-06 11:56:44 -0600730
731 vkDestroyInstance(instance, nullptr);
732}
733
Mark Lobodzinski51414032016-09-07 16:29:11 -0600734TEST_F(EnumerateInstanceLayerProperties, PropertyCountLessThanAvailable) {
Jeremy Hayes10357562016-07-06 11:56:44 -0600735 uint32_t count = 0u;
736 VkResult result = vkEnumerateInstanceLayerProperties(&count, nullptr);
737 ASSERT_EQ(result, VK_SUCCESS);
738
739 // We need atleast two for the test to be relevant.
Mark Lobodzinski51414032016-09-07 16:29:11 -0600740 if (count < 2u) {
Jeremy Hayes10357562016-07-06 11:56:44 -0600741 return;
742 }
743
744 std::unique_ptr<VkLayerProperties[]> properties(new VkLayerProperties[count]);
745 count = 1;
746 result = vkEnumerateInstanceLayerProperties(&count, properties.get());
747 ASSERT_EQ(result, VK_INCOMPLETE);
748}
749
Mark Lobodzinski51414032016-09-07 16:29:11 -0600750TEST(EnumerateDeviceLayerProperties, PropertyCountLessThanAvailable) {
Jeremy Hayes10357562016-07-06 11:56:44 -0600751 VkInstance instance = VK_NULL_HANDLE;
752 VkResult result = vkCreateInstance(VK::InstanceCreateInfo(), VK_NULL_HANDLE, &instance);
753 ASSERT_EQ(result, VK_SUCCESS);
754
755 uint32_t physicalCount = 0;
756 result = vkEnumeratePhysicalDevices(instance, &physicalCount, nullptr);
757 ASSERT_EQ(result, VK_SUCCESS);
758 ASSERT_GT(physicalCount, 0u);
759
760 std::unique_ptr<VkPhysicalDevice[]> physical(new VkPhysicalDevice[physicalCount]);
761 result = vkEnumeratePhysicalDevices(instance, &physicalCount, physical.get());
762 ASSERT_EQ(result, VK_SUCCESS);
763 ASSERT_GT(physicalCount, 0u);
764
Mark Lobodzinski51414032016-09-07 16:29:11 -0600765 for (uint32_t p = 0; p < physicalCount; ++p) {
Jeremy Hayes10357562016-07-06 11:56:44 -0600766 uint32_t count = 0u;
767 result = vkEnumerateDeviceLayerProperties(physical[p], &count, nullptr);
768 ASSERT_EQ(result, VK_SUCCESS);
769
770 // We need atleast two for the test to be relevant.
Mark Lobodzinski51414032016-09-07 16:29:11 -0600771 if (count < 2u) {
Jeremy Hayes10357562016-07-06 11:56:44 -0600772 continue;
773 }
774
775 std::unique_ptr<VkLayerProperties[]> properties(new VkLayerProperties[count]);
776 count = 1;
777 result = vkEnumerateDeviceLayerProperties(physical[p], &count, properties.get());
778 ASSERT_EQ(result, VK_INCOMPLETE);
779 }
780
781 vkDestroyInstance(instance, nullptr);
782}
783
Mark Lobodzinski51414032016-09-07 16:29:11 -0600784TEST_F(EnumerateInstanceLayerProperties, Count) {
Jeremy Hayes10357562016-07-06 11:56:44 -0600785 uint32_t count = 0u;
786 VkResult result = vkEnumerateInstanceLayerProperties(&count, nullptr);
787 ASSERT_EQ(result, VK_SUCCESS);
788
Mark Lobodzinski51414032016-09-07 16:29:11 -0600789 if (std::find(arguments.begin(), arguments.end(), "count") != arguments.end()) {
Jeremy Hayes10357562016-07-06 11:56:44 -0600790 std::cout << "count=" << count << '\n';
791 }
792}
793
Mark Lobodzinski51414032016-09-07 16:29:11 -0600794TEST_F(EnumerateInstanceLayerProperties, OnePass) {
Jeremy Hayes10357562016-07-06 11:56:44 -0600795 // Count required for this test.
Mark Lobodzinski51414032016-09-07 16:29:11 -0600796 if (std::find(arguments.begin(), arguments.end(), "count") == arguments.end()) {
Jeremy Hayes10357562016-07-06 11:56:44 -0600797 return;
798 }
799
800 uint32_t count = std::stoul(arguments[2]);
801
802 std::unique_ptr<VkLayerProperties[]> properties(new VkLayerProperties[count]);
803 VkResult result = vkEnumerateInstanceLayerProperties(&count, properties.get());
804 ASSERT_EQ(result, VK_SUCCESS);
805
Mark Lobodzinski51414032016-09-07 16:29:11 -0600806 if (std::find(arguments.begin(), arguments.end(), "properties") != arguments.end()) {
807 for (uint32_t p = 0; p < count; ++p) {
808 std::cout << "properties[" << p << "] =" << ' ' << properties[p].layerName << ' ' << properties[p].specVersion << ' '
809 << properties[p].implementationVersion << ' ' << properties[p].description << '\n';
Jeremy Hayes10357562016-07-06 11:56:44 -0600810 }
811 }
812}
813
Mark Lobodzinski51414032016-09-07 16:29:11 -0600814TEST_F(EnumerateInstanceLayerProperties, TwoPass) {
Jeremy Hayes10357562016-07-06 11:56:44 -0600815 uint32_t count = 0u;
816 VkResult result = vkEnumerateInstanceLayerProperties(&count, nullptr);
817 ASSERT_EQ(result, VK_SUCCESS);
818
819 std::unique_ptr<VkLayerProperties[]> properties(new VkLayerProperties[count]);
820 result = vkEnumerateInstanceLayerProperties(&count, properties.get());
821 ASSERT_EQ(result, VK_SUCCESS);
822
Mark Lobodzinski51414032016-09-07 16:29:11 -0600823 if (std::find(arguments.begin(), arguments.end(), "properties") != arguments.end()) {
824 for (uint32_t p = 0; p < count; ++p) {
825 std::cout << "properties[" << p << "] =" << ' ' << properties[p].layerName << ' ' << properties[p].specVersion << ' '
826 << properties[p].implementationVersion << ' ' << properties[p].description << '\n';
Jeremy Hayes10357562016-07-06 11:56:44 -0600827 }
828 }
829}
830
Mark Lobodzinski51414032016-09-07 16:29:11 -0600831TEST_F(EnumerateInstanceExtensionProperties, PropertyCountLessThanAvailable) {
Jeremy Hayes10357562016-07-06 11:56:44 -0600832 uint32_t count = 0u;
833 VkResult result = vkEnumerateInstanceExtensionProperties(nullptr, &count, nullptr);
834 ASSERT_EQ(result, VK_SUCCESS);
835
836 // We need atleast two for the test to be relevant.
Mark Lobodzinski51414032016-09-07 16:29:11 -0600837 if (count < 2u) {
Jeremy Hayes10357562016-07-06 11:56:44 -0600838 return;
839 }
840
841 std::unique_ptr<VkExtensionProperties[]> properties(new VkExtensionProperties[count]);
842 count = 1;
843 result = vkEnumerateInstanceExtensionProperties(nullptr, &count, properties.get());
844 ASSERT_EQ(result, VK_INCOMPLETE);
845}
846
Mark Lobodzinski51414032016-09-07 16:29:11 -0600847TEST(EnumerateDeviceExtensionProperties, PropertyCountLessThanAvailable) {
Jeremy Hayes10357562016-07-06 11:56:44 -0600848 VkInstance instance = VK_NULL_HANDLE;
849 VkResult result = vkCreateInstance(VK::InstanceCreateInfo(), VK_NULL_HANDLE, &instance);
850 ASSERT_EQ(result, VK_SUCCESS);
851
852 uint32_t physicalCount = 0;
853 result = vkEnumeratePhysicalDevices(instance, &physicalCount, nullptr);
854 ASSERT_EQ(result, VK_SUCCESS);
855 ASSERT_GT(physicalCount, 0u);
856
857 std::unique_ptr<VkPhysicalDevice[]> physical(new VkPhysicalDevice[physicalCount]);
858 result = vkEnumeratePhysicalDevices(instance, &physicalCount, physical.get());
859 ASSERT_EQ(result, VK_SUCCESS);
860 ASSERT_GT(physicalCount, 0u);
861
Mark Lobodzinski51414032016-09-07 16:29:11 -0600862 for (uint32_t p = 0; p < physicalCount; ++p) {
Jeremy Hayes10357562016-07-06 11:56:44 -0600863 uint32_t count = 0u;
864 result = vkEnumerateDeviceExtensionProperties(physical[p], nullptr, &count, nullptr);
865 ASSERT_EQ(result, VK_SUCCESS);
866
867 // We need atleast two for the test to be relevant.
Mark Lobodzinski51414032016-09-07 16:29:11 -0600868 if (count < 2u) {
Jeremy Hayes10357562016-07-06 11:56:44 -0600869 continue;
870 }
871
872 std::unique_ptr<VkExtensionProperties[]> properties(new VkExtensionProperties[count]);
873 count = 1;
874 result = vkEnumerateDeviceExtensionProperties(physical[p], nullptr, &count, properties.get());
875 ASSERT_EQ(result, VK_INCOMPLETE);
876 }
877
878 vkDestroyInstance(instance, nullptr);
879}
880
Mark Lobodzinski51414032016-09-07 16:29:11 -0600881TEST_F(EnumerateInstanceExtensionProperties, Count) {
Jeremy Hayes10357562016-07-06 11:56:44 -0600882 uint32_t count = 0u;
883 VkResult result = vkEnumerateInstanceExtensionProperties(nullptr, &count, nullptr);
884 ASSERT_EQ(result, VK_SUCCESS);
885
Mark Lobodzinski51414032016-09-07 16:29:11 -0600886 if (std::find(arguments.begin(), arguments.end(), "count") != arguments.end()) {
Jeremy Hayes10357562016-07-06 11:56:44 -0600887 std::cout << "count=" << count << '\n';
888 }
889}
890
Mark Lobodzinski51414032016-09-07 16:29:11 -0600891TEST_F(EnumerateInstanceExtensionProperties, OnePass) {
Jeremy Hayes10357562016-07-06 11:56:44 -0600892 // Count required for this test.
Mark Lobodzinski51414032016-09-07 16:29:11 -0600893 if (std::find(arguments.begin(), arguments.end(), "count") == arguments.end()) {
Jeremy Hayes10357562016-07-06 11:56:44 -0600894 return;
895 }
896
897 uint32_t count = std::stoul(arguments[2]);
898
899 std::unique_ptr<VkExtensionProperties[]> properties(new VkExtensionProperties[count]);
900 VkResult result = vkEnumerateInstanceExtensionProperties(nullptr, &count, properties.get());
901 ASSERT_EQ(result, VK_SUCCESS);
902
Mark Lobodzinski51414032016-09-07 16:29:11 -0600903 if (std::find(arguments.begin(), arguments.end(), "properties") != arguments.end()) {
904 for (uint32_t p = 0; p < count; ++p) {
905 std::cout << "properties[" << p << "] =" << ' ' << properties[p].extensionName << ' ' << properties[p].specVersion
906 << '\n';
Jeremy Hayes10357562016-07-06 11:56:44 -0600907 }
908 }
909}
910
Mark Lobodzinski51414032016-09-07 16:29:11 -0600911TEST_F(EnumerateInstanceExtensionProperties, TwoPass) {
Jeremy Hayes10357562016-07-06 11:56:44 -0600912 uint32_t count = 0u;
913 VkResult result = vkEnumerateInstanceExtensionProperties(nullptr, &count, nullptr);
914 ASSERT_EQ(result, VK_SUCCESS);
915
916 std::unique_ptr<VkExtensionProperties[]> properties(new VkExtensionProperties[count]);
917 result = vkEnumerateInstanceExtensionProperties(nullptr, &count, properties.get());
918 ASSERT_EQ(result, VK_SUCCESS);
919
Mark Lobodzinski51414032016-09-07 16:29:11 -0600920 if (std::find(arguments.begin(), arguments.end(), "properties") != arguments.end()) {
921 for (uint32_t p = 0; p < count; ++p) {
922 std::cout << "properties[" << p << "] =" << ' ' << properties[p].extensionName << ' ' << properties[p].specVersion
923 << '\n';
Jeremy Hayes10357562016-07-06 11:56:44 -0600924 }
925 }
926}
927
Mark Lobodzinski51414032016-09-07 16:29:11 -0600928TEST_F(EnumerateInstanceExtensionProperties, InstanceExtensionEnumerated) {
Jeremy Hayes10357562016-07-06 11:56:44 -0600929 uint32_t count = 0u;
930 VkResult result = vkEnumerateInstanceExtensionProperties(nullptr, &count, nullptr);
931 ASSERT_EQ(result, VK_SUCCESS);
932
933 std::unique_ptr<VkExtensionProperties[]> properties(new VkExtensionProperties[count]);
934 result = vkEnumerateInstanceExtensionProperties(nullptr, &count, properties.get());
935 ASSERT_EQ(result, VK_SUCCESS);
936
937 ASSERT_NE(std::find_if(
Mark Lobodzinski51414032016-09-07 16:29:11 -0600938 &properties[0], &properties[count],
939 [](VkExtensionProperties const &properties) { return strcmp(properties.extensionName, "VK_KHR_surface") == 0; }),
940 &properties[count]);
Jeremy Hayes10357562016-07-06 11:56:44 -0600941}
942
Mark Lobodzinski51414032016-09-07 16:29:11 -0600943TEST(EnumerateDeviceExtensionProperties, DeviceExtensionEnumerated) {
Jeremy Hayes10357562016-07-06 11:56:44 -0600944 VkInstance instance = VK_NULL_HANDLE;
945 VkResult result = vkCreateInstance(VK::InstanceCreateInfo(), VK_NULL_HANDLE, &instance);
946 ASSERT_EQ(result, VK_SUCCESS);
947
948 uint32_t physicalCount = 0;
949 result = vkEnumeratePhysicalDevices(instance, &physicalCount, nullptr);
950 ASSERT_EQ(result, VK_SUCCESS);
951 ASSERT_GT(physicalCount, 0u);
952
953 std::unique_ptr<VkPhysicalDevice[]> physical(new VkPhysicalDevice[physicalCount]);
954 result = vkEnumeratePhysicalDevices(instance, &physicalCount, physical.get());
955 ASSERT_EQ(result, VK_SUCCESS);
956 ASSERT_GT(physicalCount, 0u);
957
Mark Lobodzinski51414032016-09-07 16:29:11 -0600958 for (uint32_t p = 0; p < physicalCount; ++p) {
Jeremy Hayes10357562016-07-06 11:56:44 -0600959 uint32_t count = 0u;
960 result = vkEnumerateDeviceExtensionProperties(physical[p], nullptr, &count, nullptr);
961 ASSERT_EQ(result, VK_SUCCESS);
962
963 std::unique_ptr<VkExtensionProperties[]> properties(new VkExtensionProperties[count]);
964 result = vkEnumerateDeviceExtensionProperties(physical[p], nullptr, &count, properties.get());
965 ASSERT_EQ(result, VK_SUCCESS);
966
Mark Lobodzinski51414032016-09-07 16:29:11 -0600967 ASSERT_NE(std::find_if(&properties[0], &properties[count],
968 [](VkExtensionProperties const &properties) {
969 return strcmp(properties.extensionName, "VK_KHR_swapchain") == 0;
970 }),
971 &properties[count]);
Jeremy Hayes10357562016-07-06 11:56:44 -0600972 }
973
974 vkDestroyInstance(instance, nullptr);
Jeremy Hayesc5587182016-06-28 11:29:05 -0600975}
976
Mark Lobodzinski51414032016-09-07 16:29:11 -0600977TEST_F(ImplicitLayer, Present) {
Jeremy Hayes52261802016-08-15 10:37:24 -0600978 auto const info = VK::InstanceCreateInfo();
979 VkInstance instance = VK_NULL_HANDLE;
980 VkResult result = vkCreateInstance(info, VK_NULL_HANDLE, &instance);
981 ASSERT_EQ(result, VK_SUCCESS);
982
983 vkDestroyInstance(instance, nullptr);
984}
985
Mark Lobodzinski51414032016-09-07 16:29:11 -0600986TEST(WrapObjects, Insert) {
Jeremy Hayesc5587182016-06-28 11:29:05 -0600987 VkInstance instance = VK_NULL_HANDLE;
988 VkResult result = vkCreateInstance(VK::InstanceCreateInfo(), VK_NULL_HANDLE, &instance);
989 ASSERT_EQ(result, VK_SUCCESS);
990
991 uint32_t physicalCount = 0;
992 result = vkEnumeratePhysicalDevices(instance, &physicalCount, nullptr);
993 ASSERT_EQ(result, VK_SUCCESS);
994 ASSERT_GT(physicalCount, 0u);
995
996 std::unique_ptr<VkPhysicalDevice[]> physical(new VkPhysicalDevice[physicalCount]);
997 result = vkEnumeratePhysicalDevices(instance, &physicalCount, physical.get());
998 ASSERT_EQ(result, VK_SUCCESS);
999 ASSERT_GT(physicalCount, 0u);
1000
Mark Lobodzinski51414032016-09-07 16:29:11 -06001001 for (uint32_t p = 0; p < physicalCount; ++p) {
Jeremy Hayesc5587182016-06-28 11:29:05 -06001002 uint32_t familyCount = 0;
1003 vkGetPhysicalDeviceQueueFamilyProperties(physical[p], &familyCount, nullptr);
1004 ASSERT_EQ(result, VK_SUCCESS);
1005 ASSERT_GT(familyCount, 0u);
1006
1007 std::unique_ptr<VkQueueFamilyProperties[]> family(new VkQueueFamilyProperties[familyCount]);
1008 vkGetPhysicalDeviceQueueFamilyProperties(physical[p], &familyCount, family.get());
1009 ASSERT_EQ(result, VK_SUCCESS);
1010 ASSERT_GT(familyCount, 0u);
1011
Mark Lobodzinski51414032016-09-07 16:29:11 -06001012 for (uint32_t q = 0; q < familyCount; ++q) {
1013 if (~family[q].queueFlags & VK_QUEUE_GRAPHICS_BIT) {
Jeremy Hayesc5587182016-06-28 11:29:05 -06001014 continue;
1015 }
1016
Mark Lobodzinski64318ba2017-01-26 13:34:13 -07001017 float const priorities[] = {0.0f}; // Temporary required due to MSVC bug.
Mark Lobodzinski51414032016-09-07 16:29:11 -06001018 VkDeviceQueueCreateInfo const queueInfo[1]{
1019 VK::DeviceQueueCreateInfo().queueFamilyIndex(q).queueCount(1).pQueuePriorities(priorities)};
Jeremy Hayesc5587182016-06-28 11:29:05 -06001020
Mark Lobodzinski51414032016-09-07 16:29:11 -06001021 auto const deviceInfo = VK::DeviceCreateInfo().queueCreateInfoCount(1).pQueueCreateInfos(queueInfo);
Jeremy Hayesc5587182016-06-28 11:29:05 -06001022
1023 VkDevice device;
1024 result = vkCreateDevice(physical[p], deviceInfo, nullptr, &device);
Rene Lindsaye7ec3de2016-06-28 10:36:01 -06001025 ASSERT_EQ(result, VK_SUCCESS);
Jeremy Hayes10357562016-07-06 11:56:44 -06001026
1027 vkDestroyDevice(device, nullptr);
Rene Lindsaye7ec3de2016-06-28 10:36:01 -06001028 }
1029 }
Jeremy Hayes10357562016-07-06 11:56:44 -06001030
1031 vkDestroyInstance(instance, nullptr);
Rene Lindsaye7ec3de2016-06-28 10:36:01 -06001032}
1033
Mark Youngc146fc22017-02-02 18:14:21 -07001034// Test making sure the allocation functions are called to allocate and cleanup everything during
1035// a CreateInstance/DestroyInstance call pair.
1036TEST(Allocation, Instance) {
1037 auto const info = VK::InstanceCreateInfo();
1038 VkInstance instance = VK_NULL_HANDLE;
1039 VkAllocationCallbacks alloc_callbacks = {};
1040 alloc_callbacks.pUserData = (void *)0x00000001;
1041 alloc_callbacks.pfnAllocation = AllocCallbackFunc;
1042 alloc_callbacks.pfnReallocation = ReallocCallbackFunc;
1043 alloc_callbacks.pfnFree = FreeCallbackFunc;
1044
1045 InitAllocTracker(2048);
1046
1047 VkResult result = vkCreateInstance(info, &alloc_callbacks, &instance);
1048 ASSERT_EQ(result, VK_SUCCESS);
1049
1050 alloc_callbacks.pUserData = (void *)0x00000002;
1051 vkDestroyInstance(instance, &alloc_callbacks);
1052
1053 // Make sure everything's been freed
1054 ASSERT_EQ(true, IsAllocTrackerEmpty());
1055 FreeAllocTracker();
1056}
1057
1058// Test making sure the allocation functions are called to allocate and cleanup everything during
1059// a CreateInstance/DestroyInstance call pair with a call to GetInstanceProcAddr.
1060TEST(Allocation, GetInstanceProcAddr) {
1061 auto const info = VK::InstanceCreateInfo();
1062 VkInstance instance = VK_NULL_HANDLE;
1063 VkAllocationCallbacks alloc_callbacks = {};
1064 alloc_callbacks.pUserData = (void *)0x00000010;
1065 alloc_callbacks.pfnAllocation = AllocCallbackFunc;
1066 alloc_callbacks.pfnReallocation = ReallocCallbackFunc;
1067 alloc_callbacks.pfnFree = FreeCallbackFunc;
1068
1069 InitAllocTracker(2048);
1070
1071 VkResult result = vkCreateInstance(info, &alloc_callbacks, &instance);
1072 ASSERT_EQ(result, VK_SUCCESS);
1073
1074 void *pfnCreateDevice = (void *)vkGetInstanceProcAddr(instance, "vkCreateDevice");
1075 void *pfnDestroyDevice = (void *)vkGetInstanceProcAddr(instance, "vkDestroyDevice");
Mark Younga10f1f52017-03-06 13:10:56 -07001076 ASSERT_TRUE(pfnCreateDevice != NULL && pfnDestroyDevice != NULL);
Mark Youngc146fc22017-02-02 18:14:21 -07001077
1078 alloc_callbacks.pUserData = (void *)0x00000011;
1079 vkDestroyInstance(instance, &alloc_callbacks);
1080
1081 // Make sure everything's been freed
1082 ASSERT_EQ(true, IsAllocTrackerEmpty());
1083 FreeAllocTracker();
1084}
1085
1086// Test making sure the allocation functions are called to allocate and cleanup everything during
1087// a vkEnumeratePhysicalDevices call pair.
1088TEST(Allocation, EnumeratePhysicalDevices) {
1089 auto const info = VK::InstanceCreateInfo();
1090 VkInstance instance = VK_NULL_HANDLE;
1091 VkAllocationCallbacks alloc_callbacks = {};
1092 alloc_callbacks.pUserData = (void *)0x00000021;
1093 alloc_callbacks.pfnAllocation = AllocCallbackFunc;
1094 alloc_callbacks.pfnReallocation = ReallocCallbackFunc;
1095 alloc_callbacks.pfnFree = FreeCallbackFunc;
1096
1097 InitAllocTracker(2048);
1098
1099 VkResult result = vkCreateInstance(info, &alloc_callbacks, &instance);
1100 ASSERT_EQ(result, VK_SUCCESS);
1101
1102 uint32_t physicalCount = 0;
1103 alloc_callbacks.pUserData = (void *)0x00000022;
1104 result = vkEnumeratePhysicalDevices(instance, &physicalCount, nullptr);
1105 ASSERT_EQ(result, VK_SUCCESS);
1106 ASSERT_GT(physicalCount, 0u);
1107
1108 std::unique_ptr<VkPhysicalDevice[]> physical(new VkPhysicalDevice[physicalCount]);
1109 alloc_callbacks.pUserData = (void *)0x00000023;
1110 result = vkEnumeratePhysicalDevices(instance, &physicalCount, physical.get());
1111 ASSERT_EQ(result, VK_SUCCESS);
1112 ASSERT_GT(physicalCount, 0u);
1113
1114 alloc_callbacks.pUserData = (void *)0x00000024;
1115 vkDestroyInstance(instance, &alloc_callbacks);
1116
1117 // Make sure everything's been freed
1118 ASSERT_EQ(true, IsAllocTrackerEmpty());
1119 FreeAllocTracker();
1120}
1121
1122// Test making sure the allocation functions are called to allocate and cleanup everything from
1123// vkCreateInstance, to vkCreateDevicce, and then through their destructors. With special
1124// allocators used on both the instance and device.
1125TEST(Allocation, InstanceAndDevice) {
1126 auto const info = VK::InstanceCreateInfo();
1127 VkInstance instance = VK_NULL_HANDLE;
1128 VkAllocationCallbacks alloc_callbacks = {};
1129 alloc_callbacks.pUserData = (void *)0x00000031;
1130 alloc_callbacks.pfnAllocation = AllocCallbackFunc;
1131 alloc_callbacks.pfnReallocation = ReallocCallbackFunc;
1132 alloc_callbacks.pfnFree = FreeCallbackFunc;
1133
1134 InitAllocTracker(2048);
1135
1136 VkResult result = vkCreateInstance(info, &alloc_callbacks, &instance);
1137 ASSERT_EQ(result, VK_SUCCESS);
1138
1139 uint32_t physicalCount = 0;
1140 result = vkEnumeratePhysicalDevices(instance, &physicalCount, nullptr);
1141 ASSERT_EQ(result, VK_SUCCESS);
1142 ASSERT_GT(physicalCount, 0u);
1143
1144 std::unique_ptr<VkPhysicalDevice[]> physical(new VkPhysicalDevice[physicalCount]);
1145 result = vkEnumeratePhysicalDevices(instance, &physicalCount, physical.get());
1146 ASSERT_EQ(result, VK_SUCCESS);
1147 ASSERT_GT(physicalCount, 0u);
1148
1149 for (uint32_t p = 0; p < physicalCount; ++p) {
1150 uint32_t familyCount = 0;
1151 vkGetPhysicalDeviceQueueFamilyProperties(physical[p], &familyCount, nullptr);
1152 ASSERT_GT(familyCount, 0u);
1153
1154 std::unique_ptr<VkQueueFamilyProperties[]> family(new VkQueueFamilyProperties[familyCount]);
1155 vkGetPhysicalDeviceQueueFamilyProperties(physical[p], &familyCount, family.get());
1156 ASSERT_GT(familyCount, 0u);
1157
1158 for (uint32_t q = 0; q < familyCount; ++q) {
1159 if (~family[q].queueFlags & VK_QUEUE_GRAPHICS_BIT) {
1160 continue;
1161 }
1162
1163 float const priorities[] = {0.0f}; // Temporary required due to MSVC bug.
1164 VkDeviceQueueCreateInfo const queueInfo[1]{
1165 VK::DeviceQueueCreateInfo().queueFamilyIndex(q).queueCount(1).pQueuePriorities(priorities)};
1166
1167 auto const deviceInfo = VK::DeviceCreateInfo().queueCreateInfoCount(1).pQueueCreateInfos(queueInfo);
1168
1169 VkDevice device;
1170 alloc_callbacks.pUserData = (void *)0x00000032;
1171 result = vkCreateDevice(physical[p], deviceInfo, &alloc_callbacks, &device);
1172 ASSERT_EQ(result, VK_SUCCESS);
1173
1174 alloc_callbacks.pUserData = (void *)0x00000033;
1175 vkDestroyDevice(device, &alloc_callbacks);
1176 }
1177 }
1178
1179 alloc_callbacks.pUserData = (void *)0x00000034;
1180 vkDestroyInstance(instance, &alloc_callbacks);
1181
1182 // Make sure everything's been freed
1183 ASSERT_EQ(true, IsAllocTrackerEmpty());
1184 FreeAllocTracker();
1185}
1186
1187// Test making sure the allocation functions are called to allocate and cleanup everything from
1188// vkCreateInstance, to vkCreateDevicce, and then through their destructors. With special
1189// allocators used on only the instance and not the device.
1190TEST(Allocation, InstanceButNotDevice) {
1191 auto const info = VK::InstanceCreateInfo();
1192 VkInstance instance = VK_NULL_HANDLE;
1193 VkAllocationCallbacks alloc_callbacks = {};
1194 alloc_callbacks.pUserData = (void *)0x00000041;
1195 alloc_callbacks.pfnAllocation = AllocCallbackFunc;
1196 alloc_callbacks.pfnReallocation = ReallocCallbackFunc;
1197 alloc_callbacks.pfnFree = FreeCallbackFunc;
1198
1199 InitAllocTracker(2048);
1200
1201 VkResult result = vkCreateInstance(info, &alloc_callbacks, &instance);
1202 ASSERT_EQ(result, VK_SUCCESS);
1203
1204 uint32_t physicalCount = 0;
1205 result = vkEnumeratePhysicalDevices(instance, &physicalCount, nullptr);
1206 ASSERT_EQ(result, VK_SUCCESS);
1207 ASSERT_GT(physicalCount, 0u);
1208
1209 std::unique_ptr<VkPhysicalDevice[]> physical(new VkPhysicalDevice[physicalCount]);
1210 result = vkEnumeratePhysicalDevices(instance, &physicalCount, physical.get());
1211 ASSERT_EQ(result, VK_SUCCESS);
1212 ASSERT_GT(physicalCount, 0u);
1213
1214 for (uint32_t p = 0; p < physicalCount; ++p) {
1215 uint32_t familyCount = 0;
1216 vkGetPhysicalDeviceQueueFamilyProperties(physical[p], &familyCount, nullptr);
1217 ASSERT_GT(familyCount, 0u);
1218
1219 std::unique_ptr<VkQueueFamilyProperties[]> family(new VkQueueFamilyProperties[familyCount]);
1220 vkGetPhysicalDeviceQueueFamilyProperties(physical[p], &familyCount, family.get());
1221 ASSERT_GT(familyCount, 0u);
1222
1223 for (uint32_t q = 0; q < familyCount; ++q) {
1224 if (~family[q].queueFlags & VK_QUEUE_GRAPHICS_BIT) {
1225 continue;
1226 }
1227
1228 float const priorities[] = {0.0f}; // Temporary required due to MSVC bug.
1229 VkDeviceQueueCreateInfo const queueInfo[1]{
1230 VK::DeviceQueueCreateInfo().queueFamilyIndex(q).queueCount(1).pQueuePriorities(priorities)};
1231
1232 auto const deviceInfo = VK::DeviceCreateInfo().queueCreateInfoCount(1).pQueueCreateInfos(queueInfo);
1233
1234 VkDevice device;
1235 result = vkCreateDevice(physical[p], deviceInfo, NULL, &device);
1236 ASSERT_EQ(result, VK_SUCCESS);
1237
1238 vkDestroyDevice(device, NULL);
1239 }
1240 }
1241
1242 alloc_callbacks.pUserData = (void *)0x00000042;
1243 vkDestroyInstance(instance, &alloc_callbacks);
1244
1245 // Make sure everything's been freed
1246 ASSERT_EQ(true, IsAllocTrackerEmpty());
1247 FreeAllocTracker();
1248}
1249
1250// Test making sure the allocation functions are called to allocate and cleanup everything from
1251// vkCreateInstance, to vkCreateDevicce, and then through their destructors. With special
1252// allocators used on only the device and not the instance.
1253TEST(Allocation, DeviceButNotInstance) {
1254 auto const info = VK::InstanceCreateInfo();
1255 VkInstance instance = VK_NULL_HANDLE;
1256 VkAllocationCallbacks alloc_callbacks = {};
1257 alloc_callbacks.pfnAllocation = AllocCallbackFunc;
1258 alloc_callbacks.pfnReallocation = ReallocCallbackFunc;
1259 alloc_callbacks.pfnFree = FreeCallbackFunc;
1260
1261 InitAllocTracker(2048);
1262
1263 VkResult result = vkCreateInstance(info, NULL, &instance);
1264 ASSERT_EQ(result, VK_SUCCESS);
1265
1266 uint32_t physicalCount = 0;
1267 result = vkEnumeratePhysicalDevices(instance, &physicalCount, nullptr);
1268 ASSERT_EQ(result, VK_SUCCESS);
1269 ASSERT_GT(physicalCount, 0u);
1270
1271 std::unique_ptr<VkPhysicalDevice[]> physical(new VkPhysicalDevice[physicalCount]);
1272 result = vkEnumeratePhysicalDevices(instance, &physicalCount, physical.get());
1273 ASSERT_EQ(result, VK_SUCCESS);
1274 ASSERT_GT(physicalCount, 0u);
1275
1276 for (uint32_t p = 0; p < physicalCount; ++p) {
1277 uint32_t familyCount = 0;
1278 vkGetPhysicalDeviceQueueFamilyProperties(physical[p], &familyCount, nullptr);
1279 ASSERT_GT(familyCount, 0u);
1280
1281 std::unique_ptr<VkQueueFamilyProperties[]> family(new VkQueueFamilyProperties[familyCount]);
1282 vkGetPhysicalDeviceQueueFamilyProperties(physical[p], &familyCount, family.get());
1283 ASSERT_GT(familyCount, 0u);
1284
1285 for (uint32_t q = 0; q < familyCount; ++q) {
1286 if (~family[q].queueFlags & VK_QUEUE_GRAPHICS_BIT) {
1287 continue;
1288 }
1289
1290 float const priorities[] = {0.0f}; // Temporary required due to MSVC bug.
1291 VkDeviceQueueCreateInfo const queueInfo[1]{
1292 VK::DeviceQueueCreateInfo().queueFamilyIndex(q).queueCount(1).pQueuePriorities(priorities)};
1293
1294 auto const deviceInfo = VK::DeviceCreateInfo().queueCreateInfoCount(1).pQueueCreateInfos(queueInfo);
1295
1296 VkDevice device;
1297 alloc_callbacks.pUserData = (void *)0x00000051;
1298 result = vkCreateDevice(physical[p], deviceInfo, &alloc_callbacks, &device);
1299 ASSERT_EQ(result, VK_SUCCESS);
1300
1301 alloc_callbacks.pUserData = (void *)0x00000052;
1302 vkDestroyDevice(device, &alloc_callbacks);
1303 }
1304 }
1305
1306 vkDestroyInstance(instance, NULL);
1307
1308 // Make sure everything's been freed
1309 ASSERT_EQ(true, IsAllocTrackerEmpty());
1310 FreeAllocTracker();
1311}
1312
Mark Young05e4f6a2017-03-15 10:36:03 -06001313// Test failure during vkCreateInstance to make sure we don't leak memory if
1314// one of the out-of-memory conditions trigger.
Mark Youngbb3a29c2017-05-19 12:29:43 -06001315TEST(Allocation, CreateInstanceIntentionalAllocFail) {
Mark Young05e4f6a2017-03-15 10:36:03 -06001316 auto const info = VK::InstanceCreateInfo();
1317 VkInstance instance = VK_NULL_HANDLE;
1318 VkAllocationCallbacks alloc_callbacks = {};
1319 alloc_callbacks.pfnAllocation = AllocCallbackFunc;
1320 alloc_callbacks.pfnReallocation = ReallocCallbackFunc;
1321 alloc_callbacks.pfnFree = FreeCallbackFunc;
1322
1323 VkResult result;
1324 uint32_t fail_index = 1;
1325 do {
1326 InitAllocTracker(9999, fail_index);
1327
1328 result = vkCreateInstance(info, &alloc_callbacks, &instance);
1329 if (result == VK_ERROR_OUT_OF_HOST_MEMORY) {
1330 if (!IsAllocTrackerEmpty()) {
1331 std::cout << "Failed on index " << fail_index << '\n';
1332 ASSERT_EQ(true, IsAllocTrackerEmpty());
1333 }
1334 }
1335 fail_index++;
1336 // Make sure we don't overrun the memory
1337 ASSERT_LT(fail_index, 9999u);
1338
1339 FreeAllocTracker();
1340 } while (result == VK_ERROR_OUT_OF_HOST_MEMORY);
1341
Mark Youngadead782017-05-12 15:14:05 -06001342 vkDestroyInstance(instance, &alloc_callbacks);
Mark Young05e4f6a2017-03-15 10:36:03 -06001343}
1344
1345// Test failure during vkCreateDevice to make sure we don't leak memory if
1346// one of the out-of-memory conditions trigger.
Mark Youngbb3a29c2017-05-19 12:29:43 -06001347TEST(Allocation, CreateDeviceIntentionalAllocFail) {
Mark Young05e4f6a2017-03-15 10:36:03 -06001348 auto const info = VK::InstanceCreateInfo();
1349 VkInstance instance = VK_NULL_HANDLE;
1350 VkDevice device = VK_NULL_HANDLE;
1351 VkAllocationCallbacks alloc_callbacks = {};
1352 alloc_callbacks.pfnAllocation = AllocCallbackFunc;
1353 alloc_callbacks.pfnReallocation = ReallocCallbackFunc;
1354 alloc_callbacks.pfnFree = FreeCallbackFunc;
1355
1356 VkResult result = vkCreateInstance(info, NULL, &instance);
1357 ASSERT_EQ(result, VK_SUCCESS);
1358
1359 uint32_t physicalCount = 0;
1360 result = vkEnumeratePhysicalDevices(instance, &physicalCount, nullptr);
1361 ASSERT_EQ(result, VK_SUCCESS);
1362 ASSERT_GT(physicalCount, 0u);
1363
1364 std::unique_ptr<VkPhysicalDevice[]> physical(new VkPhysicalDevice[physicalCount]);
1365 result = vkEnumeratePhysicalDevices(instance, &physicalCount, physical.get());
1366 ASSERT_EQ(result, VK_SUCCESS);
1367 ASSERT_GT(physicalCount, 0u);
1368
1369 for (uint32_t p = 0; p < physicalCount; ++p) {
1370 uint32_t familyCount = 0;
1371 vkGetPhysicalDeviceQueueFamilyProperties(physical[p], &familyCount, nullptr);
1372 ASSERT_GT(familyCount, 0u);
1373
1374 std::unique_ptr<VkQueueFamilyProperties[]> family(new VkQueueFamilyProperties[familyCount]);
1375 vkGetPhysicalDeviceQueueFamilyProperties(physical[p], &familyCount, family.get());
1376 ASSERT_GT(familyCount, 0u);
1377
1378 for (uint32_t q = 0; q < familyCount; ++q) {
1379 if (~family[q].queueFlags & VK_QUEUE_GRAPHICS_BIT) {
1380 continue;
1381 }
1382
1383 float const priorities[] = {0.0f}; // Temporary required due to MSVC bug.
1384 VkDeviceQueueCreateInfo const queueInfo[1]{
1385 VK::DeviceQueueCreateInfo().queueFamilyIndex(q).queueCount(1).pQueuePriorities(priorities)};
1386
1387 auto const deviceInfo = VK::DeviceCreateInfo().queueCreateInfoCount(1).pQueueCreateInfos(queueInfo);
1388
1389 uint32_t fail_index = 1;
1390 do {
1391 InitAllocTracker(9999, fail_index);
1392
1393 result = vkCreateDevice(physical[p], deviceInfo, &alloc_callbacks, &device);
1394 if (result == VK_ERROR_OUT_OF_HOST_MEMORY) {
1395 if (!IsAllocTrackerEmpty()) {
1396 std::cout << "Failed on index " << fail_index << '\n';
1397 ASSERT_EQ(true, IsAllocTrackerEmpty());
1398 }
1399 }
1400 fail_index++;
1401 // Make sure we don't overrun the memory
1402 ASSERT_LT(fail_index, 9999u);
1403
1404 FreeAllocTracker();
1405 } while (result == VK_ERROR_OUT_OF_HOST_MEMORY);
1406 vkDestroyDevice(device, &alloc_callbacks);
1407 break;
1408 }
1409 }
1410
1411 vkDestroyInstance(instance, NULL);
1412}
1413
1414// Test failure during vkCreateInstance and vkCreateDevice to make sure we don't
1415// leak memory if one of the out-of-memory conditions trigger.
Mark Youngbb3a29c2017-05-19 12:29:43 -06001416TEST(Allocation, CreateInstanceDeviceIntentionalAllocFail) {
Mark Young05e4f6a2017-03-15 10:36:03 -06001417 auto const info = VK::InstanceCreateInfo();
1418 VkInstance instance = VK_NULL_HANDLE;
1419 VkDevice device = VK_NULL_HANDLE;
1420 VkAllocationCallbacks alloc_callbacks = {};
1421 alloc_callbacks.pfnAllocation = AllocCallbackFunc;
1422 alloc_callbacks.pfnReallocation = ReallocCallbackFunc;
1423 alloc_callbacks.pfnFree = FreeCallbackFunc;
1424
1425 VkResult result = VK_ERROR_OUT_OF_HOST_MEMORY;
1426 uint32_t fail_index = 0;
1427 uint32_t physicalCount = 0;
1428 while (result == VK_ERROR_OUT_OF_HOST_MEMORY) {
1429 InitAllocTracker(9999, ++fail_index);
1430 ASSERT_LT(fail_index, 9999u);
1431
1432 result = vkCreateInstance(info, &alloc_callbacks, &instance);
1433 if (result == VK_ERROR_OUT_OF_HOST_MEMORY) {
1434 if (!IsAllocTrackerEmpty()) {
1435 std::cout << "Failed on index " << fail_index << '\n';
1436 ASSERT_EQ(true, IsAllocTrackerEmpty());
1437 }
1438 FreeAllocTracker();
1439 continue;
1440 }
1441 ASSERT_EQ(result, VK_SUCCESS);
1442
1443 physicalCount = 0;
1444 result = vkEnumeratePhysicalDevices(instance, &physicalCount, nullptr);
1445 if (result == VK_ERROR_OUT_OF_HOST_MEMORY) {
Mark Youngadead782017-05-12 15:14:05 -06001446 vkDestroyInstance(instance, &alloc_callbacks);
Mark Young05e4f6a2017-03-15 10:36:03 -06001447 if (!IsAllocTrackerEmpty()) {
1448 std::cout << "Failed on index " << fail_index << '\n';
1449 ASSERT_EQ(true, IsAllocTrackerEmpty());
1450 }
1451 FreeAllocTracker();
1452 continue;
1453 }
1454 ASSERT_EQ(result, VK_SUCCESS);
1455
1456 std::unique_ptr<VkPhysicalDevice[]> physical(new VkPhysicalDevice[physicalCount]);
1457 result = vkEnumeratePhysicalDevices(instance, &physicalCount, physical.get());
1458 if (result == VK_ERROR_OUT_OF_HOST_MEMORY) {
Mark Youngadead782017-05-12 15:14:05 -06001459 vkDestroyInstance(instance, &alloc_callbacks);
Mark Young05e4f6a2017-03-15 10:36:03 -06001460 if (!IsAllocTrackerEmpty()) {
1461 std::cout << "Failed on index " << fail_index << '\n';
1462 ASSERT_EQ(true, IsAllocTrackerEmpty());
1463 }
1464 FreeAllocTracker();
1465 continue;
1466 }
1467 ASSERT_EQ(result, VK_SUCCESS);
1468
1469 uint32_t familyCount = 0;
1470 vkGetPhysicalDeviceQueueFamilyProperties(physical[0], &familyCount, nullptr);
1471 ASSERT_GT(familyCount, 0u);
1472
1473 std::unique_ptr<VkQueueFamilyProperties[]> family(new VkQueueFamilyProperties[familyCount]);
1474 vkGetPhysicalDeviceQueueFamilyProperties(physical[0], &familyCount, family.get());
1475 ASSERT_GT(familyCount, 0u);
1476
1477 uint32_t queue_index = 0;
1478 for (uint32_t q = 0; q < familyCount; ++q) {
1479 if (family[q].queueFlags & VK_QUEUE_GRAPHICS_BIT) {
1480 queue_index = q;
1481 break;
1482 }
1483 }
1484
1485 float const priorities[] = {0.0f}; // Temporary required due to MSVC bug.
1486 VkDeviceQueueCreateInfo const queueInfo[1]{
1487 VK::DeviceQueueCreateInfo().queueFamilyIndex(queue_index).queueCount(1).pQueuePriorities(priorities)};
1488
1489 auto const deviceInfo = VK::DeviceCreateInfo().queueCreateInfoCount(1).pQueueCreateInfos(queueInfo);
1490
1491 result = vkCreateDevice(physical[0], deviceInfo, &alloc_callbacks, &device);
1492 if (result == VK_ERROR_OUT_OF_HOST_MEMORY) {
Mark Youngadead782017-05-12 15:14:05 -06001493 vkDestroyInstance(instance, &alloc_callbacks);
Mark Young05e4f6a2017-03-15 10:36:03 -06001494 if (!IsAllocTrackerEmpty()) {
1495 std::cout << "Failed on index " << fail_index << '\n';
1496 ASSERT_EQ(true, IsAllocTrackerEmpty());
1497 }
1498 FreeAllocTracker();
1499 continue;
1500 }
1501 vkDestroyDevice(device, &alloc_callbacks);
Mark Youngadead782017-05-12 15:14:05 -06001502 vkDestroyInstance(instance, &alloc_callbacks);
Mark Young05e4f6a2017-03-15 10:36:03 -06001503 FreeAllocTracker();
1504 }
1505}
1506
Mark Youngab2c5352017-03-16 13:56:32 -06001507// Used by run_loader_tests.sh to test that calling vkEnumeratePhysicalDeviceGroupsKHX without first querying
1508// the count, works. And, that it also returns only physical devices made available by the standard
1509// enumerate call
1510TEST(EnumeratePhysicalDeviceGroupsKHX, OneCall) {
1511 VkInstance instance = VK_NULL_HANDLE;
1512 char const *const names[] = {VK_KHX_DEVICE_GROUP_CREATION_EXTENSION_NAME};
1513 auto const info = VK::InstanceCreateInfo().enabledExtensionCount(1).ppEnabledExtensionNames(names);
1514 uint32_t group;
1515 uint32_t dev;
1516 std::vector<std::pair<VkPhysicalDevice, bool>> phys_dev_normal_found;
1517 std::vector<std::pair<VkPhysicalDevice, bool>> phys_dev_group_found;
1518
1519 VkResult result = vkCreateInstance(info, VK_NULL_HANDLE, &instance);
1520 if (result == VK_ERROR_EXTENSION_NOT_PRESENT) {
1521 // Extension isn't present, just skip this test
1522 ASSERT_EQ(result, VK_ERROR_EXTENSION_NOT_PRESENT);
1523 std::cout << "Skipping EnumeratePhysicalDeviceGroupsKHX : OneCall due to Instance lacking support"
1524 << " for " << VK_KHX_DEVICE_GROUP_CREATION_EXTENSION_NAME << " extension\n";
1525 return;
1526 }
1527
1528 uint32_t phys_dev_count = 500;
1529 std::unique_ptr<VkPhysicalDevice[]> phys_devs(new VkPhysicalDevice[phys_dev_count]);
1530 result = vkEnumeratePhysicalDevices(instance, &phys_dev_count, phys_devs.get());
1531 ASSERT_EQ(result, VK_SUCCESS);
1532 ASSERT_GT(phys_dev_count, 0u);
1533
1534 // Initialize the normal physical device boolean pair array
1535 for (dev = 0; dev < phys_dev_count; dev++) {
1536 phys_dev_normal_found.push_back(std::make_pair(phys_devs[dev], false));
1537 }
1538
1539 // Get a pointer to the new vkEnumeratePhysicalDeviceGroupsKHX call
1540 PFN_vkEnumeratePhysicalDeviceGroupsKHX p_vkEnumeratePhysicalDeviceGroupsKHX =
1541 (PFN_vkEnumeratePhysicalDeviceGroupsKHX)vkGetInstanceProcAddr(instance, "vkEnumeratePhysicalDeviceGroupsKHX");
1542
1543 // Setup the group information in preparation for the call
1544 uint32_t group_count = 30;
1545 std::unique_ptr<VkPhysicalDeviceGroupPropertiesKHX[]> phys_dev_groups(new VkPhysicalDeviceGroupPropertiesKHX[group_count]);
1546 for (group = 0; group < group_count; group++) {
1547 phys_dev_groups[group].sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_GROUP_PROPERTIES_KHX;
1548 phys_dev_groups[group].pNext = nullptr;
1549 phys_dev_groups[group].physicalDeviceCount = 0;
1550 memset(phys_dev_groups[group].physicalDevices, 0, sizeof(VkPhysicalDevice) * VK_MAX_DEVICE_GROUP_SIZE_KHX);
1551 phys_dev_groups[group].subsetAllocation = VK_FALSE;
1552 }
1553
1554 result = p_vkEnumeratePhysicalDeviceGroupsKHX(instance, &group_count, phys_dev_groups.get());
1555 ASSERT_EQ(result, VK_SUCCESS);
1556 ASSERT_GT(group_count, 0u);
1557
1558 // Initialize the group physical device boolean pair array
1559 for (group = 0; group < group_count; group++) {
1560 for (dev = 0; dev < phys_dev_groups[group].physicalDeviceCount; dev++) {
1561 phys_dev_group_found.push_back(std::make_pair(phys_dev_groups[group].physicalDevices[dev], false));
1562 }
1563 }
1564
1565 // Now, make sure we can find each normal and group item in the other list
1566 for (dev = 0; dev < phys_dev_count; dev++) {
1567 for (group = 0; group < phys_dev_group_found.size(); group++) {
1568 if (phys_dev_normal_found[dev].first == phys_dev_group_found[group].first) {
1569 phys_dev_normal_found[dev].second = true;
1570 phys_dev_group_found[group].second = true;
1571 break;
1572 }
1573 }
1574 }
1575
1576 for (dev = 0; dev < phys_dev_count; dev++) {
1577 ASSERT_EQ(phys_dev_normal_found[dev].second, true);
1578 }
1579 for (dev = 0; dev < phys_dev_group_found.size(); dev++) {
1580 ASSERT_EQ(phys_dev_group_found[dev].second, true);
1581 }
1582
1583 vkDestroyInstance(instance, nullptr);
1584}
1585
1586// Used by run_loader_tests.sh to test for the expected usage of the
1587// vkEnumeratePhysicalDeviceGroupsKHX call in a two call fasion (once with NULL data
1588// to get count, and then again with data).
1589TEST(EnumeratePhysicalDeviceGroupsKHX, TwoCall) {
1590 VkInstance instance = VK_NULL_HANDLE;
1591 char const *const names[] = {VK_KHX_DEVICE_GROUP_CREATION_EXTENSION_NAME};
1592 auto const info = VK::InstanceCreateInfo().enabledExtensionCount(1).ppEnabledExtensionNames(names);
1593 uint32_t group;
1594 uint32_t group_count;
1595 uint32_t dev;
1596 std::vector<std::pair<VkPhysicalDevice, bool>> phys_dev_normal_found;
1597 std::vector<std::pair<VkPhysicalDevice, bool>> phys_dev_group_found;
1598
1599 VkResult result = vkCreateInstance(info, VK_NULL_HANDLE, &instance);
1600 if (result == VK_ERROR_EXTENSION_NOT_PRESENT) {
1601 // Extension isn't present, just skip this test
1602 ASSERT_EQ(result, VK_ERROR_EXTENSION_NOT_PRESENT);
1603 std::cout << "Skipping EnumeratePhysicalDeviceGroupsKHX : TwoCall due to Instance lacking support"
1604 << " for " << VK_KHX_DEVICE_GROUP_CREATION_EXTENSION_NAME << " extension\n";
1605 return;
1606 }
1607
1608 // Get a pointer to the new vkEnumeratePhysicalDeviceGroupsKHX call
1609 PFN_vkEnumeratePhysicalDeviceGroupsKHX p_vkEnumeratePhysicalDeviceGroupsKHX =
1610 (PFN_vkEnumeratePhysicalDeviceGroupsKHX)vkGetInstanceProcAddr(instance, "vkEnumeratePhysicalDeviceGroupsKHX");
1611
1612 // Setup the group information in preparation for the call
1613 uint32_t array_group_count = 30;
1614 std::unique_ptr<VkPhysicalDeviceGroupPropertiesKHX[]> phys_dev_groups(
1615 new VkPhysicalDeviceGroupPropertiesKHX[array_group_count]);
1616 for (group = 0; group < array_group_count; group++) {
1617 phys_dev_groups[group].sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_GROUP_PROPERTIES_KHX;
1618 phys_dev_groups[group].pNext = nullptr;
1619 phys_dev_groups[group].physicalDeviceCount = 0;
1620 memset(phys_dev_groups[group].physicalDevices, 0, sizeof(VkPhysicalDevice) * VK_MAX_DEVICE_GROUP_SIZE_KHX);
1621 phys_dev_groups[group].subsetAllocation = VK_FALSE;
1622 }
1623
1624 result = p_vkEnumeratePhysicalDeviceGroupsKHX(instance, &group_count, nullptr);
1625 ASSERT_EQ(result, VK_SUCCESS);
1626 ASSERT_GT(group_count, 0u);
1627 ASSERT_LT(group_count, array_group_count);
1628
1629 result = p_vkEnumeratePhysicalDeviceGroupsKHX(instance, &group_count, phys_dev_groups.get());
1630 ASSERT_EQ(result, VK_SUCCESS);
1631 ASSERT_GT(group_count, 0u);
1632 ASSERT_LT(group_count, array_group_count);
1633
1634 // Initialize the group physical device boolean pair array
1635 for (group = 0; group < group_count; group++) {
1636 for (dev = 0; dev < phys_dev_groups[group].physicalDeviceCount; dev++) {
1637 phys_dev_group_found.push_back(std::make_pair(phys_dev_groups[group].physicalDevices[dev], false));
1638 }
1639 }
1640
1641 uint32_t phys_dev_count = 500;
1642 std::unique_ptr<VkPhysicalDevice[]> phys_devs(new VkPhysicalDevice[phys_dev_count]);
1643 result = vkEnumeratePhysicalDevices(instance, &phys_dev_count, phys_devs.get());
1644 ASSERT_EQ(result, VK_SUCCESS);
1645 ASSERT_GT(phys_dev_count, 0u);
1646
1647 // Initialize the normal physical device boolean pair array
1648 for (dev = 0; dev < phys_dev_count; dev++) {
1649 phys_dev_normal_found.push_back(std::make_pair(phys_devs[dev], false));
1650 }
1651
1652 // Now, make sure we can find each normal and group item in the other list
1653 for (dev = 0; dev < phys_dev_count; dev++) {
1654 for (group = 0; group < phys_dev_group_found.size(); group++) {
1655 if (phys_dev_normal_found[dev].first == phys_dev_group_found[group].first) {
1656 phys_dev_normal_found[dev].second = true;
1657 phys_dev_group_found[group].second = true;
1658 break;
1659 }
1660 }
1661 }
1662
1663 for (dev = 0; dev < phys_dev_count; dev++) {
1664 ASSERT_EQ(phys_dev_normal_found[dev].second, true);
1665 }
1666 for (dev = 0; dev < phys_dev_group_found.size(); dev++) {
1667 ASSERT_EQ(phys_dev_group_found[dev].second, true);
1668 }
1669
1670 vkDestroyInstance(instance, nullptr);
1671}
1672
1673// Used by run_loader_tests.sh to test for the expected usage of the EnumeratePhysicalDeviceGroupsKHX
1674// call if not enough numbers are provided for the final list.
1675TEST(EnumeratePhysicalDeviceGroupsKHX, TwoCallIncomplete) {
1676 VkInstance instance = VK_NULL_HANDLE;
1677 char const *const names[] = {VK_KHX_DEVICE_GROUP_CREATION_EXTENSION_NAME};
1678 auto const info = VK::InstanceCreateInfo().enabledExtensionCount(1).ppEnabledExtensionNames(names);
1679 uint32_t group;
1680 uint32_t group_count;
1681
1682 VkResult result = vkCreateInstance(info, VK_NULL_HANDLE, &instance);
1683 if (result == VK_ERROR_EXTENSION_NOT_PRESENT) {
1684 // Extension isn't present, just skip this test
1685 ASSERT_EQ(result, VK_ERROR_EXTENSION_NOT_PRESENT);
1686 std::cout << "Skipping EnumeratePhysicalDeviceGroupsKHX : TwoCallIncomplete due to Instance lacking support"
1687 << " for " << VK_KHX_DEVICE_GROUP_CREATION_EXTENSION_NAME << " extension\n";
1688 return;
1689 }
1690
1691 // Get a pointer to the new vkEnumeratePhysicalDeviceGroupsKHX call
1692 PFN_vkEnumeratePhysicalDeviceGroupsKHX p_vkEnumeratePhysicalDeviceGroupsKHX =
1693 (PFN_vkEnumeratePhysicalDeviceGroupsKHX)vkGetInstanceProcAddr(instance, "vkEnumeratePhysicalDeviceGroupsKHX");
1694
1695 // Setup the group information in preparation for the call
1696 uint32_t array_group_count = 30;
1697 std::unique_ptr<VkPhysicalDeviceGroupPropertiesKHX[]> phys_dev_groups(
1698 new VkPhysicalDeviceGroupPropertiesKHX[array_group_count]);
1699 for (group = 0; group < array_group_count; group++) {
1700 phys_dev_groups[group].sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_GROUP_PROPERTIES_KHX;
1701 phys_dev_groups[group].pNext = nullptr;
1702 phys_dev_groups[group].physicalDeviceCount = 0;
1703 memset(phys_dev_groups[group].physicalDevices, 0, sizeof(VkPhysicalDevice) * VK_MAX_DEVICE_GROUP_SIZE_KHX);
1704 phys_dev_groups[group].subsetAllocation = VK_FALSE;
1705 }
1706
1707 result = p_vkEnumeratePhysicalDeviceGroupsKHX(instance, &group_count, nullptr);
1708 ASSERT_EQ(result, VK_SUCCESS);
1709 ASSERT_GT(group_count, 0u);
1710 ASSERT_LT(group_count, array_group_count);
1711
1712 group_count -= 1;
1713
1714 result = p_vkEnumeratePhysicalDeviceGroupsKHX(instance, &group_count, phys_dev_groups.get());
1715 ASSERT_EQ(result, VK_INCOMPLETE);
1716
1717 vkDestroyInstance(instance, nullptr);
1718}
1719
Mark Lobodzinski51414032016-09-07 16:29:11 -06001720int main(int argc, char **argv) {
Jeremy Hayes6650d1f2016-04-20 09:00:39 -06001721 int result;
1722
1723 ::testing::InitGoogleTest(&argc, argv);
1724
Mark Lobodzinski51414032016-09-07 16:29:11 -06001725 if (argc > 0) {
Jeremy Hayes10357562016-07-06 11:56:44 -06001726 CommandLine::Initialize(argc, argv);
1727 }
1728
Jeremy Hayes6650d1f2016-04-20 09:00:39 -06001729 result = RUN_ALL_TESTS();
1730
1731 return result;
1732}