blob: 9835c80e1943cc781b61243b37df906cda66a7fb [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 Youngc146fc22017-02-02 18:14:21 -070029#ifdef _WIN32
30#include <inttypes.h> //Needed for PRIxLEAST64
31#endif
Mark Young05e4f6a2017-03-15 10:36:03 -060032#include <stdint.h> // For UINT32_MAX
Mark Youngc146fc22017-02-02 18:14:21 -070033
Jeremy Hayes10357562016-07-06 11:56:44 -060034#include <algorithm>
35#include <iostream>
Jeremy Hayesd8726c22016-04-21 13:19:41 -060036#include <memory>
Jeremy Hayes10357562016-07-06 11:56:44 -060037#include <string>
38#include <vector>
Jeremy Hayesd8726c22016-04-21 13:19:41 -060039
Jeremy Hayes6650d1f2016-04-20 09:00:39 -060040#include "test_common.h"
Mark Lobodzinski51414032016-09-07 16:29:11 -060041#include <vulkan/vulkan.h>
Jeremy Hayes6650d1f2016-04-20 09:00:39 -060042
Mark Lobodzinski51414032016-09-07 16:29:11 -060043namespace VK {
Jeremy Hayesc5587182016-06-28 11:29:05 -060044
Mark Lobodzinski51414032016-09-07 16:29:11 -060045struct InstanceCreateInfo {
46 InstanceCreateInfo()
Mark Lobodzinski64318ba2017-01-26 13:34:13 -070047 : info // MSVC can't handle list initialization, thus explicit construction herein.
Mark Lobodzinski51414032016-09-07 16:29:11 -060048 (VkInstanceCreateInfo{
Mark Lobodzinski64318ba2017-01-26 13:34:13 -070049 VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO, // sType
50 nullptr, // pNext
51 0, // flags
52 nullptr, // pApplicationInfo
53 0, // enabledLayerCount
54 nullptr, // ppEnabledLayerNames
55 0, // enabledExtensionCount
56 nullptr // ppEnabledExtensionNames
Mark Lobodzinski51414032016-09-07 16:29:11 -060057 }) {}
Jeremy Hayesc5587182016-06-28 11:29:05 -060058
Mark Lobodzinski51414032016-09-07 16:29:11 -060059 InstanceCreateInfo &sType(VkStructureType const &sType) {
Jeremy Hayesc5587182016-06-28 11:29:05 -060060 info.sType = sType;
61
62 return *this;
63 }
64
Mark Lobodzinski51414032016-09-07 16:29:11 -060065 InstanceCreateInfo &pNext(void const *const pNext) {
Jeremy Hayesc5587182016-06-28 11:29:05 -060066 info.pNext = pNext;
67
68 return *this;
69 }
70
Mark Lobodzinski51414032016-09-07 16:29:11 -060071 InstanceCreateInfo &flags(VkInstanceCreateFlags const &flags) {
Jeremy Hayesc5587182016-06-28 11:29:05 -060072 info.flags = flags;
73
74 return *this;
75 }
76
Mark Lobodzinski51414032016-09-07 16:29:11 -060077 InstanceCreateInfo &pApplicationInfo(VkApplicationInfo const *const pApplicationInfo) {
Jeremy Hayesc5587182016-06-28 11:29:05 -060078 info.pApplicationInfo = pApplicationInfo;
79
80 return *this;
81 }
82
Mark Lobodzinski51414032016-09-07 16:29:11 -060083 InstanceCreateInfo &enabledLayerCount(uint32_t const &enabledLayerCount) {
Jeremy Hayesc5587182016-06-28 11:29:05 -060084 info.enabledLayerCount = enabledLayerCount;
85
86 return *this;
87 }
88
Mark Lobodzinski51414032016-09-07 16:29:11 -060089 InstanceCreateInfo &ppEnabledLayerNames(char const *const *const ppEnabledLayerNames) {
Jeremy Hayesc5587182016-06-28 11:29:05 -060090 info.ppEnabledLayerNames = ppEnabledLayerNames;
91
92 return *this;
93 }
94
Mark Lobodzinski51414032016-09-07 16:29:11 -060095 InstanceCreateInfo &enabledExtensionCount(uint32_t const &enabledExtensionCount) {
Jeremy Hayesc5587182016-06-28 11:29:05 -060096 info.enabledExtensionCount = enabledExtensionCount;
97
98 return *this;
99 }
100
Mark Lobodzinski51414032016-09-07 16:29:11 -0600101 InstanceCreateInfo &ppEnabledExtensionNames(char const *const *const ppEnabledExtensionNames) {
Jeremy Hayesc5587182016-06-28 11:29:05 -0600102 info.ppEnabledExtensionNames = ppEnabledExtensionNames;
103
104 return *this;
105 }
106
Mark Lobodzinski51414032016-09-07 16:29:11 -0600107 operator VkInstanceCreateInfo const *() const { return &info; }
Jeremy Hayesc5587182016-06-28 11:29:05 -0600108
Mark Lobodzinski51414032016-09-07 16:29:11 -0600109 operator VkInstanceCreateInfo *() { return &info; }
Jeremy Hayesc5587182016-06-28 11:29:05 -0600110
111 VkInstanceCreateInfo info;
112};
113
Mark Lobodzinski51414032016-09-07 16:29:11 -0600114struct DeviceQueueCreateInfo {
115 DeviceQueueCreateInfo()
Mark Lobodzinski64318ba2017-01-26 13:34:13 -0700116 : info // MSVC can't handle list initialization, thus explicit construction herein.
Mark Lobodzinski51414032016-09-07 16:29:11 -0600117 (VkDeviceQueueCreateInfo{
Mark Lobodzinski64318ba2017-01-26 13:34:13 -0700118 VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO, // sType
119 nullptr, // pNext
120 0, // flags
121 0, // queueFamilyIndex
122 0, // queueCount
123 nullptr // pQueuePriorities
Mark Lobodzinski51414032016-09-07 16:29:11 -0600124 }) {}
Jeremy Hayesc5587182016-06-28 11:29:05 -0600125
Mark Lobodzinski51414032016-09-07 16:29:11 -0600126 DeviceQueueCreateInfo &sType(VkStructureType const &sType) {
Jeremy Hayesc5587182016-06-28 11:29:05 -0600127 info.sType = sType;
128
129 return *this;
130 }
131
Mark Lobodzinski51414032016-09-07 16:29:11 -0600132 DeviceQueueCreateInfo &pNext(void const *const pNext) {
Jeremy Hayesc5587182016-06-28 11:29:05 -0600133 info.pNext = pNext;
134
135 return *this;
136 }
137
Mark Lobodzinski51414032016-09-07 16:29:11 -0600138 DeviceQueueCreateInfo &flags(VkDeviceQueueCreateFlags const &flags) {
Jeremy Hayesc5587182016-06-28 11:29:05 -0600139 info.flags = flags;
140
141 return *this;
142 }
143
Mark Lobodzinski51414032016-09-07 16:29:11 -0600144 DeviceQueueCreateInfo &queueFamilyIndex(uint32_t const &queueFamilyIndex) {
Jeremy Hayesc5587182016-06-28 11:29:05 -0600145 info.queueFamilyIndex = queueFamilyIndex;
146
147 return *this;
148 }
149
Mark Lobodzinski51414032016-09-07 16:29:11 -0600150 DeviceQueueCreateInfo &queueCount(uint32_t const &queueCount) {
Jeremy Hayesc5587182016-06-28 11:29:05 -0600151 info.queueCount = queueCount;
152
153 return *this;
154 }
155
Mark Lobodzinski51414032016-09-07 16:29:11 -0600156 DeviceQueueCreateInfo &pQueuePriorities(float const *const pQueuePriorities) {
Jeremy Hayesc5587182016-06-28 11:29:05 -0600157 info.pQueuePriorities = pQueuePriorities;
158
159 return *this;
160 }
161
Mark Lobodzinski51414032016-09-07 16:29:11 -0600162 operator VkDeviceQueueCreateInfo() { return info; }
Jeremy Hayesc5587182016-06-28 11:29:05 -0600163
164 VkDeviceQueueCreateInfo info;
165};
166
Mark Lobodzinski51414032016-09-07 16:29:11 -0600167struct DeviceCreateInfo {
168 DeviceCreateInfo()
Mark Lobodzinski64318ba2017-01-26 13:34:13 -0700169 : info // MSVC can't handle list initialization, thus explicit construction herein.
Mark Lobodzinski51414032016-09-07 16:29:11 -0600170 (VkDeviceCreateInfo{
Mark Lobodzinski64318ba2017-01-26 13:34:13 -0700171 VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO, // sType
172 nullptr, // pNext
173 0, // flags
174 0, // queueCreateInfoCount
175 nullptr, // pQueueCreateInfos
176 0, // enabledLayerCount
177 nullptr, // ppEnabledLayerNames
178 0, // enabledExtensionCount
179 nullptr, // ppEnabledExtensionNames
180 nullptr // pEnabledFeatures
Mark Lobodzinski51414032016-09-07 16:29:11 -0600181 }) {}
Jeremy Hayesc5587182016-06-28 11:29:05 -0600182
Mark Lobodzinski51414032016-09-07 16:29:11 -0600183 DeviceCreateInfo &sType(VkStructureType const &sType) {
Jeremy Hayesc5587182016-06-28 11:29:05 -0600184 info.sType = sType;
185
186 return *this;
187 }
188
Mark Lobodzinski51414032016-09-07 16:29:11 -0600189 DeviceCreateInfo &pNext(void const *const pNext) {
Jeremy Hayesc5587182016-06-28 11:29:05 -0600190 info.pNext = pNext;
191
192 return *this;
193 }
194
Mark Lobodzinski51414032016-09-07 16:29:11 -0600195 DeviceCreateInfo &flags(VkDeviceQueueCreateFlags const &flags) {
Jeremy Hayesc5587182016-06-28 11:29:05 -0600196 info.flags = flags;
197
198 return *this;
199 }
200
Mark Lobodzinski51414032016-09-07 16:29:11 -0600201 DeviceCreateInfo &queueCreateInfoCount(uint32_t const &queueCreateInfoCount) {
Jeremy Hayesc5587182016-06-28 11:29:05 -0600202 info.queueCreateInfoCount = queueCreateInfoCount;
203
204 return *this;
205 }
206
Mark Lobodzinski51414032016-09-07 16:29:11 -0600207 DeviceCreateInfo &pQueueCreateInfos(VkDeviceQueueCreateInfo const *const pQueueCreateInfos) {
Jeremy Hayesc5587182016-06-28 11:29:05 -0600208 info.pQueueCreateInfos = pQueueCreateInfos;
209
210 return *this;
211 }
212
Mark Lobodzinski51414032016-09-07 16:29:11 -0600213 DeviceCreateInfo &enabledLayerCount(uint32_t const &enabledLayerCount) {
Jeremy Hayesc5587182016-06-28 11:29:05 -0600214 info.enabledLayerCount = enabledLayerCount;
215
216 return *this;
217 }
218
Mark Lobodzinski51414032016-09-07 16:29:11 -0600219 DeviceCreateInfo &ppEnabledLayerNames(char const *const *const ppEnabledLayerNames) {
Jeremy Hayesc5587182016-06-28 11:29:05 -0600220 info.ppEnabledLayerNames = ppEnabledLayerNames;
221
222 return *this;
223 }
224
Mark Lobodzinski51414032016-09-07 16:29:11 -0600225 DeviceCreateInfo &enabledExtensionCount(uint32_t const &enabledExtensionCount) {
Jeremy Hayesc5587182016-06-28 11:29:05 -0600226 info.enabledExtensionCount = enabledExtensionCount;
227
228 return *this;
229 }
230
Mark Lobodzinski51414032016-09-07 16:29:11 -0600231 DeviceCreateInfo &ppEnabledExtensionNames(char const *const *const ppEnabledExtensionNames) {
Jeremy Hayesc5587182016-06-28 11:29:05 -0600232 info.ppEnabledExtensionNames = ppEnabledExtensionNames;
233
234 return *this;
235 }
236
Mark Lobodzinski51414032016-09-07 16:29:11 -0600237 DeviceCreateInfo &pEnabledFeatures(VkPhysicalDeviceFeatures const *const pEnabledFeatures) {
Jeremy Hayesc5587182016-06-28 11:29:05 -0600238 info.pEnabledFeatures = pEnabledFeatures;
239
240 return *this;
241 }
242
Mark Lobodzinski51414032016-09-07 16:29:11 -0600243 operator VkDeviceCreateInfo const *() const { return &info; }
Jeremy Hayesc5587182016-06-28 11:29:05 -0600244
Mark Lobodzinski51414032016-09-07 16:29:11 -0600245 operator VkDeviceCreateInfo *() { return &info; }
Jeremy Hayesc5587182016-06-28 11:29:05 -0600246
247 VkDeviceCreateInfo info;
248};
Jeremy Hayesc5587182016-06-28 11:29:05 -0600249}
250
Mark Lobodzinski51414032016-09-07 16:29:11 -0600251struct CommandLine : public ::testing::Test {
252 static void Initialize(int argc, char **argv) { arguments.assign(argv, argv + argc); };
Jeremy Hayes10357562016-07-06 11:56:44 -0600253
Mark Lobodzinski51414032016-09-07 16:29:11 -0600254 static void SetUpTestCase(){};
255 static void TearDownTestCase(){};
Jeremy Hayes10357562016-07-06 11:56:44 -0600256
257 static std::vector<std::string> arguments;
258};
259std::vector<std::string> CommandLine::arguments;
260
261struct EnumerateInstanceLayerProperties : public CommandLine {};
262struct EnumerateInstanceExtensionProperties : public CommandLine {};
Jeremy Hayes52261802016-08-15 10:37:24 -0600263struct ImplicitLayer : public CommandLine {};
Jeremy Hayes10357562016-07-06 11:56:44 -0600264
Mark Youngc146fc22017-02-02 18:14:21 -0700265// Allocation tracking utilities
266struct AllocTrack {
267 bool active;
268 bool was_allocated;
269 void *aligned_start_addr;
270 char *actual_start_addr;
271 size_t requested_size_bytes;
272 size_t actual_size_bytes;
273 VkSystemAllocationScope alloc_scope;
274 uint64_t user_data;
275
276 AllocTrack()
277 : active(false),
278 was_allocated(false),
279 aligned_start_addr(nullptr),
280 actual_start_addr(nullptr),
281 requested_size_bytes(0),
282 actual_size_bytes(0),
283 alloc_scope(VK_SYSTEM_ALLOCATION_SCOPE_COMMAND),
284 user_data(0) {}
285};
286
287// Global vector to track allocations. This will be resized before each test and emptied after.
288// However, we have to globally define it so the allocation callback functions work properly.
289std::vector<AllocTrack> g_allocated_vector;
Mark Young05e4f6a2017-03-15 10:36:03 -0600290bool g_intentional_fail_enabled = false;
291uint32_t g_intenional_fail_index = 0;
292uint32_t g_intenional_fail_count = 0;
Mark Youngc146fc22017-02-02 18:14:21 -0700293
294void FreeAllocTracker() { g_allocated_vector.clear(); }
295
Mark Young05e4f6a2017-03-15 10:36:03 -0600296void InitAllocTracker(size_t size, uint32_t intentional_fail_index = UINT32_MAX) {
Mark Youngc146fc22017-02-02 18:14:21 -0700297 if (g_allocated_vector.size() > 0) {
298 FreeAllocTracker();
299 }
300 g_allocated_vector.resize(size);
Mark Young05e4f6a2017-03-15 10:36:03 -0600301 if (intentional_fail_index != UINT32_MAX) {
302 g_intentional_fail_enabled = true;
303 g_intenional_fail_index = intentional_fail_index;
304 g_intenional_fail_count = 0;
305 } else {
306 g_intentional_fail_enabled = false;
307 g_intenional_fail_index = 0;
308 g_intenional_fail_count = 0;
309 }
Mark Youngc146fc22017-02-02 18:14:21 -0700310}
311
312bool IsAllocTrackerEmpty() {
313 bool success = true;
314 bool was_allocated = false;
315 char print_command[1024];
316 sprintf(print_command, "\t%%04d\t%%p (%%p) : 0x%%%s (0x%%%s) : scope %%d : user_data 0x%%%s\n", PRIxLEAST64, PRIxLEAST64,
317 PRIxLEAST64);
318 for (uint32_t iii = 0; iii < g_allocated_vector.size(); iii++) {
319 if (g_allocated_vector[iii].active) {
320 if (success) {
321 printf("ERROR: Allocations still remain!\n");
322 }
323 printf(print_command, iii, g_allocated_vector[iii].aligned_start_addr, g_allocated_vector[iii].actual_start_addr,
324 g_allocated_vector[iii].requested_size_bytes, g_allocated_vector[iii].actual_size_bytes,
325 g_allocated_vector[iii].alloc_scope, g_allocated_vector[iii].user_data);
326 success = false;
327 } else if (!was_allocated && g_allocated_vector[iii].was_allocated) {
328 was_allocated = true;
329 }
330 }
Mark Young05e4f6a2017-03-15 10:36:03 -0600331 if (!g_intentional_fail_enabled && !was_allocated) {
Mark Youngc146fc22017-02-02 18:14:21 -0700332 printf("No allocations ever generated!");
333 success = false;
334 }
335 return success;
336}
337
338VKAPI_ATTR void *VKAPI_CALL AllocCallbackFunc(void *pUserData, size_t size, size_t alignment,
339 VkSystemAllocationScope allocationScope) {
Mark Young05e4f6a2017-03-15 10:36:03 -0600340 if (g_intentional_fail_enabled) {
341 if (++g_intenional_fail_count >= g_intenional_fail_index) {
342 return nullptr;
343 }
344 }
Mark Youngc146fc22017-02-02 18:14:21 -0700345 for (uint32_t iii = 0; iii < g_allocated_vector.size(); iii++) {
346 if (!g_allocated_vector[iii].active) {
347 g_allocated_vector[iii].requested_size_bytes = size;
348 g_allocated_vector[iii].actual_size_bytes = size + (alignment - 1);
349 g_allocated_vector[iii].aligned_start_addr = NULL;
350 g_allocated_vector[iii].actual_start_addr = new char[g_allocated_vector[iii].actual_size_bytes];
351 if (g_allocated_vector[iii].actual_start_addr != NULL) {
352 uint64_t addr = (uint64_t)g_allocated_vector[iii].actual_start_addr;
353 addr += (alignment - 1);
354 addr &= ~(alignment - 1);
355 g_allocated_vector[iii].aligned_start_addr = (void *)addr;
356 g_allocated_vector[iii].alloc_scope = allocationScope;
357 g_allocated_vector[iii].user_data = (uint64_t)pUserData;
358 g_allocated_vector[iii].active = true;
359 g_allocated_vector[iii].was_allocated = true;
360 }
361 return g_allocated_vector[iii].aligned_start_addr;
362 }
363 }
364 return nullptr;
365}
366
367VKAPI_ATTR void VKAPI_CALL FreeCallbackFunc(void *pUserData, void *pMemory) {
368 for (uint32_t iii = 0; iii < g_allocated_vector.size(); iii++) {
369 if (g_allocated_vector[iii].active && g_allocated_vector[iii].aligned_start_addr == pMemory) {
370 delete[] g_allocated_vector[iii].actual_start_addr;
371 g_allocated_vector[iii].active = false;
372 break;
373 }
374 }
375}
376
377VKAPI_ATTR void *VKAPI_CALL ReallocCallbackFunc(void *pUserData, void *pOriginal, size_t size, size_t alignment,
378 VkSystemAllocationScope allocationScope) {
379 if (pOriginal != NULL) {
380 for (uint32_t iii = 0; iii < g_allocated_vector.size(); iii++) {
381 if (g_allocated_vector[iii].active && g_allocated_vector[iii].aligned_start_addr == pOriginal) {
382 if (size == 0) {
383 FreeCallbackFunc(pUserData, pOriginal);
384 return nullptr;
385 } else if (size < g_allocated_vector[iii].requested_size_bytes) {
386 return pOriginal;
387 } else {
388 void *pNew = AllocCallbackFunc(pUserData, size, alignment, allocationScope);
389 size_t copy_size = size;
390 if (g_allocated_vector[iii].requested_size_bytes < size) {
391 copy_size = g_allocated_vector[iii].requested_size_bytes;
392 }
393 memcpy(pNew, pOriginal, copy_size);
394 FreeCallbackFunc(pUserData, pOriginal);
395 return pNew;
396 }
397 }
398 }
399 return nullptr;
400 } else {
401 return AllocCallbackFunc(pUserData, size, alignment, allocationScope);
402 }
403}
404
Jeremy Hayesd8726c22016-04-21 13:19:41 -0600405// Test groups:
406// LX = lunar exchange
407// LVLGH = loader and validation github
408// LVLGL = lodaer and validation gitlab
409
Mark Lobodzinski51414032016-09-07 16:29:11 -0600410TEST(LX435, InstanceCreateInfoConst) {
411 VkInstanceCreateInfo const info = {VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO, nullptr, 0, nullptr, 0, nullptr, 0, nullptr};
Jeremy Hayes6650d1f2016-04-20 09:00:39 -0600412
413 VkInstance instance = VK_NULL_HANDLE;
414 VkResult result = vkCreateInstance(&info, VK_NULL_HANDLE, &instance);
415 EXPECT_EQ(result, VK_SUCCESS);
Jeremy Hayes10357562016-07-06 11:56:44 -0600416
417 vkDestroyInstance(instance, nullptr);
Jeremy Hayes6650d1f2016-04-20 09:00:39 -0600418}
419
Mark Lobodzinski51414032016-09-07 16:29:11 -0600420TEST(LX475, DestroyInstanceNullHandle) { vkDestroyInstance(VK_NULL_HANDLE, nullptr); }
Jeremy Hayesd8726c22016-04-21 13:19:41 -0600421
Mark Lobodzinski51414032016-09-07 16:29:11 -0600422TEST(LX475, DestroyDeviceNullHandle) { vkDestroyDevice(VK_NULL_HANDLE, nullptr); }
Jeremy Hayesd8726c22016-04-21 13:19:41 -0600423
Mark Lobodzinski51414032016-09-07 16:29:11 -0600424TEST(CreateInstance, ExtensionNotPresent) {
Mark Lobodzinski64318ba2017-01-26 13:34:13 -0700425 char const *const names[] = {"NotPresent"}; // Temporary required due to MSVC bug.
Mark Lobodzinski51414032016-09-07 16:29:11 -0600426 auto const info = VK::InstanceCreateInfo().enabledExtensionCount(1).ppEnabledExtensionNames(names);
Jeremy Hayes097188a2016-06-15 16:37:17 -0600427
428 VkInstance instance = VK_NULL_HANDLE;
Jeremy Hayesc5587182016-06-28 11:29:05 -0600429 VkResult result = vkCreateInstance(info, VK_NULL_HANDLE, &instance);
Jeremy Hayes097188a2016-06-15 16:37:17 -0600430 ASSERT_EQ(result, VK_ERROR_EXTENSION_NOT_PRESENT);
Jeremy Hayes10357562016-07-06 11:56:44 -0600431
432 // It's not necessary to destroy the instance because it will not be created successfully.
Jeremy Hayes097188a2016-06-15 16:37:17 -0600433}
434
Mark Lobodzinski51414032016-09-07 16:29:11 -0600435TEST(CreateInstance, LayerNotPresent) {
Mark Lobodzinski64318ba2017-01-26 13:34:13 -0700436 char const *const names[] = {"NotPresent"}; // Temporary required due to MSVC bug.
Mark Lobodzinski51414032016-09-07 16:29:11 -0600437 auto const info = VK::InstanceCreateInfo().enabledLayerCount(1).ppEnabledLayerNames(names);
Jeremy Hayes097188a2016-06-15 16:37:17 -0600438
439 VkInstance instance = VK_NULL_HANDLE;
Jeremy Hayesc5587182016-06-28 11:29:05 -0600440 VkResult result = vkCreateInstance(info, VK_NULL_HANDLE, &instance);
Jeremy Hayes097188a2016-06-15 16:37:17 -0600441 ASSERT_EQ(result, VK_ERROR_LAYER_NOT_PRESENT);
Jeremy Hayes10357562016-07-06 11:56:44 -0600442
443 // It's not necessary to destroy the instance because it will not be created successfully.
Jeremy Hayes097188a2016-06-15 16:37:17 -0600444}
445
Jeremy Hayesab9804d2016-06-30 10:13:35 -0600446// Used by run_loader_tests.sh to test for layer insertion.
Mark Lobodzinski51414032016-09-07 16:29:11 -0600447TEST(CreateInstance, LayerPresent) {
Mark Lobodzinski64318ba2017-01-26 13:34:13 -0700448 char const *const names[] = {"VK_LAYER_LUNARG_parameter_validation"}; // Temporary required due to MSVC bug.
Mark Lobodzinski51414032016-09-07 16:29:11 -0600449 auto const info = VK::InstanceCreateInfo().enabledLayerCount(1).ppEnabledLayerNames(names);
Jeremy Hayesab9804d2016-06-30 10:13:35 -0600450
451 VkInstance instance = VK_NULL_HANDLE;
452 VkResult result = vkCreateInstance(info, VK_NULL_HANDLE, &instance);
453 ASSERT_EQ(result, VK_SUCCESS);
Jeremy Hayes10357562016-07-06 11:56:44 -0600454
455 vkDestroyInstance(instance, nullptr);
Jeremy Hayesab9804d2016-06-30 10:13:35 -0600456}
457
Mark Youngb9835412017-01-25 12:25:10 -0800458// Used by run_loader_tests.sh to test that calling vkEnumeratePhysicalDevices without first querying
459// the count, works.
460TEST(EnumeratePhysicalDevicces, OneCall) {
461 VkInstance instance = VK_NULL_HANDLE;
462 VkResult result = vkCreateInstance(VK::InstanceCreateInfo(), VK_NULL_HANDLE, &instance);
463 ASSERT_EQ(result, VK_SUCCESS);
464
465 uint32_t physicalCount = 500;
466 std::unique_ptr<VkPhysicalDevice[]> physical(new VkPhysicalDevice[physicalCount]);
467 result = vkEnumeratePhysicalDevices(instance, &physicalCount, physical.get());
468 ASSERT_EQ(result, VK_SUCCESS);
469 ASSERT_GT(physicalCount, 0u);
470
471 vkDestroyInstance(instance, nullptr);
472}
473
474// Used by run_loader_tests.sh to test for the expected usage of the vkEnumeratePhysicalDevices call.
475TEST(EnumeratePhysicalDevicces, TwoCall) {
476 VkInstance instance = VK_NULL_HANDLE;
477 VkResult result = vkCreateInstance(VK::InstanceCreateInfo(), VK_NULL_HANDLE, &instance);
478 ASSERT_EQ(result, VK_SUCCESS);
479
480 uint32_t physicalCount = 0;
481 result = vkEnumeratePhysicalDevices(instance, &physicalCount, nullptr);
482 ASSERT_EQ(result, VK_SUCCESS);
483 ASSERT_GT(physicalCount, 0u);
484
485 std::unique_ptr<VkPhysicalDevice[]> physical(new VkPhysicalDevice[physicalCount]);
486 result = vkEnumeratePhysicalDevices(instance, &physicalCount, physical.get());
487 ASSERT_EQ(result, VK_SUCCESS);
488 ASSERT_GT(physicalCount, 0u);
489
490 vkDestroyInstance(instance, nullptr);
491}
492
493// Used by run_loader_tests.sh to test that calling vkEnumeratePhysicalDevices without first querying
494// the count, matches the count from the standard call.
495TEST(EnumeratePhysicalDevicces, MatchOneAndTwoCallNumbers) {
496 VkInstance instance_one = VK_NULL_HANDLE;
497 VkResult result = vkCreateInstance(VK::InstanceCreateInfo(), VK_NULL_HANDLE, &instance_one);
498 ASSERT_EQ(result, VK_SUCCESS);
499
500 uint32_t physicalCount_one = 500;
501 std::unique_ptr<VkPhysicalDevice[]> physical_one(new VkPhysicalDevice[physicalCount_one]);
502 result = vkEnumeratePhysicalDevices(instance_one, &physicalCount_one, physical_one.get());
503 ASSERT_EQ(result, VK_SUCCESS);
504 ASSERT_GT(physicalCount_one, 0u);
505
506 VkInstance instance_two = VK_NULL_HANDLE;
507 result = vkCreateInstance(VK::InstanceCreateInfo(), VK_NULL_HANDLE, &instance_two);
508 ASSERT_EQ(result, VK_SUCCESS);
509
510 uint32_t physicalCount_two = 0;
511 result = vkEnumeratePhysicalDevices(instance_two, &physicalCount_two, nullptr);
512 ASSERT_EQ(result, VK_SUCCESS);
513 ASSERT_GT(physicalCount_two, 0u);
514
515 std::unique_ptr<VkPhysicalDevice[]> physical_two(new VkPhysicalDevice[physicalCount_two]);
516 result = vkEnumeratePhysicalDevices(instance_two, &physicalCount_two, physical_two.get());
517 ASSERT_EQ(result, VK_SUCCESS);
518 ASSERT_GT(physicalCount_two, 0u);
519
520 ASSERT_EQ(physicalCount_one, physicalCount_two);
521
522 vkDestroyInstance(instance_one, nullptr);
523 vkDestroyInstance(instance_two, nullptr);
524}
525
526// Used by run_loader_tests.sh to test for the expected usage of the vkEnumeratePhysicalDevices
527// call if not enough numbers are provided for the final list.
528TEST(EnumeratePhysicalDevicces, TwoCallIncomplete) {
529 VkInstance instance = VK_NULL_HANDLE;
530 VkResult result = vkCreateInstance(VK::InstanceCreateInfo(), VK_NULL_HANDLE, &instance);
531 ASSERT_EQ(result, VK_SUCCESS);
532
533 uint32_t physicalCount = 0;
534 result = vkEnumeratePhysicalDevices(instance, &physicalCount, nullptr);
535 ASSERT_EQ(result, VK_SUCCESS);
536 ASSERT_GT(physicalCount, 0u);
537
538 std::unique_ptr<VkPhysicalDevice[]> physical(new VkPhysicalDevice[physicalCount]);
539
540 // Remove one from the physical device count so we can get the VK_INCOMPLETE message
541 physicalCount -= 1;
542
543 result = vkEnumeratePhysicalDevices(instance, &physicalCount, physical.get());
544 ASSERT_EQ(result, VK_INCOMPLETE);
545
546 vkDestroyInstance(instance, nullptr);
547}
548
Mark Lobodzinski51414032016-09-07 16:29:11 -0600549TEST(CreateDevice, ExtensionNotPresent) {
Jeremy Hayes097188a2016-06-15 16:37:17 -0600550 VkInstance instance = VK_NULL_HANDLE;
Jeremy Hayesc5587182016-06-28 11:29:05 -0600551 VkResult result = vkCreateInstance(VK::InstanceCreateInfo(), VK_NULL_HANDLE, &instance);
Jeremy Hayes097188a2016-06-15 16:37:17 -0600552 ASSERT_EQ(result, VK_SUCCESS);
553
554 uint32_t physicalCount = 0;
555 result = vkEnumeratePhysicalDevices(instance, &physicalCount, nullptr);
556 ASSERT_EQ(result, VK_SUCCESS);
Jeremy Hayesa6fb5b42016-06-21 10:54:01 -0600557 ASSERT_GT(physicalCount, 0u);
Jeremy Hayes097188a2016-06-15 16:37:17 -0600558
559 std::unique_ptr<VkPhysicalDevice[]> physical(new VkPhysicalDevice[physicalCount]);
560 result = vkEnumeratePhysicalDevices(instance, &physicalCount, physical.get());
561 ASSERT_EQ(result, VK_SUCCESS);
Jeremy Hayesa6fb5b42016-06-21 10:54:01 -0600562 ASSERT_GT(physicalCount, 0u);
Jeremy Hayes097188a2016-06-15 16:37:17 -0600563
Mark Lobodzinski51414032016-09-07 16:29:11 -0600564 for (uint32_t p = 0; p < physicalCount; ++p) {
Jeremy Hayes097188a2016-06-15 16:37:17 -0600565 uint32_t familyCount = 0;
566 vkGetPhysicalDeviceQueueFamilyProperties(physical[p], &familyCount, nullptr);
Jeremy Hayesa6fb5b42016-06-21 10:54:01 -0600567 ASSERT_GT(familyCount, 0u);
Jeremy Hayes097188a2016-06-15 16:37:17 -0600568
569 std::unique_ptr<VkQueueFamilyProperties[]> family(new VkQueueFamilyProperties[familyCount]);
570 vkGetPhysicalDeviceQueueFamilyProperties(physical[p], &familyCount, family.get());
Jeremy Hayesa6fb5b42016-06-21 10:54:01 -0600571 ASSERT_GT(familyCount, 0u);
Jeremy Hayes097188a2016-06-15 16:37:17 -0600572
Mark Lobodzinski51414032016-09-07 16:29:11 -0600573 for (uint32_t q = 0; q < familyCount; ++q) {
574 if (~family[q].queueFlags & VK_QUEUE_GRAPHICS_BIT) {
Jeremy Hayes097188a2016-06-15 16:37:17 -0600575 continue;
576 }
577
Mark Lobodzinski64318ba2017-01-26 13:34:13 -0700578 float const priorities[] = {0.0f}; // Temporary required due to MSVC bug.
Mark Lobodzinski51414032016-09-07 16:29:11 -0600579 VkDeviceQueueCreateInfo const queueInfo[1]{
580 VK::DeviceQueueCreateInfo().queueFamilyIndex(q).queueCount(1).pQueuePriorities(priorities)};
Jeremy Hayes097188a2016-06-15 16:37:17 -0600581
Mark Lobodzinski64318ba2017-01-26 13:34:13 -0700582 char const *const names[] = {"NotPresent"}; // Temporary required due to MSVC bug.
Mark Lobodzinski51414032016-09-07 16:29:11 -0600583 auto const deviceInfo = VK::DeviceCreateInfo()
584 .queueCreateInfoCount(1)
585 .pQueueCreateInfos(queueInfo)
586 .enabledExtensionCount(1)
587 .ppEnabledExtensionNames(names);
Jeremy Hayes097188a2016-06-15 16:37:17 -0600588
589 VkDevice device;
Jeremy Hayesc5587182016-06-28 11:29:05 -0600590 result = vkCreateDevice(physical[p], deviceInfo, nullptr, &device);
Jeremy Hayes097188a2016-06-15 16:37:17 -0600591 ASSERT_EQ(result, VK_ERROR_EXTENSION_NOT_PRESENT);
Jeremy Hayes10357562016-07-06 11:56:44 -0600592
593 // It's not necessary to destroy the device because it will not be created successfully.
Jeremy Hayes097188a2016-06-15 16:37:17 -0600594 }
595 }
Jeremy Hayes10357562016-07-06 11:56:44 -0600596
597 vkDestroyInstance(instance, nullptr);
Jeremy Hayes097188a2016-06-15 16:37:17 -0600598}
599
Rene Lindsaye7ec3de2016-06-28 10:36:01 -0600600// LX535 / MI-76: Device layers are deprecated.
601// For backwards compatibility, they are allowed, but must be ignored.
602// Ensure that no errors occur if a bogus device layer list is passed to vkCreateDevice.
Mark Lobodzinski51414032016-09-07 16:29:11 -0600603TEST(CreateDevice, LayersNotPresent) {
Rene Lindsaye7ec3de2016-06-28 10:36:01 -0600604 VkInstance instance = VK_NULL_HANDLE;
Jeremy Hayesc5587182016-06-28 11:29:05 -0600605 VkResult result = vkCreateInstance(VK::InstanceCreateInfo(), VK_NULL_HANDLE, &instance);
Rene Lindsaye7ec3de2016-06-28 10:36:01 -0600606 ASSERT_EQ(result, VK_SUCCESS);
607
608 uint32_t physicalCount = 0;
609 result = vkEnumeratePhysicalDevices(instance, &physicalCount, nullptr);
610 ASSERT_EQ(result, VK_SUCCESS);
611 ASSERT_GT(physicalCount, 0u);
612
613 std::unique_ptr<VkPhysicalDevice[]> physical(new VkPhysicalDevice[physicalCount]);
614 result = vkEnumeratePhysicalDevices(instance, &physicalCount, physical.get());
615 ASSERT_EQ(result, VK_SUCCESS);
616 ASSERT_GT(physicalCount, 0u);
617
Mark Lobodzinski51414032016-09-07 16:29:11 -0600618 for (uint32_t p = 0; p < physicalCount; ++p) {
Rene Lindsaye7ec3de2016-06-28 10:36:01 -0600619 uint32_t familyCount = 0;
620 vkGetPhysicalDeviceQueueFamilyProperties(physical[p], &familyCount, nullptr);
621 ASSERT_EQ(result, VK_SUCCESS);
622 ASSERT_GT(familyCount, 0u);
623
624 std::unique_ptr<VkQueueFamilyProperties[]> family(new VkQueueFamilyProperties[familyCount]);
625 vkGetPhysicalDeviceQueueFamilyProperties(physical[p], &familyCount, family.get());
626 ASSERT_EQ(result, VK_SUCCESS);
627 ASSERT_GT(familyCount, 0u);
628
Mark Lobodzinski51414032016-09-07 16:29:11 -0600629 for (uint32_t q = 0; q < familyCount; ++q) {
630 if (~family[q].queueFlags & VK_QUEUE_GRAPHICS_BIT) {
Rene Lindsaye7ec3de2016-06-28 10:36:01 -0600631 continue;
632 }
633
Mark Lobodzinski64318ba2017-01-26 13:34:13 -0700634 float const priorities[] = {0.0f}; // Temporary required due to MSVC bug.
Mark Lobodzinski51414032016-09-07 16:29:11 -0600635 VkDeviceQueueCreateInfo const queueInfo[1]{
636 VK::DeviceQueueCreateInfo().queueFamilyIndex(q).queueCount(1).pQueuePriorities(priorities)};
Rene Lindsaye7ec3de2016-06-28 10:36:01 -0600637
Mark Lobodzinski64318ba2017-01-26 13:34:13 -0700638 char const *const names[] = {"NotPresent"}; // Temporary required due to MSVC bug.
Mark Lobodzinski51414032016-09-07 16:29:11 -0600639 auto const deviceInfo = VK::DeviceCreateInfo()
640 .queueCreateInfoCount(1)
641 .pQueueCreateInfos(queueInfo)
642 .enabledLayerCount(1)
643 .ppEnabledLayerNames(names);
Rene Lindsaye7ec3de2016-06-28 10:36:01 -0600644
645 VkDevice device;
Jeremy Hayesc5587182016-06-28 11:29:05 -0600646 result = vkCreateDevice(physical[p], deviceInfo, nullptr, &device);
647 ASSERT_EQ(result, VK_SUCCESS);
Jeremy Hayes10357562016-07-06 11:56:44 -0600648
649 vkDestroyDevice(device, nullptr);
Jeremy Hayesc5587182016-06-28 11:29:05 -0600650 }
651 }
Jeremy Hayes10357562016-07-06 11:56:44 -0600652
653 vkDestroyInstance(instance, nullptr);
654}
655
Mark Lobodzinski51414032016-09-07 16:29:11 -0600656TEST_F(EnumerateInstanceLayerProperties, PropertyCountLessThanAvailable) {
Jeremy Hayes10357562016-07-06 11:56:44 -0600657 uint32_t count = 0u;
658 VkResult result = vkEnumerateInstanceLayerProperties(&count, nullptr);
659 ASSERT_EQ(result, VK_SUCCESS);
660
661 // We need atleast two for the test to be relevant.
Mark Lobodzinski51414032016-09-07 16:29:11 -0600662 if (count < 2u) {
Jeremy Hayes10357562016-07-06 11:56:44 -0600663 return;
664 }
665
666 std::unique_ptr<VkLayerProperties[]> properties(new VkLayerProperties[count]);
667 count = 1;
668 result = vkEnumerateInstanceLayerProperties(&count, properties.get());
669 ASSERT_EQ(result, VK_INCOMPLETE);
670}
671
Mark Lobodzinski51414032016-09-07 16:29:11 -0600672TEST(EnumerateDeviceLayerProperties, PropertyCountLessThanAvailable) {
Jeremy Hayes10357562016-07-06 11:56:44 -0600673 VkInstance instance = VK_NULL_HANDLE;
674 VkResult result = vkCreateInstance(VK::InstanceCreateInfo(), VK_NULL_HANDLE, &instance);
675 ASSERT_EQ(result, VK_SUCCESS);
676
677 uint32_t physicalCount = 0;
678 result = vkEnumeratePhysicalDevices(instance, &physicalCount, nullptr);
679 ASSERT_EQ(result, VK_SUCCESS);
680 ASSERT_GT(physicalCount, 0u);
681
682 std::unique_ptr<VkPhysicalDevice[]> physical(new VkPhysicalDevice[physicalCount]);
683 result = vkEnumeratePhysicalDevices(instance, &physicalCount, physical.get());
684 ASSERT_EQ(result, VK_SUCCESS);
685 ASSERT_GT(physicalCount, 0u);
686
Mark Lobodzinski51414032016-09-07 16:29:11 -0600687 for (uint32_t p = 0; p < physicalCount; ++p) {
Jeremy Hayes10357562016-07-06 11:56:44 -0600688 uint32_t count = 0u;
689 result = vkEnumerateDeviceLayerProperties(physical[p], &count, nullptr);
690 ASSERT_EQ(result, VK_SUCCESS);
691
692 // We need atleast two for the test to be relevant.
Mark Lobodzinski51414032016-09-07 16:29:11 -0600693 if (count < 2u) {
Jeremy Hayes10357562016-07-06 11:56:44 -0600694 continue;
695 }
696
697 std::unique_ptr<VkLayerProperties[]> properties(new VkLayerProperties[count]);
698 count = 1;
699 result = vkEnumerateDeviceLayerProperties(physical[p], &count, properties.get());
700 ASSERT_EQ(result, VK_INCOMPLETE);
701 }
702
703 vkDestroyInstance(instance, nullptr);
704}
705
Mark Lobodzinski51414032016-09-07 16:29:11 -0600706TEST_F(EnumerateInstanceLayerProperties, Count) {
Jeremy Hayes10357562016-07-06 11:56:44 -0600707 uint32_t count = 0u;
708 VkResult result = vkEnumerateInstanceLayerProperties(&count, nullptr);
709 ASSERT_EQ(result, VK_SUCCESS);
710
Mark Lobodzinski51414032016-09-07 16:29:11 -0600711 if (std::find(arguments.begin(), arguments.end(), "count") != arguments.end()) {
Jeremy Hayes10357562016-07-06 11:56:44 -0600712 std::cout << "count=" << count << '\n';
713 }
714}
715
Mark Lobodzinski51414032016-09-07 16:29:11 -0600716TEST_F(EnumerateInstanceLayerProperties, OnePass) {
Jeremy Hayes10357562016-07-06 11:56:44 -0600717 // Count required for this test.
Mark Lobodzinski51414032016-09-07 16:29:11 -0600718 if (std::find(arguments.begin(), arguments.end(), "count") == arguments.end()) {
Jeremy Hayes10357562016-07-06 11:56:44 -0600719 return;
720 }
721
722 uint32_t count = std::stoul(arguments[2]);
723
724 std::unique_ptr<VkLayerProperties[]> properties(new VkLayerProperties[count]);
725 VkResult result = vkEnumerateInstanceLayerProperties(&count, properties.get());
726 ASSERT_EQ(result, VK_SUCCESS);
727
Mark Lobodzinski51414032016-09-07 16:29:11 -0600728 if (std::find(arguments.begin(), arguments.end(), "properties") != arguments.end()) {
729 for (uint32_t p = 0; p < count; ++p) {
730 std::cout << "properties[" << p << "] =" << ' ' << properties[p].layerName << ' ' << properties[p].specVersion << ' '
731 << properties[p].implementationVersion << ' ' << properties[p].description << '\n';
Jeremy Hayes10357562016-07-06 11:56:44 -0600732 }
733 }
734}
735
Mark Lobodzinski51414032016-09-07 16:29:11 -0600736TEST_F(EnumerateInstanceLayerProperties, TwoPass) {
Jeremy Hayes10357562016-07-06 11:56:44 -0600737 uint32_t count = 0u;
738 VkResult result = vkEnumerateInstanceLayerProperties(&count, nullptr);
739 ASSERT_EQ(result, VK_SUCCESS);
740
741 std::unique_ptr<VkLayerProperties[]> properties(new VkLayerProperties[count]);
742 result = vkEnumerateInstanceLayerProperties(&count, properties.get());
743 ASSERT_EQ(result, VK_SUCCESS);
744
Mark Lobodzinski51414032016-09-07 16:29:11 -0600745 if (std::find(arguments.begin(), arguments.end(), "properties") != arguments.end()) {
746 for (uint32_t p = 0; p < count; ++p) {
747 std::cout << "properties[" << p << "] =" << ' ' << properties[p].layerName << ' ' << properties[p].specVersion << ' '
748 << properties[p].implementationVersion << ' ' << properties[p].description << '\n';
Jeremy Hayes10357562016-07-06 11:56:44 -0600749 }
750 }
751}
752
Mark Lobodzinski51414032016-09-07 16:29:11 -0600753TEST_F(EnumerateInstanceExtensionProperties, PropertyCountLessThanAvailable) {
Jeremy Hayes10357562016-07-06 11:56:44 -0600754 uint32_t count = 0u;
755 VkResult result = vkEnumerateInstanceExtensionProperties(nullptr, &count, nullptr);
756 ASSERT_EQ(result, VK_SUCCESS);
757
758 // We need atleast two for the test to be relevant.
Mark Lobodzinski51414032016-09-07 16:29:11 -0600759 if (count < 2u) {
Jeremy Hayes10357562016-07-06 11:56:44 -0600760 return;
761 }
762
763 std::unique_ptr<VkExtensionProperties[]> properties(new VkExtensionProperties[count]);
764 count = 1;
765 result = vkEnumerateInstanceExtensionProperties(nullptr, &count, properties.get());
766 ASSERT_EQ(result, VK_INCOMPLETE);
767}
768
Mark Lobodzinski51414032016-09-07 16:29:11 -0600769TEST(EnumerateDeviceExtensionProperties, PropertyCountLessThanAvailable) {
Jeremy Hayes10357562016-07-06 11:56:44 -0600770 VkInstance instance = VK_NULL_HANDLE;
771 VkResult result = vkCreateInstance(VK::InstanceCreateInfo(), VK_NULL_HANDLE, &instance);
772 ASSERT_EQ(result, VK_SUCCESS);
773
774 uint32_t physicalCount = 0;
775 result = vkEnumeratePhysicalDevices(instance, &physicalCount, nullptr);
776 ASSERT_EQ(result, VK_SUCCESS);
777 ASSERT_GT(physicalCount, 0u);
778
779 std::unique_ptr<VkPhysicalDevice[]> physical(new VkPhysicalDevice[physicalCount]);
780 result = vkEnumeratePhysicalDevices(instance, &physicalCount, physical.get());
781 ASSERT_EQ(result, VK_SUCCESS);
782 ASSERT_GT(physicalCount, 0u);
783
Mark Lobodzinski51414032016-09-07 16:29:11 -0600784 for (uint32_t p = 0; p < physicalCount; ++p) {
Jeremy Hayes10357562016-07-06 11:56:44 -0600785 uint32_t count = 0u;
786 result = vkEnumerateDeviceExtensionProperties(physical[p], nullptr, &count, nullptr);
787 ASSERT_EQ(result, VK_SUCCESS);
788
789 // We need atleast two for the test to be relevant.
Mark Lobodzinski51414032016-09-07 16:29:11 -0600790 if (count < 2u) {
Jeremy Hayes10357562016-07-06 11:56:44 -0600791 continue;
792 }
793
794 std::unique_ptr<VkExtensionProperties[]> properties(new VkExtensionProperties[count]);
795 count = 1;
796 result = vkEnumerateDeviceExtensionProperties(physical[p], nullptr, &count, properties.get());
797 ASSERT_EQ(result, VK_INCOMPLETE);
798 }
799
800 vkDestroyInstance(instance, nullptr);
801}
802
Mark Lobodzinski51414032016-09-07 16:29:11 -0600803TEST_F(EnumerateInstanceExtensionProperties, Count) {
Jeremy Hayes10357562016-07-06 11:56:44 -0600804 uint32_t count = 0u;
805 VkResult result = vkEnumerateInstanceExtensionProperties(nullptr, &count, nullptr);
806 ASSERT_EQ(result, VK_SUCCESS);
807
Mark Lobodzinski51414032016-09-07 16:29:11 -0600808 if (std::find(arguments.begin(), arguments.end(), "count") != arguments.end()) {
Jeremy Hayes10357562016-07-06 11:56:44 -0600809 std::cout << "count=" << count << '\n';
810 }
811}
812
Mark Lobodzinski51414032016-09-07 16:29:11 -0600813TEST_F(EnumerateInstanceExtensionProperties, OnePass) {
Jeremy Hayes10357562016-07-06 11:56:44 -0600814 // Count required for this test.
Mark Lobodzinski51414032016-09-07 16:29:11 -0600815 if (std::find(arguments.begin(), arguments.end(), "count") == arguments.end()) {
Jeremy Hayes10357562016-07-06 11:56:44 -0600816 return;
817 }
818
819 uint32_t count = std::stoul(arguments[2]);
820
821 std::unique_ptr<VkExtensionProperties[]> properties(new VkExtensionProperties[count]);
822 VkResult result = vkEnumerateInstanceExtensionProperties(nullptr, &count, properties.get());
823 ASSERT_EQ(result, VK_SUCCESS);
824
Mark Lobodzinski51414032016-09-07 16:29:11 -0600825 if (std::find(arguments.begin(), arguments.end(), "properties") != arguments.end()) {
826 for (uint32_t p = 0; p < count; ++p) {
827 std::cout << "properties[" << p << "] =" << ' ' << properties[p].extensionName << ' ' << properties[p].specVersion
828 << '\n';
Jeremy Hayes10357562016-07-06 11:56:44 -0600829 }
830 }
831}
832
Mark Lobodzinski51414032016-09-07 16:29:11 -0600833TEST_F(EnumerateInstanceExtensionProperties, TwoPass) {
Jeremy Hayes10357562016-07-06 11:56:44 -0600834 uint32_t count = 0u;
835 VkResult result = vkEnumerateInstanceExtensionProperties(nullptr, &count, nullptr);
836 ASSERT_EQ(result, VK_SUCCESS);
837
838 std::unique_ptr<VkExtensionProperties[]> properties(new VkExtensionProperties[count]);
839 result = vkEnumerateInstanceExtensionProperties(nullptr, &count, properties.get());
840 ASSERT_EQ(result, VK_SUCCESS);
841
Mark Lobodzinski51414032016-09-07 16:29:11 -0600842 if (std::find(arguments.begin(), arguments.end(), "properties") != arguments.end()) {
843 for (uint32_t p = 0; p < count; ++p) {
844 std::cout << "properties[" << p << "] =" << ' ' << properties[p].extensionName << ' ' << properties[p].specVersion
845 << '\n';
Jeremy Hayes10357562016-07-06 11:56:44 -0600846 }
847 }
848}
849
Mark Lobodzinski51414032016-09-07 16:29:11 -0600850TEST_F(EnumerateInstanceExtensionProperties, InstanceExtensionEnumerated) {
Jeremy Hayes10357562016-07-06 11:56:44 -0600851 uint32_t count = 0u;
852 VkResult result = vkEnumerateInstanceExtensionProperties(nullptr, &count, nullptr);
853 ASSERT_EQ(result, VK_SUCCESS);
854
855 std::unique_ptr<VkExtensionProperties[]> properties(new VkExtensionProperties[count]);
856 result = vkEnumerateInstanceExtensionProperties(nullptr, &count, properties.get());
857 ASSERT_EQ(result, VK_SUCCESS);
858
859 ASSERT_NE(std::find_if(
Mark Lobodzinski51414032016-09-07 16:29:11 -0600860 &properties[0], &properties[count],
861 [](VkExtensionProperties const &properties) { return strcmp(properties.extensionName, "VK_KHR_surface") == 0; }),
862 &properties[count]);
Jeremy Hayes10357562016-07-06 11:56:44 -0600863}
864
Mark Lobodzinski51414032016-09-07 16:29:11 -0600865TEST(EnumerateDeviceExtensionProperties, DeviceExtensionEnumerated) {
Jeremy Hayes10357562016-07-06 11:56:44 -0600866 VkInstance instance = VK_NULL_HANDLE;
867 VkResult result = vkCreateInstance(VK::InstanceCreateInfo(), VK_NULL_HANDLE, &instance);
868 ASSERT_EQ(result, VK_SUCCESS);
869
870 uint32_t physicalCount = 0;
871 result = vkEnumeratePhysicalDevices(instance, &physicalCount, nullptr);
872 ASSERT_EQ(result, VK_SUCCESS);
873 ASSERT_GT(physicalCount, 0u);
874
875 std::unique_ptr<VkPhysicalDevice[]> physical(new VkPhysicalDevice[physicalCount]);
876 result = vkEnumeratePhysicalDevices(instance, &physicalCount, physical.get());
877 ASSERT_EQ(result, VK_SUCCESS);
878 ASSERT_GT(physicalCount, 0u);
879
Mark Lobodzinski51414032016-09-07 16:29:11 -0600880 for (uint32_t p = 0; p < physicalCount; ++p) {
Jeremy Hayes10357562016-07-06 11:56:44 -0600881 uint32_t count = 0u;
882 result = vkEnumerateDeviceExtensionProperties(physical[p], nullptr, &count, nullptr);
883 ASSERT_EQ(result, VK_SUCCESS);
884
885 std::unique_ptr<VkExtensionProperties[]> properties(new VkExtensionProperties[count]);
886 result = vkEnumerateDeviceExtensionProperties(physical[p], nullptr, &count, properties.get());
887 ASSERT_EQ(result, VK_SUCCESS);
888
Mark Lobodzinski51414032016-09-07 16:29:11 -0600889 ASSERT_NE(std::find_if(&properties[0], &properties[count],
890 [](VkExtensionProperties const &properties) {
891 return strcmp(properties.extensionName, "VK_KHR_swapchain") == 0;
892 }),
893 &properties[count]);
Jeremy Hayes10357562016-07-06 11:56:44 -0600894 }
895
896 vkDestroyInstance(instance, nullptr);
Jeremy Hayesc5587182016-06-28 11:29:05 -0600897}
898
Mark Lobodzinski51414032016-09-07 16:29:11 -0600899TEST_F(ImplicitLayer, Present) {
Jeremy Hayes52261802016-08-15 10:37:24 -0600900 auto const info = VK::InstanceCreateInfo();
901 VkInstance instance = VK_NULL_HANDLE;
902 VkResult result = vkCreateInstance(info, VK_NULL_HANDLE, &instance);
903 ASSERT_EQ(result, VK_SUCCESS);
904
905 vkDestroyInstance(instance, nullptr);
906}
907
Mark Lobodzinski51414032016-09-07 16:29:11 -0600908TEST(WrapObjects, Insert) {
Jeremy Hayesc5587182016-06-28 11:29:05 -0600909 VkInstance instance = VK_NULL_HANDLE;
910 VkResult result = vkCreateInstance(VK::InstanceCreateInfo(), VK_NULL_HANDLE, &instance);
911 ASSERT_EQ(result, VK_SUCCESS);
912
913 uint32_t physicalCount = 0;
914 result = vkEnumeratePhysicalDevices(instance, &physicalCount, nullptr);
915 ASSERT_EQ(result, VK_SUCCESS);
916 ASSERT_GT(physicalCount, 0u);
917
918 std::unique_ptr<VkPhysicalDevice[]> physical(new VkPhysicalDevice[physicalCount]);
919 result = vkEnumeratePhysicalDevices(instance, &physicalCount, physical.get());
920 ASSERT_EQ(result, VK_SUCCESS);
921 ASSERT_GT(physicalCount, 0u);
922
Mark Lobodzinski51414032016-09-07 16:29:11 -0600923 for (uint32_t p = 0; p < physicalCount; ++p) {
Jeremy Hayesc5587182016-06-28 11:29:05 -0600924 uint32_t familyCount = 0;
925 vkGetPhysicalDeviceQueueFamilyProperties(physical[p], &familyCount, nullptr);
926 ASSERT_EQ(result, VK_SUCCESS);
927 ASSERT_GT(familyCount, 0u);
928
929 std::unique_ptr<VkQueueFamilyProperties[]> family(new VkQueueFamilyProperties[familyCount]);
930 vkGetPhysicalDeviceQueueFamilyProperties(physical[p], &familyCount, family.get());
931 ASSERT_EQ(result, VK_SUCCESS);
932 ASSERT_GT(familyCount, 0u);
933
Mark Lobodzinski51414032016-09-07 16:29:11 -0600934 for (uint32_t q = 0; q < familyCount; ++q) {
935 if (~family[q].queueFlags & VK_QUEUE_GRAPHICS_BIT) {
Jeremy Hayesc5587182016-06-28 11:29:05 -0600936 continue;
937 }
938
Mark Lobodzinski64318ba2017-01-26 13:34:13 -0700939 float const priorities[] = {0.0f}; // Temporary required due to MSVC bug.
Mark Lobodzinski51414032016-09-07 16:29:11 -0600940 VkDeviceQueueCreateInfo const queueInfo[1]{
941 VK::DeviceQueueCreateInfo().queueFamilyIndex(q).queueCount(1).pQueuePriorities(priorities)};
Jeremy Hayesc5587182016-06-28 11:29:05 -0600942
Mark Lobodzinski51414032016-09-07 16:29:11 -0600943 auto const deviceInfo = VK::DeviceCreateInfo().queueCreateInfoCount(1).pQueueCreateInfos(queueInfo);
Jeremy Hayesc5587182016-06-28 11:29:05 -0600944
945 VkDevice device;
946 result = vkCreateDevice(physical[p], deviceInfo, nullptr, &device);
Rene Lindsaye7ec3de2016-06-28 10:36:01 -0600947 ASSERT_EQ(result, VK_SUCCESS);
Jeremy Hayes10357562016-07-06 11:56:44 -0600948
949 vkDestroyDevice(device, nullptr);
Rene Lindsaye7ec3de2016-06-28 10:36:01 -0600950 }
951 }
Jeremy Hayes10357562016-07-06 11:56:44 -0600952
953 vkDestroyInstance(instance, nullptr);
Rene Lindsaye7ec3de2016-06-28 10:36:01 -0600954}
955
Mark Youngc146fc22017-02-02 18:14:21 -0700956// Test making sure the allocation functions are called to allocate and cleanup everything during
957// a CreateInstance/DestroyInstance call pair.
958TEST(Allocation, Instance) {
959 auto const info = VK::InstanceCreateInfo();
960 VkInstance instance = VK_NULL_HANDLE;
961 VkAllocationCallbacks alloc_callbacks = {};
962 alloc_callbacks.pUserData = (void *)0x00000001;
963 alloc_callbacks.pfnAllocation = AllocCallbackFunc;
964 alloc_callbacks.pfnReallocation = ReallocCallbackFunc;
965 alloc_callbacks.pfnFree = FreeCallbackFunc;
966
967 InitAllocTracker(2048);
968
969 VkResult result = vkCreateInstance(info, &alloc_callbacks, &instance);
970 ASSERT_EQ(result, VK_SUCCESS);
971
972 alloc_callbacks.pUserData = (void *)0x00000002;
973 vkDestroyInstance(instance, &alloc_callbacks);
974
975 // Make sure everything's been freed
976 ASSERT_EQ(true, IsAllocTrackerEmpty());
977 FreeAllocTracker();
978}
979
980// Test making sure the allocation functions are called to allocate and cleanup everything during
981// a CreateInstance/DestroyInstance call pair with a call to GetInstanceProcAddr.
982TEST(Allocation, GetInstanceProcAddr) {
983 auto const info = VK::InstanceCreateInfo();
984 VkInstance instance = VK_NULL_HANDLE;
985 VkAllocationCallbacks alloc_callbacks = {};
986 alloc_callbacks.pUserData = (void *)0x00000010;
987 alloc_callbacks.pfnAllocation = AllocCallbackFunc;
988 alloc_callbacks.pfnReallocation = ReallocCallbackFunc;
989 alloc_callbacks.pfnFree = FreeCallbackFunc;
990
991 InitAllocTracker(2048);
992
993 VkResult result = vkCreateInstance(info, &alloc_callbacks, &instance);
994 ASSERT_EQ(result, VK_SUCCESS);
995
996 void *pfnCreateDevice = (void *)vkGetInstanceProcAddr(instance, "vkCreateDevice");
997 void *pfnDestroyDevice = (void *)vkGetInstanceProcAddr(instance, "vkDestroyDevice");
Mark Younga10f1f52017-03-06 13:10:56 -0700998 ASSERT_TRUE(pfnCreateDevice != NULL && pfnDestroyDevice != NULL);
Mark Youngc146fc22017-02-02 18:14:21 -0700999
1000 alloc_callbacks.pUserData = (void *)0x00000011;
1001 vkDestroyInstance(instance, &alloc_callbacks);
1002
1003 // Make sure everything's been freed
1004 ASSERT_EQ(true, IsAllocTrackerEmpty());
1005 FreeAllocTracker();
1006}
1007
1008// Test making sure the allocation functions are called to allocate and cleanup everything during
1009// a vkEnumeratePhysicalDevices call pair.
1010TEST(Allocation, EnumeratePhysicalDevices) {
1011 auto const info = VK::InstanceCreateInfo();
1012 VkInstance instance = VK_NULL_HANDLE;
1013 VkAllocationCallbacks alloc_callbacks = {};
1014 alloc_callbacks.pUserData = (void *)0x00000021;
1015 alloc_callbacks.pfnAllocation = AllocCallbackFunc;
1016 alloc_callbacks.pfnReallocation = ReallocCallbackFunc;
1017 alloc_callbacks.pfnFree = FreeCallbackFunc;
1018
1019 InitAllocTracker(2048);
1020
1021 VkResult result = vkCreateInstance(info, &alloc_callbacks, &instance);
1022 ASSERT_EQ(result, VK_SUCCESS);
1023
1024 uint32_t physicalCount = 0;
1025 alloc_callbacks.pUserData = (void *)0x00000022;
1026 result = vkEnumeratePhysicalDevices(instance, &physicalCount, nullptr);
1027 ASSERT_EQ(result, VK_SUCCESS);
1028 ASSERT_GT(physicalCount, 0u);
1029
1030 std::unique_ptr<VkPhysicalDevice[]> physical(new VkPhysicalDevice[physicalCount]);
1031 alloc_callbacks.pUserData = (void *)0x00000023;
1032 result = vkEnumeratePhysicalDevices(instance, &physicalCount, physical.get());
1033 ASSERT_EQ(result, VK_SUCCESS);
1034 ASSERT_GT(physicalCount, 0u);
1035
1036 alloc_callbacks.pUserData = (void *)0x00000024;
1037 vkDestroyInstance(instance, &alloc_callbacks);
1038
1039 // Make sure everything's been freed
1040 ASSERT_EQ(true, IsAllocTrackerEmpty());
1041 FreeAllocTracker();
1042}
1043
1044// Test making sure the allocation functions are called to allocate and cleanup everything from
1045// vkCreateInstance, to vkCreateDevicce, and then through their destructors. With special
1046// allocators used on both the instance and device.
1047TEST(Allocation, InstanceAndDevice) {
1048 auto const info = VK::InstanceCreateInfo();
1049 VkInstance instance = VK_NULL_HANDLE;
1050 VkAllocationCallbacks alloc_callbacks = {};
1051 alloc_callbacks.pUserData = (void *)0x00000031;
1052 alloc_callbacks.pfnAllocation = AllocCallbackFunc;
1053 alloc_callbacks.pfnReallocation = ReallocCallbackFunc;
1054 alloc_callbacks.pfnFree = FreeCallbackFunc;
1055
1056 InitAllocTracker(2048);
1057
1058 VkResult result = vkCreateInstance(info, &alloc_callbacks, &instance);
1059 ASSERT_EQ(result, VK_SUCCESS);
1060
1061 uint32_t physicalCount = 0;
1062 result = vkEnumeratePhysicalDevices(instance, &physicalCount, nullptr);
1063 ASSERT_EQ(result, VK_SUCCESS);
1064 ASSERT_GT(physicalCount, 0u);
1065
1066 std::unique_ptr<VkPhysicalDevice[]> physical(new VkPhysicalDevice[physicalCount]);
1067 result = vkEnumeratePhysicalDevices(instance, &physicalCount, physical.get());
1068 ASSERT_EQ(result, VK_SUCCESS);
1069 ASSERT_GT(physicalCount, 0u);
1070
1071 for (uint32_t p = 0; p < physicalCount; ++p) {
1072 uint32_t familyCount = 0;
1073 vkGetPhysicalDeviceQueueFamilyProperties(physical[p], &familyCount, nullptr);
1074 ASSERT_GT(familyCount, 0u);
1075
1076 std::unique_ptr<VkQueueFamilyProperties[]> family(new VkQueueFamilyProperties[familyCount]);
1077 vkGetPhysicalDeviceQueueFamilyProperties(physical[p], &familyCount, family.get());
1078 ASSERT_GT(familyCount, 0u);
1079
1080 for (uint32_t q = 0; q < familyCount; ++q) {
1081 if (~family[q].queueFlags & VK_QUEUE_GRAPHICS_BIT) {
1082 continue;
1083 }
1084
1085 float const priorities[] = {0.0f}; // Temporary required due to MSVC bug.
1086 VkDeviceQueueCreateInfo const queueInfo[1]{
1087 VK::DeviceQueueCreateInfo().queueFamilyIndex(q).queueCount(1).pQueuePriorities(priorities)};
1088
1089 auto const deviceInfo = VK::DeviceCreateInfo().queueCreateInfoCount(1).pQueueCreateInfos(queueInfo);
1090
1091 VkDevice device;
1092 alloc_callbacks.pUserData = (void *)0x00000032;
1093 result = vkCreateDevice(physical[p], deviceInfo, &alloc_callbacks, &device);
1094 ASSERT_EQ(result, VK_SUCCESS);
1095
1096 alloc_callbacks.pUserData = (void *)0x00000033;
1097 vkDestroyDevice(device, &alloc_callbacks);
1098 }
1099 }
1100
1101 alloc_callbacks.pUserData = (void *)0x00000034;
1102 vkDestroyInstance(instance, &alloc_callbacks);
1103
1104 // Make sure everything's been freed
1105 ASSERT_EQ(true, IsAllocTrackerEmpty());
1106 FreeAllocTracker();
1107}
1108
1109// Test making sure the allocation functions are called to allocate and cleanup everything from
1110// vkCreateInstance, to vkCreateDevicce, and then through their destructors. With special
1111// allocators used on only the instance and not the device.
1112TEST(Allocation, InstanceButNotDevice) {
1113 auto const info = VK::InstanceCreateInfo();
1114 VkInstance instance = VK_NULL_HANDLE;
1115 VkAllocationCallbacks alloc_callbacks = {};
1116 alloc_callbacks.pUserData = (void *)0x00000041;
1117 alloc_callbacks.pfnAllocation = AllocCallbackFunc;
1118 alloc_callbacks.pfnReallocation = ReallocCallbackFunc;
1119 alloc_callbacks.pfnFree = FreeCallbackFunc;
1120
1121 InitAllocTracker(2048);
1122
1123 VkResult result = vkCreateInstance(info, &alloc_callbacks, &instance);
1124 ASSERT_EQ(result, VK_SUCCESS);
1125
1126 uint32_t physicalCount = 0;
1127 result = vkEnumeratePhysicalDevices(instance, &physicalCount, nullptr);
1128 ASSERT_EQ(result, VK_SUCCESS);
1129 ASSERT_GT(physicalCount, 0u);
1130
1131 std::unique_ptr<VkPhysicalDevice[]> physical(new VkPhysicalDevice[physicalCount]);
1132 result = vkEnumeratePhysicalDevices(instance, &physicalCount, physical.get());
1133 ASSERT_EQ(result, VK_SUCCESS);
1134 ASSERT_GT(physicalCount, 0u);
1135
1136 for (uint32_t p = 0; p < physicalCount; ++p) {
1137 uint32_t familyCount = 0;
1138 vkGetPhysicalDeviceQueueFamilyProperties(physical[p], &familyCount, nullptr);
1139 ASSERT_GT(familyCount, 0u);
1140
1141 std::unique_ptr<VkQueueFamilyProperties[]> family(new VkQueueFamilyProperties[familyCount]);
1142 vkGetPhysicalDeviceQueueFamilyProperties(physical[p], &familyCount, family.get());
1143 ASSERT_GT(familyCount, 0u);
1144
1145 for (uint32_t q = 0; q < familyCount; ++q) {
1146 if (~family[q].queueFlags & VK_QUEUE_GRAPHICS_BIT) {
1147 continue;
1148 }
1149
1150 float const priorities[] = {0.0f}; // Temporary required due to MSVC bug.
1151 VkDeviceQueueCreateInfo const queueInfo[1]{
1152 VK::DeviceQueueCreateInfo().queueFamilyIndex(q).queueCount(1).pQueuePriorities(priorities)};
1153
1154 auto const deviceInfo = VK::DeviceCreateInfo().queueCreateInfoCount(1).pQueueCreateInfos(queueInfo);
1155
1156 VkDevice device;
1157 result = vkCreateDevice(physical[p], deviceInfo, NULL, &device);
1158 ASSERT_EQ(result, VK_SUCCESS);
1159
1160 vkDestroyDevice(device, NULL);
1161 }
1162 }
1163
1164 alloc_callbacks.pUserData = (void *)0x00000042;
1165 vkDestroyInstance(instance, &alloc_callbacks);
1166
1167 // Make sure everything's been freed
1168 ASSERT_EQ(true, IsAllocTrackerEmpty());
1169 FreeAllocTracker();
1170}
1171
1172// Test making sure the allocation functions are called to allocate and cleanup everything from
1173// vkCreateInstance, to vkCreateDevicce, and then through their destructors. With special
1174// allocators used on only the device and not the instance.
1175TEST(Allocation, DeviceButNotInstance) {
1176 auto const info = VK::InstanceCreateInfo();
1177 VkInstance instance = VK_NULL_HANDLE;
1178 VkAllocationCallbacks alloc_callbacks = {};
1179 alloc_callbacks.pfnAllocation = AllocCallbackFunc;
1180 alloc_callbacks.pfnReallocation = ReallocCallbackFunc;
1181 alloc_callbacks.pfnFree = FreeCallbackFunc;
1182
1183 InitAllocTracker(2048);
1184
1185 VkResult result = vkCreateInstance(info, NULL, &instance);
1186 ASSERT_EQ(result, VK_SUCCESS);
1187
1188 uint32_t physicalCount = 0;
1189 result = vkEnumeratePhysicalDevices(instance, &physicalCount, nullptr);
1190 ASSERT_EQ(result, VK_SUCCESS);
1191 ASSERT_GT(physicalCount, 0u);
1192
1193 std::unique_ptr<VkPhysicalDevice[]> physical(new VkPhysicalDevice[physicalCount]);
1194 result = vkEnumeratePhysicalDevices(instance, &physicalCount, physical.get());
1195 ASSERT_EQ(result, VK_SUCCESS);
1196 ASSERT_GT(physicalCount, 0u);
1197
1198 for (uint32_t p = 0; p < physicalCount; ++p) {
1199 uint32_t familyCount = 0;
1200 vkGetPhysicalDeviceQueueFamilyProperties(physical[p], &familyCount, nullptr);
1201 ASSERT_GT(familyCount, 0u);
1202
1203 std::unique_ptr<VkQueueFamilyProperties[]> family(new VkQueueFamilyProperties[familyCount]);
1204 vkGetPhysicalDeviceQueueFamilyProperties(physical[p], &familyCount, family.get());
1205 ASSERT_GT(familyCount, 0u);
1206
1207 for (uint32_t q = 0; q < familyCount; ++q) {
1208 if (~family[q].queueFlags & VK_QUEUE_GRAPHICS_BIT) {
1209 continue;
1210 }
1211
1212 float const priorities[] = {0.0f}; // Temporary required due to MSVC bug.
1213 VkDeviceQueueCreateInfo const queueInfo[1]{
1214 VK::DeviceQueueCreateInfo().queueFamilyIndex(q).queueCount(1).pQueuePriorities(priorities)};
1215
1216 auto const deviceInfo = VK::DeviceCreateInfo().queueCreateInfoCount(1).pQueueCreateInfos(queueInfo);
1217
1218 VkDevice device;
1219 alloc_callbacks.pUserData = (void *)0x00000051;
1220 result = vkCreateDevice(physical[p], deviceInfo, &alloc_callbacks, &device);
1221 ASSERT_EQ(result, VK_SUCCESS);
1222
1223 alloc_callbacks.pUserData = (void *)0x00000052;
1224 vkDestroyDevice(device, &alloc_callbacks);
1225 }
1226 }
1227
1228 vkDestroyInstance(instance, NULL);
1229
1230 // Make sure everything's been freed
1231 ASSERT_EQ(true, IsAllocTrackerEmpty());
1232 FreeAllocTracker();
1233}
1234
Mark Young05e4f6a2017-03-15 10:36:03 -06001235// Test failure during vkCreateInstance to make sure we don't leak memory if
1236// one of the out-of-memory conditions trigger.
1237TEST(Allocation, CreateInstanceItentionalAllocFail) {
1238 auto const info = VK::InstanceCreateInfo();
1239 VkInstance instance = VK_NULL_HANDLE;
1240 VkAllocationCallbacks alloc_callbacks = {};
1241 alloc_callbacks.pfnAllocation = AllocCallbackFunc;
1242 alloc_callbacks.pfnReallocation = ReallocCallbackFunc;
1243 alloc_callbacks.pfnFree = FreeCallbackFunc;
1244
1245 VkResult result;
1246 uint32_t fail_index = 1;
1247 do {
1248 InitAllocTracker(9999, fail_index);
1249
1250 result = vkCreateInstance(info, &alloc_callbacks, &instance);
1251 if (result == VK_ERROR_OUT_OF_HOST_MEMORY) {
1252 if (!IsAllocTrackerEmpty()) {
1253 std::cout << "Failed on index " << fail_index << '\n';
1254 ASSERT_EQ(true, IsAllocTrackerEmpty());
1255 }
1256 }
1257 fail_index++;
1258 // Make sure we don't overrun the memory
1259 ASSERT_LT(fail_index, 9999u);
1260
1261 FreeAllocTracker();
1262 } while (result == VK_ERROR_OUT_OF_HOST_MEMORY);
1263
1264 vkDestroyInstance(instance, NULL);
1265}
1266
1267// Test failure during vkCreateDevice to make sure we don't leak memory if
1268// one of the out-of-memory conditions trigger.
1269TEST(Allocation, CreateDeviceItentionalAllocFail) {
1270 auto const info = VK::InstanceCreateInfo();
1271 VkInstance instance = VK_NULL_HANDLE;
1272 VkDevice device = VK_NULL_HANDLE;
1273 VkAllocationCallbacks alloc_callbacks = {};
1274 alloc_callbacks.pfnAllocation = AllocCallbackFunc;
1275 alloc_callbacks.pfnReallocation = ReallocCallbackFunc;
1276 alloc_callbacks.pfnFree = FreeCallbackFunc;
1277
1278 VkResult result = vkCreateInstance(info, NULL, &instance);
1279 ASSERT_EQ(result, VK_SUCCESS);
1280
1281 uint32_t physicalCount = 0;
1282 result = vkEnumeratePhysicalDevices(instance, &physicalCount, nullptr);
1283 ASSERT_EQ(result, VK_SUCCESS);
1284 ASSERT_GT(physicalCount, 0u);
1285
1286 std::unique_ptr<VkPhysicalDevice[]> physical(new VkPhysicalDevice[physicalCount]);
1287 result = vkEnumeratePhysicalDevices(instance, &physicalCount, physical.get());
1288 ASSERT_EQ(result, VK_SUCCESS);
1289 ASSERT_GT(physicalCount, 0u);
1290
1291 for (uint32_t p = 0; p < physicalCount; ++p) {
1292 uint32_t familyCount = 0;
1293 vkGetPhysicalDeviceQueueFamilyProperties(physical[p], &familyCount, nullptr);
1294 ASSERT_GT(familyCount, 0u);
1295
1296 std::unique_ptr<VkQueueFamilyProperties[]> family(new VkQueueFamilyProperties[familyCount]);
1297 vkGetPhysicalDeviceQueueFamilyProperties(physical[p], &familyCount, family.get());
1298 ASSERT_GT(familyCount, 0u);
1299
1300 for (uint32_t q = 0; q < familyCount; ++q) {
1301 if (~family[q].queueFlags & VK_QUEUE_GRAPHICS_BIT) {
1302 continue;
1303 }
1304
1305 float const priorities[] = {0.0f}; // Temporary required due to MSVC bug.
1306 VkDeviceQueueCreateInfo const queueInfo[1]{
1307 VK::DeviceQueueCreateInfo().queueFamilyIndex(q).queueCount(1).pQueuePriorities(priorities)};
1308
1309 auto const deviceInfo = VK::DeviceCreateInfo().queueCreateInfoCount(1).pQueueCreateInfos(queueInfo);
1310
1311 uint32_t fail_index = 1;
1312 do {
1313 InitAllocTracker(9999, fail_index);
1314
1315 result = vkCreateDevice(physical[p], deviceInfo, &alloc_callbacks, &device);
1316 if (result == VK_ERROR_OUT_OF_HOST_MEMORY) {
1317 if (!IsAllocTrackerEmpty()) {
1318 std::cout << "Failed on index " << fail_index << '\n';
1319 ASSERT_EQ(true, IsAllocTrackerEmpty());
1320 }
1321 }
1322 fail_index++;
1323 // Make sure we don't overrun the memory
1324 ASSERT_LT(fail_index, 9999u);
1325
1326 FreeAllocTracker();
1327 } while (result == VK_ERROR_OUT_OF_HOST_MEMORY);
1328 vkDestroyDevice(device, &alloc_callbacks);
1329 break;
1330 }
1331 }
1332
1333 vkDestroyInstance(instance, NULL);
1334}
1335
1336// Test failure during vkCreateInstance and vkCreateDevice to make sure we don't
1337// leak memory if one of the out-of-memory conditions trigger.
1338TEST(Allocation, CreateInstanceDeviceItentionalAllocFail) {
1339 auto const info = VK::InstanceCreateInfo();
1340 VkInstance instance = VK_NULL_HANDLE;
1341 VkDevice device = VK_NULL_HANDLE;
1342 VkAllocationCallbacks alloc_callbacks = {};
1343 alloc_callbacks.pfnAllocation = AllocCallbackFunc;
1344 alloc_callbacks.pfnReallocation = ReallocCallbackFunc;
1345 alloc_callbacks.pfnFree = FreeCallbackFunc;
1346
1347 VkResult result = VK_ERROR_OUT_OF_HOST_MEMORY;
1348 uint32_t fail_index = 0;
1349 uint32_t physicalCount = 0;
1350 while (result == VK_ERROR_OUT_OF_HOST_MEMORY) {
1351 InitAllocTracker(9999, ++fail_index);
1352 ASSERT_LT(fail_index, 9999u);
1353
1354 result = vkCreateInstance(info, &alloc_callbacks, &instance);
1355 if (result == VK_ERROR_OUT_OF_HOST_MEMORY) {
1356 if (!IsAllocTrackerEmpty()) {
1357 std::cout << "Failed on index " << fail_index << '\n';
1358 ASSERT_EQ(true, IsAllocTrackerEmpty());
1359 }
1360 FreeAllocTracker();
1361 continue;
1362 }
1363 ASSERT_EQ(result, VK_SUCCESS);
1364
1365 physicalCount = 0;
1366 result = vkEnumeratePhysicalDevices(instance, &physicalCount, nullptr);
1367 if (result == VK_ERROR_OUT_OF_HOST_MEMORY) {
1368 vkDestroyInstance(instance, NULL);
1369 if (!IsAllocTrackerEmpty()) {
1370 std::cout << "Failed on index " << fail_index << '\n';
1371 ASSERT_EQ(true, IsAllocTrackerEmpty());
1372 }
1373 FreeAllocTracker();
1374 continue;
1375 }
1376 ASSERT_EQ(result, VK_SUCCESS);
1377
1378 std::unique_ptr<VkPhysicalDevice[]> physical(new VkPhysicalDevice[physicalCount]);
1379 result = vkEnumeratePhysicalDevices(instance, &physicalCount, physical.get());
1380 if (result == VK_ERROR_OUT_OF_HOST_MEMORY) {
1381 vkDestroyInstance(instance, NULL);
1382 if (!IsAllocTrackerEmpty()) {
1383 std::cout << "Failed on index " << fail_index << '\n';
1384 ASSERT_EQ(true, IsAllocTrackerEmpty());
1385 }
1386 FreeAllocTracker();
1387 continue;
1388 }
1389 ASSERT_EQ(result, VK_SUCCESS);
1390
1391 uint32_t familyCount = 0;
1392 vkGetPhysicalDeviceQueueFamilyProperties(physical[0], &familyCount, nullptr);
1393 ASSERT_GT(familyCount, 0u);
1394
1395 std::unique_ptr<VkQueueFamilyProperties[]> family(new VkQueueFamilyProperties[familyCount]);
1396 vkGetPhysicalDeviceQueueFamilyProperties(physical[0], &familyCount, family.get());
1397 ASSERT_GT(familyCount, 0u);
1398
1399 uint32_t queue_index = 0;
1400 for (uint32_t q = 0; q < familyCount; ++q) {
1401 if (family[q].queueFlags & VK_QUEUE_GRAPHICS_BIT) {
1402 queue_index = q;
1403 break;
1404 }
1405 }
1406
1407 float const priorities[] = {0.0f}; // Temporary required due to MSVC bug.
1408 VkDeviceQueueCreateInfo const queueInfo[1]{
1409 VK::DeviceQueueCreateInfo().queueFamilyIndex(queue_index).queueCount(1).pQueuePriorities(priorities)};
1410
1411 auto const deviceInfo = VK::DeviceCreateInfo().queueCreateInfoCount(1).pQueueCreateInfos(queueInfo);
1412
1413 result = vkCreateDevice(physical[0], deviceInfo, &alloc_callbacks, &device);
1414 if (result == VK_ERROR_OUT_OF_HOST_MEMORY) {
1415 vkDestroyInstance(instance, NULL);
1416 if (!IsAllocTrackerEmpty()) {
1417 std::cout << "Failed on index " << fail_index << '\n';
1418 ASSERT_EQ(true, IsAllocTrackerEmpty());
1419 }
1420 FreeAllocTracker();
1421 continue;
1422 }
1423 vkDestroyDevice(device, &alloc_callbacks);
1424 vkDestroyInstance(instance, NULL);
1425 FreeAllocTracker();
1426 }
1427}
1428
Mark Lobodzinski51414032016-09-07 16:29:11 -06001429int main(int argc, char **argv) {
Jeremy Hayes6650d1f2016-04-20 09:00:39 -06001430 int result;
1431
1432 ::testing::InitGoogleTest(&argc, argv);
1433
Mark Lobodzinski51414032016-09-07 16:29:11 -06001434 if (argc > 0) {
Jeremy Hayes10357562016-07-06 11:56:44 -06001435 CommandLine::Initialize(argc, argv);
1436 }
1437
Jeremy Hayes6650d1f2016-04-20 09:00:39 -06001438 result = RUN_ALL_TESTS();
1439
1440 return result;
1441}