blob: e00cbe41e99dd747214a252852ac2492db7edf47 [file] [log] [blame]
Tony-LunarGa0186342021-10-11 13:17:51 -06001/* Copyright (c) 2020-2021 The Khronos Group Inc.
2 * Copyright (c) 2020-2021 Valve Corporation
3 * Copyright (c) 2020-2021 LunarG, Inc.
Petr Kraus18b7d1f2020-03-31 21:12:30 +02004 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17
18// Instanceless tests
19// Tests of validation of vkCreateInstance and vkDestroyInstance via the pNext debug callback.
20//
21// This set of test should ideally be as complete as possible. Most of the VUs are Implicit (i.e. automatically generated), but any
22// of the parameters could expose a bug or inadequacy in the Loader or the debug extension.
23//
24// Note: testing pCreateInfo pointer, the sType of a debug struct, the debug callback pointer, the ppEnabledLayerNames pointer, and
25// the ppEnabledExtensionNames would require extenally enabled debug layers, so this is currently not performed.
26//
Petr Kraus18b7d1f2020-03-31 21:12:30 +020027// TODO: VkDebugReportCallbackCreateInfoEXT::flags and VkDebugUtilsMessengerCreateInfoEXT various Flags could theoretically be
28// tested if the debug extensions are made robust enough
29
30#include <memory>
31#include <vector>
32
33#include "cast_utils.h"
34#include "layer_validation_tests.h"
35
36static VkInstance dummy_instance;
37
38TEST_F(VkLayerTest, InstanceExtensionDependencies) {
39 TEST_DESCRIPTION("Test enabling instance extension without dependencies met.");
40
41 if (!InstanceExtensionSupported(VK_KHR_GET_SURFACE_CAPABILITIES_2_EXTENSION_NAME)) {
42 printf("%s Did not find required instance extension %s.\n", kSkipPrefix, VK_KHR_GET_SURFACE_CAPABILITIES_2_EXTENSION_NAME);
43 return;
44 }
45 ASSERT_TRUE(InstanceExtensionSupported(VK_KHR_SURFACE_EXTENSION_NAME)); // Driver should always provide dependencies
46
47 Monitor().SetDesiredFailureMsg(kErrorBit, "VUID-vkCreateInstance-ppEnabledExtensionNames-01388");
48 instance_extensions_.push_back(VK_KHR_GET_SURFACE_CAPABILITIES_2_EXTENSION_NAME);
49 const auto ici = GetInstanceCreateInfo();
50 vk::CreateInstance(&ici, nullptr, &dummy_instance);
51 Monitor().VerifyFound();
Petr Kraus18b7d1f2020-03-31 21:12:30 +020052}
53
Petr Kraus18b7d1f2020-03-31 21:12:30 +020054TEST_F(VkLayerTest, InstanceBadStype) {
55 TEST_DESCRIPTION("Test creating instance with bad sType.");
56
57 auto ici = GetInstanceCreateInfo();
58
59 Monitor().SetDesiredFailureMsg(kErrorBit, "VUID-VkInstanceCreateInfo-sType-sType");
60 ici.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO;
61 vk::CreateInstance(&ici, nullptr, &dummy_instance);
62 Monitor().VerifyFound();
Petr Kraus18b7d1f2020-03-31 21:12:30 +020063}
64
Petr Kraus18b7d1f2020-03-31 21:12:30 +020065TEST_F(VkLayerTest, InstanceDuplicatePnextStype) {
66 TEST_DESCRIPTION("Test creating instance with duplicate sType in the pNext chain.");
67
68 if (!InstanceExtensionSupported(VK_EXT_VALIDATION_FEATURES_EXTENSION_NAME)) {
69 printf("%s Did not find required instance extension %s.\n", kSkipPrefix, VK_EXT_VALIDATION_FEATURES_EXTENSION_NAME);
70 return;
71 }
72 instance_extensions_.push_back(VK_EXT_VALIDATION_FEATURES_EXTENSION_NAME);
73
74 auto ici = GetInstanceCreateInfo();
75
76 Monitor().SetDesiredFailureMsg(kErrorBit, "VUID-VkInstanceCreateInfo-sType-unique");
77 const VkValidationFeaturesEXT duplicate_pnext = {VK_STRUCTURE_TYPE_VALIDATION_FEATURES_EXT, ici.pNext};
78 const VkValidationFeaturesEXT first_pnext = {VK_STRUCTURE_TYPE_VALIDATION_FEATURES_EXT, &duplicate_pnext};
79 ici.pNext = &first_pnext;
80 vk::CreateInstance(&ici, nullptr, &dummy_instance);
81 Monitor().VerifyFound();
Petr Kraus18b7d1f2020-03-31 21:12:30 +020082}
83
84TEST_F(VkLayerTest, InstanceFlags) {
85 TEST_DESCRIPTION("Test creating instance with invalid flags.");
86
87 auto ici = GetInstanceCreateInfo();
88
89 Monitor().SetDesiredFailureMsg(kErrorBit, "VUID-VkInstanceCreateInfo-flags-zerobitmask");
90 ici.flags = (VkInstanceCreateFlags)1;
91 vk::CreateInstance(&ici, nullptr, &dummy_instance);
92 Monitor().VerifyFound();
Petr Kraus18b7d1f2020-03-31 21:12:30 +020093}
94
95TEST_F(VkLayerTest, InstanceAppInfoBadStype) {
96 TEST_DESCRIPTION("Test creating instance with invalid sType in VkApplicationInfo.");
97
98 auto ici = GetInstanceCreateInfo();
99
100 VkApplicationInfo bad_app_info = {};
101 if (ici.pApplicationInfo) bad_app_info = *ici.pApplicationInfo;
102 bad_app_info.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO;
103 ici.pApplicationInfo = &bad_app_info;
104
105 Monitor().SetDesiredFailureMsg(kErrorBit, "VUID-VkApplicationInfo-sType-sType");
106 vk::CreateInstance(&ici, nullptr, &dummy_instance);
107 Monitor().VerifyFound();
Petr Kraus18b7d1f2020-03-31 21:12:30 +0200108}
109
Petr Kraus18b7d1f2020-03-31 21:12:30 +0200110TEST_F(VkLayerTest, InstanceValidationFeaturesBadFlags) {
111 TEST_DESCRIPTION("Test creating instance with invalid flags in VkValidationFeaturesEXT.");
112
113 if (!InstanceExtensionSupported(VK_EXT_VALIDATION_FEATURES_EXTENSION_NAME)) {
114 printf("%s Did not find required instance extension %s.\n", kSkipPrefix, VK_EXT_VALIDATION_FEATURES_EXTENSION_NAME);
115 return;
116 }
117 instance_extensions_.push_back(VK_EXT_VALIDATION_FEATURES_EXTENSION_NAME);
118
119 auto ici = GetInstanceCreateInfo();
120
121 // the test framework should not be using VkValidationFeatureEnableEXT itself
122 for (auto traversable_pnext = reinterpret_cast<const VkBaseInStructure*>(ici.pNext); traversable_pnext;
123 traversable_pnext = traversable_pnext->pNext) {
124 ASSERT_NE(traversable_pnext->sType, VK_STRUCTURE_TYPE_VALIDATION_FEATURES_EXT);
125 }
126
Petr Kraus77430942020-04-04 01:43:08 +0200127 VkValidationFeaturesEXT validation_features_template = {};
128 validation_features_template.sType = VK_STRUCTURE_TYPE_VALIDATION_FEATURES_EXT;
129 validation_features_template.pNext = ici.pNext;
Petr Kraus18b7d1f2020-03-31 21:12:30 +0200130
131 {
Petr Kraus18b7d1f2020-03-31 21:12:30 +0200132 const VkValidationFeatureEnableEXT bad_enable = (VkValidationFeatureEnableEXT)0x42;
Petr Kraus77430942020-04-04 01:43:08 +0200133 VkValidationFeaturesEXT validation_features = validation_features_template;
134 validation_features.enabledValidationFeatureCount = 1;
Petr Kraus18b7d1f2020-03-31 21:12:30 +0200135 validation_features.pEnabledValidationFeatures = &bad_enable;
Petr Kraus77430942020-04-04 01:43:08 +0200136 ici.pNext = &validation_features;
Petr Kraus18b7d1f2020-03-31 21:12:30 +0200137
Petr Kraus77430942020-04-04 01:43:08 +0200138 // VUID-VkValidationFeaturesEXT-pEnabledValidationFeatures-parameter
Petr Kraus18b7d1f2020-03-31 21:12:30 +0200139 Monitor().SetDesiredFailureMsg(kErrorBit, "UNASSIGNED-GeneralParameterError-UnrecognizedValue");
140 vk::CreateInstance(&ici, nullptr, &dummy_instance);
141 Monitor().VerifyFound();
Petr Kraus18b7d1f2020-03-31 21:12:30 +0200142 }
143
144 {
Petr Kraus18b7d1f2020-03-31 21:12:30 +0200145 const VkValidationFeatureDisableEXT bad_disable = (VkValidationFeatureDisableEXT)0x42;
Petr Kraus77430942020-04-04 01:43:08 +0200146 VkValidationFeaturesEXT validation_features = validation_features_template;
147 validation_features.disabledValidationFeatureCount = 1;
Petr Kraus18b7d1f2020-03-31 21:12:30 +0200148 validation_features.pDisabledValidationFeatures = &bad_disable;
Petr Kraus77430942020-04-04 01:43:08 +0200149 ici.pNext = &validation_features;
Petr Kraus18b7d1f2020-03-31 21:12:30 +0200150
Petr Kraus77430942020-04-04 01:43:08 +0200151 // VUID-VkValidationFeaturesEXT-pEnabledValidationFeatures-parameter
Petr Kraus18b7d1f2020-03-31 21:12:30 +0200152 Monitor().SetDesiredFailureMsg(kErrorBit, "UNASSIGNED-GeneralParameterError-UnrecognizedValue");
153 vk::CreateInstance(&ici, nullptr, &dummy_instance);
154 Monitor().VerifyFound();
Petr Kraus18b7d1f2020-03-31 21:12:30 +0200155 }
Petr Kraus18b7d1f2020-03-31 21:12:30 +0200156}
157
158TEST_F(VkLayerTest, InstanceBadValidationFlags) {
159 TEST_DESCRIPTION("Test creating instance with invalid VkValidationFlagsEXT.");
160
161 if (!InstanceExtensionSupported(VK_EXT_VALIDATION_FLAGS_EXTENSION_NAME)) {
162 printf("%s Did not find required instance extension %s.\n", kSkipPrefix, VK_EXT_VALIDATION_FLAGS_EXTENSION_NAME);
163 return;
164 }
165 instance_extensions_.push_back(VK_EXT_VALIDATION_FLAGS_EXTENSION_NAME);
166
167 auto ici = GetInstanceCreateInfo();
168
169 // the test framework should not be using VkValidationFlagsEXT itself
170 for (auto traversable_pnext = reinterpret_cast<const VkBaseInStructure*>(ici.pNext); traversable_pnext;
171 traversable_pnext = traversable_pnext->pNext) {
172 ASSERT_NE(traversable_pnext->sType, VK_STRUCTURE_TYPE_VALIDATION_FLAGS_EXT);
173 }
174
Petr Kraus77430942020-04-04 01:43:08 +0200175 VkValidationFlagsEXT validation_flags_template = {};
176 validation_flags_template.sType = VK_STRUCTURE_TYPE_VALIDATION_FLAGS_EXT;
177 validation_flags_template.pNext = ici.pNext;
Petr Kraus18b7d1f2020-03-31 21:12:30 +0200178
179 {
Petr Kraus18b7d1f2020-03-31 21:12:30 +0200180 const VkValidationCheckEXT bad_disable = (VkValidationCheckEXT)0x42;
Petr Kraus77430942020-04-04 01:43:08 +0200181 VkValidationFlagsEXT validation_flags = validation_flags_template;
182 validation_flags.disabledValidationCheckCount = 1;
Petr Kraus18b7d1f2020-03-31 21:12:30 +0200183 validation_flags.pDisabledValidationChecks = &bad_disable;
Petr Kraus77430942020-04-04 01:43:08 +0200184 ici.pNext = &validation_flags;
Petr Kraus18b7d1f2020-03-31 21:12:30 +0200185
Petr Kraus77430942020-04-04 01:43:08 +0200186 // VUID-VkValidationFlagsEXT-pDisabledValidationChecks-parameter
Petr Kraus18b7d1f2020-03-31 21:12:30 +0200187 Monitor().SetDesiredFailureMsg(kErrorBit, "UNASSIGNED-GeneralParameterError-UnrecognizedValue");
188 vk::CreateInstance(&ici, nullptr, &dummy_instance);
189 Monitor().VerifyFound();
Petr Kraus18b7d1f2020-03-31 21:12:30 +0200190 }
191
192 {
Petr Kraus77430942020-04-04 01:43:08 +0200193 VkValidationFlagsEXT validation_flags = validation_flags_template;
Petr Kraus18b7d1f2020-03-31 21:12:30 +0200194 validation_flags.disabledValidationCheckCount = 0;
Petr Kraus77430942020-04-04 01:43:08 +0200195 ici.pNext = &validation_flags;
Petr Kraus18b7d1f2020-03-31 21:12:30 +0200196
Petr Kraus77430942020-04-04 01:43:08 +0200197 // VUID-VkValidationFlagsEXT-disabledValidationCheckCount-arraylength
Petr Kraus18b7d1f2020-03-31 21:12:30 +0200198 Monitor().SetDesiredFailureMsg(kErrorBit, "parameter disabledValidationCheckCount must be greater than 0");
199 vk::CreateInstance(&ici, nullptr, &dummy_instance);
200 Monitor().VerifyFound();
Petr Kraus18b7d1f2020-03-31 21:12:30 +0200201 }
Petr Kraus18b7d1f2020-03-31 21:12:30 +0200202}
203
Petr Kraus77430942020-04-04 01:43:08 +0200204void* VKAPI_PTR DummyAlloc(void*, size_t size, size_t alignment, VkSystemAllocationScope) {
205 size_t space = size + alignment - 1;
206 void* mem_ptr = std::malloc(space);
207 return std::align(alignment, size, mem_ptr, space);
208}
209void VKAPI_PTR DummyFree(void*, void* pMemory) {
210 // just leak it
211}
212void* VKAPI_PTR DummyRealloc(void* pUserData, void* pOriginal, size_t size, size_t alignment,
213 VkSystemAllocationScope allocationScope) {
214 DummyFree(pUserData, pOriginal);
215 return DummyAlloc(pUserData, size, alignment, allocationScope);
216}
217void VKAPI_PTR DummyInfoAlloc(void*, size_t, VkInternalAllocationType, VkSystemAllocationScope) {}
218void VKAPI_PTR DummyInfoFree(void*, size_t, VkInternalAllocationType, VkSystemAllocationScope) {}
219
Petr Kraus18b7d1f2020-03-31 21:12:30 +0200220TEST_F(VkLayerTest, DestroyInstanceAllocationCallbacksCompatibility) {
221 TEST_DESCRIPTION("Test vkDestroyInstance with incompatible allocation callbacks.");
222
223 const auto ici = GetInstanceCreateInfo();
224 const VkAllocationCallbacks alloc_callbacks = {nullptr, &DummyAlloc, &DummyRealloc,
225 &DummyFree, &DummyInfoAlloc, &DummyInfoFree};
226
Petr Kraus18b7d1f2020-03-31 21:12:30 +0200227 {
228 VkInstance instance;
229 ASSERT_VK_SUCCESS(vk::CreateInstance(&ici, nullptr, &instance));
230
231 Monitor().SetDesiredFailureMsg(kErrorBit, "VUID-vkDestroyInstance-instance-00631");
232 vk::DestroyInstance(instance, &alloc_callbacks);
233 Monitor().VerifyFound();
234 }
235}
236
237TEST_F(VkLayerTest, DestroyInstanceHandleLeak) {
238 TEST_DESCRIPTION("Test vkDestroyInstance while leaking a VkDevice object.");
Tony-LunarGa0186342021-10-11 13:17:51 -0600239 ASSERT_NO_FATAL_FAILURE(InitFramework());
240 if (!IsPlatform(kMockICD)) {
241 // This test leaks a device (on purpose) and should not be run on a real driver
242 printf("%s This test only runs on the mock ICD\n", kSkipPrefix);
243 return;
244 }
Petr Kraus18b7d1f2020-03-31 21:12:30 +0200245 const auto ici = GetInstanceCreateInfo();
246
247 VkInstance instance;
248 ASSERT_VK_SUCCESS(vk::CreateInstance(&ici, nullptr, &instance));
249 uint32_t physical_device_count = 1;
250 VkPhysicalDevice physical_device;
Petr Kraus75ae8d92020-04-07 21:20:04 +0200251 const VkResult err = vk::EnumeratePhysicalDevices(instance, &physical_device_count, &physical_device);
252 ASSERT_TRUE(err == VK_SUCCESS || err == VK_INCOMPLETE) << vk_result_string(err);
Petr Kraus18b7d1f2020-03-31 21:12:30 +0200253 ASSERT_EQ(physical_device_count, 1);
254
255 float dqci_priorities[] = {1.0};
256 VkDeviceQueueCreateInfo dqci = {};
257 dqci.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
258 dqci.queueFamilyIndex = 0;
259 dqci.queueCount = 1;
260 dqci.pQueuePriorities = dqci_priorities;
261
262 VkDeviceCreateInfo dci = {};
263 dci.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
264 dci.queueCreateInfoCount = 1;
265 dci.pQueueCreateInfos = &dqci;
266
267 VkDevice leaked_device;
268 ASSERT_VK_SUCCESS(vk::CreateDevice(physical_device, &dci, nullptr, &leaked_device));
269
Petr Kraus77430942020-04-04 01:43:08 +0200270 // VUID-vkDestroyInstance-instance-00629
Petr Kraus18b7d1f2020-03-31 21:12:30 +0200271 Monitor().SetDesiredFailureMsg(kErrorBit, "UNASSIGNED-ObjectTracker-ObjectLeak");
272 vk::DestroyInstance(instance, nullptr);
273 Monitor().VerifyFound();
274}