1 /*
2 * Copyright (c) 2015-2019 The Khronos Group Inc.
3 * Copyright (c) 2015-2019 Valve Corporation
4 * Copyright (c) 2015-2019 LunarG, Inc.
5 * Copyright (c) 2015-2019 Google, Inc.
6 *
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Author: Chia-I Wu <olvaffe@gmail.com>
14 * Author: Chris Forbes <chrisf@ijw.co.nz>
15 * Author: Courtney Goeltzenleuchter <courtney@LunarG.com>
16 * Author: Mark Lobodzinski <mark@lunarg.com>
17 * Author: Mike Stroyan <mike@LunarG.com>
18 * Author: Tobin Ehlis <tobine@google.com>
19 * Author: Tony Barbour <tony@LunarG.com>
20 * Author: Cody Northrop <cnorthrop@google.com>
21 * Author: Dave Houlton <daveh@lunarg.com>
22 * Author: Jeremy Kniager <jeremyk@lunarg.com>
23 * Author: Shannon McPherson <shannon@lunarg.com>
24 * Author: John Zulauf <jzulauf@lunarg.com>
25 */
26
27 #include "cast_utils.h"
28 #include "layer_validation_tests.h"
29
TEST_F(VkLayerTest,RequiredParameter)30 TEST_F(VkLayerTest, RequiredParameter) {
31 TEST_DESCRIPTION("Specify VK_NULL_HANDLE, NULL, and 0 for required handle, pointer, array, and array count parameters");
32
33 ASSERT_NO_FATAL_FAILURE(Init());
34
35 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "required parameter pFeatures specified as NULL");
36 // Specify NULL for a pointer to a handle
37 // Expected to trigger an error with
38 // parameter_validation::validate_required_pointer
39 vkGetPhysicalDeviceFeatures(gpu(), NULL);
40 m_errorMonitor->VerifyFound();
41
42 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
43 "required parameter pQueueFamilyPropertyCount specified as NULL");
44 // Specify NULL for pointer to array count
45 // Expected to trigger an error with parameter_validation::validate_array
46 vkGetPhysicalDeviceQueueFamilyProperties(gpu(), NULL, NULL);
47 m_errorMonitor->VerifyFound();
48
49 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdSetViewport-viewportCount-arraylength");
50 // Specify 0 for a required array count
51 // Expected to trigger an error with parameter_validation::validate_array
52 VkViewport viewport = {0.0f, 0.0f, 64.0f, 64.0f, 0.0f, 1.0f};
53 m_commandBuffer->SetViewport(0, 0, &viewport);
54 m_errorMonitor->VerifyFound();
55
56 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCreateImage-pCreateInfo-parameter");
57 // Specify a null pImageCreateInfo struct pointer
58 VkImage test_image;
59 vkCreateImage(device(), NULL, NULL, &test_image);
60 m_errorMonitor->VerifyFound();
61
62 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdSetViewport-pViewports-parameter");
63 // Specify NULL for a required array
64 // Expected to trigger an error with parameter_validation::validate_array
65 m_commandBuffer->SetViewport(0, 1, NULL);
66 m_errorMonitor->VerifyFound();
67
68 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "required parameter memory specified as VK_NULL_HANDLE");
69 // Specify VK_NULL_HANDLE for a required handle
70 // Expected to trigger an error with
71 // parameter_validation::validate_required_handle
72 vkUnmapMemory(device(), VK_NULL_HANDLE);
73 m_errorMonitor->VerifyFound();
74
75 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
76 "required parameter pFences[0] specified as VK_NULL_HANDLE");
77 // Specify VK_NULL_HANDLE for a required handle array entry
78 // Expected to trigger an error with
79 // parameter_validation::validate_required_handle_array
80 VkFence fence = VK_NULL_HANDLE;
81 vkResetFences(device(), 1, &fence);
82 m_errorMonitor->VerifyFound();
83
84 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "required parameter pAllocateInfo specified as NULL");
85 // Specify NULL for a required struct pointer
86 // Expected to trigger an error with
87 // parameter_validation::validate_struct_type
88 VkDeviceMemory memory = VK_NULL_HANDLE;
89 vkAllocateMemory(device(), NULL, NULL, &memory);
90 m_errorMonitor->VerifyFound();
91
92 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "value of faceMask must not be 0");
93 // Specify 0 for a required VkFlags parameter
94 // Expected to trigger an error with parameter_validation::validate_flags
95 m_commandBuffer->SetStencilReference(0, 0);
96 m_errorMonitor->VerifyFound();
97
98 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "value of pSubmits[0].pWaitDstStageMask[0] must not be 0");
99 // Specify 0 for a required VkFlags array entry
100 // Expected to trigger an error with
101 // parameter_validation::validate_flags_array
102 VkSemaphore semaphore = VK_NULL_HANDLE;
103 VkPipelineStageFlags stageFlags = 0;
104 VkSubmitInfo submitInfo = {};
105 submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
106 submitInfo.waitSemaphoreCount = 1;
107 submitInfo.pWaitSemaphores = &semaphore;
108 submitInfo.pWaitDstStageMask = &stageFlags;
109 vkQueueSubmit(m_device->m_queue, 1, &submitInfo, VK_NULL_HANDLE);
110 m_errorMonitor->VerifyFound();
111
112 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkSubmitInfo-sType-sType");
113 stageFlags = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT;
114 // Set a bogus sType and see what happens
115 submitInfo.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
116 submitInfo.waitSemaphoreCount = 1;
117 submitInfo.pWaitSemaphores = &semaphore;
118 submitInfo.pWaitDstStageMask = &stageFlags;
119 vkQueueSubmit(m_device->m_queue, 1, &submitInfo, VK_NULL_HANDLE);
120 m_errorMonitor->VerifyFound();
121
122 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkSubmitInfo-pWaitSemaphores-parameter");
123 stageFlags = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT;
124 submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
125 submitInfo.waitSemaphoreCount = 1;
126 // Set a null pointer for pWaitSemaphores
127 submitInfo.pWaitSemaphores = NULL;
128 submitInfo.pWaitDstStageMask = &stageFlags;
129 vkQueueSubmit(m_device->m_queue, 1, &submitInfo, VK_NULL_HANDLE);
130 m_errorMonitor->VerifyFound();
131
132 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCreateRenderPass-pCreateInfo-parameter");
133 VkRenderPass render_pass;
134 vkCreateRenderPass(device(), nullptr, nullptr, &render_pass);
135 m_errorMonitor->VerifyFound();
136 }
137
TEST_F(VkLayerTest,PnextOnlyStructValidation)138 TEST_F(VkLayerTest, PnextOnlyStructValidation) {
139 TEST_DESCRIPTION("See if checks occur on structs ONLY used in pnext chains.");
140
141 if (!(CheckDescriptorIndexingSupportAndInitFramework(this, m_instance_extension_names, m_device_extension_names, NULL,
142 m_errorMonitor))) {
143 printf("Descriptor indexing or one of its dependencies not supported, skipping tests\n");
144 return;
145 }
146
147 PFN_vkGetPhysicalDeviceFeatures2KHR vkGetPhysicalDeviceFeatures2KHR =
148 (PFN_vkGetPhysicalDeviceFeatures2KHR)vkGetInstanceProcAddr(instance(), "vkGetPhysicalDeviceFeatures2KHR");
149 ASSERT_TRUE(vkGetPhysicalDeviceFeatures2KHR != nullptr);
150
151 // Create a device passing in a bad PdevFeatures2 value
152 auto indexing_features = lvl_init_struct<VkPhysicalDeviceDescriptorIndexingFeaturesEXT>();
153 auto features2 = lvl_init_struct<VkPhysicalDeviceFeatures2KHR>(&indexing_features);
154 vkGetPhysicalDeviceFeatures2KHR(gpu(), &features2);
155 // Set one of the features values to an invalid boolean value
156 indexing_features.descriptorBindingUniformBufferUpdateAfterBind = 800;
157
158 uint32_t queue_node_count;
159 vkGetPhysicalDeviceQueueFamilyProperties(gpu(), &queue_node_count, NULL);
160 VkQueueFamilyProperties *queue_props = new VkQueueFamilyProperties[queue_node_count];
161 vkGetPhysicalDeviceQueueFamilyProperties(gpu(), &queue_node_count, queue_props);
162 float priorities[] = {1.0f};
163 VkDeviceQueueCreateInfo queue_info{};
164 queue_info.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
165 queue_info.pNext = NULL;
166 queue_info.flags = 0;
167 queue_info.queueFamilyIndex = 0;
168 queue_info.queueCount = 1;
169 queue_info.pQueuePriorities = &priorities[0];
170 VkDeviceCreateInfo dev_info = {};
171 dev_info.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
172 dev_info.pNext = NULL;
173 dev_info.queueCreateInfoCount = 1;
174 dev_info.pQueueCreateInfos = &queue_info;
175 dev_info.enabledLayerCount = 0;
176 dev_info.ppEnabledLayerNames = NULL;
177 dev_info.enabledExtensionCount = m_device_extension_names.size();
178 dev_info.ppEnabledExtensionNames = m_device_extension_names.data();
179 dev_info.pNext = &features2;
180 VkDevice dev;
181 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_WARNING_BIT_EXT, "is neither VK_TRUE nor VK_FALSE");
182 m_errorMonitor->SetUnexpectedError("Failed to create");
183 vkCreateDevice(gpu(), &dev_info, NULL, &dev);
184 m_errorMonitor->VerifyFound();
185 }
186
TEST_F(VkLayerTest,ReservedParameter)187 TEST_F(VkLayerTest, ReservedParameter) {
188 TEST_DESCRIPTION("Specify a non-zero value for a reserved parameter");
189
190 ASSERT_NO_FATAL_FAILURE(Init());
191
192 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, " must be 0");
193 // Specify 0 for a reserved VkFlags parameter
194 // Expected to trigger an error with
195 // parameter_validation::validate_reserved_flags
196 VkEvent event_handle = VK_NULL_HANDLE;
197 VkEventCreateInfo event_info = {};
198 event_info.sType = VK_STRUCTURE_TYPE_EVENT_CREATE_INFO;
199 event_info.flags = 1;
200 vkCreateEvent(device(), &event_info, NULL, &event_handle);
201 m_errorMonitor->VerifyFound();
202 }
203
TEST_F(VkLayerTest,DebugMarkerNameTest)204 TEST_F(VkLayerTest, DebugMarkerNameTest) {
205 TEST_DESCRIPTION("Ensure debug marker object names are printed in debug report output");
206
207 ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor));
208 if (DeviceExtensionSupported(gpu(), "VK_LAYER_LUNARG_core_validation", VK_EXT_DEBUG_MARKER_EXTENSION_NAME)) {
209 m_device_extension_names.push_back(VK_EXT_DEBUG_MARKER_EXTENSION_NAME);
210 } else {
211 printf("%s Debug Marker Extension not supported, skipping test\n", kSkipPrefix);
212 return;
213 }
214 ASSERT_NO_FATAL_FAILURE(InitState());
215
216 PFN_vkDebugMarkerSetObjectNameEXT fpvkDebugMarkerSetObjectNameEXT =
217 (PFN_vkDebugMarkerSetObjectNameEXT)vkGetInstanceProcAddr(instance(), "vkDebugMarkerSetObjectNameEXT");
218 if (!(fpvkDebugMarkerSetObjectNameEXT)) {
219 printf("%s Can't find fpvkDebugMarkerSetObjectNameEXT; skipped.\n", kSkipPrefix);
220 return;
221 }
222
223 if (DeviceSimulation()) {
224 printf("%sSkipping object naming test.\n", kSkipPrefix);
225 return;
226 }
227
228 VkBuffer buffer;
229 VkDeviceMemory memory_1, memory_2;
230 std::string memory_name = "memory_name";
231
232 VkBufferCreateInfo buffer_create_info = {};
233 buffer_create_info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
234 buffer_create_info.usage = VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT;
235 buffer_create_info.size = 1;
236
237 vkCreateBuffer(device(), &buffer_create_info, nullptr, &buffer);
238
239 VkMemoryRequirements memRequirements;
240 vkGetBufferMemoryRequirements(device(), buffer, &memRequirements);
241
242 VkMemoryAllocateInfo memory_allocate_info = {};
243 memory_allocate_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
244 memory_allocate_info.allocationSize = memRequirements.size;
245 memory_allocate_info.memoryTypeIndex = 0;
246
247 vkAllocateMemory(device(), &memory_allocate_info, nullptr, &memory_1);
248 vkAllocateMemory(device(), &memory_allocate_info, nullptr, &memory_2);
249
250 VkDebugMarkerObjectNameInfoEXT name_info = {};
251 name_info.sType = VK_STRUCTURE_TYPE_DEBUG_MARKER_OBJECT_NAME_INFO_EXT;
252 name_info.pNext = nullptr;
253 name_info.object = (uint64_t)memory_2;
254 name_info.objectType = VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_MEMORY_EXT;
255 name_info.pObjectName = memory_name.c_str();
256 fpvkDebugMarkerSetObjectNameEXT(device(), &name_info);
257
258 vkBindBufferMemory(device(), buffer, memory_1, 0);
259
260 // Test core_validation layer
261 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, memory_name);
262 vkBindBufferMemory(device(), buffer, memory_2, 0);
263 m_errorMonitor->VerifyFound();
264
265 vkFreeMemory(device(), memory_1, nullptr);
266 memory_1 = VK_NULL_HANDLE;
267 vkFreeMemory(device(), memory_2, nullptr);
268 memory_2 = VK_NULL_HANDLE;
269 vkDestroyBuffer(device(), buffer, nullptr);
270 buffer = VK_NULL_HANDLE;
271
272 VkCommandBuffer commandBuffer;
273 std::string commandBuffer_name = "command_buffer_name";
274 VkCommandPool commandpool_1;
275 VkCommandPool commandpool_2;
276 VkCommandPoolCreateInfo pool_create_info{};
277 pool_create_info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
278 pool_create_info.queueFamilyIndex = m_device->graphics_queue_node_index_;
279 pool_create_info.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT;
280 vkCreateCommandPool(device(), &pool_create_info, nullptr, &commandpool_1);
281 vkCreateCommandPool(device(), &pool_create_info, nullptr, &commandpool_2);
282
283 VkCommandBufferAllocateInfo command_buffer_allocate_info{};
284 command_buffer_allocate_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
285 command_buffer_allocate_info.commandPool = commandpool_1;
286 command_buffer_allocate_info.commandBufferCount = 1;
287 command_buffer_allocate_info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
288 vkAllocateCommandBuffers(device(), &command_buffer_allocate_info, &commandBuffer);
289
290 name_info.object = (uint64_t)commandBuffer;
291 name_info.objectType = VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT;
292 name_info.pObjectName = commandBuffer_name.c_str();
293 fpvkDebugMarkerSetObjectNameEXT(device(), &name_info);
294
295 VkCommandBufferBeginInfo cb_begin_Info = {};
296 cb_begin_Info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
297 cb_begin_Info.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT;
298 vkBeginCommandBuffer(commandBuffer, &cb_begin_Info);
299
300 const VkRect2D scissor = {{-1, 0}, {16, 16}};
301 const VkRect2D scissors[] = {scissor, scissor};
302
303 // Test parameter_validation layer
304 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, commandBuffer_name);
305 vkCmdSetScissor(commandBuffer, 1, 1, scissors);
306 m_errorMonitor->VerifyFound();
307
308 // Test object_tracker layer
309 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, commandBuffer_name);
310 vkFreeCommandBuffers(device(), commandpool_2, 1, &commandBuffer);
311 m_errorMonitor->VerifyFound();
312
313 vkDestroyCommandPool(device(), commandpool_1, NULL);
314 vkDestroyCommandPool(device(), commandpool_2, NULL);
315 }
316
TEST_F(VkLayerTest,DebugUtilsNameTest)317 TEST_F(VkLayerTest, DebugUtilsNameTest) {
318 TEST_DESCRIPTION("Ensure debug utils object names are printed in debug messenger output");
319
320 // Skip test if extension not supported
321 if (InstanceExtensionSupported(VK_EXT_DEBUG_UTILS_EXTENSION_NAME)) {
322 m_instance_extension_names.push_back(VK_EXT_DEBUG_UTILS_EXTENSION_NAME);
323 } else {
324 printf("%s Debug Utils Extension not supported, skipping test\n", kSkipPrefix);
325 return;
326 }
327
328 ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor));
329 ASSERT_NO_FATAL_FAILURE(InitState());
330
331 PFN_vkSetDebugUtilsObjectNameEXT fpvkSetDebugUtilsObjectNameEXT =
332 (PFN_vkSetDebugUtilsObjectNameEXT)vkGetInstanceProcAddr(instance(), "vkSetDebugUtilsObjectNameEXT");
333 ASSERT_TRUE(fpvkSetDebugUtilsObjectNameEXT); // Must be extant if extension is enabled
334 PFN_vkCreateDebugUtilsMessengerEXT fpvkCreateDebugUtilsMessengerEXT =
335 (PFN_vkCreateDebugUtilsMessengerEXT)vkGetInstanceProcAddr(instance(), "vkCreateDebugUtilsMessengerEXT");
336 ASSERT_TRUE(fpvkCreateDebugUtilsMessengerEXT); // Must be extant if extension is enabled
337 PFN_vkDestroyDebugUtilsMessengerEXT fpvkDestroyDebugUtilsMessengerEXT =
338 (PFN_vkDestroyDebugUtilsMessengerEXT)vkGetInstanceProcAddr(instance(), "vkDestroyDebugUtilsMessengerEXT");
339 ASSERT_TRUE(fpvkDestroyDebugUtilsMessengerEXT); // Must be extant if extension is enabled
340 PFN_vkCmdInsertDebugUtilsLabelEXT fpvkCmdInsertDebugUtilsLabelEXT =
341 (PFN_vkCmdInsertDebugUtilsLabelEXT)vkGetInstanceProcAddr(instance(), "vkCmdInsertDebugUtilsLabelEXT");
342 ASSERT_TRUE(fpvkCmdInsertDebugUtilsLabelEXT); // Must be extant if extension is enabled
343
344 if (DeviceSimulation()) {
345 printf("%sSkipping object naming test.\n", kSkipPrefix);
346 return;
347 }
348
349 DebugUtilsLabelCheckData callback_data;
350 auto empty_callback = [](const VkDebugUtilsMessengerCallbackDataEXT *pCallbackData, DebugUtilsLabelCheckData *data) {
351 data->count++;
352 };
353 callback_data.count = 0;
354 callback_data.callback = empty_callback;
355
356 auto callback_create_info = lvl_init_struct<VkDebugUtilsMessengerCreateInfoEXT>();
357 callback_create_info.messageSeverity =
358 VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT | VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT;
359 callback_create_info.messageType = VK_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT;
360 callback_create_info.pfnUserCallback = DebugUtilsCallback;
361 callback_create_info.pUserData = &callback_data;
362 VkDebugUtilsMessengerEXT my_messenger = VK_NULL_HANDLE;
363 fpvkCreateDebugUtilsMessengerEXT(instance(), &callback_create_info, nullptr, &my_messenger);
364
365 VkBuffer buffer;
366 VkDeviceMemory memory_1, memory_2;
367 std::string memory_name = "memory_name";
368
369 VkBufferCreateInfo buffer_create_info = {};
370 buffer_create_info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
371 buffer_create_info.usage = VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT;
372 buffer_create_info.size = 1;
373
374 vkCreateBuffer(device(), &buffer_create_info, nullptr, &buffer);
375
376 VkMemoryRequirements memRequirements;
377 vkGetBufferMemoryRequirements(device(), buffer, &memRequirements);
378
379 VkMemoryAllocateInfo memory_allocate_info = {};
380 memory_allocate_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
381 memory_allocate_info.allocationSize = memRequirements.size;
382 memory_allocate_info.memoryTypeIndex = 0;
383
384 vkAllocateMemory(device(), &memory_allocate_info, nullptr, &memory_1);
385 vkAllocateMemory(device(), &memory_allocate_info, nullptr, &memory_2);
386
387 VkDebugUtilsObjectNameInfoEXT name_info = {};
388 name_info.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_OBJECT_NAME_INFO_EXT;
389 name_info.pNext = nullptr;
390 name_info.objectHandle = (uint64_t)memory_2;
391 name_info.objectType = VK_OBJECT_TYPE_DEVICE_MEMORY;
392 name_info.pObjectName = memory_name.c_str();
393 fpvkSetDebugUtilsObjectNameEXT(device(), &name_info);
394
395 vkBindBufferMemory(device(), buffer, memory_1, 0);
396
397 // Test core_validation layer
398 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, memory_name);
399 vkBindBufferMemory(device(), buffer, memory_2, 0);
400 m_errorMonitor->VerifyFound();
401
402 vkFreeMemory(device(), memory_1, nullptr);
403 memory_1 = VK_NULL_HANDLE;
404 vkFreeMemory(device(), memory_2, nullptr);
405 memory_2 = VK_NULL_HANDLE;
406 vkDestroyBuffer(device(), buffer, nullptr);
407 buffer = VK_NULL_HANDLE;
408
409 VkCommandBuffer commandBuffer;
410 std::string commandBuffer_name = "command_buffer_name";
411 VkCommandPool commandpool_1;
412 VkCommandPool commandpool_2;
413 VkCommandPoolCreateInfo pool_create_info{};
414 pool_create_info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
415 pool_create_info.queueFamilyIndex = m_device->graphics_queue_node_index_;
416 pool_create_info.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT;
417 vkCreateCommandPool(device(), &pool_create_info, nullptr, &commandpool_1);
418 vkCreateCommandPool(device(), &pool_create_info, nullptr, &commandpool_2);
419
420 VkCommandBufferAllocateInfo command_buffer_allocate_info{};
421 command_buffer_allocate_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
422 command_buffer_allocate_info.commandPool = commandpool_1;
423 command_buffer_allocate_info.commandBufferCount = 1;
424 command_buffer_allocate_info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
425 vkAllocateCommandBuffers(device(), &command_buffer_allocate_info, &commandBuffer);
426
427 name_info.objectHandle = (uint64_t)commandBuffer;
428 name_info.objectType = VK_OBJECT_TYPE_COMMAND_BUFFER;
429 name_info.pObjectName = commandBuffer_name.c_str();
430 fpvkSetDebugUtilsObjectNameEXT(device(), &name_info);
431
432 VkCommandBufferBeginInfo cb_begin_Info = {};
433 cb_begin_Info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
434 cb_begin_Info.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT;
435 vkBeginCommandBuffer(commandBuffer, &cb_begin_Info);
436
437 const VkRect2D scissor = {{-1, 0}, {16, 16}};
438 const VkRect2D scissors[] = {scissor, scissor};
439
440 auto command_label = lvl_init_struct<VkDebugUtilsLabelEXT>();
441 command_label.pLabelName = "Command Label 0123";
442 command_label.color[0] = 0.;
443 command_label.color[1] = 1.;
444 command_label.color[2] = 2.;
445 command_label.color[3] = 3.0;
446 bool command_label_test = false;
447 auto command_label_callback = [command_label, &command_label_test](const VkDebugUtilsMessengerCallbackDataEXT *pCallbackData,
448 DebugUtilsLabelCheckData *data) {
449 data->count++;
450 command_label_test = false;
451 if (pCallbackData->cmdBufLabelCount == 1) {
452 command_label_test = pCallbackData->pCmdBufLabels[0] == command_label;
453 }
454 };
455 callback_data.callback = command_label_callback;
456
457 fpvkCmdInsertDebugUtilsLabelEXT(commandBuffer, &command_label);
458 // Test parameter_validation layer
459 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, commandBuffer_name);
460 vkCmdSetScissor(commandBuffer, 1, 1, scissors);
461 m_errorMonitor->VerifyFound();
462
463 // Check the label test
464 if (!command_label_test) {
465 ADD_FAILURE() << "Command label '" << command_label.pLabelName << "' not passed to callback.";
466 }
467
468 // Test object_tracker layer
469 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, commandBuffer_name);
470 vkFreeCommandBuffers(device(), commandpool_2, 1, &commandBuffer);
471 m_errorMonitor->VerifyFound();
472
473 vkDestroyCommandPool(device(), commandpool_1, NULL);
474 vkDestroyCommandPool(device(), commandpool_2, NULL);
475 fpvkDestroyDebugUtilsMessengerEXT(instance(), my_messenger, nullptr);
476 }
477
TEST_F(VkLayerTest,InvalidStructSType)478 TEST_F(VkLayerTest, InvalidStructSType) {
479 TEST_DESCRIPTION("Specify an invalid VkStructureType for a Vulkan structure's sType field");
480
481 ASSERT_NO_FATAL_FAILURE(Init());
482
483 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "parameter pAllocateInfo->sType must be");
484 // Zero struct memory, effectively setting sType to
485 // VK_STRUCTURE_TYPE_APPLICATION_INFO
486 // Expected to trigger an error with
487 // parameter_validation::validate_struct_type
488 VkMemoryAllocateInfo alloc_info = {};
489 VkDeviceMemory memory = VK_NULL_HANDLE;
490 vkAllocateMemory(device(), &alloc_info, NULL, &memory);
491 m_errorMonitor->VerifyFound();
492
493 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "parameter pSubmits[0].sType must be");
494 // Zero struct memory, effectively setting sType to
495 // VK_STRUCTURE_TYPE_APPLICATION_INFO
496 // Expected to trigger an error with
497 // parameter_validation::validate_struct_type_array
498 VkSubmitInfo submit_info = {};
499 vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
500 m_errorMonitor->VerifyFound();
501 }
502
TEST_F(VkLayerTest,InvalidStructPNext)503 TEST_F(VkLayerTest, InvalidStructPNext) {
504 TEST_DESCRIPTION("Specify an invalid value for a Vulkan structure's pNext field");
505
506 ASSERT_NO_FATAL_FAILURE(Init());
507
508 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_WARNING_BIT_EXT, "value of pCreateInfo->pNext must be NULL");
509 // Set VkMemoryAllocateInfo::pNext to a non-NULL value, when pNext must be NULL.
510 // Need to pick a function that has no allowed pNext structure types.
511 // Expected to trigger an error with parameter_validation::validate_struct_pnext
512 VkEvent event = VK_NULL_HANDLE;
513 VkEventCreateInfo event_alloc_info = {};
514 // Zero-initialization will provide the correct sType
515 VkApplicationInfo app_info = {};
516 event_alloc_info.sType = VK_STRUCTURE_TYPE_EVENT_CREATE_INFO;
517 event_alloc_info.pNext = &app_info;
518 vkCreateEvent(device(), &event_alloc_info, NULL, &event);
519 m_errorMonitor->VerifyFound();
520
521 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_WARNING_BIT_EXT,
522 " chain includes a structure with unexpected VkStructureType ");
523 // Set VkMemoryAllocateInfo::pNext to a non-NULL value, but use
524 // a function that has allowed pNext structure types and specify
525 // a structure type that is not allowed.
526 // Expected to trigger an error with parameter_validation::validate_struct_pnext
527 VkDeviceMemory memory = VK_NULL_HANDLE;
528 VkMemoryAllocateInfo memory_alloc_info = {};
529 memory_alloc_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
530 memory_alloc_info.pNext = &app_info;
531 vkAllocateMemory(device(), &memory_alloc_info, NULL, &memory);
532 m_errorMonitor->VerifyFound();
533 }
534
TEST_F(VkLayerTest,UnrecognizedValueOutOfRange)535 TEST_F(VkLayerTest, UnrecognizedValueOutOfRange) {
536 ASSERT_NO_FATAL_FAILURE(Init());
537
538 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
539 "does not fall within the begin..end range of the core VkFormat enumeration tokens");
540 // Specify an invalid VkFormat value
541 // Expected to trigger an error with
542 // parameter_validation::validate_ranged_enum
543 VkFormatProperties format_properties;
544 vkGetPhysicalDeviceFormatProperties(gpu(), static_cast<VkFormat>(8000), &format_properties);
545 m_errorMonitor->VerifyFound();
546 }
547
TEST_F(VkLayerTest,UnrecognizedValueBadMask)548 TEST_F(VkLayerTest, UnrecognizedValueBadMask) {
549 ASSERT_NO_FATAL_FAILURE(Init());
550
551 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "contains flag bits that are not recognized members of");
552 // Specify an invalid VkFlags bitmask value
553 // Expected to trigger an error with parameter_validation::validate_flags
554 VkImageFormatProperties image_format_properties;
555 vkGetPhysicalDeviceImageFormatProperties(gpu(), VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_TYPE_2D, VK_IMAGE_TILING_OPTIMAL,
556 static_cast<VkImageUsageFlags>(1 << 25), 0, &image_format_properties);
557 m_errorMonitor->VerifyFound();
558 }
559
TEST_F(VkLayerTest,UnrecognizedValueBadFlag)560 TEST_F(VkLayerTest, UnrecognizedValueBadFlag) {
561 ASSERT_NO_FATAL_FAILURE(Init());
562
563 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "contains flag bits that are not recognized members of");
564 // Specify an invalid VkFlags array entry
565 // Expected to trigger an error with parameter_validation::validate_flags_array
566 VkSemaphore semaphore;
567 VkSemaphoreCreateInfo semaphore_create_info{};
568 semaphore_create_info.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO;
569 vkCreateSemaphore(m_device->device(), &semaphore_create_info, nullptr, &semaphore);
570 // `stage_flags` is set to a value which, currently, is not a defined stage flag
571 // `VK_IMAGE_ASPECT_FLAG_BITS_MAX_ENUM` works well for this
572 VkPipelineStageFlags stage_flags = VK_IMAGE_ASPECT_FLAG_BITS_MAX_ENUM;
573 // `waitSemaphoreCount` *must* be greater than 0 to perform this check
574 VkSubmitInfo submit_info = {};
575 submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
576 submit_info.waitSemaphoreCount = 1;
577 submit_info.pWaitSemaphores = &semaphore;
578 submit_info.pWaitDstStageMask = &stage_flags;
579 vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
580 vkDestroySemaphore(m_device->device(), semaphore, nullptr);
581
582 m_errorMonitor->VerifyFound();
583 }
584
TEST_F(VkLayerTest,UnrecognizedValueBadBool)585 TEST_F(VkLayerTest, UnrecognizedValueBadBool) {
586 // Make sure using VK_SAMPLER_ADDRESS_MODE_MIRROR_CLAMP_TO_EDGE doesn't trigger a false positive.
587 ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor));
588 if (DeviceExtensionSupported(gpu(), nullptr, VK_KHR_SAMPLER_MIRROR_CLAMP_TO_EDGE_EXTENSION_NAME)) {
589 m_device_extension_names.push_back(VK_KHR_SAMPLER_MIRROR_CLAMP_TO_EDGE_EXTENSION_NAME);
590 } else {
591 printf("%s VK_KHR_sampler_mirror_clamp_to_edge extension not supported, skipping test\n", kSkipPrefix);
592 return;
593 }
594 ASSERT_NO_FATAL_FAILURE(InitState());
595
596 // Specify an invalid VkBool32 value, expecting a warning with parameter_validation::validate_bool32
597 VkSamplerCreateInfo sampler_info = SafeSaneSamplerCreateInfo();
598 sampler_info.addressModeU = VK_SAMPLER_ADDRESS_MODE_MIRROR_CLAMP_TO_EDGE;
599 sampler_info.addressModeV = VK_SAMPLER_ADDRESS_MODE_MIRROR_CLAMP_TO_EDGE;
600 sampler_info.addressModeW = VK_SAMPLER_ADDRESS_MODE_MIRROR_CLAMP_TO_EDGE;
601
602 // Not VK_TRUE or VK_FALSE
603 sampler_info.anisotropyEnable = 3;
604 CreateSamplerTest(*this, &sampler_info, "is neither VK_TRUE nor VK_FALSE");
605 }
606
TEST_F(VkLayerTest,UnrecognizedValueMaxEnum)607 TEST_F(VkLayerTest, UnrecognizedValueMaxEnum) {
608 ASSERT_NO_FATAL_FAILURE(Init());
609
610 // Specify MAX_ENUM
611 VkFormatProperties format_properties;
612 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "does not fall within the begin..end range");
613 vkGetPhysicalDeviceFormatProperties(gpu(), VK_FORMAT_MAX_ENUM, &format_properties);
614 m_errorMonitor->VerifyFound();
615 }
616
TEST_F(VkLayerTest,SubmitSignaledFence)617 TEST_F(VkLayerTest, SubmitSignaledFence) {
618 vk_testing::Fence testFence;
619
620 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
621 "submitted in SIGNALED state. Fences must be reset before being submitted");
622
623 VkFenceCreateInfo fenceInfo = {};
624 fenceInfo.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
625 fenceInfo.pNext = NULL;
626 fenceInfo.flags = VK_FENCE_CREATE_SIGNALED_BIT;
627
628 ASSERT_NO_FATAL_FAILURE(Init());
629 ASSERT_NO_FATAL_FAILURE(InitViewport());
630 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
631
632 m_commandBuffer->begin();
633 m_commandBuffer->ClearAllBuffers(m_renderTargets, m_clear_color, nullptr, m_depth_clear_color, m_stencil_clear_color);
634 m_commandBuffer->end();
635
636 testFence.init(*m_device, fenceInfo);
637
638 VkSubmitInfo submit_info;
639 submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
640 submit_info.pNext = NULL;
641 submit_info.waitSemaphoreCount = 0;
642 submit_info.pWaitSemaphores = NULL;
643 submit_info.pWaitDstStageMask = NULL;
644 submit_info.commandBufferCount = 1;
645 submit_info.pCommandBuffers = &m_commandBuffer->handle();
646 submit_info.signalSemaphoreCount = 0;
647 submit_info.pSignalSemaphores = NULL;
648
649 vkQueueSubmit(m_device->m_queue, 1, &submit_info, testFence.handle());
650 vkQueueWaitIdle(m_device->m_queue);
651
652 m_errorMonitor->VerifyFound();
653 }
654
TEST_F(VkLayerTest,LeakAnObject)655 TEST_F(VkLayerTest, LeakAnObject) {
656 TEST_DESCRIPTION("Create a fence and destroy its device without first destroying the fence.");
657
658 ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor));
659
660 // Workaround for overzealous layers checking even the guaranteed 0th queue family
661 const auto q_props = vk_testing::PhysicalDevice(gpu()).queue_properties();
662 ASSERT_TRUE(q_props.size() > 0);
663 ASSERT_TRUE(q_props[0].queueCount > 0);
664
665 const float q_priority[] = {1.0f};
666 VkDeviceQueueCreateInfo queue_ci = {};
667 queue_ci.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
668 queue_ci.queueFamilyIndex = 0;
669 queue_ci.queueCount = 1;
670 queue_ci.pQueuePriorities = q_priority;
671
672 VkDeviceCreateInfo device_ci = {};
673 device_ci.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
674 device_ci.queueCreateInfoCount = 1;
675 device_ci.pQueueCreateInfos = &queue_ci;
676
677 VkDevice leaky_device;
678 ASSERT_VK_SUCCESS(vkCreateDevice(gpu(), &device_ci, nullptr, &leaky_device));
679
680 const VkFenceCreateInfo fence_ci = {VK_STRUCTURE_TYPE_FENCE_CREATE_INFO};
681 VkFence leaked_fence;
682 ASSERT_VK_SUCCESS(vkCreateFence(leaky_device, &fence_ci, nullptr, &leaked_fence));
683
684 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkDestroyDevice-device-00378");
685 vkDestroyDevice(leaky_device, nullptr);
686 m_errorMonitor->VerifyFound();
687 }
688
TEST_F(VkLayerTest,UseObjectWithWrongDevice)689 TEST_F(VkLayerTest, UseObjectWithWrongDevice) {
690 TEST_DESCRIPTION(
691 "Try to destroy a render pass object using a device other than the one it was created on. This should generate a distinct "
692 "error from the invalid handle error.");
693 // Create first device and renderpass
694 ASSERT_NO_FATAL_FAILURE(Init());
695 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
696
697 // Create second device
698 float priorities[] = {1.0f};
699 VkDeviceQueueCreateInfo queue_info{};
700 queue_info.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
701 queue_info.pNext = NULL;
702 queue_info.flags = 0;
703 queue_info.queueFamilyIndex = 0;
704 queue_info.queueCount = 1;
705 queue_info.pQueuePriorities = &priorities[0];
706
707 VkDeviceCreateInfo device_create_info = {};
708 auto features = m_device->phy().features();
709 device_create_info.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
710 device_create_info.pNext = NULL;
711 device_create_info.queueCreateInfoCount = 1;
712 device_create_info.pQueueCreateInfos = &queue_info;
713 device_create_info.enabledLayerCount = 0;
714 device_create_info.ppEnabledLayerNames = NULL;
715 device_create_info.pEnabledFeatures = &features;
716
717 VkDevice second_device;
718 ASSERT_VK_SUCCESS(vkCreateDevice(gpu(), &device_create_info, NULL, &second_device));
719
720 // Try to destroy the renderpass from the first device using the second device
721 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkDestroyRenderPass-renderPass-parent");
722 vkDestroyRenderPass(second_device, m_renderPass, NULL);
723 m_errorMonitor->VerifyFound();
724
725 vkDestroyDevice(second_device, NULL);
726 }
727
TEST_F(VkLayerTest,InvalidAllocationCallbacks)728 TEST_F(VkLayerTest, InvalidAllocationCallbacks) {
729 TEST_DESCRIPTION("Test with invalid VkAllocationCallbacks");
730
731 ASSERT_NO_FATAL_FAILURE(Init());
732
733 // vkCreateInstance, and vkCreateDevice tend to crash in the Loader Trampoline ATM, so choosing vkCreateCommandPool
734 const VkCommandPoolCreateInfo cpci = {VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO, nullptr, 0,
735 DeviceObj()->QueueFamilyMatching(0, 0, true)};
736 VkCommandPool cmdPool;
737
738 struct Alloc {
739 static VKAPI_ATTR void *VKAPI_CALL alloc(void *, size_t, size_t, VkSystemAllocationScope) { return nullptr; };
740 static VKAPI_ATTR void *VKAPI_CALL realloc(void *, void *, size_t, size_t, VkSystemAllocationScope) { return nullptr; };
741 static VKAPI_ATTR void VKAPI_CALL free(void *, void *){};
742 static VKAPI_ATTR void VKAPI_CALL internalAlloc(void *, size_t, VkInternalAllocationType, VkSystemAllocationScope){};
743 static VKAPI_ATTR void VKAPI_CALL internalFree(void *, size_t, VkInternalAllocationType, VkSystemAllocationScope){};
744 };
745
746 {
747 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkAllocationCallbacks-pfnAllocation-00632");
748 const VkAllocationCallbacks allocator = {nullptr, nullptr, Alloc::realloc, Alloc::free, nullptr, nullptr};
749 vkCreateCommandPool(device(), &cpci, &allocator, &cmdPool);
750 m_errorMonitor->VerifyFound();
751 }
752
753 {
754 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkAllocationCallbacks-pfnReallocation-00633");
755 const VkAllocationCallbacks allocator = {nullptr, Alloc::alloc, nullptr, Alloc::free, nullptr, nullptr};
756 vkCreateCommandPool(device(), &cpci, &allocator, &cmdPool);
757 m_errorMonitor->VerifyFound();
758 }
759
760 {
761 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkAllocationCallbacks-pfnFree-00634");
762 const VkAllocationCallbacks allocator = {nullptr, Alloc::alloc, Alloc::realloc, nullptr, nullptr, nullptr};
763 vkCreateCommandPool(device(), &cpci, &allocator, &cmdPool);
764 m_errorMonitor->VerifyFound();
765 }
766
767 {
768 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
769 "VUID-VkAllocationCallbacks-pfnInternalAllocation-00635");
770 const VkAllocationCallbacks allocator = {nullptr, Alloc::alloc, Alloc::realloc, Alloc::free, nullptr, Alloc::internalFree};
771 vkCreateCommandPool(device(), &cpci, &allocator, &cmdPool);
772 m_errorMonitor->VerifyFound();
773 }
774
775 {
776 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
777 "VUID-VkAllocationCallbacks-pfnInternalAllocation-00635");
778 const VkAllocationCallbacks allocator = {nullptr, Alloc::alloc, Alloc::realloc, Alloc::free, Alloc::internalAlloc, nullptr};
779 vkCreateCommandPool(device(), &cpci, &allocator, &cmdPool);
780 m_errorMonitor->VerifyFound();
781 }
782 }
783
TEST_F(VkLayerTest,MismatchedQueueFamiliesOnSubmit)784 TEST_F(VkLayerTest, MismatchedQueueFamiliesOnSubmit) {
785 TEST_DESCRIPTION(
786 "Submit command buffer created using one queue family and attempt to submit them on a queue created in a different queue "
787 "family.");
788
789 ASSERT_NO_FATAL_FAILURE(Init()); // assumes it initializes all queue families on vkCreateDevice
790
791 // This test is meaningless unless we have multiple queue families
792 auto queue_family_properties = m_device->phy().queue_properties();
793 std::vector<uint32_t> queue_families;
794 for (uint32_t i = 0; i < queue_family_properties.size(); ++i)
795 if (queue_family_properties[i].queueCount > 0) queue_families.push_back(i);
796
797 if (queue_families.size() < 2) {
798 printf("%s Device only has one queue family; skipped.\n", kSkipPrefix);
799 return;
800 }
801
802 const uint32_t queue_family = queue_families[0];
803
804 const uint32_t other_queue_family = queue_families[1];
805 VkQueue other_queue;
806 vkGetDeviceQueue(m_device->device(), other_queue_family, 0, &other_queue);
807
808 VkCommandPoolObj cmd_pool(m_device, queue_family);
809 VkCommandBufferObj cmd_buff(m_device, &cmd_pool);
810
811 cmd_buff.begin();
812 cmd_buff.end();
813
814 // Submit on the wrong queue
815 VkSubmitInfo submit_info = {};
816 submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
817 submit_info.commandBufferCount = 1;
818 submit_info.pCommandBuffers = &cmd_buff.handle();
819
820 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkQueueSubmit-pCommandBuffers-00074");
821 vkQueueSubmit(other_queue, 1, &submit_info, VK_NULL_HANDLE);
822 m_errorMonitor->VerifyFound();
823 }
824
TEST_F(VkLayerTest,TemporaryExternalSemaphore)825 TEST_F(VkLayerTest, TemporaryExternalSemaphore) {
826 #ifdef _WIN32
827 const auto extension_name = VK_KHR_EXTERNAL_SEMAPHORE_WIN32_EXTENSION_NAME;
828 const auto handle_type = VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT_KHR;
829 #else
830 const auto extension_name = VK_KHR_EXTERNAL_SEMAPHORE_FD_EXTENSION_NAME;
831 const auto handle_type = VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_FD_BIT_KHR;
832 #endif
833 // Check for external semaphore instance extensions
834 if (InstanceExtensionSupported(VK_KHR_EXTERNAL_SEMAPHORE_CAPABILITIES_EXTENSION_NAME)) {
835 m_instance_extension_names.push_back(VK_KHR_EXTERNAL_SEMAPHORE_CAPABILITIES_EXTENSION_NAME);
836 m_instance_extension_names.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
837 } else {
838 printf("%s External semaphore extension not supported, skipping test\n", kSkipPrefix);
839 return;
840 }
841 ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor));
842
843 // Check for external semaphore device extensions
844 if (DeviceExtensionSupported(gpu(), nullptr, extension_name)) {
845 m_device_extension_names.push_back(extension_name);
846 m_device_extension_names.push_back(VK_KHR_EXTERNAL_SEMAPHORE_EXTENSION_NAME);
847 } else {
848 printf("%s External semaphore extension not supported, skipping test\n", kSkipPrefix);
849 return;
850 }
851 ASSERT_NO_FATAL_FAILURE(InitState());
852
853 // Check for external semaphore import and export capability
854 VkPhysicalDeviceExternalSemaphoreInfoKHR esi = {VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_SEMAPHORE_INFO_KHR, nullptr,
855 handle_type};
856 VkExternalSemaphorePropertiesKHR esp = {VK_STRUCTURE_TYPE_EXTERNAL_SEMAPHORE_PROPERTIES_KHR, nullptr};
857 auto vkGetPhysicalDeviceExternalSemaphorePropertiesKHR =
858 (PFN_vkGetPhysicalDeviceExternalSemaphorePropertiesKHR)vkGetInstanceProcAddr(
859 instance(), "vkGetPhysicalDeviceExternalSemaphorePropertiesKHR");
860 vkGetPhysicalDeviceExternalSemaphorePropertiesKHR(gpu(), &esi, &esp);
861
862 if (!(esp.externalSemaphoreFeatures & VK_EXTERNAL_SEMAPHORE_FEATURE_EXPORTABLE_BIT_KHR) ||
863 !(esp.externalSemaphoreFeatures & VK_EXTERNAL_SEMAPHORE_FEATURE_IMPORTABLE_BIT_KHR)) {
864 printf("%s External semaphore does not support importing and exporting, skipping test\n", kSkipPrefix);
865 return;
866 }
867
868 VkResult err;
869
870 // Create a semaphore to export payload from
871 VkExportSemaphoreCreateInfoKHR esci = {VK_STRUCTURE_TYPE_EXPORT_SEMAPHORE_CREATE_INFO_KHR, nullptr, handle_type};
872 VkSemaphoreCreateInfo sci = {VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO, &esci, 0};
873
874 VkSemaphore export_semaphore;
875 err = vkCreateSemaphore(m_device->device(), &sci, nullptr, &export_semaphore);
876 ASSERT_VK_SUCCESS(err);
877
878 // Create a semaphore to import payload into
879 sci.pNext = nullptr;
880 VkSemaphore import_semaphore;
881 err = vkCreateSemaphore(m_device->device(), &sci, nullptr, &import_semaphore);
882 ASSERT_VK_SUCCESS(err);
883
884 #ifdef _WIN32
885 // Export semaphore payload to an opaque handle
886 HANDLE handle = nullptr;
887 VkSemaphoreGetWin32HandleInfoKHR ghi = {VK_STRUCTURE_TYPE_SEMAPHORE_GET_WIN32_HANDLE_INFO_KHR, nullptr, export_semaphore,
888 handle_type};
889 auto vkGetSemaphoreWin32HandleKHR =
890 (PFN_vkGetSemaphoreWin32HandleKHR)vkGetDeviceProcAddr(m_device->device(), "vkGetSemaphoreWin32HandleKHR");
891 err = vkGetSemaphoreWin32HandleKHR(m_device->device(), &ghi, &handle);
892 ASSERT_VK_SUCCESS(err);
893
894 // Import opaque handle exported above *temporarily*
895 VkImportSemaphoreWin32HandleInfoKHR ihi = {VK_STRUCTURE_TYPE_IMPORT_SEMAPHORE_WIN32_HANDLE_INFO_KHR,
896 nullptr,
897 import_semaphore,
898 VK_SEMAPHORE_IMPORT_TEMPORARY_BIT_KHR,
899 handle_type,
900 handle,
901 nullptr};
902 auto vkImportSemaphoreWin32HandleKHR =
903 (PFN_vkImportSemaphoreWin32HandleKHR)vkGetDeviceProcAddr(m_device->device(), "vkImportSemaphoreWin32HandleKHR");
904 err = vkImportSemaphoreWin32HandleKHR(m_device->device(), &ihi);
905 ASSERT_VK_SUCCESS(err);
906 #else
907 // Export semaphore payload to an opaque handle
908 int fd = 0;
909 VkSemaphoreGetFdInfoKHR ghi = {VK_STRUCTURE_TYPE_SEMAPHORE_GET_FD_INFO_KHR, nullptr, export_semaphore, handle_type};
910 auto vkGetSemaphoreFdKHR = (PFN_vkGetSemaphoreFdKHR)vkGetDeviceProcAddr(m_device->device(), "vkGetSemaphoreFdKHR");
911 err = vkGetSemaphoreFdKHR(m_device->device(), &ghi, &fd);
912 ASSERT_VK_SUCCESS(err);
913
914 // Import opaque handle exported above *temporarily*
915 VkImportSemaphoreFdInfoKHR ihi = {VK_STRUCTURE_TYPE_IMPORT_SEMAPHORE_FD_INFO_KHR, nullptr, import_semaphore,
916 VK_SEMAPHORE_IMPORT_TEMPORARY_BIT_KHR, handle_type, fd};
917 auto vkImportSemaphoreFdKHR = (PFN_vkImportSemaphoreFdKHR)vkGetDeviceProcAddr(m_device->device(), "vkImportSemaphoreFdKHR");
918 err = vkImportSemaphoreFdKHR(m_device->device(), &ihi);
919 ASSERT_VK_SUCCESS(err);
920 #endif
921
922 // Wait on the imported semaphore twice in vkQueueSubmit, the second wait should be an error
923 VkPipelineStageFlags flags = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT;
924 VkSubmitInfo si[] = {
925 {VK_STRUCTURE_TYPE_SUBMIT_INFO, nullptr, 0, nullptr, &flags, 0, nullptr, 1, &export_semaphore},
926 {VK_STRUCTURE_TYPE_SUBMIT_INFO, nullptr, 1, &import_semaphore, &flags, 0, nullptr, 0, nullptr},
927 {VK_STRUCTURE_TYPE_SUBMIT_INFO, nullptr, 0, nullptr, &flags, 0, nullptr, 1, &export_semaphore},
928 {VK_STRUCTURE_TYPE_SUBMIT_INFO, nullptr, 1, &import_semaphore, &flags, 0, nullptr, 0, nullptr},
929 };
930 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "has no way to be signaled");
931 vkQueueSubmit(m_device->m_queue, 4, si, VK_NULL_HANDLE);
932 m_errorMonitor->VerifyFound();
933
934 auto index = m_device->graphics_queue_node_index_;
935 if (m_device->queue_props[index].queueFlags & VK_QUEUE_SPARSE_BINDING_BIT) {
936 // Wait on the imported semaphore twice in vkQueueBindSparse, the second wait should be an error
937 VkBindSparseInfo bi[] = {
938 {VK_STRUCTURE_TYPE_BIND_SPARSE_INFO, nullptr, 0, nullptr, 0, nullptr, 0, nullptr, 0, nullptr, 1, &export_semaphore},
939 {VK_STRUCTURE_TYPE_BIND_SPARSE_INFO, nullptr, 1, &import_semaphore, 0, nullptr, 0, nullptr, 0, nullptr, 0, nullptr},
940 {VK_STRUCTURE_TYPE_BIND_SPARSE_INFO, nullptr, 0, nullptr, 0, nullptr, 0, nullptr, 0, nullptr, 1, &export_semaphore},
941 {VK_STRUCTURE_TYPE_BIND_SPARSE_INFO, nullptr, 1, &import_semaphore, 0, nullptr, 0, nullptr, 0, nullptr, 0, nullptr},
942 };
943 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "has no way to be signaled");
944 vkQueueBindSparse(m_device->m_queue, 4, bi, VK_NULL_HANDLE);
945 m_errorMonitor->VerifyFound();
946 }
947
948 // Cleanup
949 err = vkQueueWaitIdle(m_device->m_queue);
950 ASSERT_VK_SUCCESS(err);
951 vkDestroySemaphore(m_device->device(), export_semaphore, nullptr);
952 vkDestroySemaphore(m_device->device(), import_semaphore, nullptr);
953 }
954
TEST_F(VkLayerTest,TemporaryExternalFence)955 TEST_F(VkLayerTest, TemporaryExternalFence) {
956 #ifdef _WIN32
957 const auto extension_name = VK_KHR_EXTERNAL_FENCE_WIN32_EXTENSION_NAME;
958 const auto handle_type = VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_WIN32_BIT_KHR;
959 #else
960 const auto extension_name = VK_KHR_EXTERNAL_FENCE_FD_EXTENSION_NAME;
961 const auto handle_type = VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_FD_BIT_KHR;
962 #endif
963 // Check for external fence instance extensions
964 if (InstanceExtensionSupported(VK_KHR_EXTERNAL_FENCE_CAPABILITIES_EXTENSION_NAME)) {
965 m_instance_extension_names.push_back(VK_KHR_EXTERNAL_FENCE_CAPABILITIES_EXTENSION_NAME);
966 m_instance_extension_names.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
967 } else {
968 printf("%s External fence extension not supported, skipping test\n", kSkipPrefix);
969 return;
970 }
971 ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor));
972
973 // Check for external fence device extensions
974 if (DeviceExtensionSupported(gpu(), nullptr, extension_name)) {
975 m_device_extension_names.push_back(extension_name);
976 m_device_extension_names.push_back(VK_KHR_EXTERNAL_FENCE_EXTENSION_NAME);
977 } else {
978 printf("%s External fence extension not supported, skipping test\n", kSkipPrefix);
979 return;
980 }
981 ASSERT_NO_FATAL_FAILURE(InitState());
982
983 // Check for external fence import and export capability
984 VkPhysicalDeviceExternalFenceInfoKHR efi = {VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_FENCE_INFO_KHR, nullptr, handle_type};
985 VkExternalFencePropertiesKHR efp = {VK_STRUCTURE_TYPE_EXTERNAL_FENCE_PROPERTIES_KHR, nullptr};
986 auto vkGetPhysicalDeviceExternalFencePropertiesKHR = (PFN_vkGetPhysicalDeviceExternalFencePropertiesKHR)vkGetInstanceProcAddr(
987 instance(), "vkGetPhysicalDeviceExternalFencePropertiesKHR");
988 vkGetPhysicalDeviceExternalFencePropertiesKHR(gpu(), &efi, &efp);
989
990 if (!(efp.externalFenceFeatures & VK_EXTERNAL_FENCE_FEATURE_EXPORTABLE_BIT_KHR) ||
991 !(efp.externalFenceFeatures & VK_EXTERNAL_FENCE_FEATURE_IMPORTABLE_BIT_KHR)) {
992 printf("%s External fence does not support importing and exporting, skipping test\n", kSkipPrefix);
993 return;
994 }
995
996 VkResult err;
997
998 // Create a fence to export payload from
999 VkFence export_fence;
1000 {
1001 VkExportFenceCreateInfoKHR efci = {VK_STRUCTURE_TYPE_EXPORT_FENCE_CREATE_INFO_KHR, nullptr, handle_type};
1002 VkFenceCreateInfo fci = {VK_STRUCTURE_TYPE_FENCE_CREATE_INFO, &efci, 0};
1003 err = vkCreateFence(m_device->device(), &fci, nullptr, &export_fence);
1004 ASSERT_VK_SUCCESS(err);
1005 }
1006
1007 // Create a fence to import payload into
1008 VkFence import_fence;
1009 {
1010 VkFenceCreateInfo fci = {VK_STRUCTURE_TYPE_FENCE_CREATE_INFO, nullptr, 0};
1011 err = vkCreateFence(m_device->device(), &fci, nullptr, &import_fence);
1012 ASSERT_VK_SUCCESS(err);
1013 }
1014
1015 #ifdef _WIN32
1016 // Export fence payload to an opaque handle
1017 HANDLE handle = nullptr;
1018 {
1019 VkFenceGetWin32HandleInfoKHR ghi = {VK_STRUCTURE_TYPE_FENCE_GET_WIN32_HANDLE_INFO_KHR, nullptr, export_fence, handle_type};
1020 auto vkGetFenceWin32HandleKHR =
1021 (PFN_vkGetFenceWin32HandleKHR)vkGetDeviceProcAddr(m_device->device(), "vkGetFenceWin32HandleKHR");
1022 err = vkGetFenceWin32HandleKHR(m_device->device(), &ghi, &handle);
1023 ASSERT_VK_SUCCESS(err);
1024 }
1025
1026 // Import opaque handle exported above
1027 {
1028 VkImportFenceWin32HandleInfoKHR ifi = {VK_STRUCTURE_TYPE_IMPORT_FENCE_WIN32_HANDLE_INFO_KHR,
1029 nullptr,
1030 import_fence,
1031 VK_FENCE_IMPORT_TEMPORARY_BIT_KHR,
1032 handle_type,
1033 handle,
1034 nullptr};
1035 auto vkImportFenceWin32HandleKHR =
1036 (PFN_vkImportFenceWin32HandleKHR)vkGetDeviceProcAddr(m_device->device(), "vkImportFenceWin32HandleKHR");
1037 err = vkImportFenceWin32HandleKHR(m_device->device(), &ifi);
1038 ASSERT_VK_SUCCESS(err);
1039 }
1040 #else
1041 // Export fence payload to an opaque handle
1042 int fd = 0;
1043 {
1044 VkFenceGetFdInfoKHR gfi = {VK_STRUCTURE_TYPE_FENCE_GET_FD_INFO_KHR, nullptr, export_fence, handle_type};
1045 auto vkGetFenceFdKHR = (PFN_vkGetFenceFdKHR)vkGetDeviceProcAddr(m_device->device(), "vkGetFenceFdKHR");
1046 err = vkGetFenceFdKHR(m_device->device(), &gfi, &fd);
1047 ASSERT_VK_SUCCESS(err);
1048 }
1049
1050 // Import opaque handle exported above
1051 {
1052 VkImportFenceFdInfoKHR ifi = {VK_STRUCTURE_TYPE_IMPORT_FENCE_FD_INFO_KHR, nullptr, import_fence,
1053 VK_FENCE_IMPORT_TEMPORARY_BIT_KHR, handle_type, fd};
1054 auto vkImportFenceFdKHR = (PFN_vkImportFenceFdKHR)vkGetDeviceProcAddr(m_device->device(), "vkImportFenceFdKHR");
1055 err = vkImportFenceFdKHR(m_device->device(), &ifi);
1056 ASSERT_VK_SUCCESS(err);
1057 }
1058 #endif
1059
1060 // Undo the temporary import
1061 vkResetFences(m_device->device(), 1, &import_fence);
1062
1063 // Signal the previously imported fence twice, the second signal should produce a validation error
1064 vkQueueSubmit(m_device->m_queue, 0, nullptr, import_fence);
1065 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "is already in use by another submission.");
1066 vkQueueSubmit(m_device->m_queue, 0, nullptr, import_fence);
1067 m_errorMonitor->VerifyFound();
1068
1069 // Cleanup
1070 err = vkQueueWaitIdle(m_device->m_queue);
1071 ASSERT_VK_SUCCESS(err);
1072 vkDestroyFence(m_device->device(), export_fence, nullptr);
1073 vkDestroyFence(m_device->device(), import_fence, nullptr);
1074 }
1075
TEST_F(VkLayerTest,InvalidCmdBufferEventDestroyed)1076 TEST_F(VkLayerTest, InvalidCmdBufferEventDestroyed) {
1077 TEST_DESCRIPTION("Attempt to draw with a command buffer that is invalid due to an event dependency being destroyed.");
1078 ASSERT_NO_FATAL_FAILURE(Init());
1079
1080 VkEvent event;
1081 VkEventCreateInfo evci = {};
1082 evci.sType = VK_STRUCTURE_TYPE_EVENT_CREATE_INFO;
1083 VkResult result = vkCreateEvent(m_device->device(), &evci, NULL, &event);
1084 ASSERT_VK_SUCCESS(result);
1085
1086 m_commandBuffer->begin();
1087 vkCmdSetEvent(m_commandBuffer->handle(), event, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT);
1088 m_commandBuffer->end();
1089
1090 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
1091 "UNASSIGNED-CoreValidation-DrawState-InvalidCommandBuffer-VkEvent");
1092 // Destroy event dependency prior to submit to cause ERROR
1093 vkDestroyEvent(m_device->device(), event, NULL);
1094
1095 VkSubmitInfo submit_info = {};
1096 submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
1097 submit_info.commandBufferCount = 1;
1098 submit_info.pCommandBuffers = &m_commandBuffer->handle();
1099 vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
1100
1101 m_errorMonitor->VerifyFound();
1102 }
1103
TEST_F(VkLayerTest,InvalidCmdBufferQueryPoolDestroyed)1104 TEST_F(VkLayerTest, InvalidCmdBufferQueryPoolDestroyed) {
1105 TEST_DESCRIPTION("Attempt to draw with a command buffer that is invalid due to a query pool dependency being destroyed.");
1106 ASSERT_NO_FATAL_FAILURE(Init());
1107
1108 VkQueryPool query_pool;
1109 VkQueryPoolCreateInfo qpci{};
1110 qpci.sType = VK_STRUCTURE_TYPE_QUERY_POOL_CREATE_INFO;
1111 qpci.queryType = VK_QUERY_TYPE_TIMESTAMP;
1112 qpci.queryCount = 1;
1113 VkResult result = vkCreateQueryPool(m_device->device(), &qpci, nullptr, &query_pool);
1114 ASSERT_VK_SUCCESS(result);
1115
1116 m_commandBuffer->begin();
1117 vkCmdResetQueryPool(m_commandBuffer->handle(), query_pool, 0, 1);
1118 m_commandBuffer->end();
1119
1120 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
1121 "UNASSIGNED-CoreValidation-DrawState-InvalidCommandBuffer-VkQueryPool");
1122 // Destroy query pool dependency prior to submit to cause ERROR
1123 vkDestroyQueryPool(m_device->device(), query_pool, NULL);
1124
1125 VkSubmitInfo submit_info = {};
1126 submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
1127 submit_info.commandBufferCount = 1;
1128 submit_info.pCommandBuffers = &m_commandBuffer->handle();
1129 vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
1130
1131 m_errorMonitor->VerifyFound();
1132 }
1133
TEST_F(VkLayerTest,DeviceFeature2AndVertexAttributeDivisorExtensionUnenabled)1134 TEST_F(VkLayerTest, DeviceFeature2AndVertexAttributeDivisorExtensionUnenabled) {
1135 TEST_DESCRIPTION(
1136 "Test unenabled VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME & "
1137 "VK_EXT_VERTEX_ATTRIBUTE_DIVISOR_EXTENSION_NAME.");
1138
1139 VkPhysicalDeviceVertexAttributeDivisorFeaturesEXT vadf = {};
1140 vadf.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VERTEX_ATTRIBUTE_DIVISOR_FEATURES_EXT;
1141 VkPhysicalDeviceFeatures2 pd_features2 = {};
1142 pd_features2.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2;
1143 pd_features2.pNext = &vadf;
1144
1145 ASSERT_NO_FATAL_FAILURE(Init());
1146 vk_testing::QueueCreateInfoArray queue_info(m_device->queue_props);
1147 VkDeviceCreateInfo device_create_info = {};
1148 device_create_info.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
1149 device_create_info.pNext = &pd_features2;
1150 device_create_info.queueCreateInfoCount = queue_info.size();
1151 device_create_info.pQueueCreateInfos = queue_info.data();
1152 VkDevice testDevice;
1153
1154 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
1155 "VK_KHR_get_physical_device_properties2 must be enabled when it creates an instance");
1156 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
1157 "VK_EXT_vertex_attribute_divisor must be enabled when it creates a device");
1158 m_errorMonitor->SetUnexpectedError("Failed to create device chain");
1159 vkCreateDevice(gpu(), &device_create_info, NULL, &testDevice);
1160 m_errorMonitor->VerifyFound();
1161 }
1162
TEST_F(VkLayerTest,InvalidDeviceMask)1163 TEST_F(VkLayerTest, InvalidDeviceMask) {
1164 TEST_DESCRIPTION("Invalid deviceMask.");
1165 SetTargetApiVersion(VK_API_VERSION_1_1);
1166
1167 bool support_surface = true;
1168 if (!AddSurfaceInstanceExtension()) {
1169 printf("%s surface extensions not supported, skipping VkAcquireNextImageInfoKHR test\n", kSkipPrefix);
1170 support_surface = false;
1171 }
1172
1173 ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor));
1174
1175 if (support_surface) {
1176 if (!AddSwapchainDeviceExtension()) {
1177 printf("%s swapchain extensions not supported, skipping BindSwapchainImageMemory test\n", kSkipPrefix);
1178 support_surface = false;
1179 }
1180 }
1181
1182 if (DeviceValidationVersion() < VK_API_VERSION_1_1) {
1183 printf("%s Device Groups requires Vulkan 1.1+, skipping test\n", kSkipPrefix);
1184 return;
1185 }
1186 uint32_t physical_device_group_count = 0;
1187 vkEnumeratePhysicalDeviceGroups(instance(), &physical_device_group_count, nullptr);
1188
1189 if (physical_device_group_count == 0) {
1190 printf("%s physical_device_group_count is 0, skipping test\n", kSkipPrefix);
1191 return;
1192 }
1193
1194 std::vector<VkPhysicalDeviceGroupProperties> physical_device_group(physical_device_group_count,
1195 {VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_GROUP_PROPERTIES});
1196 vkEnumeratePhysicalDeviceGroups(instance(), &physical_device_group_count, physical_device_group.data());
1197 VkDeviceGroupDeviceCreateInfo create_device_pnext = {};
1198 create_device_pnext.sType = VK_STRUCTURE_TYPE_DEVICE_GROUP_DEVICE_CREATE_INFO;
1199 create_device_pnext.physicalDeviceCount = physical_device_group[0].physicalDeviceCount;
1200 create_device_pnext.pPhysicalDevices = physical_device_group[0].physicalDevices;
1201 ASSERT_NO_FATAL_FAILURE(InitState(nullptr, &create_device_pnext, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT));
1202 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
1203
1204 if (!InitSwapchain()) {
1205 printf("%s Cannot create surface or swapchain, skipping VkAcquireNextImageInfoKHR test\n", kSkipPrefix);
1206 support_surface = false;
1207 }
1208
1209 // Test VkMemoryAllocateFlagsInfo
1210 VkMemoryAllocateFlagsInfo alloc_flags_info = {};
1211 alloc_flags_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_FLAGS_INFO;
1212 alloc_flags_info.flags = VK_MEMORY_ALLOCATE_DEVICE_MASK_BIT;
1213 alloc_flags_info.deviceMask = 0xFFFFFFFF;
1214 VkMemoryAllocateInfo alloc_info = {};
1215 alloc_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
1216 alloc_info.pNext = &alloc_flags_info;
1217 alloc_info.memoryTypeIndex = 0;
1218 alloc_info.allocationSize = 32;
1219
1220 VkDeviceMemory mem;
1221 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkMemoryAllocateFlagsInfo-deviceMask-00675");
1222 vkAllocateMemory(m_device->device(), &alloc_info, NULL, &mem);
1223 m_errorMonitor->VerifyFound();
1224
1225 alloc_flags_info.deviceMask = 0;
1226 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkMemoryAllocateFlagsInfo-deviceMask-00676");
1227 vkAllocateMemory(m_device->device(), &alloc_info, NULL, &mem);
1228 m_errorMonitor->VerifyFound();
1229
1230 // Test VkDeviceGroupCommandBufferBeginInfo
1231 VkDeviceGroupCommandBufferBeginInfo dev_grp_cmd_buf_info = {};
1232 dev_grp_cmd_buf_info.sType = VK_STRUCTURE_TYPE_DEVICE_GROUP_COMMAND_BUFFER_BEGIN_INFO;
1233 dev_grp_cmd_buf_info.deviceMask = 0xFFFFFFFF;
1234 VkCommandBufferBeginInfo cmd_buf_info = {};
1235 cmd_buf_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
1236 cmd_buf_info.pNext = &dev_grp_cmd_buf_info;
1237
1238 m_commandBuffer->reset();
1239 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
1240 "VUID-VkDeviceGroupCommandBufferBeginInfo-deviceMask-00106");
1241 vkBeginCommandBuffer(m_commandBuffer->handle(), &cmd_buf_info);
1242 m_errorMonitor->VerifyFound();
1243
1244 dev_grp_cmd_buf_info.deviceMask = 0;
1245 m_commandBuffer->reset();
1246 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
1247 "VUID-VkDeviceGroupCommandBufferBeginInfo-deviceMask-00107");
1248 vkBeginCommandBuffer(m_commandBuffer->handle(), &cmd_buf_info);
1249 m_errorMonitor->VerifyFound();
1250
1251 // Test VkDeviceGroupRenderPassBeginInfo
1252 dev_grp_cmd_buf_info.deviceMask = 0x00000001;
1253 m_commandBuffer->reset();
1254 vkBeginCommandBuffer(m_commandBuffer->handle(), &cmd_buf_info);
1255
1256 VkDeviceGroupRenderPassBeginInfo dev_grp_rp_info = {};
1257 dev_grp_rp_info.sType = VK_STRUCTURE_TYPE_DEVICE_GROUP_RENDER_PASS_BEGIN_INFO;
1258 dev_grp_rp_info.deviceMask = 0xFFFFFFFF;
1259 m_renderPassBeginInfo.pNext = &dev_grp_rp_info;
1260
1261 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkDeviceGroupRenderPassBeginInfo-deviceMask-00905");
1262 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkDeviceGroupRenderPassBeginInfo-deviceMask-00907");
1263 vkCmdBeginRenderPass(m_commandBuffer->handle(), &m_renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE);
1264 m_errorMonitor->VerifyFound();
1265
1266 dev_grp_rp_info.deviceMask = 0;
1267 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkDeviceGroupRenderPassBeginInfo-deviceMask-00906");
1268 vkCmdBeginRenderPass(m_commandBuffer->handle(), &m_renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE);
1269 m_errorMonitor->VerifyFound();
1270
1271 dev_grp_rp_info.deviceMask = 0x00000001;
1272 dev_grp_rp_info.deviceRenderAreaCount = physical_device_group[0].physicalDeviceCount + 1;
1273 std::vector<VkRect2D> device_render_areas(dev_grp_rp_info.deviceRenderAreaCount, m_renderPassBeginInfo.renderArea);
1274 dev_grp_rp_info.pDeviceRenderAreas = device_render_areas.data();
1275
1276 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
1277 "VUID-VkDeviceGroupRenderPassBeginInfo-deviceRenderAreaCount-00908");
1278 vkCmdBeginRenderPass(m_commandBuffer->handle(), &m_renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE);
1279 m_errorMonitor->VerifyFound();
1280
1281 // Test vkCmdSetDeviceMask()
1282 vkCmdSetDeviceMask(m_commandBuffer->handle(), 0x00000001);
1283
1284 dev_grp_rp_info.deviceRenderAreaCount = physical_device_group[0].physicalDeviceCount;
1285 vkCmdBeginRenderPass(m_commandBuffer->handle(), &m_renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE);
1286 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdSetDeviceMask-deviceMask-00108");
1287 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdSetDeviceMask-deviceMask-00110");
1288 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdSetDeviceMask-deviceMask-00111");
1289 vkCmdSetDeviceMask(m_commandBuffer->handle(), 0xFFFFFFFF);
1290 m_errorMonitor->VerifyFound();
1291
1292 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdSetDeviceMask-deviceMask-00109");
1293 vkCmdSetDeviceMask(m_commandBuffer->handle(), 0);
1294 m_errorMonitor->VerifyFound();
1295
1296 VkSemaphoreCreateInfo semaphore_create_info = {};
1297 semaphore_create_info.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO;
1298 VkSemaphore semaphore;
1299 ASSERT_VK_SUCCESS(vkCreateSemaphore(m_device->device(), &semaphore_create_info, nullptr, &semaphore));
1300 VkSemaphore semaphore2;
1301 ASSERT_VK_SUCCESS(vkCreateSemaphore(m_device->device(), &semaphore_create_info, nullptr, &semaphore2));
1302 VkFenceCreateInfo fence_create_info = {};
1303 fence_create_info.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
1304 VkFence fence;
1305 ASSERT_VK_SUCCESS(vkCreateFence(m_device->device(), &fence_create_info, nullptr, &fence));
1306
1307 if (support_surface) {
1308 // Test VkAcquireNextImageInfoKHR
1309 uint32_t imageIndex = 0;
1310 VkAcquireNextImageInfoKHR acquire_next_image_info = {};
1311 acquire_next_image_info.sType = VK_STRUCTURE_TYPE_ACQUIRE_NEXT_IMAGE_INFO_KHR;
1312 acquire_next_image_info.semaphore = semaphore;
1313 acquire_next_image_info.swapchain = m_swapchain;
1314 acquire_next_image_info.fence = fence;
1315 acquire_next_image_info.deviceMask = 0xFFFFFFFF;
1316
1317 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkAcquireNextImageInfoKHR-deviceMask-01290");
1318 vkAcquireNextImage2KHR(m_device->device(), &acquire_next_image_info, &imageIndex);
1319 m_errorMonitor->VerifyFound();
1320
1321 vkWaitForFences(m_device->device(), 1, &fence, VK_TRUE, std::numeric_limits<int>::max());
1322 vkResetFences(m_device->device(), 1, &fence);
1323
1324 acquire_next_image_info.semaphore = semaphore2;
1325 acquire_next_image_info.deviceMask = 0;
1326
1327 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkAcquireNextImageInfoKHR-deviceMask-01291");
1328 vkAcquireNextImage2KHR(m_device->device(), &acquire_next_image_info, &imageIndex);
1329 m_errorMonitor->VerifyFound();
1330 DestroySwapchain();
1331 }
1332
1333 // Test VkDeviceGroupSubmitInfo
1334 VkDeviceGroupSubmitInfo device_group_submit_info = {};
1335 device_group_submit_info.sType = VK_STRUCTURE_TYPE_DEVICE_GROUP_SUBMIT_INFO;
1336 device_group_submit_info.commandBufferCount = 1;
1337 std::array<uint32_t, 1> command_buffer_device_masks = {0xFFFFFFFF};
1338 device_group_submit_info.pCommandBufferDeviceMasks = command_buffer_device_masks.data();
1339
1340 VkSubmitInfo submit_info = {};
1341 submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
1342 submit_info.pNext = &device_group_submit_info;
1343 submit_info.commandBufferCount = 1;
1344 submit_info.pCommandBuffers = &m_commandBuffer->handle();
1345
1346 m_commandBuffer->reset();
1347 vkBeginCommandBuffer(m_commandBuffer->handle(), &cmd_buf_info);
1348 vkEndCommandBuffer(m_commandBuffer->handle());
1349 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
1350 "VUID-VkDeviceGroupSubmitInfo-pCommandBufferDeviceMasks-00086");
1351 vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
1352 m_errorMonitor->VerifyFound();
1353 vkQueueWaitIdle(m_device->m_queue);
1354
1355 vkWaitForFences(m_device->device(), 1, &fence, VK_TRUE, std::numeric_limits<int>::max());
1356 vkDestroyFence(m_device->device(), fence, nullptr);
1357 vkDestroySemaphore(m_device->device(), semaphore, nullptr);
1358 vkDestroySemaphore(m_device->device(), semaphore2, nullptr);
1359 }
1360
TEST_F(VkLayerTest,ValidationCacheTestBadMerge)1361 TEST_F(VkLayerTest, ValidationCacheTestBadMerge) {
1362 ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor));
1363 if (DeviceExtensionSupported(gpu(), "VK_LAYER_LUNARG_core_validation", VK_EXT_VALIDATION_CACHE_EXTENSION_NAME)) {
1364 m_device_extension_names.push_back(VK_EXT_VALIDATION_CACHE_EXTENSION_NAME);
1365 } else {
1366 printf("%s %s not supported, skipping test\n", kSkipPrefix, VK_EXT_VALIDATION_CACHE_EXTENSION_NAME);
1367 return;
1368 }
1369 ASSERT_NO_FATAL_FAILURE(InitState());
1370
1371 // Load extension functions
1372 auto fpCreateValidationCache =
1373 (PFN_vkCreateValidationCacheEXT)vkGetDeviceProcAddr(m_device->device(), "vkCreateValidationCacheEXT");
1374 auto fpDestroyValidationCache =
1375 (PFN_vkDestroyValidationCacheEXT)vkGetDeviceProcAddr(m_device->device(), "vkDestroyValidationCacheEXT");
1376 auto fpMergeValidationCaches =
1377 (PFN_vkMergeValidationCachesEXT)vkGetDeviceProcAddr(m_device->device(), "vkMergeValidationCachesEXT");
1378 if (!fpCreateValidationCache || !fpDestroyValidationCache || !fpMergeValidationCaches) {
1379 printf("%s Failed to load function pointers for %s\n", kSkipPrefix, VK_EXT_VALIDATION_CACHE_EXTENSION_NAME);
1380 return;
1381 }
1382
1383 VkValidationCacheCreateInfoEXT validationCacheCreateInfo;
1384 validationCacheCreateInfo.sType = VK_STRUCTURE_TYPE_VALIDATION_CACHE_CREATE_INFO_EXT;
1385 validationCacheCreateInfo.pNext = NULL;
1386 validationCacheCreateInfo.initialDataSize = 0;
1387 validationCacheCreateInfo.pInitialData = NULL;
1388 validationCacheCreateInfo.flags = 0;
1389 VkValidationCacheEXT validationCache = VK_NULL_HANDLE;
1390 VkResult res = fpCreateValidationCache(m_device->device(), &validationCacheCreateInfo, nullptr, &validationCache);
1391 ASSERT_VK_SUCCESS(res);
1392
1393 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkMergeValidationCachesEXT-dstCache-01536");
1394 res = fpMergeValidationCaches(m_device->device(), validationCache, 1, &validationCache);
1395 m_errorMonitor->VerifyFound();
1396
1397 fpDestroyValidationCache(m_device->device(), validationCache, nullptr);
1398 }
1399
TEST_F(VkLayerTest,InvalidQueueFamilyIndex)1400 TEST_F(VkLayerTest, InvalidQueueFamilyIndex) {
1401 // Miscellaneous queueFamilyIndex validation tests
1402 ASSERT_NO_FATAL_FAILURE(Init());
1403 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
1404 VkBufferCreateInfo buffCI = {};
1405 buffCI.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
1406 buffCI.size = 1024;
1407 buffCI.usage = VK_BUFFER_USAGE_TRANSFER_DST_BIT;
1408 buffCI.queueFamilyIndexCount = 2;
1409 // Introduce failure by specifying invalid queue_family_index
1410 uint32_t qfi[2];
1411 qfi[0] = 777;
1412 qfi[1] = 0;
1413
1414 buffCI.pQueueFamilyIndices = qfi;
1415 buffCI.sharingMode = VK_SHARING_MODE_CONCURRENT; // qfi only matters in CONCURRENT mode
1416
1417 // Test for queue family index out of range
1418 CreateBufferTest(*this, &buffCI, "VUID-VkBufferCreateInfo-sharingMode-01419");
1419
1420 // Test for non-unique QFI in array
1421 qfi[0] = 0;
1422 CreateBufferTest(*this, &buffCI, "VUID-VkBufferCreateInfo-sharingMode-01419");
1423
1424 if (m_device->queue_props.size() > 2) {
1425 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "which was not created allowing concurrent");
1426
1427 // Create buffer shared to queue families 1 and 2, but submitted on queue family 0
1428 buffCI.queueFamilyIndexCount = 2;
1429 qfi[0] = 1;
1430 qfi[1] = 2;
1431 VkBufferObj ib;
1432 ib.init(*m_device, buffCI);
1433
1434 m_commandBuffer->begin();
1435 vkCmdFillBuffer(m_commandBuffer->handle(), ib.handle(), 0, 16, 5);
1436 m_commandBuffer->end();
1437 m_commandBuffer->QueueCommandBuffer(false);
1438 m_errorMonitor->VerifyFound();
1439 }
1440 }
1441
TEST_F(VkLayerTest,InvalidQueryPoolCreate)1442 TEST_F(VkLayerTest, InvalidQueryPoolCreate) {
1443 TEST_DESCRIPTION("Attempt to create a query pool for PIPELINE_STATISTICS without enabling pipeline stats for the device.");
1444
1445 ASSERT_NO_FATAL_FAILURE(Init());
1446
1447 vk_testing::QueueCreateInfoArray queue_info(m_device->queue_props);
1448
1449 VkDevice local_device;
1450 VkDeviceCreateInfo device_create_info = {};
1451 auto features = m_device->phy().features();
1452 // Intentionally disable pipeline stats
1453 features.pipelineStatisticsQuery = VK_FALSE;
1454 device_create_info.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
1455 device_create_info.pNext = NULL;
1456 device_create_info.queueCreateInfoCount = queue_info.size();
1457 device_create_info.pQueueCreateInfos = queue_info.data();
1458 device_create_info.enabledLayerCount = 0;
1459 device_create_info.ppEnabledLayerNames = NULL;
1460 device_create_info.pEnabledFeatures = &features;
1461 VkResult err = vkCreateDevice(gpu(), &device_create_info, nullptr, &local_device);
1462 ASSERT_VK_SUCCESS(err);
1463
1464 VkQueryPoolCreateInfo qpci{};
1465 qpci.sType = VK_STRUCTURE_TYPE_QUERY_POOL_CREATE_INFO;
1466 qpci.queryType = VK_QUERY_TYPE_PIPELINE_STATISTICS;
1467 qpci.queryCount = 1;
1468 VkQueryPool query_pool;
1469
1470 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkQueryPoolCreateInfo-queryType-00791");
1471 vkCreateQueryPool(local_device, &qpci, nullptr, &query_pool);
1472 m_errorMonitor->VerifyFound();
1473
1474 vkDestroyDevice(local_device, nullptr);
1475 }
1476
TEST_F(VkLayerTest,UnclosedQuery)1477 TEST_F(VkLayerTest, UnclosedQuery) {
1478 TEST_DESCRIPTION("End a command buffer with a query still in progress.");
1479
1480 const char *invalid_query = "VUID-vkEndCommandBuffer-commandBuffer-00061";
1481
1482 ASSERT_NO_FATAL_FAILURE(Init());
1483
1484 VkEvent event;
1485 VkEventCreateInfo event_create_info{};
1486 event_create_info.sType = VK_STRUCTURE_TYPE_EVENT_CREATE_INFO;
1487 vkCreateEvent(m_device->device(), &event_create_info, nullptr, &event);
1488
1489 VkQueue queue = VK_NULL_HANDLE;
1490 vkGetDeviceQueue(m_device->device(), m_device->graphics_queue_node_index_, 0, &queue);
1491
1492 m_commandBuffer->begin();
1493 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, invalid_query);
1494
1495 VkQueryPool query_pool;
1496 VkQueryPoolCreateInfo query_pool_create_info = {};
1497 query_pool_create_info.sType = VK_STRUCTURE_TYPE_QUERY_POOL_CREATE_INFO;
1498 query_pool_create_info.queryType = VK_QUERY_TYPE_OCCLUSION;
1499 query_pool_create_info.queryCount = 1;
1500 vkCreateQueryPool(m_device->device(), &query_pool_create_info, nullptr, &query_pool);
1501
1502 vkCmdResetQueryPool(m_commandBuffer->handle(), query_pool, 0 /*startQuery*/, 1 /*queryCount*/);
1503 vkCmdBeginQuery(m_commandBuffer->handle(), query_pool, 0, 0);
1504
1505 vkEndCommandBuffer(m_commandBuffer->handle());
1506 m_errorMonitor->VerifyFound();
1507
1508 vkDestroyQueryPool(m_device->device(), query_pool, nullptr);
1509 vkDestroyEvent(m_device->device(), event, nullptr);
1510 }
1511
TEST_F(VkLayerTest,QueryPreciseBit)1512 TEST_F(VkLayerTest, QueryPreciseBit) {
1513 TEST_DESCRIPTION("Check for correct Query Precise Bit circumstances.");
1514 ASSERT_NO_FATAL_FAILURE(Init());
1515
1516 // These tests require that the device support pipeline statistics query
1517 VkPhysicalDeviceFeatures device_features = {};
1518 ASSERT_NO_FATAL_FAILURE(GetPhysicalDeviceFeatures(&device_features));
1519 if (VK_TRUE != device_features.pipelineStatisticsQuery) {
1520 printf("%s Test requires unsupported pipelineStatisticsQuery feature. Skipped.\n", kSkipPrefix);
1521 return;
1522 }
1523
1524 std::vector<const char *> device_extension_names;
1525 auto features = m_device->phy().features();
1526
1527 // Test for precise bit when query type is not OCCLUSION
1528 if (features.occlusionQueryPrecise) {
1529 VkEvent event;
1530 VkEventCreateInfo event_create_info{};
1531 event_create_info.sType = VK_STRUCTURE_TYPE_EVENT_CREATE_INFO;
1532 vkCreateEvent(m_device->handle(), &event_create_info, nullptr, &event);
1533
1534 m_commandBuffer->begin();
1535 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdBeginQuery-queryType-00800");
1536
1537 VkQueryPool query_pool;
1538 VkQueryPoolCreateInfo query_pool_create_info = {};
1539 query_pool_create_info.sType = VK_STRUCTURE_TYPE_QUERY_POOL_CREATE_INFO;
1540 query_pool_create_info.queryType = VK_QUERY_TYPE_PIPELINE_STATISTICS;
1541 query_pool_create_info.queryCount = 1;
1542 vkCreateQueryPool(m_device->handle(), &query_pool_create_info, nullptr, &query_pool);
1543
1544 vkCmdResetQueryPool(m_commandBuffer->handle(), query_pool, 0, 1);
1545 vkCmdBeginQuery(m_commandBuffer->handle(), query_pool, 0, VK_QUERY_CONTROL_PRECISE_BIT);
1546 m_errorMonitor->VerifyFound();
1547
1548 m_commandBuffer->end();
1549 vkDestroyQueryPool(m_device->handle(), query_pool, nullptr);
1550 vkDestroyEvent(m_device->handle(), event, nullptr);
1551 }
1552
1553 // Test for precise bit when precise feature is not available
1554 features.occlusionQueryPrecise = false;
1555 VkDeviceObj test_device(0, gpu(), device_extension_names, &features);
1556
1557 VkCommandPoolCreateInfo pool_create_info{};
1558 pool_create_info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
1559 pool_create_info.queueFamilyIndex = test_device.graphics_queue_node_index_;
1560
1561 VkCommandPool command_pool;
1562 vkCreateCommandPool(test_device.handle(), &pool_create_info, nullptr, &command_pool);
1563
1564 VkCommandBufferAllocateInfo cmd = {};
1565 cmd.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
1566 cmd.pNext = NULL;
1567 cmd.commandPool = command_pool;
1568 cmd.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
1569 cmd.commandBufferCount = 1;
1570
1571 VkCommandBuffer cmd_buffer;
1572 VkResult err = vkAllocateCommandBuffers(test_device.handle(), &cmd, &cmd_buffer);
1573 ASSERT_VK_SUCCESS(err);
1574
1575 VkEvent event;
1576 VkEventCreateInfo event_create_info{};
1577 event_create_info.sType = VK_STRUCTURE_TYPE_EVENT_CREATE_INFO;
1578 vkCreateEvent(test_device.handle(), &event_create_info, nullptr, &event);
1579
1580 VkCommandBufferBeginInfo begin_info = {VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, nullptr,
1581 VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT, nullptr};
1582
1583 vkBeginCommandBuffer(cmd_buffer, &begin_info);
1584 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdBeginQuery-queryType-00800");
1585
1586 VkQueryPool query_pool;
1587 VkQueryPoolCreateInfo query_pool_create_info = {};
1588 query_pool_create_info.sType = VK_STRUCTURE_TYPE_QUERY_POOL_CREATE_INFO;
1589 query_pool_create_info.queryType = VK_QUERY_TYPE_OCCLUSION;
1590 query_pool_create_info.queryCount = 1;
1591 vkCreateQueryPool(test_device.handle(), &query_pool_create_info, nullptr, &query_pool);
1592
1593 vkCmdResetQueryPool(cmd_buffer, query_pool, 0, 1);
1594 vkCmdBeginQuery(cmd_buffer, query_pool, 0, VK_QUERY_CONTROL_PRECISE_BIT);
1595 m_errorMonitor->VerifyFound();
1596
1597 vkEndCommandBuffer(cmd_buffer);
1598 vkDestroyQueryPool(test_device.handle(), query_pool, nullptr);
1599 vkDestroyEvent(test_device.handle(), event, nullptr);
1600 vkDestroyCommandPool(test_device.handle(), command_pool, nullptr);
1601 }
1602
TEST_F(VkLayerTest,StageMaskGsTsEnabled)1603 TEST_F(VkLayerTest, StageMaskGsTsEnabled) {
1604 TEST_DESCRIPTION(
1605 "Attempt to use a stageMask w/ geometry shader and tesselation shader bits enabled when those features are disabled on the "
1606 "device.");
1607
1608 ASSERT_NO_FATAL_FAILURE(Init());
1609 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
1610
1611 std::vector<const char *> device_extension_names;
1612 auto features = m_device->phy().features();
1613 // Make sure gs & ts are disabled
1614 features.geometryShader = false;
1615 features.tessellationShader = false;
1616 // The sacrificial device object
1617 VkDeviceObj test_device(0, gpu(), device_extension_names, &features);
1618
1619 VkCommandPoolCreateInfo pool_create_info{};
1620 pool_create_info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
1621 pool_create_info.queueFamilyIndex = test_device.graphics_queue_node_index_;
1622
1623 VkCommandPool command_pool;
1624 vkCreateCommandPool(test_device.handle(), &pool_create_info, nullptr, &command_pool);
1625
1626 VkCommandBufferAllocateInfo cmd = {};
1627 cmd.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
1628 cmd.pNext = NULL;
1629 cmd.commandPool = command_pool;
1630 cmd.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
1631 cmd.commandBufferCount = 1;
1632
1633 VkCommandBuffer cmd_buffer;
1634 VkResult err = vkAllocateCommandBuffers(test_device.handle(), &cmd, &cmd_buffer);
1635 ASSERT_VK_SUCCESS(err);
1636
1637 VkEvent event;
1638 VkEventCreateInfo evci = {};
1639 evci.sType = VK_STRUCTURE_TYPE_EVENT_CREATE_INFO;
1640 VkResult result = vkCreateEvent(test_device.handle(), &evci, NULL, &event);
1641 ASSERT_VK_SUCCESS(result);
1642
1643 VkCommandBufferBeginInfo cbbi = {};
1644 cbbi.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
1645 vkBeginCommandBuffer(cmd_buffer, &cbbi);
1646 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdSetEvent-stageMask-01150");
1647 vkCmdSetEvent(cmd_buffer, event, VK_PIPELINE_STAGE_GEOMETRY_SHADER_BIT);
1648 m_errorMonitor->VerifyFound();
1649
1650 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdSetEvent-stageMask-01151");
1651 vkCmdSetEvent(cmd_buffer, event, VK_PIPELINE_STAGE_TESSELLATION_CONTROL_SHADER_BIT);
1652 m_errorMonitor->VerifyFound();
1653
1654 vkDestroyEvent(test_device.handle(), event, NULL);
1655 vkDestroyCommandPool(test_device.handle(), command_pool, NULL);
1656 }
1657
TEST_F(VkLayerTest,DescriptorPoolInUseDestroyedSignaled)1658 TEST_F(VkLayerTest, DescriptorPoolInUseDestroyedSignaled) {
1659 TEST_DESCRIPTION("Delete a DescriptorPool with a DescriptorSet that is in use.");
1660 ASSERT_NO_FATAL_FAILURE(Init());
1661 ASSERT_NO_FATAL_FAILURE(InitViewport());
1662 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
1663
1664 // Create image to update the descriptor with
1665 VkImageObj image(m_device);
1666 image.Init(32, 32, 1, VK_FORMAT_B8G8R8A8_UNORM, VK_IMAGE_USAGE_SAMPLED_BIT, VK_IMAGE_TILING_OPTIMAL, 0);
1667 ASSERT_TRUE(image.initialized());
1668
1669 VkImageView view = image.targetView(VK_FORMAT_B8G8R8A8_UNORM);
1670 // Create Sampler
1671 VkSamplerCreateInfo sampler_ci = SafeSaneSamplerCreateInfo();
1672 VkSampler sampler;
1673 VkResult err = vkCreateSampler(m_device->device(), &sampler_ci, NULL, &sampler);
1674 ASSERT_VK_SUCCESS(err);
1675
1676 // Create PSO to be used for draw-time errors below
1677 VkShaderObj fs(m_device, bindStateFragSamplerShaderText, VK_SHADER_STAGE_FRAGMENT_BIT, this);
1678
1679 CreatePipelineHelper pipe(*this);
1680 pipe.InitInfo();
1681 pipe.shader_stages_ = {pipe.vs_->GetStageCreateInfo(), fs.GetStageCreateInfo()};
1682 pipe.dsl_bindings_ = {
1683 {0, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_ALL, nullptr},
1684 };
1685 const VkDynamicState dyn_states[] = {VK_DYNAMIC_STATE_VIEWPORT, VK_DYNAMIC_STATE_SCISSOR};
1686 VkPipelineDynamicStateCreateInfo dyn_state_ci = {};
1687 dyn_state_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO;
1688 dyn_state_ci.dynamicStateCount = size(dyn_states);
1689 dyn_state_ci.pDynamicStates = dyn_states;
1690 pipe.dyn_state_ci_ = dyn_state_ci;
1691 pipe.InitState();
1692 pipe.CreateGraphicsPipeline();
1693
1694 // Update descriptor with image and sampler
1695 pipe.descriptor_set_->WriteDescriptorImageInfo(0, view, sampler, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER);
1696 pipe.descriptor_set_->UpdateDescriptorSets();
1697
1698 m_commandBuffer->begin();
1699 m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
1700 vkCmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.pipeline_);
1701 vkCmdBindDescriptorSets(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.pipeline_layout_.handle(), 0, 1,
1702 &pipe.descriptor_set_->set_, 0, NULL);
1703
1704 VkViewport viewport = {0, 0, 16, 16, 0, 1};
1705 VkRect2D scissor = {{0, 0}, {16, 16}};
1706 vkCmdSetViewport(m_commandBuffer->handle(), 0, 1, &viewport);
1707 vkCmdSetScissor(m_commandBuffer->handle(), 0, 1, &scissor);
1708
1709 m_commandBuffer->Draw(1, 0, 0, 0);
1710 m_commandBuffer->EndRenderPass();
1711 m_commandBuffer->end();
1712 // Submit cmd buffer to put pool in-flight
1713 VkSubmitInfo submit_info = {};
1714 submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
1715 submit_info.commandBufferCount = 1;
1716 submit_info.pCommandBuffers = &m_commandBuffer->handle();
1717 vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
1718 // Destroy pool while in-flight, causing error
1719 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkDestroyDescriptorPool-descriptorPool-00303");
1720 vkDestroyDescriptorPool(m_device->device(), pipe.descriptor_set_->pool_, NULL);
1721 m_errorMonitor->VerifyFound();
1722 vkQueueWaitIdle(m_device->m_queue);
1723 // Cleanup
1724 vkDestroySampler(m_device->device(), sampler, NULL);
1725 m_errorMonitor->SetUnexpectedError(
1726 "If descriptorPool is not VK_NULL_HANDLE, descriptorPool must be a valid VkDescriptorPool handle");
1727 m_errorMonitor->SetUnexpectedError("Unable to remove DescriptorPool obj");
1728 // TODO : It seems Validation layers think ds_pool was already destroyed, even though it wasn't?
1729 }
1730
TEST_F(VkLayerTest,FramebufferInUseDestroyedSignaled)1731 TEST_F(VkLayerTest, FramebufferInUseDestroyedSignaled) {
1732 TEST_DESCRIPTION("Delete in-use framebuffer.");
1733 ASSERT_NO_FATAL_FAILURE(Init());
1734 VkFormatProperties format_properties;
1735 VkResult err = VK_SUCCESS;
1736 vkGetPhysicalDeviceFormatProperties(gpu(), VK_FORMAT_B8G8R8A8_UNORM, &format_properties);
1737
1738 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
1739
1740 VkImageObj image(m_device);
1741 image.Init(256, 256, 1, VK_FORMAT_B8G8R8A8_UNORM, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, VK_IMAGE_TILING_OPTIMAL, 0);
1742 ASSERT_TRUE(image.initialized());
1743 VkImageView view = image.targetView(VK_FORMAT_B8G8R8A8_UNORM);
1744
1745 VkFramebufferCreateInfo fci = {VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, nullptr, 0, m_renderPass, 1, &view, 256, 256, 1};
1746 VkFramebuffer fb;
1747 err = vkCreateFramebuffer(m_device->device(), &fci, nullptr, &fb);
1748 ASSERT_VK_SUCCESS(err);
1749
1750 // Just use default renderpass with our framebuffer
1751 m_renderPassBeginInfo.framebuffer = fb;
1752 // Create Null cmd buffer for submit
1753 m_commandBuffer->begin();
1754 m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
1755 m_commandBuffer->EndRenderPass();
1756 m_commandBuffer->end();
1757 // Submit cmd buffer to put it in-flight
1758 VkSubmitInfo submit_info = {};
1759 submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
1760 submit_info.commandBufferCount = 1;
1761 submit_info.pCommandBuffers = &m_commandBuffer->handle();
1762 vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
1763 // Destroy framebuffer while in-flight
1764 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkDestroyFramebuffer-framebuffer-00892");
1765 vkDestroyFramebuffer(m_device->device(), fb, NULL);
1766 m_errorMonitor->VerifyFound();
1767 // Wait for queue to complete so we can safely destroy everything
1768 vkQueueWaitIdle(m_device->m_queue);
1769 m_errorMonitor->SetUnexpectedError("If framebuffer is not VK_NULL_HANDLE, framebuffer must be a valid VkFramebuffer handle");
1770 m_errorMonitor->SetUnexpectedError("Unable to remove Framebuffer obj");
1771 vkDestroyFramebuffer(m_device->device(), fb, nullptr);
1772 }
1773
TEST_F(VkLayerTest,FramebufferImageInUseDestroyedSignaled)1774 TEST_F(VkLayerTest, FramebufferImageInUseDestroyedSignaled) {
1775 TEST_DESCRIPTION("Delete in-use image that's child of framebuffer.");
1776 ASSERT_NO_FATAL_FAILURE(Init());
1777 VkFormatProperties format_properties;
1778 VkResult err = VK_SUCCESS;
1779 vkGetPhysicalDeviceFormatProperties(gpu(), VK_FORMAT_B8G8R8A8_UNORM, &format_properties);
1780
1781 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
1782
1783 VkImageCreateInfo image_ci = {};
1784 image_ci.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
1785 image_ci.pNext = NULL;
1786 image_ci.imageType = VK_IMAGE_TYPE_2D;
1787 image_ci.format = VK_FORMAT_B8G8R8A8_UNORM;
1788 image_ci.extent.width = 256;
1789 image_ci.extent.height = 256;
1790 image_ci.extent.depth = 1;
1791 image_ci.mipLevels = 1;
1792 image_ci.arrayLayers = 1;
1793 image_ci.samples = VK_SAMPLE_COUNT_1_BIT;
1794 image_ci.tiling = VK_IMAGE_TILING_OPTIMAL;
1795 image_ci.usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
1796 image_ci.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
1797 image_ci.flags = 0;
1798 VkImageObj image(m_device);
1799 image.init(&image_ci);
1800
1801 VkImageView view = image.targetView(VK_FORMAT_B8G8R8A8_UNORM);
1802
1803 VkFramebufferCreateInfo fci = {VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, nullptr, 0, m_renderPass, 1, &view, 256, 256, 1};
1804 VkFramebuffer fb;
1805 err = vkCreateFramebuffer(m_device->device(), &fci, nullptr, &fb);
1806 ASSERT_VK_SUCCESS(err);
1807
1808 // Just use default renderpass with our framebuffer
1809 m_renderPassBeginInfo.framebuffer = fb;
1810 // Create Null cmd buffer for submit
1811 m_commandBuffer->begin();
1812 m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
1813 m_commandBuffer->EndRenderPass();
1814 m_commandBuffer->end();
1815 // Submit cmd buffer to put it (and attached imageView) in-flight
1816 VkSubmitInfo submit_info = {};
1817 submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
1818 submit_info.commandBufferCount = 1;
1819 submit_info.pCommandBuffers = &m_commandBuffer->handle();
1820 // Submit cmd buffer to put framebuffer and children in-flight
1821 vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
1822 // Destroy image attached to framebuffer while in-flight
1823 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkDestroyImage-image-01000");
1824 vkDestroyImage(m_device->device(), image.handle(), NULL);
1825 m_errorMonitor->VerifyFound();
1826 // Wait for queue to complete so we can safely destroy image and other objects
1827 vkQueueWaitIdle(m_device->m_queue);
1828 m_errorMonitor->SetUnexpectedError("If image is not VK_NULL_HANDLE, image must be a valid VkImage handle");
1829 m_errorMonitor->SetUnexpectedError("Unable to remove Image obj");
1830 vkDestroyFramebuffer(m_device->device(), fb, nullptr);
1831 }
1832
TEST_F(VkLayerTest,EventInUseDestroyedSignaled)1833 TEST_F(VkLayerTest, EventInUseDestroyedSignaled) {
1834 ASSERT_NO_FATAL_FAILURE(Init());
1835 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
1836
1837 m_commandBuffer->begin();
1838
1839 VkEvent event;
1840 VkEventCreateInfo event_create_info = {};
1841 event_create_info.sType = VK_STRUCTURE_TYPE_EVENT_CREATE_INFO;
1842 vkCreateEvent(m_device->device(), &event_create_info, nullptr, &event);
1843 vkCmdSetEvent(m_commandBuffer->handle(), event, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT);
1844
1845 m_commandBuffer->end();
1846 vkDestroyEvent(m_device->device(), event, nullptr);
1847
1848 VkSubmitInfo submit_info = {};
1849 submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
1850 submit_info.commandBufferCount = 1;
1851 submit_info.pCommandBuffers = &m_commandBuffer->handle();
1852 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "that is invalid because bound");
1853 vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
1854 m_errorMonitor->VerifyFound();
1855 }
1856
TEST_F(VkLayerTest,InUseDestroyedSignaled)1857 TEST_F(VkLayerTest, InUseDestroyedSignaled) {
1858 TEST_DESCRIPTION(
1859 "Use vkCmdExecuteCommands with invalid state in primary and secondary command buffers. Delete objects that are in use. "
1860 "Call VkQueueSubmit with an event that has been deleted.");
1861
1862 ASSERT_NO_FATAL_FAILURE(Init());
1863 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
1864
1865 m_errorMonitor->ExpectSuccess();
1866
1867 VkSemaphoreCreateInfo semaphore_create_info = {};
1868 semaphore_create_info.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO;
1869 VkSemaphore semaphore;
1870 ASSERT_VK_SUCCESS(vkCreateSemaphore(m_device->device(), &semaphore_create_info, nullptr, &semaphore));
1871 VkFenceCreateInfo fence_create_info = {};
1872 fence_create_info.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
1873 VkFence fence;
1874 ASSERT_VK_SUCCESS(vkCreateFence(m_device->device(), &fence_create_info, nullptr, &fence));
1875
1876 VkBufferTest buffer_test(m_device, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT);
1877
1878 CreatePipelineHelper pipe(*this);
1879 pipe.InitInfo();
1880 pipe.InitState();
1881 pipe.CreateGraphicsPipeline();
1882
1883 pipe.descriptor_set_->WriteDescriptorBufferInfo(0, buffer_test.GetBuffer(), 1024, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER);
1884 pipe.descriptor_set_->UpdateDescriptorSets();
1885
1886 VkEvent event;
1887 VkEventCreateInfo event_create_info = {};
1888 event_create_info.sType = VK_STRUCTURE_TYPE_EVENT_CREATE_INFO;
1889 vkCreateEvent(m_device->device(), &event_create_info, nullptr, &event);
1890
1891 m_commandBuffer->begin();
1892
1893 vkCmdSetEvent(m_commandBuffer->handle(), event, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT);
1894
1895 vkCmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.pipeline_);
1896 vkCmdBindDescriptorSets(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.pipeline_layout_.handle(), 0, 1,
1897 &pipe.descriptor_set_->set_, 0, NULL);
1898
1899 m_commandBuffer->end();
1900
1901 VkSubmitInfo submit_info = {};
1902 submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
1903 submit_info.commandBufferCount = 1;
1904 submit_info.pCommandBuffers = &m_commandBuffer->handle();
1905 submit_info.signalSemaphoreCount = 1;
1906 submit_info.pSignalSemaphores = &semaphore;
1907 vkQueueSubmit(m_device->m_queue, 1, &submit_info, fence);
1908 m_errorMonitor->Reset(); // resume logmsg processing
1909
1910 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkDestroyEvent-event-01145");
1911 vkDestroyEvent(m_device->device(), event, nullptr);
1912 m_errorMonitor->VerifyFound();
1913
1914 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkDestroySemaphore-semaphore-01137");
1915 vkDestroySemaphore(m_device->device(), semaphore, nullptr);
1916 m_errorMonitor->VerifyFound();
1917
1918 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkDestroyFence-fence-01120");
1919 vkDestroyFence(m_device->device(), fence, nullptr);
1920 m_errorMonitor->VerifyFound();
1921
1922 vkQueueWaitIdle(m_device->m_queue);
1923 m_errorMonitor->SetUnexpectedError("If semaphore is not VK_NULL_HANDLE, semaphore must be a valid VkSemaphore handle");
1924 m_errorMonitor->SetUnexpectedError("Unable to remove Semaphore obj");
1925 vkDestroySemaphore(m_device->device(), semaphore, nullptr);
1926 m_errorMonitor->SetUnexpectedError("If fence is not VK_NULL_HANDLE, fence must be a valid VkFence handle");
1927 m_errorMonitor->SetUnexpectedError("Unable to remove Fence obj");
1928 vkDestroyFence(m_device->device(), fence, nullptr);
1929 m_errorMonitor->SetUnexpectedError("If event is not VK_NULL_HANDLE, event must be a valid VkEvent handle");
1930 m_errorMonitor->SetUnexpectedError("Unable to remove Event obj");
1931 vkDestroyEvent(m_device->device(), event, nullptr);
1932 }
1933
TEST_F(VkLayerTest,QueryPoolPartialTimestamp)1934 TEST_F(VkLayerTest, QueryPoolPartialTimestamp) {
1935 TEST_DESCRIPTION("Request partial result on timestamp query.");
1936
1937 ASSERT_NO_FATAL_FAILURE(Init());
1938 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
1939
1940 VkQueryPool query_pool;
1941 VkQueryPoolCreateInfo query_pool_ci{};
1942 query_pool_ci.sType = VK_STRUCTURE_TYPE_QUERY_POOL_CREATE_INFO;
1943 query_pool_ci.queryType = VK_QUERY_TYPE_TIMESTAMP;
1944 query_pool_ci.queryCount = 1;
1945 vkCreateQueryPool(m_device->device(), &query_pool_ci, nullptr, &query_pool);
1946
1947 m_commandBuffer->begin();
1948 vkCmdResetQueryPool(m_commandBuffer->handle(), query_pool, 0, 1);
1949 vkCmdWriteTimestamp(m_commandBuffer->handle(), VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, query_pool, 0);
1950 m_commandBuffer->end();
1951
1952 // Submit cmd buffer and wait for it.
1953 VkSubmitInfo submit_info = {};
1954 submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
1955 submit_info.commandBufferCount = 1;
1956 submit_info.pCommandBuffers = &m_commandBuffer->handle();
1957 vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
1958 vkQueueWaitIdle(m_device->m_queue);
1959
1960 // Attempt to obtain partial results.
1961 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkGetQueryPoolResults-queryType-00818");
1962 uint32_t data_space[16];
1963 m_errorMonitor->SetUnexpectedError("Cannot get query results on queryPool");
1964 vkGetQueryPoolResults(m_device->handle(), query_pool, 0, 1, sizeof(data_space), &data_space, sizeof(uint32_t),
1965 VK_QUERY_RESULT_PARTIAL_BIT);
1966 m_errorMonitor->VerifyFound();
1967
1968 // Destroy query pool.
1969 vkDestroyQueryPool(m_device->handle(), query_pool, NULL);
1970 }
1971
TEST_F(VkLayerTest,QueryPoolInUseDestroyedSignaled)1972 TEST_F(VkLayerTest, QueryPoolInUseDestroyedSignaled) {
1973 TEST_DESCRIPTION("Delete in-use query pool.");
1974
1975 ASSERT_NO_FATAL_FAILURE(Init());
1976 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
1977
1978 VkQueryPool query_pool;
1979 VkQueryPoolCreateInfo query_pool_ci{};
1980 query_pool_ci.sType = VK_STRUCTURE_TYPE_QUERY_POOL_CREATE_INFO;
1981 query_pool_ci.queryType = VK_QUERY_TYPE_TIMESTAMP;
1982 query_pool_ci.queryCount = 1;
1983 vkCreateQueryPool(m_device->device(), &query_pool_ci, nullptr, &query_pool);
1984
1985 m_commandBuffer->begin();
1986 // Use query pool to create binding with cmd buffer
1987 vkCmdResetQueryPool(m_commandBuffer->handle(), query_pool, 0, 1);
1988 vkCmdWriteTimestamp(m_commandBuffer->handle(), VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, query_pool, 0);
1989 m_commandBuffer->end();
1990
1991 // Submit cmd buffer and then destroy query pool while in-flight
1992 VkSubmitInfo submit_info = {};
1993 submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
1994 submit_info.commandBufferCount = 1;
1995 submit_info.pCommandBuffers = &m_commandBuffer->handle();
1996 vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
1997
1998 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkDestroyQueryPool-queryPool-00793");
1999 vkDestroyQueryPool(m_device->handle(), query_pool, NULL);
2000 m_errorMonitor->VerifyFound();
2001
2002 vkQueueWaitIdle(m_device->m_queue);
2003 // Now that cmd buffer done we can safely destroy query_pool
2004 m_errorMonitor->SetUnexpectedError("If queryPool is not VK_NULL_HANDLE, queryPool must be a valid VkQueryPool handle");
2005 m_errorMonitor->SetUnexpectedError("Unable to remove QueryPool obj");
2006 vkDestroyQueryPool(m_device->handle(), query_pool, NULL);
2007 }
2008
TEST_F(VkLayerTest,PipelineInUseDestroyedSignaled)2009 TEST_F(VkLayerTest, PipelineInUseDestroyedSignaled) {
2010 TEST_DESCRIPTION("Delete in-use pipeline.");
2011
2012 ASSERT_NO_FATAL_FAILURE(Init());
2013 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
2014
2015 const VkPipelineLayoutObj pipeline_layout(m_device);
2016
2017 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkDestroyPipeline-pipeline-00765");
2018 // Create PSO to be used for draw-time errors below
2019
2020 // Store pipeline handle so we can actually delete it before test finishes
2021 VkPipeline delete_this_pipeline;
2022 { // Scope pipeline so it will be auto-deleted
2023 CreatePipelineHelper pipe(*this);
2024 pipe.InitInfo();
2025 pipe.InitState();
2026 pipe.CreateGraphicsPipeline();
2027
2028 delete_this_pipeline = pipe.pipeline_;
2029
2030 m_commandBuffer->begin();
2031 // Bind pipeline to cmd buffer
2032 vkCmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.pipeline_);
2033
2034 m_commandBuffer->end();
2035
2036 VkSubmitInfo submit_info = {};
2037 submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
2038 submit_info.commandBufferCount = 1;
2039 submit_info.pCommandBuffers = &m_commandBuffer->handle();
2040 // Submit cmd buffer and then pipeline destroyed while in-flight
2041 vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
2042 } // Pipeline deletion triggered here
2043 m_errorMonitor->VerifyFound();
2044 // Make sure queue finished and then actually delete pipeline
2045 vkQueueWaitIdle(m_device->m_queue);
2046 m_errorMonitor->SetUnexpectedError("If pipeline is not VK_NULL_HANDLE, pipeline must be a valid VkPipeline handle");
2047 m_errorMonitor->SetUnexpectedError("Unable to remove Pipeline obj");
2048 vkDestroyPipeline(m_device->handle(), delete_this_pipeline, nullptr);
2049 }
2050
TEST_F(VkLayerTest,ImageViewInUseDestroyedSignaled)2051 TEST_F(VkLayerTest, ImageViewInUseDestroyedSignaled) {
2052 TEST_DESCRIPTION("Delete in-use imageView.");
2053
2054 ASSERT_NO_FATAL_FAILURE(Init());
2055 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
2056
2057 VkSamplerCreateInfo sampler_ci = SafeSaneSamplerCreateInfo();
2058 VkSampler sampler;
2059
2060 VkResult err;
2061 err = vkCreateSampler(m_device->device(), &sampler_ci, NULL, &sampler);
2062 ASSERT_VK_SUCCESS(err);
2063
2064 VkImageObj image(m_device);
2065 image.Init(128, 128, 1, VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_USAGE_SAMPLED_BIT, VK_IMAGE_TILING_OPTIMAL, 0);
2066 ASSERT_TRUE(image.initialized());
2067
2068 VkImageView view = image.targetView(VK_FORMAT_R8G8B8A8_UNORM);
2069
2070 // Create PSO to use the sampler
2071 VkShaderObj fs(m_device, bindStateFragSamplerShaderText, VK_SHADER_STAGE_FRAGMENT_BIT, this);
2072
2073 CreatePipelineHelper pipe(*this);
2074 pipe.InitInfo();
2075 pipe.shader_stages_ = {pipe.vs_->GetStageCreateInfo(), fs.GetStageCreateInfo()};
2076 pipe.dsl_bindings_ = {
2077 {0, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_ALL, nullptr},
2078 };
2079 const VkDynamicState dyn_states[] = {VK_DYNAMIC_STATE_VIEWPORT, VK_DYNAMIC_STATE_SCISSOR};
2080 VkPipelineDynamicStateCreateInfo dyn_state_ci = {};
2081 dyn_state_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO;
2082 dyn_state_ci.dynamicStateCount = size(dyn_states);
2083 dyn_state_ci.pDynamicStates = dyn_states;
2084 pipe.dyn_state_ci_ = dyn_state_ci;
2085 pipe.InitState();
2086 pipe.CreateGraphicsPipeline();
2087
2088 pipe.descriptor_set_->WriteDescriptorImageInfo(0, view, sampler, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER);
2089 pipe.descriptor_set_->UpdateDescriptorSets();
2090
2091 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkDestroyImageView-imageView-01026");
2092
2093 m_commandBuffer->begin();
2094 m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
2095 // Bind pipeline to cmd buffer
2096 vkCmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.pipeline_);
2097 vkCmdBindDescriptorSets(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.pipeline_layout_.handle(), 0, 1,
2098 &pipe.descriptor_set_->set_, 0, nullptr);
2099
2100 VkViewport viewport = {0, 0, 16, 16, 0, 1};
2101 VkRect2D scissor = {{0, 0}, {16, 16}};
2102 vkCmdSetViewport(m_commandBuffer->handle(), 0, 1, &viewport);
2103 vkCmdSetScissor(m_commandBuffer->handle(), 0, 1, &scissor);
2104
2105 m_commandBuffer->Draw(1, 0, 0, 0);
2106 m_commandBuffer->EndRenderPass();
2107 m_commandBuffer->end();
2108 // Submit cmd buffer then destroy sampler
2109 VkSubmitInfo submit_info = {};
2110 submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
2111 submit_info.commandBufferCount = 1;
2112 submit_info.pCommandBuffers = &m_commandBuffer->handle();
2113 // Submit cmd buffer and then destroy imageView while in-flight
2114 vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
2115
2116 vkDestroyImageView(m_device->device(), view, nullptr);
2117 m_errorMonitor->VerifyFound();
2118 vkQueueWaitIdle(m_device->m_queue);
2119 // Now we can actually destroy imageView
2120 m_errorMonitor->SetUnexpectedError("If imageView is not VK_NULL_HANDLE, imageView must be a valid VkImageView handle");
2121 m_errorMonitor->SetUnexpectedError("Unable to remove ImageView obj");
2122 vkDestroySampler(m_device->device(), sampler, nullptr);
2123 }
2124
TEST_F(VkLayerTest,BufferViewInUseDestroyedSignaled)2125 TEST_F(VkLayerTest, BufferViewInUseDestroyedSignaled) {
2126 TEST_DESCRIPTION("Delete in-use bufferView.");
2127
2128 ASSERT_NO_FATAL_FAILURE(Init());
2129 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
2130
2131 uint32_t queue_family_index = 0;
2132 VkBufferCreateInfo buffer_create_info = {};
2133 buffer_create_info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
2134 buffer_create_info.size = 1024;
2135 buffer_create_info.usage = VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT;
2136 buffer_create_info.queueFamilyIndexCount = 1;
2137 buffer_create_info.pQueueFamilyIndices = &queue_family_index;
2138 VkBufferObj buffer;
2139 buffer.init(*m_device, buffer_create_info);
2140
2141 VkBufferView view;
2142 VkBufferViewCreateInfo bvci = {};
2143 bvci.sType = VK_STRUCTURE_TYPE_BUFFER_VIEW_CREATE_INFO;
2144 bvci.buffer = buffer.handle();
2145 bvci.format = VK_FORMAT_R32_SFLOAT;
2146 bvci.range = VK_WHOLE_SIZE;
2147
2148 VkResult err = vkCreateBufferView(m_device->device(), &bvci, NULL, &view);
2149 ASSERT_VK_SUCCESS(err);
2150
2151 char const *fsSource =
2152 "#version 450\n"
2153 "\n"
2154 "layout(set=0, binding=0, r32f) uniform readonly imageBuffer s;\n"
2155 "layout(location=0) out vec4 x;\n"
2156 "void main(){\n"
2157 " x = imageLoad(s, 0);\n"
2158 "}\n";
2159 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
2160
2161 CreatePipelineHelper pipe(*this);
2162 pipe.InitInfo();
2163 pipe.shader_stages_ = {pipe.vs_->GetStageCreateInfo(), fs.GetStageCreateInfo()};
2164 pipe.dsl_bindings_ = {
2165 {0, VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER, 1, VK_SHADER_STAGE_ALL, nullptr},
2166 };
2167 const VkDynamicState dyn_states[] = {VK_DYNAMIC_STATE_VIEWPORT, VK_DYNAMIC_STATE_SCISSOR};
2168 VkPipelineDynamicStateCreateInfo dyn_state_ci = {};
2169 dyn_state_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO;
2170 dyn_state_ci.dynamicStateCount = size(dyn_states);
2171 dyn_state_ci.pDynamicStates = dyn_states;
2172 pipe.dyn_state_ci_ = dyn_state_ci;
2173 pipe.InitState();
2174 pipe.CreateGraphicsPipeline();
2175
2176 pipe.descriptor_set_->WriteDescriptorBufferView(0, view, VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER);
2177 pipe.descriptor_set_->UpdateDescriptorSets();
2178
2179 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkDestroyBufferView-bufferView-00936");
2180
2181 m_commandBuffer->begin();
2182 m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
2183 VkViewport viewport = {0, 0, 16, 16, 0, 1};
2184 vkCmdSetViewport(m_commandBuffer->handle(), 0, 1, &viewport);
2185 VkRect2D scissor = {{0, 0}, {16, 16}};
2186 vkCmdSetScissor(m_commandBuffer->handle(), 0, 1, &scissor);
2187 // Bind pipeline to cmd buffer
2188 vkCmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.pipeline_);
2189 vkCmdBindDescriptorSets(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.pipeline_layout_.handle(), 0, 1,
2190 &pipe.descriptor_set_->set_, 0, nullptr);
2191 m_commandBuffer->Draw(1, 0, 0, 0);
2192 m_commandBuffer->EndRenderPass();
2193 m_commandBuffer->end();
2194
2195 VkSubmitInfo submit_info = {};
2196 submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
2197 submit_info.commandBufferCount = 1;
2198 submit_info.pCommandBuffers = &m_commandBuffer->handle();
2199 // Submit cmd buffer and then destroy bufferView while in-flight
2200 vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
2201
2202 vkDestroyBufferView(m_device->device(), view, nullptr);
2203 m_errorMonitor->VerifyFound();
2204 vkQueueWaitIdle(m_device->m_queue);
2205 // Now we can actually destroy bufferView
2206 m_errorMonitor->SetUnexpectedError("If bufferView is not VK_NULL_HANDLE, bufferView must be a valid VkBufferView handle");
2207 m_errorMonitor->SetUnexpectedError("Unable to remove BufferView obj");
2208 vkDestroyBufferView(m_device->device(), view, NULL);
2209 }
2210
TEST_F(VkLayerTest,SamplerInUseDestroyedSignaled)2211 TEST_F(VkLayerTest, SamplerInUseDestroyedSignaled) {
2212 TEST_DESCRIPTION("Delete in-use sampler.");
2213
2214 ASSERT_NO_FATAL_FAILURE(Init());
2215 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
2216
2217 VkSamplerCreateInfo sampler_ci = SafeSaneSamplerCreateInfo();
2218 VkSampler sampler;
2219
2220 VkResult err;
2221 err = vkCreateSampler(m_device->device(), &sampler_ci, NULL, &sampler);
2222 ASSERT_VK_SUCCESS(err);
2223
2224 VkImageObj image(m_device);
2225 image.Init(128, 128, 1, VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_USAGE_SAMPLED_BIT, VK_IMAGE_TILING_OPTIMAL, 0);
2226 ASSERT_TRUE(image.initialized());
2227
2228 VkImageView view = image.targetView(VK_FORMAT_R8G8B8A8_UNORM);
2229
2230 // Create PSO to use the sampler
2231 VkShaderObj fs(m_device, bindStateFragSamplerShaderText, VK_SHADER_STAGE_FRAGMENT_BIT, this);
2232
2233 CreatePipelineHelper pipe(*this);
2234 pipe.InitInfo();
2235 pipe.shader_stages_ = {pipe.vs_->GetStageCreateInfo(), fs.GetStageCreateInfo()};
2236 pipe.dsl_bindings_ = {
2237 {0, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_ALL, nullptr},
2238 };
2239 const VkDynamicState dyn_states[] = {VK_DYNAMIC_STATE_VIEWPORT, VK_DYNAMIC_STATE_SCISSOR};
2240 VkPipelineDynamicStateCreateInfo dyn_state_ci = {};
2241 dyn_state_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO;
2242 dyn_state_ci.dynamicStateCount = size(dyn_states);
2243 dyn_state_ci.pDynamicStates = dyn_states;
2244 pipe.dyn_state_ci_ = dyn_state_ci;
2245 pipe.InitState();
2246 pipe.CreateGraphicsPipeline();
2247
2248 pipe.descriptor_set_->WriteDescriptorImageInfo(0, view, sampler, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER);
2249 pipe.descriptor_set_->UpdateDescriptorSets();
2250
2251 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkDestroySampler-sampler-01082");
2252
2253 m_commandBuffer->begin();
2254 m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
2255 // Bind pipeline to cmd buffer
2256 vkCmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.pipeline_);
2257 vkCmdBindDescriptorSets(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.pipeline_layout_.handle(), 0, 1,
2258 &pipe.descriptor_set_->set_, 0, nullptr);
2259
2260 VkViewport viewport = {0, 0, 16, 16, 0, 1};
2261 VkRect2D scissor = {{0, 0}, {16, 16}};
2262 vkCmdSetViewport(m_commandBuffer->handle(), 0, 1, &viewport);
2263 vkCmdSetScissor(m_commandBuffer->handle(), 0, 1, &scissor);
2264
2265 m_commandBuffer->Draw(1, 0, 0, 0);
2266 m_commandBuffer->EndRenderPass();
2267 m_commandBuffer->end();
2268 // Submit cmd buffer then destroy sampler
2269 VkSubmitInfo submit_info = {};
2270 submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
2271 submit_info.commandBufferCount = 1;
2272 submit_info.pCommandBuffers = &m_commandBuffer->handle();
2273 // Submit cmd buffer and then destroy sampler while in-flight
2274 vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
2275
2276 vkDestroySampler(m_device->device(), sampler, nullptr); // Destroyed too soon
2277 m_errorMonitor->VerifyFound();
2278 vkQueueWaitIdle(m_device->m_queue);
2279
2280 // Now we can actually destroy sampler
2281 m_errorMonitor->SetUnexpectedError("If sampler is not VK_NULL_HANDLE, sampler must be a valid VkSampler handle");
2282 m_errorMonitor->SetUnexpectedError("Unable to remove Sampler obj");
2283 vkDestroySampler(m_device->device(), sampler, NULL); // Destroyed for real
2284 }
2285
TEST_F(VkLayerTest,QueueForwardProgressFenceWait)2286 TEST_F(VkLayerTest, QueueForwardProgressFenceWait) {
2287 TEST_DESCRIPTION("Call VkQueueSubmit with a semaphore that is already signaled but not waited on by the queue.");
2288
2289 ASSERT_NO_FATAL_FAILURE(Init());
2290 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
2291
2292 const char *queue_forward_progress_message = "UNASSIGNED-CoreValidation-DrawState-QueueForwardProgress";
2293
2294 VkCommandBufferObj cb1(m_device, m_commandPool);
2295 cb1.begin();
2296 cb1.end();
2297
2298 VkSemaphoreCreateInfo semaphore_create_info = {};
2299 semaphore_create_info.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO;
2300 VkSemaphore semaphore;
2301 ASSERT_VK_SUCCESS(vkCreateSemaphore(m_device->device(), &semaphore_create_info, nullptr, &semaphore));
2302 VkSubmitInfo submit_info = {};
2303 submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
2304 submit_info.commandBufferCount = 1;
2305 submit_info.pCommandBuffers = &cb1.handle();
2306 submit_info.signalSemaphoreCount = 1;
2307 submit_info.pSignalSemaphores = &semaphore;
2308 vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
2309
2310 m_commandBuffer->begin();
2311 m_commandBuffer->end();
2312 submit_info.pCommandBuffers = &m_commandBuffer->handle();
2313 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, queue_forward_progress_message);
2314 vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
2315 m_errorMonitor->VerifyFound();
2316
2317 vkDeviceWaitIdle(m_device->device());
2318 vkDestroySemaphore(m_device->device(), semaphore, nullptr);
2319 }
2320
2321 #if GTEST_IS_THREADSAFE
TEST_F(VkLayerTest,ThreadCommandBufferCollision)2322 TEST_F(VkLayerTest, ThreadCommandBufferCollision) {
2323 test_platform_thread thread;
2324
2325 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "THREADING ERROR");
2326
2327 ASSERT_NO_FATAL_FAILURE(Init());
2328 ASSERT_NO_FATAL_FAILURE(InitViewport());
2329 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
2330
2331 // Calls AllocateCommandBuffers
2332 VkCommandBufferObj commandBuffer(m_device, m_commandPool);
2333
2334 commandBuffer.begin();
2335
2336 VkEventCreateInfo event_info;
2337 VkEvent event;
2338 VkResult err;
2339
2340 memset(&event_info, 0, sizeof(event_info));
2341 event_info.sType = VK_STRUCTURE_TYPE_EVENT_CREATE_INFO;
2342
2343 err = vkCreateEvent(device(), &event_info, NULL, &event);
2344 ASSERT_VK_SUCCESS(err);
2345
2346 err = vkResetEvent(device(), event);
2347 ASSERT_VK_SUCCESS(err);
2348
2349 struct thread_data_struct data;
2350 data.commandBuffer = commandBuffer.handle();
2351 data.event = event;
2352 data.bailout = false;
2353 m_errorMonitor->SetBailout(&data.bailout);
2354
2355 // First do some correct operations using multiple threads.
2356 // Add many entries to command buffer from another thread.
2357 test_platform_thread_create(&thread, AddToCommandBuffer, (void *)&data);
2358 // Make non-conflicting calls from this thread at the same time.
2359 for (int i = 0; i < 80000; i++) {
2360 uint32_t count;
2361 vkEnumeratePhysicalDevices(instance(), &count, NULL);
2362 }
2363 test_platform_thread_join(thread, NULL);
2364
2365 // Then do some incorrect operations using multiple threads.
2366 // Add many entries to command buffer from another thread.
2367 test_platform_thread_create(&thread, AddToCommandBuffer, (void *)&data);
2368 // Add many entries to command buffer from this thread at the same time.
2369 AddToCommandBuffer(&data);
2370
2371 test_platform_thread_join(thread, NULL);
2372 commandBuffer.end();
2373
2374 m_errorMonitor->SetBailout(NULL);
2375
2376 m_errorMonitor->VerifyFound();
2377
2378 vkDestroyEvent(device(), event, NULL);
2379 }
2380 #endif // GTEST_IS_THREADSAFE
2381
TEST_F(VkLayerTest,ExecuteUnrecordedPrimaryCB)2382 TEST_F(VkLayerTest, ExecuteUnrecordedPrimaryCB) {
2383 TEST_DESCRIPTION("Attempt vkQueueSubmit with a CB in the initial state");
2384 ASSERT_NO_FATAL_FAILURE(Init());
2385 // never record m_commandBuffer
2386
2387 VkSubmitInfo si = {};
2388 si.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
2389 si.commandBufferCount = 1;
2390 si.pCommandBuffers = &m_commandBuffer->handle();
2391
2392 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkQueueSubmit-pCommandBuffers-00072");
2393 vkQueueSubmit(m_device->m_queue, 1, &si, VK_NULL_HANDLE);
2394 m_errorMonitor->VerifyFound();
2395 }
2396
TEST_F(VkLayerTest,Maintenance1AndNegativeViewport)2397 TEST_F(VkLayerTest, Maintenance1AndNegativeViewport) {
2398 TEST_DESCRIPTION("Attempt to enable AMD_negative_viewport_height and Maintenance1_KHR extension simultaneously");
2399
2400 ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor));
2401 if (!((DeviceExtensionSupported(gpu(), nullptr, VK_KHR_MAINTENANCE1_EXTENSION_NAME)) &&
2402 (DeviceExtensionSupported(gpu(), nullptr, VK_AMD_NEGATIVE_VIEWPORT_HEIGHT_EXTENSION_NAME)))) {
2403 printf("%s Maintenance1 and AMD_negative viewport height extensions not supported, skipping test\n", kSkipPrefix);
2404 return;
2405 }
2406 ASSERT_NO_FATAL_FAILURE(InitState());
2407
2408 vk_testing::QueueCreateInfoArray queue_info(m_device->queue_props);
2409 const char *extension_names[2] = {"VK_KHR_maintenance1", "VK_AMD_negative_viewport_height"};
2410 VkDevice testDevice;
2411 VkDeviceCreateInfo device_create_info = {};
2412 auto features = m_device->phy().features();
2413 device_create_info.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
2414 device_create_info.pNext = NULL;
2415 device_create_info.queueCreateInfoCount = queue_info.size();
2416 device_create_info.pQueueCreateInfos = queue_info.data();
2417 device_create_info.enabledLayerCount = 0;
2418 device_create_info.ppEnabledLayerNames = NULL;
2419 device_create_info.enabledExtensionCount = 2;
2420 device_create_info.ppEnabledExtensionNames = (const char *const *)extension_names;
2421 device_create_info.pEnabledFeatures = &features;
2422
2423 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkDeviceCreateInfo-ppEnabledExtensionNames-00374");
2424 // The following unexpected error is coming from the LunarG loader. Do not make it a desired message because platforms that do
2425 // not use the LunarG loader (e.g. Android) will not see the message and the test will fail.
2426 m_errorMonitor->SetUnexpectedError("Failed to create device chain.");
2427 vkCreateDevice(gpu(), &device_create_info, NULL, &testDevice);
2428 m_errorMonitor->VerifyFound();
2429 }
2430
TEST_F(VkLayerTest,HostQueryResetNotEnabled)2431 TEST_F(VkLayerTest, HostQueryResetNotEnabled) {
2432 TEST_DESCRIPTION("Use vkResetQueryPoolEXT without enabling the feature");
2433
2434 if (!InstanceExtensionSupported(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME)) {
2435 printf("%s Did not find required instance extension %s; skipped.\n", kSkipPrefix,
2436 VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
2437 return;
2438 }
2439
2440 m_instance_extension_names.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
2441 ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor));
2442
2443 if (!DeviceExtensionSupported(gpu(), nullptr, VK_EXT_HOST_QUERY_RESET_EXTENSION_NAME)) {
2444 printf("%s Extension %s not supported by device; skipped.\n", kSkipPrefix, VK_EXT_HOST_QUERY_RESET_EXTENSION_NAME);
2445 return;
2446 }
2447
2448 m_device_extension_names.push_back(VK_EXT_HOST_QUERY_RESET_EXTENSION_NAME);
2449 ASSERT_NO_FATAL_FAILURE(InitState());
2450
2451 auto fpvkResetQueryPoolEXT = (PFN_vkResetQueryPoolEXT)vkGetDeviceProcAddr(m_device->device(), "vkResetQueryPoolEXT");
2452
2453 VkQueryPool query_pool;
2454 VkQueryPoolCreateInfo query_pool_create_info{};
2455 query_pool_create_info.sType = VK_STRUCTURE_TYPE_QUERY_POOL_CREATE_INFO;
2456 query_pool_create_info.queryType = VK_QUERY_TYPE_TIMESTAMP;
2457 query_pool_create_info.queryCount = 1;
2458 vkCreateQueryPool(m_device->device(), &query_pool_create_info, nullptr, &query_pool);
2459
2460 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkResetQueryPoolEXT-None-02665");
2461 fpvkResetQueryPoolEXT(m_device->device(), query_pool, 0, 1);
2462 m_errorMonitor->VerifyFound();
2463
2464 vkDestroyQueryPool(m_device->device(), query_pool, nullptr);
2465 }
2466
TEST_F(VkLayerTest,HostQueryResetBadFirstQuery)2467 TEST_F(VkLayerTest, HostQueryResetBadFirstQuery) {
2468 TEST_DESCRIPTION("Bad firstQuery in vkResetQueryPoolEXT");
2469
2470 if (!InstanceExtensionSupported(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME)) {
2471 printf("%s Did not find required instance extension %s; skipped.\n", kSkipPrefix,
2472 VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
2473 return;
2474 }
2475
2476 m_instance_extension_names.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
2477 ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor));
2478
2479 if (!DeviceExtensionSupported(gpu(), nullptr, VK_EXT_HOST_QUERY_RESET_EXTENSION_NAME)) {
2480 printf("%s Extension %s not supported by device; skipped.\n", kSkipPrefix, VK_EXT_HOST_QUERY_RESET_EXTENSION_NAME);
2481 return;
2482 }
2483
2484 m_device_extension_names.push_back(VK_EXT_HOST_QUERY_RESET_EXTENSION_NAME);
2485
2486 VkPhysicalDeviceHostQueryResetFeaturesEXT host_query_reset_features{};
2487 host_query_reset_features.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_HOST_QUERY_RESET_FEATURES_EXT;
2488 host_query_reset_features.hostQueryReset = VK_TRUE;
2489
2490 VkPhysicalDeviceFeatures2 pd_features2{};
2491 pd_features2.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2;
2492 pd_features2.pNext = &host_query_reset_features;
2493
2494 ASSERT_NO_FATAL_FAILURE(InitState(nullptr, &pd_features2));
2495
2496 auto fpvkResetQueryPoolEXT = (PFN_vkResetQueryPoolEXT)vkGetDeviceProcAddr(m_device->device(), "vkResetQueryPoolEXT");
2497
2498 VkQueryPool query_pool;
2499 VkQueryPoolCreateInfo query_pool_create_info{};
2500 query_pool_create_info.sType = VK_STRUCTURE_TYPE_QUERY_POOL_CREATE_INFO;
2501 query_pool_create_info.queryType = VK_QUERY_TYPE_TIMESTAMP;
2502 query_pool_create_info.queryCount = 1;
2503 vkCreateQueryPool(m_device->device(), &query_pool_create_info, nullptr, &query_pool);
2504
2505 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkResetQueryPoolEXT-firstQuery-02666");
2506 fpvkResetQueryPoolEXT(m_device->device(), query_pool, 1, 0);
2507 m_errorMonitor->VerifyFound();
2508
2509 vkDestroyQueryPool(m_device->device(), query_pool, nullptr);
2510 }
2511
TEST_F(VkLayerTest,HostQueryResetBadRange)2512 TEST_F(VkLayerTest, HostQueryResetBadRange) {
2513 TEST_DESCRIPTION("Bad range in vkResetQueryPoolEXT");
2514
2515 if (!InstanceExtensionSupported(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME)) {
2516 printf("%s Did not find required instance extension %s; skipped.\n", kSkipPrefix,
2517 VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
2518 return;
2519 }
2520
2521 m_instance_extension_names.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
2522 ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor));
2523
2524 if (!DeviceExtensionSupported(gpu(), nullptr, VK_EXT_HOST_QUERY_RESET_EXTENSION_NAME)) {
2525 printf("%s Extension %s not supported by device; skipped.\n", kSkipPrefix, VK_EXT_HOST_QUERY_RESET_EXTENSION_NAME);
2526 return;
2527 }
2528
2529 m_device_extension_names.push_back(VK_EXT_HOST_QUERY_RESET_EXTENSION_NAME);
2530
2531 VkPhysicalDeviceHostQueryResetFeaturesEXT host_query_reset_features{};
2532 host_query_reset_features.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_HOST_QUERY_RESET_FEATURES_EXT;
2533 host_query_reset_features.hostQueryReset = VK_TRUE;
2534
2535 VkPhysicalDeviceFeatures2 pd_features2{};
2536 pd_features2.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2;
2537 pd_features2.pNext = &host_query_reset_features;
2538
2539 ASSERT_NO_FATAL_FAILURE(InitState(nullptr, &pd_features2));
2540
2541 auto fpvkResetQueryPoolEXT = (PFN_vkResetQueryPoolEXT)vkGetDeviceProcAddr(m_device->device(), "vkResetQueryPoolEXT");
2542
2543 VkQueryPool query_pool;
2544 VkQueryPoolCreateInfo query_pool_create_info{};
2545 query_pool_create_info.sType = VK_STRUCTURE_TYPE_QUERY_POOL_CREATE_INFO;
2546 query_pool_create_info.queryType = VK_QUERY_TYPE_TIMESTAMP;
2547 query_pool_create_info.queryCount = 1;
2548 vkCreateQueryPool(m_device->device(), &query_pool_create_info, nullptr, &query_pool);
2549
2550 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkResetQueryPoolEXT-firstQuery-02667");
2551 fpvkResetQueryPoolEXT(m_device->device(), query_pool, 0, 2);
2552 m_errorMonitor->VerifyFound();
2553
2554 vkDestroyQueryPool(m_device->device(), query_pool, nullptr);
2555 }
2556
TEST_F(VkLayerTest,HostQueryResetInvalidQueryPool)2557 TEST_F(VkLayerTest, HostQueryResetInvalidQueryPool) {
2558 TEST_DESCRIPTION("Invalid queryPool in vkResetQueryPoolEXT");
2559
2560 if (!InstanceExtensionSupported(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME)) {
2561 printf("%s Did not find required instance extension %s; skipped.\n", kSkipPrefix,
2562 VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
2563 return;
2564 }
2565
2566 m_instance_extension_names.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
2567 ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor));
2568
2569 if (!DeviceExtensionSupported(gpu(), nullptr, VK_EXT_HOST_QUERY_RESET_EXTENSION_NAME)) {
2570 printf("%s Extension %s not supported by device; skipped.\n", kSkipPrefix, VK_EXT_HOST_QUERY_RESET_EXTENSION_NAME);
2571 return;
2572 }
2573
2574 m_device_extension_names.push_back(VK_EXT_HOST_QUERY_RESET_EXTENSION_NAME);
2575
2576 VkPhysicalDeviceHostQueryResetFeaturesEXT host_query_reset_features{};
2577 host_query_reset_features.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_HOST_QUERY_RESET_FEATURES_EXT;
2578 host_query_reset_features.hostQueryReset = VK_TRUE;
2579
2580 VkPhysicalDeviceFeatures2 pd_features2{};
2581 pd_features2.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2;
2582 pd_features2.pNext = &host_query_reset_features;
2583
2584 ASSERT_NO_FATAL_FAILURE(InitState(nullptr, &pd_features2));
2585
2586 auto fpvkResetQueryPoolEXT = (PFN_vkResetQueryPoolEXT)vkGetDeviceProcAddr(m_device->device(), "vkResetQueryPoolEXT");
2587
2588 // Create and destroy a query pool.
2589 VkQueryPool query_pool;
2590 VkQueryPoolCreateInfo query_pool_create_info{};
2591 query_pool_create_info.sType = VK_STRUCTURE_TYPE_QUERY_POOL_CREATE_INFO;
2592 query_pool_create_info.queryType = VK_QUERY_TYPE_TIMESTAMP;
2593 query_pool_create_info.queryCount = 1;
2594 vkCreateQueryPool(m_device->device(), &query_pool_create_info, nullptr, &query_pool);
2595 vkDestroyQueryPool(m_device->device(), query_pool, nullptr);
2596
2597 // Attempt to reuse the query pool handle.
2598 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkResetQueryPoolEXT-queryPool-parameter");
2599 fpvkResetQueryPoolEXT(m_device->device(), query_pool, 0, 1);
2600 m_errorMonitor->VerifyFound();
2601 }
2602
TEST_F(VkLayerTest,HostQueryResetWrongDevice)2603 TEST_F(VkLayerTest, HostQueryResetWrongDevice) {
2604 TEST_DESCRIPTION("Device not matching queryPool in vkResetQueryPoolEXT");
2605
2606 if (!InstanceExtensionSupported(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME)) {
2607 printf("%s Did not find required instance extension %s; skipped.\n", kSkipPrefix,
2608 VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
2609 return;
2610 }
2611
2612 m_instance_extension_names.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
2613 ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor));
2614
2615 if (!DeviceExtensionSupported(gpu(), nullptr, VK_EXT_HOST_QUERY_RESET_EXTENSION_NAME)) {
2616 printf("%s Extension %s not supported by device; skipped.\n", kSkipPrefix, VK_EXT_HOST_QUERY_RESET_EXTENSION_NAME);
2617 return;
2618 }
2619
2620 m_device_extension_names.push_back(VK_EXT_HOST_QUERY_RESET_EXTENSION_NAME);
2621
2622 VkPhysicalDeviceHostQueryResetFeaturesEXT host_query_reset_features{};
2623 host_query_reset_features.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_HOST_QUERY_RESET_FEATURES_EXT;
2624 host_query_reset_features.hostQueryReset = VK_TRUE;
2625
2626 VkPhysicalDeviceFeatures2 pd_features2{};
2627 pd_features2.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2;
2628 pd_features2.pNext = &host_query_reset_features;
2629
2630 ASSERT_NO_FATAL_FAILURE(InitState(nullptr, &pd_features2));
2631
2632 auto fpvkResetQueryPoolEXT = (PFN_vkResetQueryPoolEXT)vkGetDeviceProcAddr(m_device->device(), "vkResetQueryPoolEXT");
2633
2634 VkQueryPool query_pool;
2635 VkQueryPoolCreateInfo query_pool_create_info{};
2636 query_pool_create_info.sType = VK_STRUCTURE_TYPE_QUERY_POOL_CREATE_INFO;
2637 query_pool_create_info.queryType = VK_QUERY_TYPE_TIMESTAMP;
2638 query_pool_create_info.queryCount = 1;
2639 vkCreateQueryPool(m_device->device(), &query_pool_create_info, nullptr, &query_pool);
2640
2641 // Create a second device with the feature enabled.
2642 vk_testing::QueueCreateInfoArray queue_info(m_device->queue_props);
2643 auto features = m_device->phy().features();
2644
2645 VkDeviceCreateInfo device_create_info = {};
2646 device_create_info.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
2647 device_create_info.pNext = &host_query_reset_features;
2648 device_create_info.queueCreateInfoCount = queue_info.size();
2649 device_create_info.pQueueCreateInfos = queue_info.data();
2650 device_create_info.pEnabledFeatures = &features;
2651 device_create_info.enabledExtensionCount = m_device_extension_names.size();
2652 device_create_info.ppEnabledExtensionNames = m_device_extension_names.data();
2653
2654 VkDevice second_device;
2655 ASSERT_VK_SUCCESS(vkCreateDevice(gpu(), &device_create_info, nullptr, &second_device));
2656
2657 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkResetQueryPoolEXT-queryPool-parent");
2658 // Run vkResetQueryPoolExt on the wrong device.
2659 fpvkResetQueryPoolEXT(second_device, query_pool, 0, 1);
2660 m_errorMonitor->VerifyFound();
2661
2662 vkDestroyQueryPool(m_device->device(), query_pool, nullptr);
2663 vkDestroyDevice(second_device, nullptr);
2664 }
2665
TEST_F(VkLayerTest,ResetEventThenSet)2666 TEST_F(VkLayerTest, ResetEventThenSet) {
2667 TEST_DESCRIPTION("Reset an event then set it after the reset has been submitted.");
2668
2669 ASSERT_NO_FATAL_FAILURE(Init());
2670 VkEvent event;
2671 VkEventCreateInfo event_create_info{};
2672 event_create_info.sType = VK_STRUCTURE_TYPE_EVENT_CREATE_INFO;
2673 vkCreateEvent(m_device->device(), &event_create_info, nullptr, &event);
2674
2675 VkCommandPool command_pool;
2676 VkCommandPoolCreateInfo pool_create_info{};
2677 pool_create_info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
2678 pool_create_info.queueFamilyIndex = m_device->graphics_queue_node_index_;
2679 pool_create_info.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT;
2680 vkCreateCommandPool(m_device->device(), &pool_create_info, nullptr, &command_pool);
2681
2682 VkCommandBuffer command_buffer;
2683 VkCommandBufferAllocateInfo command_buffer_allocate_info{};
2684 command_buffer_allocate_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
2685 command_buffer_allocate_info.commandPool = command_pool;
2686 command_buffer_allocate_info.commandBufferCount = 1;
2687 command_buffer_allocate_info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
2688 vkAllocateCommandBuffers(m_device->device(), &command_buffer_allocate_info, &command_buffer);
2689
2690 VkQueue queue = VK_NULL_HANDLE;
2691 vkGetDeviceQueue(m_device->device(), m_device->graphics_queue_node_index_, 0, &queue);
2692
2693 {
2694 VkCommandBufferBeginInfo begin_info{};
2695 begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
2696 vkBeginCommandBuffer(command_buffer, &begin_info);
2697
2698 vkCmdResetEvent(command_buffer, event, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT);
2699 vkEndCommandBuffer(command_buffer);
2700 }
2701 {
2702 VkSubmitInfo submit_info{};
2703 submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
2704 submit_info.commandBufferCount = 1;
2705 submit_info.pCommandBuffers = &command_buffer;
2706 submit_info.signalSemaphoreCount = 0;
2707 submit_info.pSignalSemaphores = nullptr;
2708 vkQueueSubmit(queue, 1, &submit_info, VK_NULL_HANDLE);
2709 }
2710 {
2711 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "that is already in use by a command buffer.");
2712 vkSetEvent(m_device->device(), event);
2713 m_errorMonitor->VerifyFound();
2714 }
2715
2716 vkQueueWaitIdle(queue);
2717
2718 vkDestroyEvent(m_device->device(), event, nullptr);
2719 vkFreeCommandBuffers(m_device->device(), command_pool, 1, &command_buffer);
2720 vkDestroyCommandPool(m_device->device(), command_pool, NULL);
2721 }
2722
TEST_F(VkLayerTest,ShadingRateImageNV)2723 TEST_F(VkLayerTest, ShadingRateImageNV) {
2724 TEST_DESCRIPTION("Test VK_NV_shading_rate_image.");
2725
2726 if (InstanceExtensionSupported(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME)) {
2727 m_instance_extension_names.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
2728 } else {
2729 printf("%s Did not find required instance extension %s; skipped.\n", kSkipPrefix,
2730 VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
2731 return;
2732 }
2733 ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor));
2734 std::array<const char *, 1> required_device_extensions = {{VK_NV_SHADING_RATE_IMAGE_EXTENSION_NAME}};
2735 for (auto device_extension : required_device_extensions) {
2736 if (DeviceExtensionSupported(gpu(), nullptr, device_extension)) {
2737 m_device_extension_names.push_back(device_extension);
2738 } else {
2739 printf("%s %s Extension not supported, skipping tests\n", kSkipPrefix, device_extension);
2740 return;
2741 }
2742 }
2743
2744 if (DeviceIsMockICD() || DeviceSimulation()) {
2745 printf("%s Test not supported by MockICD, skipping tests\n", kSkipPrefix);
2746 return;
2747 }
2748
2749 PFN_vkGetPhysicalDeviceFeatures2KHR vkGetPhysicalDeviceFeatures2KHR =
2750 (PFN_vkGetPhysicalDeviceFeatures2KHR)vkGetInstanceProcAddr(instance(), "vkGetPhysicalDeviceFeatures2KHR");
2751 ASSERT_TRUE(vkGetPhysicalDeviceFeatures2KHR != nullptr);
2752
2753 // Create a device that enables shading_rate_image but disables multiViewport
2754 auto shading_rate_image_features = lvl_init_struct<VkPhysicalDeviceShadingRateImageFeaturesNV>();
2755 auto features2 = lvl_init_struct<VkPhysicalDeviceFeatures2KHR>(&shading_rate_image_features);
2756 vkGetPhysicalDeviceFeatures2KHR(gpu(), &features2);
2757
2758 features2.features.multiViewport = VK_FALSE;
2759
2760 ASSERT_NO_FATAL_FAILURE(InitState(nullptr, &features2));
2761 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
2762
2763 // Test shading rate image creation
2764 VkResult result = VK_RESULT_MAX_ENUM;
2765 VkImageCreateInfo image_create_info = {};
2766 image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
2767 image_create_info.pNext = NULL;
2768 image_create_info.imageType = VK_IMAGE_TYPE_2D;
2769 image_create_info.format = VK_FORMAT_R8_UINT;
2770 image_create_info.extent.width = 4;
2771 image_create_info.extent.height = 4;
2772 image_create_info.extent.depth = 1;
2773 image_create_info.mipLevels = 1;
2774 image_create_info.arrayLayers = 1;
2775 image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
2776 image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL;
2777 image_create_info.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
2778 image_create_info.usage = VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SHADING_RATE_IMAGE_BIT_NV;
2779 image_create_info.queueFamilyIndexCount = 0;
2780 image_create_info.pQueueFamilyIndices = NULL;
2781 image_create_info.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
2782 image_create_info.flags = VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT;
2783
2784 // image type must be 2D
2785 image_create_info.imageType = VK_IMAGE_TYPE_3D;
2786 CreateImageTest(*this, &image_create_info, "VUID-VkImageCreateInfo-imageType-02082");
2787
2788 image_create_info.imageType = VK_IMAGE_TYPE_2D;
2789
2790 // must be single sample
2791 image_create_info.samples = VK_SAMPLE_COUNT_2_BIT;
2792 CreateImageTest(*this, &image_create_info, "VUID-VkImageCreateInfo-samples-02083");
2793
2794 image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
2795
2796 // tiling must be optimal
2797 image_create_info.tiling = VK_IMAGE_TILING_LINEAR;
2798 CreateImageTest(*this, &image_create_info, "VUID-VkImageCreateInfo-tiling-02084");
2799
2800 image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL;
2801
2802 // Should succeed.
2803 VkImageObj image(m_device);
2804 image.init(&image_create_info);
2805
2806 // Test image view creation
2807 VkImageView view;
2808 VkImageViewCreateInfo ivci = {};
2809 ivci.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
2810 ivci.image = image.handle();
2811 ivci.viewType = VK_IMAGE_VIEW_TYPE_2D;
2812 ivci.format = VK_FORMAT_R8_UINT;
2813 ivci.subresourceRange.layerCount = 1;
2814 ivci.subresourceRange.baseMipLevel = 0;
2815 ivci.subresourceRange.levelCount = 1;
2816 ivci.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
2817
2818 // view type must be 2D or 2D_ARRAY
2819 ivci.viewType = VK_IMAGE_VIEW_TYPE_CUBE;
2820 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkImageViewCreateInfo-image-02086");
2821 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkImageViewCreateInfo-image-01003");
2822 result = vkCreateImageView(m_device->device(), &ivci, nullptr, &view);
2823 m_errorMonitor->VerifyFound();
2824 if (VK_SUCCESS == result) {
2825 vkDestroyImageView(m_device->device(), view, NULL);
2826 view = VK_NULL_HANDLE;
2827 }
2828 ivci.viewType = VK_IMAGE_VIEW_TYPE_2D;
2829
2830 // format must be R8_UINT
2831 ivci.format = VK_FORMAT_R8_UNORM;
2832 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkImageViewCreateInfo-image-02087");
2833 result = vkCreateImageView(m_device->device(), &ivci, nullptr, &view);
2834 m_errorMonitor->VerifyFound();
2835 if (VK_SUCCESS == result) {
2836 vkDestroyImageView(m_device->device(), view, NULL);
2837 view = VK_NULL_HANDLE;
2838 }
2839 ivci.format = VK_FORMAT_R8_UINT;
2840
2841 vkCreateImageView(m_device->device(), &ivci, nullptr, &view);
2842 m_errorMonitor->VerifyNotFound();
2843
2844 // Test pipeline creation
2845 VkPipelineViewportShadingRateImageStateCreateInfoNV vsrisci = {
2846 VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_SHADING_RATE_IMAGE_STATE_CREATE_INFO_NV};
2847
2848 VkViewport viewport = {0.0f, 0.0f, 64.0f, 64.0f, 0.0f, 1.0f};
2849 VkViewport viewports[20] = {viewport, viewport};
2850 VkRect2D scissor = {{0, 0}, {64, 64}};
2851 VkRect2D scissors[20] = {scissor, scissor};
2852 VkDynamicState dynPalette = VK_DYNAMIC_STATE_VIEWPORT_SHADING_RATE_PALETTE_NV;
2853 VkPipelineDynamicStateCreateInfo dyn = {VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO, nullptr, 0, 1, &dynPalette};
2854
2855 // viewportCount must be 0 or 1 when multiViewport is disabled
2856 {
2857 const auto break_vp = [&](CreatePipelineHelper &helper) {
2858 helper.vp_state_ci_.viewportCount = 2;
2859 helper.vp_state_ci_.pViewports = viewports;
2860 helper.vp_state_ci_.scissorCount = 2;
2861 helper.vp_state_ci_.pScissors = scissors;
2862 helper.vp_state_ci_.pNext = &vsrisci;
2863 helper.dyn_state_ci_ = dyn;
2864
2865 vsrisci.shadingRateImageEnable = VK_TRUE;
2866 vsrisci.viewportCount = 2;
2867 };
2868 CreatePipelineHelper::OneshotTest(
2869 *this, break_vp, VK_DEBUG_REPORT_ERROR_BIT_EXT,
2870 vector<std::string>({"VUID-VkPipelineViewportShadingRateImageStateCreateInfoNV-viewportCount-02054",
2871 "VUID-VkPipelineViewportStateCreateInfo-viewportCount-01216",
2872 "VUID-VkPipelineViewportStateCreateInfo-scissorCount-01217"}));
2873 }
2874
2875 // viewportCounts must match
2876 {
2877 const auto break_vp = [&](CreatePipelineHelper &helper) {
2878 helper.vp_state_ci_.viewportCount = 1;
2879 helper.vp_state_ci_.pViewports = viewports;
2880 helper.vp_state_ci_.scissorCount = 1;
2881 helper.vp_state_ci_.pScissors = scissors;
2882 helper.vp_state_ci_.pNext = &vsrisci;
2883 helper.dyn_state_ci_ = dyn;
2884
2885 vsrisci.shadingRateImageEnable = VK_TRUE;
2886 vsrisci.viewportCount = 0;
2887 };
2888 CreatePipelineHelper::OneshotTest(
2889 *this, break_vp, VK_DEBUG_REPORT_ERROR_BIT_EXT,
2890 vector<std::string>({"VUID-VkPipelineViewportShadingRateImageStateCreateInfoNV-shadingRateImageEnable-02056"}));
2891 }
2892
2893 // pShadingRatePalettes must not be NULL.
2894 {
2895 const auto break_vp = [&](CreatePipelineHelper &helper) {
2896 helper.vp_state_ci_.viewportCount = 1;
2897 helper.vp_state_ci_.pViewports = viewports;
2898 helper.vp_state_ci_.scissorCount = 1;
2899 helper.vp_state_ci_.pScissors = scissors;
2900 helper.vp_state_ci_.pNext = &vsrisci;
2901
2902 vsrisci.shadingRateImageEnable = VK_TRUE;
2903 vsrisci.viewportCount = 1;
2904 };
2905 CreatePipelineHelper::OneshotTest(
2906 *this, break_vp, VK_DEBUG_REPORT_ERROR_BIT_EXT,
2907 vector<std::string>({"VUID-VkPipelineViewportShadingRateImageStateCreateInfoNV-pDynamicStates-02057"}));
2908 }
2909
2910 // Create an image without the SRI bit
2911 VkImageObj nonSRIimage(m_device);
2912 nonSRIimage.Init(256, 256, 1, VK_FORMAT_B8G8R8A8_UNORM, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, VK_IMAGE_TILING_OPTIMAL, 0);
2913 ASSERT_TRUE(nonSRIimage.initialized());
2914 VkImageView nonSRIview = nonSRIimage.targetView(VK_FORMAT_B8G8R8A8_UNORM);
2915
2916 // Test SRI layout on non-SRI image
2917 VkImageMemoryBarrier img_barrier = {};
2918 img_barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
2919 img_barrier.pNext = nullptr;
2920 img_barrier.srcAccessMask = 0;
2921 img_barrier.dstAccessMask = 0;
2922 img_barrier.oldLayout = VK_IMAGE_LAYOUT_GENERAL;
2923 img_barrier.newLayout = VK_IMAGE_LAYOUT_SHADING_RATE_OPTIMAL_NV;
2924 img_barrier.image = nonSRIimage.handle();
2925 img_barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
2926 img_barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
2927 img_barrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
2928 img_barrier.subresourceRange.baseArrayLayer = 0;
2929 img_barrier.subresourceRange.baseMipLevel = 0;
2930 img_barrier.subresourceRange.layerCount = 1;
2931 img_barrier.subresourceRange.levelCount = 1;
2932
2933 m_commandBuffer->begin();
2934
2935 // Error trying to convert it to SRI layout
2936 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkImageMemoryBarrier-oldLayout-02088");
2937 vkCmdPipelineBarrier(m_commandBuffer->handle(), VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, 0, 0,
2938 nullptr, 0, nullptr, 1, &img_barrier);
2939 m_errorMonitor->VerifyFound();
2940
2941 // succeed converting it to GENERAL
2942 img_barrier.newLayout = VK_IMAGE_LAYOUT_GENERAL;
2943 vkCmdPipelineBarrier(m_commandBuffer->handle(), VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, 0, 0,
2944 nullptr, 0, nullptr, 1, &img_barrier);
2945 m_errorMonitor->VerifyNotFound();
2946
2947 // Test vkCmdBindShadingRateImageNV errors
2948 auto vkCmdBindShadingRateImageNV =
2949 (PFN_vkCmdBindShadingRateImageNV)vkGetDeviceProcAddr(m_device->device(), "vkCmdBindShadingRateImageNV");
2950
2951 // if the view is non-NULL, it must be R8_UINT, USAGE_SRI, image layout must match, layout must be valid
2952 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdBindShadingRateImageNV-imageView-02060");
2953 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdBindShadingRateImageNV-imageView-02061");
2954 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdBindShadingRateImageNV-imageView-02062");
2955 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdBindShadingRateImageNV-imageLayout-02063");
2956 vkCmdBindShadingRateImageNV(m_commandBuffer->handle(), nonSRIview, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
2957 m_errorMonitor->VerifyFound();
2958
2959 // Test vkCmdSetViewportShadingRatePaletteNV errors
2960 auto vkCmdSetViewportShadingRatePaletteNV =
2961 (PFN_vkCmdSetViewportShadingRatePaletteNV)vkGetDeviceProcAddr(m_device->device(), "vkCmdSetViewportShadingRatePaletteNV");
2962
2963 VkShadingRatePaletteEntryNV paletteEntries[100] = {};
2964 VkShadingRatePaletteNV palette = {100, paletteEntries};
2965 VkShadingRatePaletteNV palettes[] = {palette, palette};
2966
2967 // errors on firstViewport/viewportCount
2968 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
2969 "VUID-vkCmdSetViewportShadingRatePaletteNV-firstViewport-02066");
2970 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
2971 "VUID-vkCmdSetViewportShadingRatePaletteNV-firstViewport-02067");
2972 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
2973 "VUID-vkCmdSetViewportShadingRatePaletteNV-firstViewport-02068");
2974 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
2975 "VUID-vkCmdSetViewportShadingRatePaletteNV-viewportCount-02069");
2976 vkCmdSetViewportShadingRatePaletteNV(m_commandBuffer->handle(), 20, 2, palettes);
2977 m_errorMonitor->VerifyFound();
2978
2979 // shadingRatePaletteEntryCount must be in range
2980 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
2981 "VUID-VkShadingRatePaletteNV-shadingRatePaletteEntryCount-02071");
2982 vkCmdSetViewportShadingRatePaletteNV(m_commandBuffer->handle(), 0, 1, palettes);
2983 m_errorMonitor->VerifyFound();
2984
2985 VkCoarseSampleLocationNV locations[100] = {
2986 {0, 0, 0}, {0, 0, 1}, {0, 1, 0}, {0, 1, 1}, {0, 1, 1}, // duplicate
2987 {1000, 0, 0}, // pixelX too large
2988 {0, 1000, 0}, // pixelY too large
2989 {0, 0, 1000}, // sample too large
2990 };
2991
2992 // Test custom sample orders, both via pipeline state and via dynamic state
2993 {
2994 VkCoarseSampleOrderCustomNV sampOrdBadShadingRate = {VK_SHADING_RATE_PALETTE_ENTRY_1_INVOCATION_PER_PIXEL_NV, 1, 1,
2995 locations};
2996 VkCoarseSampleOrderCustomNV sampOrdBadSampleCount = {VK_SHADING_RATE_PALETTE_ENTRY_1_INVOCATION_PER_1X2_PIXELS_NV, 3, 1,
2997 locations};
2998 VkCoarseSampleOrderCustomNV sampOrdBadSampleLocationCount = {VK_SHADING_RATE_PALETTE_ENTRY_1_INVOCATION_PER_1X2_PIXELS_NV,
2999 2, 2, locations};
3000 VkCoarseSampleOrderCustomNV sampOrdDuplicateLocations = {VK_SHADING_RATE_PALETTE_ENTRY_1_INVOCATION_PER_1X2_PIXELS_NV, 2,
3001 1 * 2 * 2, &locations[1]};
3002 VkCoarseSampleOrderCustomNV sampOrdOutOfRangeLocations = {VK_SHADING_RATE_PALETTE_ENTRY_1_INVOCATION_PER_1X2_PIXELS_NV, 2,
3003 1 * 2 * 2, &locations[4]};
3004 VkCoarseSampleOrderCustomNV sampOrdTooLargeSampleLocationCount = {
3005 VK_SHADING_RATE_PALETTE_ENTRY_1_INVOCATION_PER_4X4_PIXELS_NV, 4, 64, &locations[8]};
3006 VkCoarseSampleOrderCustomNV sampOrdGood = {VK_SHADING_RATE_PALETTE_ENTRY_1_INVOCATION_PER_1X2_PIXELS_NV, 2, 1 * 2 * 2,
3007 &locations[0]};
3008
3009 VkPipelineViewportCoarseSampleOrderStateCreateInfoNV csosci = {
3010 VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_COARSE_SAMPLE_ORDER_STATE_CREATE_INFO_NV};
3011 csosci.sampleOrderType = VK_COARSE_SAMPLE_ORDER_TYPE_CUSTOM_NV;
3012 csosci.customSampleOrderCount = 1;
3013
3014 using std::vector;
3015 struct TestCase {
3016 const VkCoarseSampleOrderCustomNV *order;
3017 vector<std::string> vuids;
3018 };
3019
3020 vector<TestCase> test_cases = {
3021 {&sampOrdBadShadingRate, {"VUID-VkCoarseSampleOrderCustomNV-shadingRate-02073"}},
3022 {&sampOrdBadSampleCount,
3023 {"VUID-VkCoarseSampleOrderCustomNV-sampleCount-02074", "VUID-VkCoarseSampleOrderCustomNV-sampleLocationCount-02075"}},
3024 {&sampOrdBadSampleLocationCount, {"VUID-VkCoarseSampleOrderCustomNV-sampleLocationCount-02075"}},
3025 {&sampOrdDuplicateLocations, {"VUID-VkCoarseSampleOrderCustomNV-pSampleLocations-02077"}},
3026 {&sampOrdOutOfRangeLocations,
3027 {"VUID-VkCoarseSampleOrderCustomNV-pSampleLocations-02077", "VUID-VkCoarseSampleLocationNV-pixelX-02078",
3028 "VUID-VkCoarseSampleLocationNV-pixelY-02079", "VUID-VkCoarseSampleLocationNV-sample-02080"}},
3029 {&sampOrdTooLargeSampleLocationCount,
3030 {"VUID-VkCoarseSampleOrderCustomNV-sampleLocationCount-02076",
3031 "VUID-VkCoarseSampleOrderCustomNV-pSampleLocations-02077"}},
3032 {&sampOrdGood, {}},
3033 };
3034
3035 for (const auto &test_case : test_cases) {
3036 const auto break_vp = [&](CreatePipelineHelper &helper) {
3037 helper.vp_state_ci_.pNext = &csosci;
3038 csosci.pCustomSampleOrders = test_case.order;
3039 };
3040 CreatePipelineHelper::OneshotTest(*this, break_vp, VK_DEBUG_REPORT_ERROR_BIT_EXT, test_case.vuids);
3041 }
3042
3043 // Test vkCmdSetCoarseSampleOrderNV errors
3044 auto vkCmdSetCoarseSampleOrderNV =
3045 (PFN_vkCmdSetCoarseSampleOrderNV)vkGetDeviceProcAddr(m_device->device(), "vkCmdSetCoarseSampleOrderNV");
3046
3047 for (const auto &test_case : test_cases) {
3048 for (uint32_t i = 0; i < test_case.vuids.size(); ++i) {
3049 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, test_case.vuids[i]);
3050 }
3051 vkCmdSetCoarseSampleOrderNV(m_commandBuffer->handle(), VK_COARSE_SAMPLE_ORDER_TYPE_CUSTOM_NV, 1, test_case.order);
3052 if (test_case.vuids.size()) {
3053 m_errorMonitor->VerifyFound();
3054 } else {
3055 m_errorMonitor->VerifyNotFound();
3056 }
3057 }
3058
3059 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
3060 "VUID-vkCmdSetCoarseSampleOrderNV-sampleOrderType-02081");
3061 vkCmdSetCoarseSampleOrderNV(m_commandBuffer->handle(), VK_COARSE_SAMPLE_ORDER_TYPE_PIXEL_MAJOR_NV, 1, &sampOrdGood);
3062 m_errorMonitor->VerifyFound();
3063 }
3064
3065 m_commandBuffer->end();
3066
3067 vkDestroyImageView(m_device->device(), view, NULL);
3068 }
3069
3070 #ifdef VK_USE_PLATFORM_ANDROID_KHR
3071 #include "android_ndk_types.h"
3072
TEST_F(VkLayerTest,AndroidHardwareBufferImageCreate)3073 TEST_F(VkLayerTest, AndroidHardwareBufferImageCreate) {
3074 TEST_DESCRIPTION("Verify AndroidHardwareBuffer image create info.");
3075
3076 SetTargetApiVersion(VK_API_VERSION_1_1);
3077 ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor));
3078
3079 if ((DeviceExtensionSupported(gpu(), nullptr, VK_ANDROID_EXTERNAL_MEMORY_ANDROID_HARDWARE_BUFFER_EXTENSION_NAME)) &&
3080 // Also skip on devices that advertise AHB, but not the pre-requisite foreign_queue extension
3081 (DeviceExtensionSupported(gpu(), nullptr, VK_EXT_QUEUE_FAMILY_FOREIGN_EXTENSION_NAME))) {
3082 m_device_extension_names.push_back(VK_ANDROID_EXTERNAL_MEMORY_ANDROID_HARDWARE_BUFFER_EXTENSION_NAME);
3083 m_device_extension_names.push_back(VK_KHR_SAMPLER_YCBCR_CONVERSION_EXTENSION_NAME);
3084 m_device_extension_names.push_back(VK_KHR_MAINTENANCE1_EXTENSION_NAME);
3085 m_device_extension_names.push_back(VK_KHR_BIND_MEMORY_2_EXTENSION_NAME);
3086 m_device_extension_names.push_back(VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME);
3087 m_device_extension_names.push_back(VK_KHR_EXTERNAL_MEMORY_EXTENSION_NAME);
3088 m_device_extension_names.push_back(VK_EXT_QUEUE_FAMILY_FOREIGN_EXTENSION_NAME);
3089 } else {
3090 printf("%s %s extension not supported, skipping tests\n", kSkipPrefix,
3091 VK_ANDROID_EXTERNAL_MEMORY_ANDROID_HARDWARE_BUFFER_EXTENSION_NAME);
3092 return;
3093 }
3094
3095 ASSERT_NO_FATAL_FAILURE(InitState());
3096 VkDevice dev = m_device->device();
3097
3098 VkImage img = VK_NULL_HANDLE;
3099 auto reset_img = [&img, dev]() {
3100 if (VK_NULL_HANDLE != img) vkDestroyImage(dev, img, NULL);
3101 img = VK_NULL_HANDLE;
3102 };
3103
3104 VkImageCreateInfo ici = {};
3105 ici.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
3106 ici.pNext = nullptr;
3107 ici.imageType = VK_IMAGE_TYPE_2D;
3108 ici.arrayLayers = 1;
3109 ici.extent = {64, 64, 1};
3110 ici.format = VK_FORMAT_UNDEFINED;
3111 ici.mipLevels = 1;
3112 ici.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
3113 ici.samples = VK_SAMPLE_COUNT_1_BIT;
3114 ici.tiling = VK_IMAGE_TILING_OPTIMAL;
3115 ici.usage = VK_IMAGE_USAGE_SAMPLED_BIT;
3116
3117 // undefined format
3118 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkImageCreateInfo-pNext-01975");
3119 m_errorMonitor->SetUnexpectedError("VUID_Undefined");
3120 vkCreateImage(dev, &ici, NULL, &img);
3121 m_errorMonitor->VerifyFound();
3122 reset_img();
3123
3124 // also undefined format
3125 VkExternalFormatANDROID efa = {};
3126 efa.sType = VK_STRUCTURE_TYPE_EXTERNAL_FORMAT_ANDROID;
3127 efa.externalFormat = 0;
3128 ici.pNext = &efa;
3129 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkImageCreateInfo-pNext-01975");
3130 vkCreateImage(dev, &ici, NULL, &img);
3131 m_errorMonitor->VerifyFound();
3132 reset_img();
3133
3134 // undefined format with an unknown external format
3135 efa.externalFormat = 0xBADC0DE;
3136 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkExternalFormatANDROID-externalFormat-01894");
3137 vkCreateImage(dev, &ici, NULL, &img);
3138 m_errorMonitor->VerifyFound();
3139 reset_img();
3140
3141 AHardwareBuffer *ahb;
3142 AHardwareBuffer_Desc ahb_desc = {};
3143 ahb_desc.format = AHARDWAREBUFFER_FORMAT_R8G8B8X8_UNORM;
3144 ahb_desc.usage = AHARDWAREBUFFER_USAGE_GPU_SAMPLED_IMAGE;
3145 ahb_desc.width = 64;
3146 ahb_desc.height = 64;
3147 ahb_desc.layers = 1;
3148 // Allocate an AHardwareBuffer
3149 AHardwareBuffer_allocate(&ahb_desc, &ahb);
3150
3151 // Retrieve it's properties to make it's external format 'known' (AHARDWAREBUFFER_FORMAT_R8G8B8X8_UNORM)
3152 VkAndroidHardwareBufferFormatPropertiesANDROID ahb_fmt_props = {};
3153 ahb_fmt_props.sType = VK_STRUCTURE_TYPE_ANDROID_HARDWARE_BUFFER_FORMAT_PROPERTIES_ANDROID;
3154 VkAndroidHardwareBufferPropertiesANDROID ahb_props = {};
3155 ahb_props.sType = VK_STRUCTURE_TYPE_ANDROID_HARDWARE_BUFFER_PROPERTIES_ANDROID;
3156 ahb_props.pNext = &ahb_fmt_props;
3157 PFN_vkGetAndroidHardwareBufferPropertiesANDROID pfn_GetAHBProps =
3158 (PFN_vkGetAndroidHardwareBufferPropertiesANDROID)vkGetDeviceProcAddr(dev, "vkGetAndroidHardwareBufferPropertiesANDROID");
3159 ASSERT_TRUE(pfn_GetAHBProps != nullptr);
3160 pfn_GetAHBProps(dev, ahb, &ahb_props);
3161
3162 // a defined image format with a non-zero external format
3163 ici.format = VK_FORMAT_R8G8B8A8_UNORM;
3164 efa.externalFormat = ahb_fmt_props.externalFormat;
3165 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkImageCreateInfo-pNext-01974");
3166 vkCreateImage(dev, &ici, NULL, &img);
3167 m_errorMonitor->VerifyFound();
3168 reset_img();
3169 ici.format = VK_FORMAT_UNDEFINED;
3170
3171 // external format while MUTABLE
3172 ici.flags = VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT;
3173 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkImageCreateInfo-pNext-02396");
3174 vkCreateImage(dev, &ici, NULL, &img);
3175 m_errorMonitor->VerifyFound();
3176 reset_img();
3177 ici.flags = 0;
3178
3179 // external format while usage other than SAMPLED
3180 ici.usage |= VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT;
3181 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkImageCreateInfo-pNext-02397");
3182 vkCreateImage(dev, &ici, NULL, &img);
3183 m_errorMonitor->VerifyFound();
3184 reset_img();
3185 ici.usage = VK_IMAGE_USAGE_SAMPLED_BIT;
3186
3187 // external format while tiline other than OPTIMAL
3188 ici.tiling = VK_IMAGE_TILING_LINEAR;
3189 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkImageCreateInfo-pNext-02398");
3190 vkCreateImage(dev, &ici, NULL, &img);
3191 m_errorMonitor->VerifyFound();
3192 reset_img();
3193 ici.tiling = VK_IMAGE_TILING_OPTIMAL;
3194
3195 // imageType
3196 VkExternalMemoryImageCreateInfo emici = {};
3197 emici.sType = VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_IMAGE_CREATE_INFO;
3198 emici.handleTypes = VK_EXTERNAL_MEMORY_HANDLE_TYPE_ANDROID_HARDWARE_BUFFER_BIT_ANDROID;
3199 ici.pNext = &emici; // remove efa from chain, insert emici
3200 ici.format = VK_FORMAT_R8G8B8A8_UNORM;
3201 ici.imageType = VK_IMAGE_TYPE_3D;
3202 ici.extent = {64, 64, 64};
3203
3204 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkImageCreateInfo-pNext-02393");
3205 vkCreateImage(dev, &ici, NULL, &img);
3206 m_errorMonitor->VerifyFound();
3207 reset_img();
3208
3209 // wrong mipLevels
3210 ici.imageType = VK_IMAGE_TYPE_2D;
3211 ici.extent = {64, 64, 1};
3212 ici.mipLevels = 6; // should be 7
3213 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkImageCreateInfo-pNext-02394");
3214 vkCreateImage(dev, &ici, NULL, &img);
3215 m_errorMonitor->VerifyFound();
3216 reset_img();
3217 }
3218
TEST_F(VkLayerTest,AndroidHardwareBufferFetchUnboundImageInfo)3219 TEST_F(VkLayerTest, AndroidHardwareBufferFetchUnboundImageInfo) {
3220 TEST_DESCRIPTION("Verify AndroidHardwareBuffer retreive image properties while memory unbound.");
3221
3222 SetTargetApiVersion(VK_API_VERSION_1_1);
3223 ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor));
3224
3225 if ((DeviceExtensionSupported(gpu(), nullptr, VK_ANDROID_EXTERNAL_MEMORY_ANDROID_HARDWARE_BUFFER_EXTENSION_NAME)) &&
3226 // Also skip on devices that advertise AHB, but not the pre-requisite foreign_queue extension
3227 (DeviceExtensionSupported(gpu(), nullptr, VK_EXT_QUEUE_FAMILY_FOREIGN_EXTENSION_NAME))) {
3228 m_device_extension_names.push_back(VK_ANDROID_EXTERNAL_MEMORY_ANDROID_HARDWARE_BUFFER_EXTENSION_NAME);
3229 m_device_extension_names.push_back(VK_KHR_SAMPLER_YCBCR_CONVERSION_EXTENSION_NAME);
3230 m_device_extension_names.push_back(VK_KHR_MAINTENANCE1_EXTENSION_NAME);
3231 m_device_extension_names.push_back(VK_KHR_BIND_MEMORY_2_EXTENSION_NAME);
3232 m_device_extension_names.push_back(VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME);
3233 m_device_extension_names.push_back(VK_KHR_EXTERNAL_MEMORY_EXTENSION_NAME);
3234 m_device_extension_names.push_back(VK_EXT_QUEUE_FAMILY_FOREIGN_EXTENSION_NAME);
3235 } else {
3236 printf("%s %s extension not supported, skipping tests\n", kSkipPrefix,
3237 VK_ANDROID_EXTERNAL_MEMORY_ANDROID_HARDWARE_BUFFER_EXTENSION_NAME);
3238 return;
3239 }
3240
3241 ASSERT_NO_FATAL_FAILURE(InitState());
3242 VkDevice dev = m_device->device();
3243
3244 VkImage img = VK_NULL_HANDLE;
3245 auto reset_img = [&img, dev]() {
3246 if (VK_NULL_HANDLE != img) vkDestroyImage(dev, img, NULL);
3247 img = VK_NULL_HANDLE;
3248 };
3249
3250 VkImageCreateInfo ici = {};
3251 ici.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
3252 ici.pNext = nullptr;
3253 ici.imageType = VK_IMAGE_TYPE_2D;
3254 ici.arrayLayers = 1;
3255 ici.extent = {64, 64, 1};
3256 ici.format = VK_FORMAT_R8G8B8A8_UNORM;
3257 ici.mipLevels = 1;
3258 ici.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
3259 ici.samples = VK_SAMPLE_COUNT_1_BIT;
3260 ici.tiling = VK_IMAGE_TILING_LINEAR;
3261 ici.usage = VK_IMAGE_USAGE_SAMPLED_BIT;
3262
3263 VkExternalMemoryImageCreateInfo emici = {};
3264 emici.sType = VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_IMAGE_CREATE_INFO;
3265 emici.handleTypes = VK_EXTERNAL_MEMORY_HANDLE_TYPE_ANDROID_HARDWARE_BUFFER_BIT_ANDROID;
3266 ici.pNext = &emici;
3267
3268 m_errorMonitor->ExpectSuccess();
3269 vkCreateImage(dev, &ici, NULL, &img);
3270 m_errorMonitor->VerifyNotFound();
3271
3272 // attempt to fetch layout from unbound image
3273 VkImageSubresource sub_rsrc = {};
3274 sub_rsrc.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
3275 VkSubresourceLayout sub_layout = {};
3276 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkGetImageSubresourceLayout-image-01895");
3277 vkGetImageSubresourceLayout(dev, img, &sub_rsrc, &sub_layout);
3278 m_errorMonitor->VerifyFound();
3279
3280 // attempt to get memory reqs from unbound image
3281 VkImageMemoryRequirementsInfo2 imri = {};
3282 imri.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_REQUIREMENTS_INFO_2;
3283 imri.image = img;
3284 VkMemoryRequirements2 mem_reqs = {};
3285 mem_reqs.sType = VK_STRUCTURE_TYPE_MEMORY_REQUIREMENTS_2;
3286 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkImageMemoryRequirementsInfo2-image-01897");
3287 vkGetImageMemoryRequirements2(dev, &imri, &mem_reqs);
3288 m_errorMonitor->VerifyFound();
3289
3290 reset_img();
3291 }
3292
TEST_F(VkLayerTest,AndroidHardwareBufferMemoryAllocation)3293 TEST_F(VkLayerTest, AndroidHardwareBufferMemoryAllocation) {
3294 TEST_DESCRIPTION("Verify AndroidHardwareBuffer memory allocation.");
3295
3296 SetTargetApiVersion(VK_API_VERSION_1_1);
3297 ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor));
3298
3299 if ((DeviceExtensionSupported(gpu(), nullptr, VK_ANDROID_EXTERNAL_MEMORY_ANDROID_HARDWARE_BUFFER_EXTENSION_NAME)) &&
3300 // Also skip on devices that advertise AHB, but not the pre-requisite foreign_queue extension
3301 (DeviceExtensionSupported(gpu(), nullptr, VK_EXT_QUEUE_FAMILY_FOREIGN_EXTENSION_NAME))) {
3302 m_device_extension_names.push_back(VK_ANDROID_EXTERNAL_MEMORY_ANDROID_HARDWARE_BUFFER_EXTENSION_NAME);
3303 m_device_extension_names.push_back(VK_KHR_SAMPLER_YCBCR_CONVERSION_EXTENSION_NAME);
3304 m_device_extension_names.push_back(VK_KHR_MAINTENANCE1_EXTENSION_NAME);
3305 m_device_extension_names.push_back(VK_KHR_BIND_MEMORY_2_EXTENSION_NAME);
3306 m_device_extension_names.push_back(VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME);
3307 m_device_extension_names.push_back(VK_KHR_EXTERNAL_MEMORY_EXTENSION_NAME);
3308 m_device_extension_names.push_back(VK_EXT_QUEUE_FAMILY_FOREIGN_EXTENSION_NAME);
3309 } else {
3310 printf("%s %s extension not supported, skipping tests\n", kSkipPrefix,
3311 VK_ANDROID_EXTERNAL_MEMORY_ANDROID_HARDWARE_BUFFER_EXTENSION_NAME);
3312 return;
3313 }
3314
3315 ASSERT_NO_FATAL_FAILURE(InitState());
3316 VkDevice dev = m_device->device();
3317
3318 VkImage img = VK_NULL_HANDLE;
3319 auto reset_img = [&img, dev]() {
3320 if (VK_NULL_HANDLE != img) vkDestroyImage(dev, img, NULL);
3321 img = VK_NULL_HANDLE;
3322 };
3323 VkDeviceMemory mem_handle = VK_NULL_HANDLE;
3324 auto reset_mem = [&mem_handle, dev]() {
3325 if (VK_NULL_HANDLE != mem_handle) vkFreeMemory(dev, mem_handle, NULL);
3326 mem_handle = VK_NULL_HANDLE;
3327 };
3328
3329 PFN_vkGetAndroidHardwareBufferPropertiesANDROID pfn_GetAHBProps =
3330 (PFN_vkGetAndroidHardwareBufferPropertiesANDROID)vkGetDeviceProcAddr(dev, "vkGetAndroidHardwareBufferPropertiesANDROID");
3331 ASSERT_TRUE(pfn_GetAHBProps != nullptr);
3332
3333 // AHB structs
3334 AHardwareBuffer *ahb = nullptr;
3335 AHardwareBuffer_Desc ahb_desc = {};
3336 VkAndroidHardwareBufferFormatPropertiesANDROID ahb_fmt_props = {};
3337 ahb_fmt_props.sType = VK_STRUCTURE_TYPE_ANDROID_HARDWARE_BUFFER_FORMAT_PROPERTIES_ANDROID;
3338 VkAndroidHardwareBufferPropertiesANDROID ahb_props = {};
3339 ahb_props.sType = VK_STRUCTURE_TYPE_ANDROID_HARDWARE_BUFFER_PROPERTIES_ANDROID;
3340 ahb_props.pNext = &ahb_fmt_props;
3341 VkImportAndroidHardwareBufferInfoANDROID iahbi = {};
3342 iahbi.sType = VK_STRUCTURE_TYPE_IMPORT_ANDROID_HARDWARE_BUFFER_INFO_ANDROID;
3343
3344 // destroy and re-acquire an AHB, and fetch it's properties
3345 auto recreate_ahb = [&ahb, &iahbi, &ahb_desc, &ahb_props, dev, pfn_GetAHBProps]() {
3346 if (ahb) AHardwareBuffer_release(ahb);
3347 ahb = nullptr;
3348 AHardwareBuffer_allocate(&ahb_desc, &ahb);
3349 if (ahb) {
3350 pfn_GetAHBProps(dev, ahb, &ahb_props);
3351 iahbi.buffer = ahb;
3352 }
3353 };
3354
3355 // Allocate an AHardwareBuffer
3356 ahb_desc.format = AHARDWAREBUFFER_FORMAT_R8G8B8X8_UNORM;
3357 ahb_desc.usage = AHARDWAREBUFFER_USAGE_GPU_SAMPLED_IMAGE;
3358 ahb_desc.width = 64;
3359 ahb_desc.height = 64;
3360 ahb_desc.layers = 1;
3361 recreate_ahb();
3362
3363 // Create an image w/ external format
3364 VkExternalFormatANDROID efa = {};
3365 efa.sType = VK_STRUCTURE_TYPE_EXTERNAL_FORMAT_ANDROID;
3366 efa.externalFormat = ahb_fmt_props.externalFormat;
3367
3368 VkImageCreateInfo ici = {};
3369 ici.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
3370 ici.pNext = &efa;
3371 ici.imageType = VK_IMAGE_TYPE_2D;
3372 ici.arrayLayers = 1;
3373 ici.extent = {64, 64, 1};
3374 ici.format = VK_FORMAT_UNDEFINED;
3375 ici.mipLevels = 1;
3376 ici.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
3377 ici.samples = VK_SAMPLE_COUNT_1_BIT;
3378 ici.tiling = VK_IMAGE_TILING_OPTIMAL;
3379 ici.usage = VK_IMAGE_USAGE_SAMPLED_BIT;
3380 VkResult res = vkCreateImage(dev, &ici, NULL, &img);
3381 ASSERT_VK_SUCCESS(res);
3382
3383 VkMemoryAllocateInfo mai = {};
3384 mai.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
3385 mai.pNext = &iahbi; // Chained import struct
3386 mai.allocationSize = ahb_props.allocationSize;
3387 mai.memoryTypeIndex = 32;
3388 // Set index to match one of the bits in ahb_props
3389 for (int i = 0; i < 32; i++) {
3390 if (ahb_props.memoryTypeBits & (1 << i)) {
3391 mai.memoryTypeIndex = i;
3392 break;
3393 }
3394 }
3395 ASSERT_NE(32, mai.memoryTypeIndex);
3396
3397 // Import w/ non-dedicated memory allocation
3398
3399 // Import requires format AHB_FMT_BLOB and usage AHB_USAGE_GPU_DATA_BUFFER
3400 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkMemoryAllocateInfo-pNext-02384");
3401 vkAllocateMemory(dev, &mai, NULL, &mem_handle);
3402 m_errorMonitor->VerifyFound();
3403 reset_mem();
3404
3405 // Allocation size mismatch
3406 ahb_desc.format = AHARDWAREBUFFER_FORMAT_BLOB;
3407 ahb_desc.usage = AHARDWAREBUFFER_USAGE_GPU_DATA_BUFFER;
3408 ahb_desc.height = 1;
3409 recreate_ahb();
3410 mai.allocationSize = ahb_props.allocationSize + 1;
3411 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkMemoryAllocateInfo-allocationSize-02383");
3412 vkAllocateMemory(dev, &mai, NULL, &mem_handle);
3413 m_errorMonitor->VerifyFound();
3414 mai.allocationSize = ahb_props.allocationSize;
3415 reset_mem();
3416
3417 // memoryTypeIndex mismatch
3418 mai.memoryTypeIndex++;
3419 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkMemoryAllocateInfo-memoryTypeIndex-02385");
3420 vkAllocateMemory(dev, &mai, NULL, &mem_handle);
3421 m_errorMonitor->VerifyFound();
3422 mai.memoryTypeIndex--;
3423 reset_mem();
3424
3425 // Insert dedicated image memory allocation to mai chain
3426 VkMemoryDedicatedAllocateInfo mdai = {};
3427 mdai.sType = VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO;
3428 mdai.image = img;
3429 mdai.buffer = VK_NULL_HANDLE;
3430 mdai.pNext = mai.pNext;
3431 mai.pNext = &mdai;
3432
3433 // Dedicated allocation with unmatched usage bits
3434 ahb_desc.format = AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM;
3435 ahb_desc.usage = AHARDWAREBUFFER_USAGE_GPU_COLOR_OUTPUT;
3436 ahb_desc.height = 64;
3437 recreate_ahb();
3438 mai.allocationSize = ahb_props.allocationSize;
3439 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkMemoryAllocateInfo-pNext-02390");
3440 vkAllocateMemory(dev, &mai, NULL, &mem_handle);
3441 m_errorMonitor->VerifyFound();
3442 reset_mem();
3443
3444 // Dedicated allocation with incomplete mip chain
3445 reset_img();
3446 ici.mipLevels = 2;
3447 vkCreateImage(dev, &ici, NULL, &img);
3448 mdai.image = img;
3449 ahb_desc.usage = AHARDWAREBUFFER_USAGE_GPU_SAMPLED_IMAGE | AHARDWAREBUFFER_USAGE_GPU_MIPMAP_COMPLETE;
3450 recreate_ahb();
3451
3452 if (ahb) {
3453 mai.allocationSize = ahb_props.allocationSize;
3454 for (int i = 0; i < 32; i++) {
3455 if (ahb_props.memoryTypeBits & (1 << i)) {
3456 mai.memoryTypeIndex = i;
3457 break;
3458 }
3459 }
3460 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkMemoryAllocateInfo-pNext-02389");
3461 vkAllocateMemory(dev, &mai, NULL, &mem_handle);
3462 m_errorMonitor->VerifyFound();
3463 reset_mem();
3464 } else {
3465 // ERROR: AHardwareBuffer_allocate() with MIPMAP_COMPLETE fails. It returns -12, NO_MEMORY.
3466 // The problem seems to happen in Pixel 2, not Pixel 3.
3467 printf("%s AHARDWAREBUFFER_USAGE_GPU_MIPMAP_COMPLETE not supported, skipping tests\n", kSkipPrefix);
3468 }
3469
3470 // Dedicated allocation with mis-matched dimension
3471 ahb_desc.usage = AHARDWAREBUFFER_USAGE_GPU_SAMPLED_IMAGE;
3472 ahb_desc.height = 32;
3473 ahb_desc.width = 128;
3474 recreate_ahb();
3475 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkMemoryAllocateInfo-pNext-02388");
3476 vkAllocateMemory(dev, &mai, NULL, &mem_handle);
3477 m_errorMonitor->VerifyFound();
3478 reset_mem();
3479
3480 // Dedicated allocation with mis-matched VkFormat
3481 ahb_desc.usage = AHARDWAREBUFFER_USAGE_GPU_SAMPLED_IMAGE;
3482 ahb_desc.height = 64;
3483 ahb_desc.width = 64;
3484 recreate_ahb();
3485 ici.mipLevels = 1;
3486 ici.format = VK_FORMAT_B8G8R8A8_UNORM;
3487 ici.pNext = NULL;
3488 VkImage img2;
3489 vkCreateImage(dev, &ici, NULL, &img2);
3490 mdai.image = img2;
3491 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkMemoryAllocateInfo-pNext-02387");
3492 vkAllocateMemory(dev, &mai, NULL, &mem_handle);
3493 m_errorMonitor->VerifyFound();
3494 vkDestroyImage(dev, img2, NULL);
3495 mdai.image = img;
3496 reset_mem();
3497
3498 // Missing required ahb usage
3499 ahb_desc.usage = AHARDWAREBUFFER_USAGE_PROTECTED_CONTENT;
3500 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
3501 "VUID-vkGetAndroidHardwareBufferPropertiesANDROID-buffer-01884");
3502 recreate_ahb();
3503 m_errorMonitor->VerifyFound();
3504
3505 // Dedicated allocation with missing usage bits
3506 // Setting up this test also triggers a slew of others
3507 mai.allocationSize = ahb_props.allocationSize + 1;
3508 mai.memoryTypeIndex = 0;
3509 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkMemoryAllocateInfo-pNext-02390");
3510 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkMemoryAllocateInfo-memoryTypeIndex-02385");
3511 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkMemoryAllocateInfo-allocationSize-02383");
3512 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkMemoryAllocateInfo-pNext-02386");
3513 vkAllocateMemory(dev, &mai, NULL, &mem_handle);
3514 m_errorMonitor->VerifyFound();
3515 reset_mem();
3516
3517 // Non-import allocation - replace import struct in chain with export struct
3518 VkExportMemoryAllocateInfo emai = {};
3519 emai.sType = VK_STRUCTURE_TYPE_EXPORT_MEMORY_ALLOCATE_INFO;
3520 emai.handleTypes = VK_EXTERNAL_MEMORY_HANDLE_TYPE_ANDROID_HARDWARE_BUFFER_BIT_ANDROID;
3521 mai.pNext = &emai;
3522 emai.pNext = &mdai; // still dedicated
3523 mdai.pNext = nullptr;
3524
3525 // Export with allocation size non-zero
3526 ahb_desc.usage = AHARDWAREBUFFER_USAGE_GPU_SAMPLED_IMAGE;
3527 recreate_ahb();
3528 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkMemoryAllocateInfo-pNext-01874");
3529 vkAllocateMemory(dev, &mai, NULL, &mem_handle);
3530 m_errorMonitor->VerifyFound();
3531 reset_mem();
3532
3533 AHardwareBuffer_release(ahb);
3534 reset_mem();
3535 reset_img();
3536 }
3537
TEST_F(VkLayerTest,AndroidHardwareBufferCreateYCbCrSampler)3538 TEST_F(VkLayerTest, AndroidHardwareBufferCreateYCbCrSampler) {
3539 TEST_DESCRIPTION("Verify AndroidHardwareBuffer YCbCr sampler creation.");
3540
3541 SetTargetApiVersion(VK_API_VERSION_1_1);
3542 ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor));
3543
3544 if ((DeviceExtensionSupported(gpu(), nullptr, VK_ANDROID_EXTERNAL_MEMORY_ANDROID_HARDWARE_BUFFER_EXTENSION_NAME)) &&
3545 // Also skip on devices that advertise AHB, but not the pre-requisite foreign_queue extension
3546 (DeviceExtensionSupported(gpu(), nullptr, VK_EXT_QUEUE_FAMILY_FOREIGN_EXTENSION_NAME))) {
3547 m_device_extension_names.push_back(VK_ANDROID_EXTERNAL_MEMORY_ANDROID_HARDWARE_BUFFER_EXTENSION_NAME);
3548 m_device_extension_names.push_back(VK_KHR_SAMPLER_YCBCR_CONVERSION_EXTENSION_NAME);
3549 m_device_extension_names.push_back(VK_KHR_MAINTENANCE1_EXTENSION_NAME);
3550 m_device_extension_names.push_back(VK_KHR_BIND_MEMORY_2_EXTENSION_NAME);
3551 m_device_extension_names.push_back(VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME);
3552 m_device_extension_names.push_back(VK_KHR_EXTERNAL_MEMORY_EXTENSION_NAME);
3553 m_device_extension_names.push_back(VK_EXT_QUEUE_FAMILY_FOREIGN_EXTENSION_NAME);
3554 } else {
3555 printf("%s %s extension not supported, skipping tests\n", kSkipPrefix,
3556 VK_ANDROID_EXTERNAL_MEMORY_ANDROID_HARDWARE_BUFFER_EXTENSION_NAME);
3557 return;
3558 }
3559
3560 ASSERT_NO_FATAL_FAILURE(InitState());
3561 VkDevice dev = m_device->device();
3562
3563 VkSamplerYcbcrConversion ycbcr_conv = VK_NULL_HANDLE;
3564 VkSamplerYcbcrConversionCreateInfo sycci = {};
3565 sycci.sType = VK_STRUCTURE_TYPE_SAMPLER_YCBCR_CONVERSION_CREATE_INFO;
3566 sycci.format = VK_FORMAT_UNDEFINED;
3567 sycci.ycbcrModel = VK_SAMPLER_YCBCR_MODEL_CONVERSION_RGB_IDENTITY;
3568 sycci.ycbcrRange = VK_SAMPLER_YCBCR_RANGE_ITU_FULL;
3569
3570 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkSamplerYcbcrConversionCreateInfo-format-01904");
3571 vkCreateSamplerYcbcrConversion(dev, &sycci, NULL, &ycbcr_conv);
3572 m_errorMonitor->VerifyFound();
3573
3574 VkExternalFormatANDROID efa = {};
3575 efa.sType = VK_STRUCTURE_TYPE_EXTERNAL_FORMAT_ANDROID;
3576 efa.externalFormat = AHARDWAREBUFFER_FORMAT_R8G8B8X8_UNORM;
3577 sycci.format = VK_FORMAT_R8G8B8A8_UNORM;
3578 sycci.pNext = &efa;
3579 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkSamplerYcbcrConversionCreateInfo-format-01904");
3580 vkCreateSamplerYcbcrConversion(dev, &sycci, NULL, &ycbcr_conv);
3581 m_errorMonitor->VerifyFound();
3582 }
3583
TEST_F(VkLayerTest,AndroidHardwareBufferPhysDevImageFormatProp2)3584 TEST_F(VkLayerTest, AndroidHardwareBufferPhysDevImageFormatProp2) {
3585 TEST_DESCRIPTION("Verify AndroidHardwareBuffer GetPhysicalDeviceImageFormatProperties.");
3586
3587 SetTargetApiVersion(VK_API_VERSION_1_1);
3588 ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor));
3589
3590 if ((DeviceExtensionSupported(gpu(), nullptr, VK_ANDROID_EXTERNAL_MEMORY_ANDROID_HARDWARE_BUFFER_EXTENSION_NAME)) &&
3591 // Also skip on devices that advertise AHB, but not the pre-requisite foreign_queue extension
3592 (DeviceExtensionSupported(gpu(), nullptr, VK_EXT_QUEUE_FAMILY_FOREIGN_EXTENSION_NAME))) {
3593 m_device_extension_names.push_back(VK_ANDROID_EXTERNAL_MEMORY_ANDROID_HARDWARE_BUFFER_EXTENSION_NAME);
3594 m_device_extension_names.push_back(VK_KHR_SAMPLER_YCBCR_CONVERSION_EXTENSION_NAME);
3595 m_device_extension_names.push_back(VK_KHR_MAINTENANCE1_EXTENSION_NAME);
3596 m_device_extension_names.push_back(VK_KHR_BIND_MEMORY_2_EXTENSION_NAME);
3597 m_device_extension_names.push_back(VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME);
3598 m_device_extension_names.push_back(VK_KHR_EXTERNAL_MEMORY_EXTENSION_NAME);
3599 m_device_extension_names.push_back(VK_EXT_QUEUE_FAMILY_FOREIGN_EXTENSION_NAME);
3600 } else {
3601 printf("%s %s extension not supported, skipping test\n", kSkipPrefix,
3602 VK_ANDROID_EXTERNAL_MEMORY_ANDROID_HARDWARE_BUFFER_EXTENSION_NAME);
3603 return;
3604 }
3605
3606 ASSERT_NO_FATAL_FAILURE(InitState());
3607
3608 if ((m_instance_api_version < VK_API_VERSION_1_1) &&
3609 !InstanceExtensionEnabled(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME)) {
3610 printf("%s %s extension not supported, skipping test\n", kSkipPrefix,
3611 VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
3612 return;
3613 }
3614
3615 VkImageFormatProperties2 ifp = {};
3616 ifp.sType = VK_STRUCTURE_TYPE_IMAGE_FORMAT_PROPERTIES_2;
3617 VkPhysicalDeviceImageFormatInfo2 pdifi = {};
3618 pdifi.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_FORMAT_INFO_2;
3619 pdifi.format = VK_FORMAT_R8G8B8A8_UNORM;
3620 pdifi.tiling = VK_IMAGE_TILING_OPTIMAL;
3621 pdifi.type = VK_IMAGE_TYPE_2D;
3622 pdifi.usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
3623 VkAndroidHardwareBufferUsageANDROID ahbu = {};
3624 ahbu.sType = VK_STRUCTURE_TYPE_ANDROID_HARDWARE_BUFFER_USAGE_ANDROID;
3625 ahbu.androidHardwareBufferUsage = AHARDWAREBUFFER_USAGE_GPU_SAMPLED_IMAGE;
3626 ifp.pNext = &ahbu;
3627
3628 // AHB_usage chained to input without a matching external image format struc chained to output
3629 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
3630 "VUID-vkGetPhysicalDeviceImageFormatProperties2-pNext-01868");
3631 vkGetPhysicalDeviceImageFormatProperties2(m_device->phy().handle(), &pdifi, &ifp);
3632 m_errorMonitor->VerifyFound();
3633
3634 // output struct chained, but does not include VK_EXTERNAL_MEMORY_HANDLE_TYPE_ANDROID_HARDWARE_BUFFER_BIT_ANDROID usage
3635 VkPhysicalDeviceExternalImageFormatInfo pdeifi = {};
3636 pdeifi.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_IMAGE_FORMAT_INFO;
3637 pdeifi.handleType = VK_EXTERNAL_MEMORY_HANDLE_TYPE_HOST_ALLOCATION_BIT_EXT;
3638 pdifi.pNext = &pdeifi;
3639 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
3640 "VUID-vkGetPhysicalDeviceImageFormatProperties2-pNext-01868");
3641 vkGetPhysicalDeviceImageFormatProperties2(m_device->phy().handle(), &pdifi, &ifp);
3642 m_errorMonitor->VerifyFound();
3643 }
3644
TEST_F(VkLayerTest,AndroidHardwareBufferCreateImageView)3645 TEST_F(VkLayerTest, AndroidHardwareBufferCreateImageView) {
3646 TEST_DESCRIPTION("Verify AndroidHardwareBuffer image view creation.");
3647
3648 SetTargetApiVersion(VK_API_VERSION_1_1);
3649 ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor));
3650
3651 if ((DeviceExtensionSupported(gpu(), nullptr, VK_ANDROID_EXTERNAL_MEMORY_ANDROID_HARDWARE_BUFFER_EXTENSION_NAME)) &&
3652 // Also skip on devices that advertise AHB, but not the pre-requisite foreign_queue extension
3653 (DeviceExtensionSupported(gpu(), nullptr, VK_EXT_QUEUE_FAMILY_FOREIGN_EXTENSION_NAME))) {
3654 m_device_extension_names.push_back(VK_ANDROID_EXTERNAL_MEMORY_ANDROID_HARDWARE_BUFFER_EXTENSION_NAME);
3655 m_device_extension_names.push_back(VK_KHR_SAMPLER_YCBCR_CONVERSION_EXTENSION_NAME);
3656 m_device_extension_names.push_back(VK_KHR_MAINTENANCE1_EXTENSION_NAME);
3657 m_device_extension_names.push_back(VK_KHR_BIND_MEMORY_2_EXTENSION_NAME);
3658 m_device_extension_names.push_back(VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME);
3659 m_device_extension_names.push_back(VK_KHR_EXTERNAL_MEMORY_EXTENSION_NAME);
3660 m_device_extension_names.push_back(VK_EXT_QUEUE_FAMILY_FOREIGN_EXTENSION_NAME);
3661 } else {
3662 printf("%s %s extension not supported, skipping tests\n", kSkipPrefix,
3663 VK_ANDROID_EXTERNAL_MEMORY_ANDROID_HARDWARE_BUFFER_EXTENSION_NAME);
3664 return;
3665 }
3666
3667 ASSERT_NO_FATAL_FAILURE(InitState());
3668 VkDevice dev = m_device->device();
3669
3670 // Allocate an AHB and fetch its properties
3671 AHardwareBuffer *ahb = nullptr;
3672 AHardwareBuffer_Desc ahb_desc = {};
3673 ahb_desc.format = AHARDWAREBUFFER_FORMAT_R5G6B5_UNORM;
3674 ahb_desc.usage = AHARDWAREBUFFER_USAGE_GPU_SAMPLED_IMAGE;
3675 ahb_desc.width = 64;
3676 ahb_desc.height = 64;
3677 ahb_desc.layers = 1;
3678 AHardwareBuffer_allocate(&ahb_desc, &ahb);
3679
3680 // Retrieve AHB properties to make it's external format 'known'
3681 VkAndroidHardwareBufferFormatPropertiesANDROID ahb_fmt_props = {};
3682 ahb_fmt_props.sType = VK_STRUCTURE_TYPE_ANDROID_HARDWARE_BUFFER_FORMAT_PROPERTIES_ANDROID;
3683 VkAndroidHardwareBufferPropertiesANDROID ahb_props = {};
3684 ahb_props.sType = VK_STRUCTURE_TYPE_ANDROID_HARDWARE_BUFFER_PROPERTIES_ANDROID;
3685 ahb_props.pNext = &ahb_fmt_props;
3686 PFN_vkGetAndroidHardwareBufferPropertiesANDROID pfn_GetAHBProps =
3687 (PFN_vkGetAndroidHardwareBufferPropertiesANDROID)vkGetDeviceProcAddr(dev, "vkGetAndroidHardwareBufferPropertiesANDROID");
3688 ASSERT_TRUE(pfn_GetAHBProps != nullptr);
3689 pfn_GetAHBProps(dev, ahb, &ahb_props);
3690 AHardwareBuffer_release(ahb);
3691
3692 // Give image an external format
3693 VkExternalFormatANDROID efa = {};
3694 efa.sType = VK_STRUCTURE_TYPE_EXTERNAL_FORMAT_ANDROID;
3695 efa.externalFormat = ahb_fmt_props.externalFormat;
3696
3697 ahb_desc.format = AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM;
3698 ahb_desc.usage = AHARDWAREBUFFER_USAGE_GPU_SAMPLED_IMAGE;
3699 ahb_desc.width = 64;
3700 ahb_desc.height = 1;
3701 ahb_desc.layers = 1;
3702 AHardwareBuffer_allocate(&ahb_desc, &ahb);
3703
3704 // Create another VkExternalFormatANDROID for test VUID-VkImageViewCreateInfo-image-02400
3705 VkAndroidHardwareBufferFormatPropertiesANDROID ahb_fmt_props_Ycbcr = {};
3706 ahb_fmt_props_Ycbcr.sType = VK_STRUCTURE_TYPE_ANDROID_HARDWARE_BUFFER_FORMAT_PROPERTIES_ANDROID;
3707 VkAndroidHardwareBufferPropertiesANDROID ahb_props_Ycbcr = {};
3708 ahb_props_Ycbcr.sType = VK_STRUCTURE_TYPE_ANDROID_HARDWARE_BUFFER_PROPERTIES_ANDROID;
3709 ahb_props_Ycbcr.pNext = &ahb_fmt_props_Ycbcr;
3710 pfn_GetAHBProps(dev, ahb, &ahb_props_Ycbcr);
3711 AHardwareBuffer_release(ahb);
3712
3713 VkExternalFormatANDROID efa_Ycbcr = {};
3714 efa_Ycbcr.sType = VK_STRUCTURE_TYPE_EXTERNAL_FORMAT_ANDROID;
3715 efa_Ycbcr.externalFormat = ahb_fmt_props_Ycbcr.externalFormat;
3716
3717 // Create the image
3718 VkImage img = VK_NULL_HANDLE;
3719 VkImageCreateInfo ici = {};
3720 ici.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
3721 ici.pNext = &efa;
3722 ici.imageType = VK_IMAGE_TYPE_2D;
3723 ici.arrayLayers = 1;
3724 ici.extent = {64, 64, 1};
3725 ici.format = VK_FORMAT_UNDEFINED;
3726 ici.mipLevels = 1;
3727 ici.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
3728 ici.samples = VK_SAMPLE_COUNT_1_BIT;
3729 ici.tiling = VK_IMAGE_TILING_OPTIMAL;
3730 ici.usage = VK_IMAGE_USAGE_SAMPLED_BIT;
3731 vkCreateImage(dev, &ici, NULL, &img);
3732
3733 // Set up memory allocation
3734 VkDeviceMemory img_mem = VK_NULL_HANDLE;
3735 VkMemoryAllocateInfo mai = {};
3736 mai.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
3737 mai.allocationSize = 64 * 64 * 4;
3738 mai.memoryTypeIndex = 0;
3739 vkAllocateMemory(dev, &mai, NULL, &img_mem);
3740
3741 // It shouldn't use vkGetImageMemoryRequirements for AndroidHardwareBuffer.
3742 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "UNASSIGNED-CoreValidation-DrawState-InvalidImage");
3743 VkMemoryRequirements img_mem_reqs = {};
3744 vkGetImageMemoryRequirements(m_device->device(), img, &img_mem_reqs);
3745 vkBindImageMemory(dev, img, img_mem, 0);
3746 m_errorMonitor->VerifyFound();
3747
3748 // Bind image to memory
3749 vkDestroyImage(dev, img, NULL);
3750 vkFreeMemory(dev, img_mem, NULL);
3751 vkCreateImage(dev, &ici, NULL, &img);
3752 vkAllocateMemory(dev, &mai, NULL, &img_mem);
3753 vkBindImageMemory(dev, img, img_mem, 0);
3754
3755 // Create a YCbCr conversion, with different external format, chain to view
3756 VkSamplerYcbcrConversion ycbcr_conv = VK_NULL_HANDLE;
3757 VkSamplerYcbcrConversionCreateInfo sycci = {};
3758 sycci.sType = VK_STRUCTURE_TYPE_SAMPLER_YCBCR_CONVERSION_CREATE_INFO;
3759 sycci.pNext = &efa_Ycbcr;
3760 sycci.format = VK_FORMAT_UNDEFINED;
3761 sycci.ycbcrModel = VK_SAMPLER_YCBCR_MODEL_CONVERSION_RGB_IDENTITY;
3762 sycci.ycbcrRange = VK_SAMPLER_YCBCR_RANGE_ITU_FULL;
3763 vkCreateSamplerYcbcrConversion(dev, &sycci, NULL, &ycbcr_conv);
3764 VkSamplerYcbcrConversionInfo syci = {};
3765 syci.sType = VK_STRUCTURE_TYPE_SAMPLER_YCBCR_CONVERSION_INFO;
3766 syci.conversion = ycbcr_conv;
3767
3768 // Create a view
3769 VkImageView image_view = VK_NULL_HANDLE;
3770 VkImageViewCreateInfo ivci = {};
3771 ivci.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
3772 ivci.pNext = &syci;
3773 ivci.image = img;
3774 ivci.viewType = VK_IMAGE_VIEW_TYPE_2D;
3775 ivci.format = VK_FORMAT_UNDEFINED;
3776 ivci.subresourceRange = {VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1};
3777
3778 auto reset_view = [&image_view, dev]() {
3779 if (VK_NULL_HANDLE != image_view) vkDestroyImageView(dev, image_view, NULL);
3780 image_view = VK_NULL_HANDLE;
3781 };
3782
3783 // Up to this point, no errors expected
3784 m_errorMonitor->VerifyNotFound();
3785
3786 // Chained ycbcr conversion has different (external) format than image
3787 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkImageViewCreateInfo-image-02400");
3788 // Also causes "unsupported format" - should be removed in future spec update
3789 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkImageViewCreateInfo-None-02273");
3790 vkCreateImageView(dev, &ivci, NULL, &image_view);
3791 m_errorMonitor->VerifyFound();
3792
3793 reset_view();
3794 vkDestroySamplerYcbcrConversion(dev, ycbcr_conv, NULL);
3795 sycci.pNext = &efa;
3796 vkCreateSamplerYcbcrConversion(dev, &sycci, NULL, &ycbcr_conv);
3797 syci.conversion = ycbcr_conv;
3798
3799 // View component swizzle not IDENTITY
3800 ivci.components.r = VK_COMPONENT_SWIZZLE_B;
3801 ivci.components.b = VK_COMPONENT_SWIZZLE_R;
3802 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkImageViewCreateInfo-image-02401");
3803 // Also causes "unsupported format" - should be removed in future spec update
3804 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkImageViewCreateInfo-None-02273");
3805 vkCreateImageView(dev, &ivci, NULL, &image_view);
3806 m_errorMonitor->VerifyFound();
3807
3808 reset_view();
3809 ivci.components.r = VK_COMPONENT_SWIZZLE_IDENTITY;
3810 ivci.components.b = VK_COMPONENT_SWIZZLE_IDENTITY;
3811
3812 // View with external format, when format is not UNDEFINED
3813 ivci.format = VK_FORMAT_R5G6B5_UNORM_PACK16;
3814 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkImageViewCreateInfo-image-02399");
3815 // Also causes "view format different from image format"
3816 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkImageViewCreateInfo-image-01019");
3817 vkCreateImageView(dev, &ivci, NULL, &image_view);
3818 m_errorMonitor->VerifyFound();
3819
3820 reset_view();
3821 vkDestroySamplerYcbcrConversion(dev, ycbcr_conv, NULL);
3822 vkDestroyImageView(dev, image_view, NULL);
3823 vkDestroyImage(dev, img, NULL);
3824 vkFreeMemory(dev, img_mem, NULL);
3825 }
3826
TEST_F(VkLayerTest,AndroidHardwareBufferImportBuffer)3827 TEST_F(VkLayerTest, AndroidHardwareBufferImportBuffer) {
3828 TEST_DESCRIPTION("Verify AndroidHardwareBuffer import as buffer.");
3829
3830 SetTargetApiVersion(VK_API_VERSION_1_1);
3831 ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor));
3832
3833 if ((DeviceExtensionSupported(gpu(), nullptr, VK_ANDROID_EXTERNAL_MEMORY_ANDROID_HARDWARE_BUFFER_EXTENSION_NAME)) &&
3834 // Also skip on devices that advertise AHB, but not the pre-requisite foreign_queue extension
3835 (DeviceExtensionSupported(gpu(), nullptr, VK_EXT_QUEUE_FAMILY_FOREIGN_EXTENSION_NAME))) {
3836 m_device_extension_names.push_back(VK_ANDROID_EXTERNAL_MEMORY_ANDROID_HARDWARE_BUFFER_EXTENSION_NAME);
3837 m_device_extension_names.push_back(VK_KHR_SAMPLER_YCBCR_CONVERSION_EXTENSION_NAME);
3838 m_device_extension_names.push_back(VK_KHR_MAINTENANCE1_EXTENSION_NAME);
3839 m_device_extension_names.push_back(VK_KHR_BIND_MEMORY_2_EXTENSION_NAME);
3840 m_device_extension_names.push_back(VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME);
3841 m_device_extension_names.push_back(VK_KHR_EXTERNAL_MEMORY_EXTENSION_NAME);
3842 m_device_extension_names.push_back(VK_EXT_QUEUE_FAMILY_FOREIGN_EXTENSION_NAME);
3843 } else {
3844 printf("%s %s extension not supported, skipping tests\n", kSkipPrefix,
3845 VK_ANDROID_EXTERNAL_MEMORY_ANDROID_HARDWARE_BUFFER_EXTENSION_NAME);
3846 return;
3847 }
3848
3849 ASSERT_NO_FATAL_FAILURE(InitState());
3850 VkDevice dev = m_device->device();
3851
3852 VkDeviceMemory mem_handle = VK_NULL_HANDLE;
3853 auto reset_mem = [&mem_handle, dev]() {
3854 if (VK_NULL_HANDLE != mem_handle) vkFreeMemory(dev, mem_handle, NULL);
3855 mem_handle = VK_NULL_HANDLE;
3856 };
3857
3858 PFN_vkGetAndroidHardwareBufferPropertiesANDROID pfn_GetAHBProps =
3859 (PFN_vkGetAndroidHardwareBufferPropertiesANDROID)vkGetDeviceProcAddr(dev, "vkGetAndroidHardwareBufferPropertiesANDROID");
3860 ASSERT_TRUE(pfn_GetAHBProps != nullptr);
3861
3862 // AHB structs
3863 AHardwareBuffer *ahb = nullptr;
3864 AHardwareBuffer_Desc ahb_desc = {};
3865 VkAndroidHardwareBufferPropertiesANDROID ahb_props = {};
3866 ahb_props.sType = VK_STRUCTURE_TYPE_ANDROID_HARDWARE_BUFFER_PROPERTIES_ANDROID;
3867 VkImportAndroidHardwareBufferInfoANDROID iahbi = {};
3868 iahbi.sType = VK_STRUCTURE_TYPE_IMPORT_ANDROID_HARDWARE_BUFFER_INFO_ANDROID;
3869
3870 // Allocate an AHardwareBuffer
3871 ahb_desc.format = AHARDWAREBUFFER_FORMAT_BLOB;
3872 ahb_desc.usage = AHARDWAREBUFFER_USAGE_SENSOR_DIRECT_DATA;
3873 ahb_desc.width = 512;
3874 ahb_desc.height = 1;
3875 ahb_desc.layers = 1;
3876 AHardwareBuffer_allocate(&ahb_desc, &ahb);
3877 m_errorMonitor->SetUnexpectedError("VUID-vkGetAndroidHardwareBufferPropertiesANDROID-buffer-01884");
3878 pfn_GetAHBProps(dev, ahb, &ahb_props);
3879 iahbi.buffer = ahb;
3880
3881 // Create export and import buffers
3882 VkExternalMemoryBufferCreateInfo ext_buf_info = {};
3883 ext_buf_info.sType = VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_BUFFER_CREATE_INFO_KHR;
3884 ext_buf_info.handleTypes = VK_EXTERNAL_MEMORY_HANDLE_TYPE_HOST_ALLOCATION_BIT_EXT;
3885
3886 VkBufferCreateInfo bci = {};
3887 bci.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
3888 bci.pNext = &ext_buf_info;
3889 bci.size = ahb_props.allocationSize;
3890 bci.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT;
3891
3892 VkBuffer buf = VK_NULL_HANDLE;
3893 vkCreateBuffer(dev, &bci, NULL, &buf);
3894 VkMemoryRequirements mem_reqs;
3895 vkGetBufferMemoryRequirements(dev, buf, &mem_reqs);
3896
3897 // Allocation info
3898 VkMemoryAllocateInfo mai = vk_testing::DeviceMemory::get_resource_alloc_info(*m_device, mem_reqs, 0);
3899 mai.pNext = &iahbi; // Chained import struct
3900 VkPhysicalDeviceMemoryProperties memory_info;
3901 vkGetPhysicalDeviceMemoryProperties(gpu(), &memory_info);
3902 unsigned int i;
3903 for (i = 0; i < memory_info.memoryTypeCount; i++) {
3904 if ((ahb_props.memoryTypeBits & (1 << i))) {
3905 mai.memoryTypeIndex = i;
3906 break;
3907 }
3908 }
3909 if (i >= memory_info.memoryTypeCount) {
3910 printf("%s No invalid memory type index could be found; skipped.\n", kSkipPrefix);
3911 AHardwareBuffer_release(ahb);
3912 reset_mem();
3913 vkDestroyBuffer(dev, buf, NULL);
3914 return;
3915 }
3916
3917 // Import as buffer requires format AHB_FMT_BLOB and usage AHB_USAGE_GPU_DATA_BUFFER
3918 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
3919 "VUID-VkImportAndroidHardwareBufferInfoANDROID-buffer-01881");
3920 // Also causes "non-dedicated allocation format/usage" error
3921 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkMemoryAllocateInfo-pNext-02384");
3922 vkAllocateMemory(dev, &mai, NULL, &mem_handle);
3923 m_errorMonitor->VerifyFound();
3924
3925 AHardwareBuffer_release(ahb);
3926 reset_mem();
3927 vkDestroyBuffer(dev, buf, NULL);
3928 }
3929
TEST_F(VkLayerTest,AndroidHardwareBufferExporttBuffer)3930 TEST_F(VkLayerTest, AndroidHardwareBufferExporttBuffer) {
3931 TEST_DESCRIPTION("Verify AndroidHardwareBuffer export memory as AHB.");
3932
3933 SetTargetApiVersion(VK_API_VERSION_1_1);
3934 ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor));
3935
3936 if ((DeviceExtensionSupported(gpu(), nullptr, VK_ANDROID_EXTERNAL_MEMORY_ANDROID_HARDWARE_BUFFER_EXTENSION_NAME)) &&
3937 // Also skip on devices that advertise AHB, but not the pre-requisite foreign_queue extension
3938 (DeviceExtensionSupported(gpu(), nullptr, VK_EXT_QUEUE_FAMILY_FOREIGN_EXTENSION_NAME))) {
3939 m_device_extension_names.push_back(VK_ANDROID_EXTERNAL_MEMORY_ANDROID_HARDWARE_BUFFER_EXTENSION_NAME);
3940 m_device_extension_names.push_back(VK_KHR_SAMPLER_YCBCR_CONVERSION_EXTENSION_NAME);
3941 m_device_extension_names.push_back(VK_KHR_MAINTENANCE1_EXTENSION_NAME);
3942 m_device_extension_names.push_back(VK_KHR_BIND_MEMORY_2_EXTENSION_NAME);
3943 m_device_extension_names.push_back(VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME);
3944 m_device_extension_names.push_back(VK_KHR_EXTERNAL_MEMORY_EXTENSION_NAME);
3945 m_device_extension_names.push_back(VK_EXT_QUEUE_FAMILY_FOREIGN_EXTENSION_NAME);
3946 } else {
3947 printf("%s %s extension not supported, skipping tests\n", kSkipPrefix,
3948 VK_ANDROID_EXTERNAL_MEMORY_ANDROID_HARDWARE_BUFFER_EXTENSION_NAME);
3949 return;
3950 }
3951
3952 ASSERT_NO_FATAL_FAILURE(InitState());
3953 VkDevice dev = m_device->device();
3954
3955 VkDeviceMemory mem_handle = VK_NULL_HANDLE;
3956
3957 // Allocate device memory, no linked export struct indicating AHB handle type
3958 VkMemoryAllocateInfo mai = {};
3959 mai.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
3960 mai.allocationSize = 65536;
3961 mai.memoryTypeIndex = 0;
3962 vkAllocateMemory(dev, &mai, NULL, &mem_handle);
3963
3964 PFN_vkGetMemoryAndroidHardwareBufferANDROID pfn_GetMemAHB =
3965 (PFN_vkGetMemoryAndroidHardwareBufferANDROID)vkGetDeviceProcAddr(dev, "vkGetMemoryAndroidHardwareBufferANDROID");
3966 ASSERT_TRUE(pfn_GetMemAHB != nullptr);
3967
3968 VkMemoryGetAndroidHardwareBufferInfoANDROID mgahbi = {};
3969 mgahbi.sType = VK_STRUCTURE_TYPE_MEMORY_GET_ANDROID_HARDWARE_BUFFER_INFO_ANDROID;
3970 mgahbi.memory = mem_handle;
3971 AHardwareBuffer *ahb = nullptr;
3972 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
3973 "VUID-VkMemoryGetAndroidHardwareBufferInfoANDROID-handleTypes-01882");
3974 pfn_GetMemAHB(dev, &mgahbi, &ahb);
3975 m_errorMonitor->VerifyFound();
3976
3977 if (ahb) AHardwareBuffer_release(ahb);
3978 ahb = nullptr;
3979 if (VK_NULL_HANDLE != mem_handle) vkFreeMemory(dev, mem_handle, NULL);
3980 mem_handle = VK_NULL_HANDLE;
3981
3982 // Add an export struct with AHB handle type to allocation info
3983 VkExportMemoryAllocateInfo emai = {};
3984 emai.sType = VK_STRUCTURE_TYPE_EXPORT_MEMORY_ALLOCATE_INFO;
3985 emai.handleTypes = VK_EXTERNAL_MEMORY_HANDLE_TYPE_ANDROID_HARDWARE_BUFFER_BIT_ANDROID;
3986 mai.pNext = &emai;
3987
3988 // Create an image, do not bind memory
3989 VkImage img = VK_NULL_HANDLE;
3990 VkImageCreateInfo ici = {};
3991 ici.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
3992 ici.imageType = VK_IMAGE_TYPE_2D;
3993 ici.arrayLayers = 1;
3994 ici.extent = {128, 128, 1};
3995 ici.format = VK_FORMAT_R8G8B8A8_UNORM;
3996 ici.mipLevels = 1;
3997 ici.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
3998 ici.samples = VK_SAMPLE_COUNT_1_BIT;
3999 ici.tiling = VK_IMAGE_TILING_OPTIMAL;
4000 ici.usage = VK_IMAGE_USAGE_SAMPLED_BIT;
4001 vkCreateImage(dev, &ici, NULL, &img);
4002 ASSERT_TRUE(VK_NULL_HANDLE != img);
4003
4004 // Add image to allocation chain as dedicated info, re-allocate
4005 VkMemoryDedicatedAllocateInfo mdai = {VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO};
4006 mdai.image = img;
4007 emai.pNext = &mdai;
4008 mai.allocationSize = 0;
4009 vkAllocateMemory(dev, &mai, NULL, &mem_handle);
4010 mgahbi.memory = mem_handle;
4011
4012 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
4013 "VUID-VkMemoryGetAndroidHardwareBufferInfoANDROID-pNext-01883");
4014 pfn_GetMemAHB(dev, &mgahbi, &ahb);
4015 m_errorMonitor->VerifyFound();
4016
4017 if (ahb) AHardwareBuffer_release(ahb);
4018 if (VK_NULL_HANDLE != mem_handle) vkFreeMemory(dev, mem_handle, NULL);
4019 vkDestroyImage(dev, img, NULL);
4020 }
4021
4022 #endif // VK_USE_PLATFORM_ANDROID_KHR
4023
TEST_F(VkLayerTest,ValidateStride)4024 TEST_F(VkLayerTest, ValidateStride) {
4025 TEST_DESCRIPTION("Validate Stride.");
4026 ASSERT_NO_FATAL_FAILURE(Init(nullptr, nullptr, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT));
4027 ASSERT_NO_FATAL_FAILURE(InitViewport());
4028 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
4029
4030 VkQueryPool query_pool;
4031 VkQueryPoolCreateInfo query_pool_ci{};
4032 query_pool_ci.sType = VK_STRUCTURE_TYPE_QUERY_POOL_CREATE_INFO;
4033 query_pool_ci.queryType = VK_QUERY_TYPE_TIMESTAMP;
4034 query_pool_ci.queryCount = 1;
4035 vkCreateQueryPool(m_device->device(), &query_pool_ci, nullptr, &query_pool);
4036
4037 m_commandBuffer->begin();
4038 vkCmdResetQueryPool(m_commandBuffer->handle(), query_pool, 0, 1);
4039 vkCmdWriteTimestamp(m_commandBuffer->handle(), VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, query_pool, 0);
4040 m_commandBuffer->end();
4041
4042 VkSubmitInfo submit_info = {};
4043 submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
4044 submit_info.commandBufferCount = 1;
4045 submit_info.pCommandBuffers = &m_commandBuffer->handle();
4046 vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
4047 vkQueueWaitIdle(m_device->m_queue);
4048
4049 char data_space;
4050 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkGetQueryPoolResults-flags-00814");
4051 vkGetQueryPoolResults(m_device->handle(), query_pool, 0, 1, sizeof(data_space), &data_space, 1, VK_QUERY_RESULT_WAIT_BIT);
4052 m_errorMonitor->VerifyFound();
4053
4054 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkGetQueryPoolResults-flags-00815");
4055 vkGetQueryPoolResults(m_device->handle(), query_pool, 0, 1, sizeof(data_space), &data_space, 1,
4056 (VK_QUERY_RESULT_WAIT_BIT | VK_QUERY_RESULT_64_BIT));
4057 m_errorMonitor->VerifyFound();
4058
4059 char data_space4[4] = "";
4060 m_errorMonitor->ExpectSuccess();
4061 vkGetQueryPoolResults(m_device->handle(), query_pool, 0, 1, sizeof(data_space4), &data_space4, 4, VK_QUERY_RESULT_WAIT_BIT);
4062 m_errorMonitor->VerifyNotFound();
4063
4064 char data_space8[8] = "";
4065 m_errorMonitor->ExpectSuccess();
4066 vkGetQueryPoolResults(m_device->handle(), query_pool, 0, 1, sizeof(data_space8), &data_space8, 8,
4067 (VK_QUERY_RESULT_WAIT_BIT | VK_QUERY_RESULT_64_BIT));
4068 m_errorMonitor->VerifyNotFound();
4069
4070 uint32_t qfi = 0;
4071 VkBufferCreateInfo buff_create_info = {};
4072 buff_create_info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
4073 buff_create_info.size = 128;
4074 buff_create_info.usage =
4075 VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT | VK_BUFFER_USAGE_INDEX_BUFFER_BIT;
4076 buff_create_info.queueFamilyIndexCount = 1;
4077 buff_create_info.pQueueFamilyIndices = &qfi;
4078 VkBufferObj buffer;
4079 buffer.init(*m_device, buff_create_info);
4080
4081 m_commandBuffer->reset();
4082 m_commandBuffer->begin();
4083 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdCopyQueryPoolResults-flags-00822");
4084 vkCmdCopyQueryPoolResults(m_commandBuffer->handle(), query_pool, 0, 1, buffer.handle(), 1, 1, 0);
4085 m_errorMonitor->VerifyFound();
4086
4087 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdCopyQueryPoolResults-flags-00823");
4088 vkCmdCopyQueryPoolResults(m_commandBuffer->handle(), query_pool, 0, 1, buffer.handle(), 1, 1, VK_QUERY_RESULT_64_BIT);
4089 m_errorMonitor->VerifyFound();
4090
4091 m_errorMonitor->ExpectSuccess();
4092 vkCmdCopyQueryPoolResults(m_commandBuffer->handle(), query_pool, 0, 1, buffer.handle(), 4, 4, 0);
4093 m_errorMonitor->VerifyNotFound();
4094
4095 m_errorMonitor->ExpectSuccess();
4096 vkCmdCopyQueryPoolResults(m_commandBuffer->handle(), query_pool, 0, 1, buffer.handle(), 8, 8, VK_QUERY_RESULT_64_BIT);
4097 m_errorMonitor->VerifyNotFound();
4098
4099 if (m_device->phy().features().multiDrawIndirect) {
4100 CreatePipelineHelper helper(*this);
4101 helper.InitInfo();
4102 helper.InitState();
4103 helper.CreateGraphicsPipeline();
4104 m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
4105 vkCmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, helper.pipeline_);
4106
4107 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdDrawIndirect-drawCount-00476");
4108 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdDrawIndirect-drawCount-00488");
4109 vkCmdDrawIndirect(m_commandBuffer->handle(), buffer.handle(), 0, 100, 2);
4110 m_errorMonitor->VerifyFound();
4111
4112 m_errorMonitor->ExpectSuccess();
4113 vkCmdDrawIndirect(m_commandBuffer->handle(), buffer.handle(), 0, 2, 24);
4114 m_errorMonitor->VerifyNotFound();
4115
4116 vkCmdBindIndexBuffer(m_commandBuffer->handle(), buffer.handle(), 0, VK_INDEX_TYPE_UINT16);
4117 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdDrawIndexedIndirect-drawCount-00528");
4118 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdDrawIndexedIndirect-drawCount-00540");
4119 vkCmdDrawIndexedIndirect(m_commandBuffer->handle(), buffer.handle(), 0, 100, 2);
4120 m_errorMonitor->VerifyFound();
4121
4122 m_errorMonitor->ExpectSuccess();
4123 vkCmdDrawIndexedIndirect(m_commandBuffer->handle(), buffer.handle(), 0, 2, 24);
4124 m_errorMonitor->VerifyNotFound();
4125
4126 vkCmdEndRenderPass(m_commandBuffer->handle());
4127 m_commandBuffer->end();
4128
4129 } else {
4130 printf("%s Test requires unsupported multiDrawIndirect feature. Skipped.\n", kSkipPrefix);
4131 }
4132 vkDestroyQueryPool(m_device->handle(), query_pool, NULL);
4133 }
4134
TEST_F(VkLayerTest,WarningSwapchainCreateInfoPreTransform)4135 TEST_F(VkLayerTest, WarningSwapchainCreateInfoPreTransform) {
4136 TEST_DESCRIPTION("Print warning when preTransform doesn't match curretTransform");
4137
4138 if (!AddSurfaceInstanceExtension()) {
4139 printf("%s surface extensions not supported, skipping test\n", kSkipPrefix);
4140 return;
4141 }
4142
4143 ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor));
4144
4145 if (!AddSwapchainDeviceExtension()) {
4146 printf("%s swapchain extensions not supported, skipping test\n", kSkipPrefix);
4147 return;
4148 }
4149
4150 ASSERT_NO_FATAL_FAILURE(InitState());
4151 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
4152
4153 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT,
4154 "UNASSIGNED-CoreValidation-SwapchainPreTransform");
4155 m_errorMonitor->SetUnexpectedError("VUID-VkSwapchainCreateInfoKHR-preTransform-01279");
4156 InitSwapchain(VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, VK_SURFACE_TRANSFORM_INHERIT_BIT_KHR);
4157 m_errorMonitor->VerifyFound();
4158 }
4159
InitFrameworkForRayTracingTest(VkRenderFramework * renderFramework,std::vector<const char * > & instance_extension_names,std::vector<const char * > & device_extension_names,void * user_data)4160 bool InitFrameworkForRayTracingTest(VkRenderFramework *renderFramework, std::vector<const char *> &instance_extension_names,
4161 std::vector<const char *> &device_extension_names, void *user_data) {
4162 const std::array<const char *, 1> required_instance_extensions = {VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME};
4163 for (const char *required_instance_extension : required_instance_extensions) {
4164 if (renderFramework->InstanceExtensionSupported(required_instance_extension)) {
4165 instance_extension_names.push_back(required_instance_extension);
4166 } else {
4167 printf("%s %s instance extension not supported, skipping test\n", kSkipPrefix, required_instance_extension);
4168 return false;
4169 }
4170 }
4171 renderFramework->InitFramework(myDbgFunc, user_data);
4172
4173 if (renderFramework->DeviceIsMockICD() || renderFramework->DeviceSimulation()) {
4174 printf("%s Test not supported by MockICD, skipping tests\n", kSkipPrefix);
4175 return false;
4176 }
4177
4178 const std::array<const char *, 2> required_device_extensions = {
4179 VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME,
4180 VK_NV_RAY_TRACING_EXTENSION_NAME,
4181 };
4182 for (const char *required_device_extension : required_device_extensions) {
4183 if (renderFramework->DeviceExtensionSupported(renderFramework->gpu(), nullptr, required_device_extension)) {
4184 device_extension_names.push_back(required_device_extension);
4185 } else {
4186 printf("%s %s device extension not supported, skipping test\n", kSkipPrefix, required_device_extension);
4187 return false;
4188 }
4189 }
4190 renderFramework->InitState();
4191 return true;
4192 }
4193
TEST_F(VkLayerTest,ValidateGeometryNV)4194 TEST_F(VkLayerTest, ValidateGeometryNV) {
4195 TEST_DESCRIPTION("Validate acceleration structure geometries.");
4196 if (!InitFrameworkForRayTracingTest(this, m_instance_extension_names, m_device_extension_names, m_errorMonitor)) {
4197 return;
4198 }
4199
4200 VkBufferObj vbo;
4201 vbo.init(*m_device, 1024, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT,
4202 VK_BUFFER_USAGE_RAY_TRACING_BIT_NV);
4203
4204 VkBufferObj ibo;
4205 ibo.init(*m_device, 1024, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT,
4206 VK_BUFFER_USAGE_RAY_TRACING_BIT_NV);
4207
4208 VkBufferObj tbo;
4209 tbo.init(*m_device, 1024, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT,
4210 VK_BUFFER_USAGE_RAY_TRACING_BIT_NV);
4211
4212 VkBufferObj aabbbo;
4213 aabbbo.init(*m_device, 1024, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT,
4214 VK_BUFFER_USAGE_RAY_TRACING_BIT_NV);
4215
4216 VkBufferCreateInfo unbound_buffer_ci = {};
4217 unbound_buffer_ci.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
4218 unbound_buffer_ci.size = 1024;
4219 unbound_buffer_ci.usage = VK_BUFFER_USAGE_RAY_TRACING_BIT_NV;
4220 VkBufferObj unbound_buffer;
4221 unbound_buffer.init_no_mem(*m_device, unbound_buffer_ci);
4222
4223 const std::vector<float> vertices = {1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, -1.0f, 0.0f, 0.0f};
4224 const std::vector<uint32_t> indicies = {0, 1, 2};
4225 const std::vector<float> aabbs = {0.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f};
4226 const std::vector<float> transforms = {1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f};
4227
4228 uint8_t *mapped_vbo_buffer_data = (uint8_t *)vbo.memory().map();
4229 std::memcpy(mapped_vbo_buffer_data, (uint8_t *)vertices.data(), sizeof(float) * vertices.size());
4230 vbo.memory().unmap();
4231
4232 uint8_t *mapped_ibo_buffer_data = (uint8_t *)ibo.memory().map();
4233 std::memcpy(mapped_ibo_buffer_data, (uint8_t *)indicies.data(), sizeof(uint32_t) * indicies.size());
4234 ibo.memory().unmap();
4235
4236 uint8_t *mapped_tbo_buffer_data = (uint8_t *)tbo.memory().map();
4237 std::memcpy(mapped_tbo_buffer_data, (uint8_t *)transforms.data(), sizeof(float) * transforms.size());
4238 tbo.memory().unmap();
4239
4240 uint8_t *mapped_aabbbo_buffer_data = (uint8_t *)aabbbo.memory().map();
4241 std::memcpy(mapped_aabbbo_buffer_data, (uint8_t *)aabbs.data(), sizeof(float) * aabbs.size());
4242 aabbbo.memory().unmap();
4243
4244 VkGeometryNV valid_geometry_triangles = {};
4245 valid_geometry_triangles.sType = VK_STRUCTURE_TYPE_GEOMETRY_NV;
4246 valid_geometry_triangles.geometryType = VK_GEOMETRY_TYPE_TRIANGLES_NV;
4247 valid_geometry_triangles.geometry.triangles.sType = VK_STRUCTURE_TYPE_GEOMETRY_TRIANGLES_NV;
4248 valid_geometry_triangles.geometry.triangles.vertexData = vbo.handle();
4249 valid_geometry_triangles.geometry.triangles.vertexOffset = 0;
4250 valid_geometry_triangles.geometry.triangles.vertexCount = 3;
4251 valid_geometry_triangles.geometry.triangles.vertexStride = 12;
4252 valid_geometry_triangles.geometry.triangles.vertexFormat = VK_FORMAT_R32G32B32_SFLOAT;
4253 valid_geometry_triangles.geometry.triangles.indexData = ibo.handle();
4254 valid_geometry_triangles.geometry.triangles.indexOffset = 0;
4255 valid_geometry_triangles.geometry.triangles.indexCount = 3;
4256 valid_geometry_triangles.geometry.triangles.indexType = VK_INDEX_TYPE_UINT32;
4257 valid_geometry_triangles.geometry.triangles.transformData = tbo.handle();
4258 valid_geometry_triangles.geometry.triangles.transformOffset = 0;
4259 valid_geometry_triangles.geometry.aabbs = {};
4260 valid_geometry_triangles.geometry.aabbs.sType = VK_STRUCTURE_TYPE_GEOMETRY_AABB_NV;
4261
4262 VkGeometryNV valid_geometry_aabbs = {};
4263 valid_geometry_aabbs.sType = VK_STRUCTURE_TYPE_GEOMETRY_NV;
4264 valid_geometry_aabbs.geometryType = VK_GEOMETRY_TYPE_AABBS_NV;
4265 valid_geometry_aabbs.geometry.triangles = {};
4266 valid_geometry_aabbs.geometry.triangles.sType = VK_STRUCTURE_TYPE_GEOMETRY_TRIANGLES_NV;
4267 valid_geometry_aabbs.geometry.aabbs = {};
4268 valid_geometry_aabbs.geometry.aabbs.sType = VK_STRUCTURE_TYPE_GEOMETRY_AABB_NV;
4269 valid_geometry_aabbs.geometry.aabbs.aabbData = aabbbo.handle();
4270 valid_geometry_aabbs.geometry.aabbs.numAABBs = 1;
4271 valid_geometry_aabbs.geometry.aabbs.offset = 0;
4272 valid_geometry_aabbs.geometry.aabbs.stride = 24;
4273
4274 PFN_vkCreateAccelerationStructureNV vkCreateAccelerationStructureNV = reinterpret_cast<PFN_vkCreateAccelerationStructureNV>(
4275 vkGetDeviceProcAddr(m_device->handle(), "vkCreateAccelerationStructureNV"));
4276 assert(vkCreateAccelerationStructureNV != nullptr);
4277
4278 const auto GetCreateInfo = [](const VkGeometryNV &geometry) {
4279 VkAccelerationStructureCreateInfoNV as_create_info = {};
4280 as_create_info.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_CREATE_INFO_NV;
4281 as_create_info.info.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_INFO_NV;
4282 as_create_info.info.type = VK_ACCELERATION_STRUCTURE_TYPE_BOTTOM_LEVEL_NV;
4283 as_create_info.info.instanceCount = 0;
4284 as_create_info.info.geometryCount = 1;
4285 as_create_info.info.pGeometries = &geometry;
4286 return as_create_info;
4287 };
4288
4289 VkAccelerationStructureNV as;
4290
4291 // Invalid vertex format.
4292 {
4293 VkGeometryNV geometry = valid_geometry_triangles;
4294 geometry.geometry.triangles.vertexFormat = VK_FORMAT_R64_UINT;
4295
4296 VkAccelerationStructureCreateInfoNV as_create_info = GetCreateInfo(geometry);
4297 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkGeometryTrianglesNV-vertexFormat-02430");
4298 vkCreateAccelerationStructureNV(m_device->handle(), &as_create_info, nullptr, &as);
4299 m_errorMonitor->VerifyFound();
4300 }
4301 // Invalid vertex offset - not multiple of component size.
4302 {
4303 VkGeometryNV geometry = valid_geometry_triangles;
4304 geometry.geometry.triangles.vertexOffset = 1;
4305
4306 VkAccelerationStructureCreateInfoNV as_create_info = GetCreateInfo(geometry);
4307 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkGeometryTrianglesNV-vertexOffset-02429");
4308 vkCreateAccelerationStructureNV(m_device->handle(), &as_create_info, nullptr, &as);
4309 m_errorMonitor->VerifyFound();
4310 }
4311 // Invalid vertex offset - bigger than buffer.
4312 {
4313 VkGeometryNV geometry = valid_geometry_triangles;
4314 geometry.geometry.triangles.vertexOffset = 12 * 1024;
4315
4316 VkAccelerationStructureCreateInfoNV as_create_info = GetCreateInfo(geometry);
4317 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkGeometryTrianglesNV-vertexOffset-02428");
4318 vkCreateAccelerationStructureNV(m_device->handle(), &as_create_info, nullptr, &as);
4319 m_errorMonitor->VerifyFound();
4320 }
4321 // Invalid vertex buffer - no such buffer.
4322 {
4323 VkGeometryNV geometry = valid_geometry_triangles;
4324 geometry.geometry.triangles.vertexData = VkBuffer(123456789);
4325
4326 VkAccelerationStructureCreateInfoNV as_create_info = GetCreateInfo(geometry);
4327 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkGeometryTrianglesNV-vertexData-parameter");
4328 vkCreateAccelerationStructureNV(m_device->handle(), &as_create_info, nullptr, &as);
4329 m_errorMonitor->VerifyFound();
4330 }
4331 // Invalid vertex buffer - no memory bound.
4332 {
4333 VkGeometryNV geometry = valid_geometry_triangles;
4334 geometry.geometry.triangles.vertexData = unbound_buffer.handle();
4335
4336 VkAccelerationStructureCreateInfoNV as_create_info = GetCreateInfo(geometry);
4337 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkGeometryTrianglesNV-vertexOffset-02428");
4338 vkCreateAccelerationStructureNV(m_device->handle(), &as_create_info, nullptr, &as);
4339 m_errorMonitor->VerifyFound();
4340 }
4341
4342 // Invalid index offset - not multiple of index size.
4343 {
4344 VkGeometryNV geometry = valid_geometry_triangles;
4345 geometry.geometry.triangles.indexOffset = 1;
4346
4347 VkAccelerationStructureCreateInfoNV as_create_info = GetCreateInfo(geometry);
4348 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkGeometryTrianglesNV-indexOffset-02432");
4349 vkCreateAccelerationStructureNV(m_device->handle(), &as_create_info, nullptr, &as);
4350 m_errorMonitor->VerifyFound();
4351 }
4352 // Invalid index offset - bigger than buffer.
4353 {
4354 VkGeometryNV geometry = valid_geometry_triangles;
4355 geometry.geometry.triangles.indexOffset = 2048;
4356
4357 VkAccelerationStructureCreateInfoNV as_create_info = GetCreateInfo(geometry);
4358 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkGeometryTrianglesNV-indexOffset-02431");
4359 vkCreateAccelerationStructureNV(m_device->handle(), &as_create_info, nullptr, &as);
4360 m_errorMonitor->VerifyFound();
4361 }
4362 // Invalid index count - must be 0 if type is VK_INDEX_TYPE_NONE_NV.
4363 {
4364 VkGeometryNV geometry = valid_geometry_triangles;
4365 geometry.geometry.triangles.indexType = VK_INDEX_TYPE_NONE_NV;
4366 geometry.geometry.triangles.indexData = VK_NULL_HANDLE;
4367 geometry.geometry.triangles.indexCount = 1;
4368
4369 VkAccelerationStructureCreateInfoNV as_create_info = GetCreateInfo(geometry);
4370 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkGeometryTrianglesNV-indexCount-02436");
4371 vkCreateAccelerationStructureNV(m_device->handle(), &as_create_info, nullptr, &as);
4372 m_errorMonitor->VerifyFound();
4373 }
4374 // Invalid index data - must be VK_NULL_HANDLE if type is VK_INDEX_TYPE_NONE_NV.
4375 {
4376 VkGeometryNV geometry = valid_geometry_triangles;
4377 geometry.geometry.triangles.indexType = VK_INDEX_TYPE_NONE_NV;
4378 geometry.geometry.triangles.indexData = ibo.handle();
4379 geometry.geometry.triangles.indexCount = 0;
4380
4381 VkAccelerationStructureCreateInfoNV as_create_info = GetCreateInfo(geometry);
4382 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkGeometryTrianglesNV-indexData-02434");
4383 vkCreateAccelerationStructureNV(m_device->handle(), &as_create_info, nullptr, &as);
4384 m_errorMonitor->VerifyFound();
4385 }
4386
4387 // Invalid transform offset - not multiple of 16.
4388 {
4389 VkGeometryNV geometry = valid_geometry_triangles;
4390 geometry.geometry.triangles.transformOffset = 1;
4391
4392 VkAccelerationStructureCreateInfoNV as_create_info = GetCreateInfo(geometry);
4393 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkGeometryTrianglesNV-transformOffset-02438");
4394 vkCreateAccelerationStructureNV(m_device->handle(), &as_create_info, nullptr, &as);
4395 m_errorMonitor->VerifyFound();
4396 }
4397 // Invalid transform offset - bigger than buffer.
4398 {
4399 VkGeometryNV geometry = valid_geometry_triangles;
4400 geometry.geometry.triangles.transformOffset = 2048;
4401
4402 VkAccelerationStructureCreateInfoNV as_create_info = GetCreateInfo(geometry);
4403 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkGeometryTrianglesNV-transformOffset-02437");
4404 vkCreateAccelerationStructureNV(m_device->handle(), &as_create_info, nullptr, &as);
4405 m_errorMonitor->VerifyFound();
4406 }
4407
4408 // Invalid aabb offset - not multiple of 8.
4409 {
4410 VkGeometryNV geometry = valid_geometry_aabbs;
4411 geometry.geometry.aabbs.offset = 1;
4412
4413 VkAccelerationStructureCreateInfoNV as_create_info = GetCreateInfo(geometry);
4414 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkGeometryAABBNV-offset-02440");
4415 vkCreateAccelerationStructureNV(m_device->handle(), &as_create_info, nullptr, &as);
4416 m_errorMonitor->VerifyFound();
4417 }
4418 // Invalid aabb offset - bigger than buffer.
4419 {
4420 VkGeometryNV geometry = valid_geometry_aabbs;
4421 geometry.geometry.aabbs.offset = 8 * 1024;
4422
4423 VkAccelerationStructureCreateInfoNV as_create_info = GetCreateInfo(geometry);
4424 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkGeometryAABBNV-offset-02439");
4425 vkCreateAccelerationStructureNV(m_device->handle(), &as_create_info, nullptr, &as);
4426 m_errorMonitor->VerifyFound();
4427 }
4428 // Invalid aabb stride - not multiple of 8.
4429 {
4430 VkGeometryNV geometry = valid_geometry_aabbs;
4431 geometry.geometry.aabbs.stride = 1;
4432
4433 VkAccelerationStructureCreateInfoNV as_create_info = GetCreateInfo(geometry);
4434 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkGeometryAABBNV-stride-02441");
4435 vkCreateAccelerationStructureNV(m_device->handle(), &as_create_info, nullptr, &as);
4436 m_errorMonitor->VerifyFound();
4437 }
4438 }
4439
GetSimpleGeometryForAccelerationStructureTests(const VkDeviceObj & device,VkBufferObj * vbo,VkBufferObj * ibo,VkGeometryNV * geometry)4440 void GetSimpleGeometryForAccelerationStructureTests(const VkDeviceObj &device, VkBufferObj *vbo, VkBufferObj *ibo,
4441 VkGeometryNV *geometry) {
4442 vbo->init(device, 1024);
4443 ibo->init(device, 1024);
4444
4445 *geometry = {};
4446 geometry->sType = VK_STRUCTURE_TYPE_GEOMETRY_NV;
4447 geometry->geometryType = VK_GEOMETRY_TYPE_TRIANGLES_NV;
4448 geometry->geometry.triangles.sType = VK_STRUCTURE_TYPE_GEOMETRY_TRIANGLES_NV;
4449 geometry->geometry.triangles.vertexData = vbo->handle();
4450 geometry->geometry.triangles.vertexOffset = 0;
4451 geometry->geometry.triangles.vertexCount = 3;
4452 geometry->geometry.triangles.vertexStride = 12;
4453 geometry->geometry.triangles.vertexFormat = VK_FORMAT_R32G32B32_SFLOAT;
4454 geometry->geometry.triangles.indexData = ibo->handle();
4455 geometry->geometry.triangles.indexOffset = 0;
4456 geometry->geometry.triangles.indexCount = 3;
4457 geometry->geometry.triangles.indexType = VK_INDEX_TYPE_UINT32;
4458 geometry->geometry.triangles.transformData = VK_NULL_HANDLE;
4459 geometry->geometry.triangles.transformOffset = 0;
4460 geometry->geometry.aabbs = {};
4461 geometry->geometry.aabbs.sType = VK_STRUCTURE_TYPE_GEOMETRY_AABB_NV;
4462 }
4463
TEST_F(VkLayerTest,ValidateCreateAccelerationStructureNV)4464 TEST_F(VkLayerTest, ValidateCreateAccelerationStructureNV) {
4465 TEST_DESCRIPTION("Validate acceleration structure creation.");
4466 if (!InitFrameworkForRayTracingTest(this, m_instance_extension_names, m_device_extension_names, m_errorMonitor)) {
4467 return;
4468 }
4469
4470 PFN_vkCreateAccelerationStructureNV vkCreateAccelerationStructureNV = reinterpret_cast<PFN_vkCreateAccelerationStructureNV>(
4471 vkGetDeviceProcAddr(m_device->handle(), "vkCreateAccelerationStructureNV"));
4472 assert(vkCreateAccelerationStructureNV != nullptr);
4473
4474 VkBufferObj vbo;
4475 VkBufferObj ibo;
4476 VkGeometryNV geometry;
4477 GetSimpleGeometryForAccelerationStructureTests(*m_device, &vbo, &ibo, &geometry);
4478
4479 VkAccelerationStructureCreateInfoNV as_create_info = {};
4480 as_create_info.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_CREATE_INFO_NV;
4481 as_create_info.info.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_INFO_NV;
4482
4483 VkAccelerationStructureNV as = VK_NULL_HANDLE;
4484
4485 // Top level can not have geometry
4486 {
4487 VkAccelerationStructureCreateInfoNV bad_top_level_create_info = as_create_info;
4488 bad_top_level_create_info.info.type = VK_ACCELERATION_STRUCTURE_TYPE_TOP_LEVEL_NV;
4489 bad_top_level_create_info.info.instanceCount = 0;
4490 bad_top_level_create_info.info.geometryCount = 1;
4491 bad_top_level_create_info.info.pGeometries = &geometry;
4492 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkAccelerationStructureInfoNV-type-02425");
4493 vkCreateAccelerationStructureNV(m_device->handle(), &bad_top_level_create_info, nullptr, &as);
4494 m_errorMonitor->VerifyFound();
4495 }
4496
4497 // Bot level can not have instances
4498 {
4499 VkAccelerationStructureCreateInfoNV bad_bot_level_create_info = as_create_info;
4500 bad_bot_level_create_info.info.type = VK_ACCELERATION_STRUCTURE_TYPE_BOTTOM_LEVEL_NV;
4501 bad_bot_level_create_info.info.instanceCount = 1;
4502 bad_bot_level_create_info.info.geometryCount = 0;
4503 bad_bot_level_create_info.info.pGeometries = nullptr;
4504 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkAccelerationStructureInfoNV-type-02426");
4505 vkCreateAccelerationStructureNV(m_device->handle(), &bad_bot_level_create_info, nullptr, &as);
4506 m_errorMonitor->VerifyFound();
4507 }
4508
4509 // Can not prefer both fast trace and fast build
4510 {
4511 VkAccelerationStructureCreateInfoNV bad_flags_level_create_info = as_create_info;
4512 bad_flags_level_create_info.info.type = VK_ACCELERATION_STRUCTURE_TYPE_BOTTOM_LEVEL_NV;
4513 bad_flags_level_create_info.info.instanceCount = 0;
4514 bad_flags_level_create_info.info.geometryCount = 1;
4515 bad_flags_level_create_info.info.pGeometries = &geometry;
4516 bad_flags_level_create_info.info.flags =
4517 VK_BUILD_ACCELERATION_STRUCTURE_PREFER_FAST_TRACE_BIT_NV | VK_BUILD_ACCELERATION_STRUCTURE_PREFER_FAST_BUILD_BIT_NV;
4518 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkAccelerationStructureInfoNV-flags-02592");
4519 vkCreateAccelerationStructureNV(m_device->handle(), &bad_flags_level_create_info, nullptr, &as);
4520 m_errorMonitor->VerifyFound();
4521 }
4522
4523 // Can not have geometry or instance for compacting
4524 {
4525 VkAccelerationStructureCreateInfoNV bad_compacting_as_create_info = as_create_info;
4526 bad_compacting_as_create_info.info.type = VK_ACCELERATION_STRUCTURE_TYPE_BOTTOM_LEVEL_NV;
4527 bad_compacting_as_create_info.info.instanceCount = 0;
4528 bad_compacting_as_create_info.info.geometryCount = 1;
4529 bad_compacting_as_create_info.info.pGeometries = &geometry;
4530 bad_compacting_as_create_info.info.flags = 0;
4531 bad_compacting_as_create_info.compactedSize = 1024;
4532 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
4533 "VUID-VkAccelerationStructureCreateInfoNV-compactedSize-02421");
4534 vkCreateAccelerationStructureNV(m_device->handle(), &bad_compacting_as_create_info, nullptr, &as);
4535 m_errorMonitor->VerifyFound();
4536 }
4537
4538 // Can not mix different geometry types into single bottom level acceleration structure
4539 {
4540 VkGeometryNV aabb_geometry = {};
4541 aabb_geometry.sType = VK_STRUCTURE_TYPE_GEOMETRY_NV;
4542 aabb_geometry.geometryType = VK_GEOMETRY_TYPE_AABBS_NV;
4543 aabb_geometry.geometry.triangles.sType = VK_STRUCTURE_TYPE_GEOMETRY_TRIANGLES_NV;
4544 aabb_geometry.geometry.aabbs = {};
4545 aabb_geometry.geometry.aabbs.sType = VK_STRUCTURE_TYPE_GEOMETRY_AABB_NV;
4546 // Buffer contents do not matter for this test.
4547 aabb_geometry.geometry.aabbs.aabbData = geometry.geometry.triangles.vertexData;
4548 aabb_geometry.geometry.aabbs.numAABBs = 1;
4549 aabb_geometry.geometry.aabbs.offset = 0;
4550 aabb_geometry.geometry.aabbs.stride = 24;
4551
4552 std::vector<VkGeometryNV> geometries = {geometry, aabb_geometry};
4553
4554 VkAccelerationStructureCreateInfoNV mix_geometry_types_as_create_info = as_create_info;
4555 mix_geometry_types_as_create_info.info.type = VK_ACCELERATION_STRUCTURE_TYPE_BOTTOM_LEVEL_NV;
4556 mix_geometry_types_as_create_info.info.instanceCount = 0;
4557 mix_geometry_types_as_create_info.info.geometryCount = static_cast<uint32_t>(geometries.size());
4558 mix_geometry_types_as_create_info.info.pGeometries = geometries.data();
4559 mix_geometry_types_as_create_info.info.flags = 0;
4560
4561 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
4562 "UNASSIGNED-VkAccelerationStructureInfoNV-pGeometries-XXXX");
4563 vkCreateAccelerationStructureNV(m_device->handle(), &mix_geometry_types_as_create_info, nullptr, &as);
4564 m_errorMonitor->VerifyFound();
4565 }
4566 }
4567
TEST_F(VkLayerTest,ValidateBindAccelerationStructureNV)4568 TEST_F(VkLayerTest, ValidateBindAccelerationStructureNV) {
4569 TEST_DESCRIPTION("Validate acceleration structure binding.");
4570 if (!InitFrameworkForRayTracingTest(this, m_instance_extension_names, m_device_extension_names, m_errorMonitor)) {
4571 return;
4572 }
4573
4574 PFN_vkBindAccelerationStructureMemoryNV vkBindAccelerationStructureMemoryNV =
4575 reinterpret_cast<PFN_vkBindAccelerationStructureMemoryNV>(
4576 vkGetDeviceProcAddr(m_device->handle(), "vkBindAccelerationStructureMemoryNV"));
4577 assert(vkBindAccelerationStructureMemoryNV != nullptr);
4578
4579 VkBufferObj vbo;
4580 VkBufferObj ibo;
4581 VkGeometryNV geometry;
4582 GetSimpleGeometryForAccelerationStructureTests(*m_device, &vbo, &ibo, &geometry);
4583
4584 VkAccelerationStructureCreateInfoNV as_create_info = {};
4585 as_create_info.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_CREATE_INFO_NV;
4586 as_create_info.info.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_INFO_NV;
4587 as_create_info.info.type = VK_ACCELERATION_STRUCTURE_TYPE_BOTTOM_LEVEL_NV;
4588 as_create_info.info.geometryCount = 1;
4589 as_create_info.info.pGeometries = &geometry;
4590 as_create_info.info.instanceCount = 0;
4591
4592 VkAccelerationStructureObj as(*m_device, as_create_info, false);
4593 m_errorMonitor->VerifyNotFound();
4594
4595 VkMemoryRequirements as_memory_requirements = as.memory_requirements().memoryRequirements;
4596
4597 VkBindAccelerationStructureMemoryInfoNV as_bind_info = {};
4598 as_bind_info.sType = VK_STRUCTURE_TYPE_BIND_ACCELERATION_STRUCTURE_MEMORY_INFO_NV;
4599 as_bind_info.accelerationStructure = as.handle();
4600
4601 VkMemoryAllocateInfo as_memory_alloc = {};
4602 as_memory_alloc.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
4603 as_memory_alloc.allocationSize = as_memory_requirements.size;
4604 ASSERT_TRUE(m_device->phy().set_memory_type(as_memory_requirements.memoryTypeBits, &as_memory_alloc, 0));
4605
4606 // Can not bind already freed memory
4607 {
4608 VkDeviceMemory as_memory_freed = VK_NULL_HANDLE;
4609 ASSERT_VK_SUCCESS(vkAllocateMemory(device(), &as_memory_alloc, NULL, &as_memory_freed));
4610 vkFreeMemory(device(), as_memory_freed, NULL);
4611
4612 VkBindAccelerationStructureMemoryInfoNV as_bind_info_freed = as_bind_info;
4613 as_bind_info_freed.memory = as_memory_freed;
4614 as_bind_info_freed.memoryOffset = 0;
4615
4616 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
4617 "VUID-VkBindAccelerationStructureMemoryInfoNV-memory-parameter");
4618 (void)vkBindAccelerationStructureMemoryNV(device(), 1, &as_bind_info_freed);
4619 m_errorMonitor->VerifyFound();
4620 }
4621
4622 // Can not bind with bad alignment
4623 if (as_memory_requirements.alignment > 1) {
4624 VkMemoryAllocateInfo as_memory_alloc_bad_alignment = as_memory_alloc;
4625 as_memory_alloc_bad_alignment.allocationSize += 1;
4626
4627 VkDeviceMemory as_memory_bad_alignment = VK_NULL_HANDLE;
4628 ASSERT_VK_SUCCESS(vkAllocateMemory(device(), &as_memory_alloc_bad_alignment, NULL, &as_memory_bad_alignment));
4629
4630 VkBindAccelerationStructureMemoryInfoNV as_bind_info_bad_alignment = as_bind_info;
4631 as_bind_info_bad_alignment.memory = as_memory_bad_alignment;
4632 as_bind_info_bad_alignment.memoryOffset = 1;
4633
4634 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
4635 "VUID-VkBindAccelerationStructureMemoryInfoNV-memoryOffset-02594");
4636 (void)vkBindAccelerationStructureMemoryNV(device(), 1, &as_bind_info_bad_alignment);
4637 m_errorMonitor->VerifyFound();
4638
4639 vkFreeMemory(device(), as_memory_bad_alignment, NULL);
4640 }
4641
4642 // Can not bind with offset outside the allocation
4643 {
4644 VkDeviceMemory as_memory_bad_offset = VK_NULL_HANDLE;
4645 ASSERT_VK_SUCCESS(vkAllocateMemory(device(), &as_memory_alloc, NULL, &as_memory_bad_offset));
4646
4647 VkBindAccelerationStructureMemoryInfoNV as_bind_info_bad_offset = as_bind_info;
4648 as_bind_info_bad_offset.memory = as_memory_bad_offset;
4649 as_bind_info_bad_offset.memoryOffset =
4650 (as_memory_alloc.allocationSize + as_memory_requirements.alignment) & ~(as_memory_requirements.alignment - 1);
4651
4652 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
4653 "VUID-VkBindAccelerationStructureMemoryInfoNV-memoryOffset-02451");
4654 (void)vkBindAccelerationStructureMemoryNV(device(), 1, &as_bind_info_bad_offset);
4655 m_errorMonitor->VerifyFound();
4656
4657 vkFreeMemory(device(), as_memory_bad_offset, NULL);
4658 }
4659
4660 // Can not bind with offset that doesn't leave enough size
4661 {
4662 VkDeviceSize offset = (as_memory_requirements.size - 1) & ~(as_memory_requirements.alignment - 1);
4663 if (offset > 0 && (as_memory_requirements.size < (as_memory_alloc.allocationSize - as_memory_requirements.alignment))) {
4664 VkDeviceMemory as_memory_bad_offset = VK_NULL_HANDLE;
4665 ASSERT_VK_SUCCESS(vkAllocateMemory(device(), &as_memory_alloc, NULL, &as_memory_bad_offset));
4666
4667 VkBindAccelerationStructureMemoryInfoNV as_bind_info_bad_offset = as_bind_info;
4668 as_bind_info_bad_offset.memory = as_memory_bad_offset;
4669 as_bind_info_bad_offset.memoryOffset = offset;
4670
4671 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
4672 "VUID-VkBindAccelerationStructureMemoryInfoNV-size-02595");
4673 (void)vkBindAccelerationStructureMemoryNV(device(), 1, &as_bind_info_bad_offset);
4674 m_errorMonitor->VerifyFound();
4675
4676 vkFreeMemory(device(), as_memory_bad_offset, NULL);
4677 }
4678 }
4679
4680 // Can not bind with memory that has unsupported memory type
4681 {
4682 VkPhysicalDeviceMemoryProperties memory_properties = {};
4683 vkGetPhysicalDeviceMemoryProperties(m_device->phy().handle(), &memory_properties);
4684
4685 uint32_t supported_memory_type_bits = as_memory_requirements.memoryTypeBits;
4686 uint32_t unsupported_mem_type_bits = ((1 << memory_properties.memoryTypeCount) - 1) & ~supported_memory_type_bits;
4687 if (unsupported_mem_type_bits != 0) {
4688 VkMemoryAllocateInfo as_memory_alloc_bad_type = as_memory_alloc;
4689 ASSERT_TRUE(m_device->phy().set_memory_type(unsupported_mem_type_bits, &as_memory_alloc_bad_type, 0));
4690
4691 VkDeviceMemory as_memory_bad_type = VK_NULL_HANDLE;
4692 ASSERT_VK_SUCCESS(vkAllocateMemory(device(), &as_memory_alloc_bad_type, NULL, &as_memory_bad_type));
4693
4694 VkBindAccelerationStructureMemoryInfoNV as_bind_info_bad_type = as_bind_info;
4695 as_bind_info_bad_type.memory = as_memory_bad_type;
4696
4697 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
4698 "VUID-VkBindAccelerationStructureMemoryInfoNV-memory-02593");
4699 (void)vkBindAccelerationStructureMemoryNV(device(), 1, &as_bind_info_bad_type);
4700 m_errorMonitor->VerifyFound();
4701
4702 vkFreeMemory(device(), as_memory_bad_type, NULL);
4703 }
4704 }
4705
4706 // Can not bind memory twice
4707 {
4708 VkAccelerationStructureObj as_twice(*m_device, as_create_info, false);
4709
4710 VkDeviceMemory as_memory_twice_1 = VK_NULL_HANDLE;
4711 VkDeviceMemory as_memory_twice_2 = VK_NULL_HANDLE;
4712 ASSERT_VK_SUCCESS(vkAllocateMemory(device(), &as_memory_alloc, NULL, &as_memory_twice_1));
4713 ASSERT_VK_SUCCESS(vkAllocateMemory(device(), &as_memory_alloc, NULL, &as_memory_twice_2));
4714 VkBindAccelerationStructureMemoryInfoNV as_bind_info_twice_1 = as_bind_info;
4715 VkBindAccelerationStructureMemoryInfoNV as_bind_info_twice_2 = as_bind_info;
4716 as_bind_info_twice_1.accelerationStructure = as_twice.handle();
4717 as_bind_info_twice_2.accelerationStructure = as_twice.handle();
4718 as_bind_info_twice_1.memory = as_memory_twice_1;
4719 as_bind_info_twice_2.memory = as_memory_twice_2;
4720
4721 ASSERT_VK_SUCCESS(vkBindAccelerationStructureMemoryNV(device(), 1, &as_bind_info_twice_1));
4722 m_errorMonitor->VerifyNotFound();
4723 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
4724 "VUID-VkBindAccelerationStructureMemoryInfoNV-accelerationStructure-02450");
4725 (void)vkBindAccelerationStructureMemoryNV(device(), 1, &as_bind_info_twice_2);
4726 m_errorMonitor->VerifyFound();
4727
4728 vkFreeMemory(device(), as_memory_twice_1, NULL);
4729 vkFreeMemory(device(), as_memory_twice_2, NULL);
4730 }
4731 }
4732
TEST_F(VkLayerTest,ValidateCmdBuildAccelerationStructureNV)4733 TEST_F(VkLayerTest, ValidateCmdBuildAccelerationStructureNV) {
4734 TEST_DESCRIPTION("Validate acceleration structure building.");
4735 if (!InitFrameworkForRayTracingTest(this, m_instance_extension_names, m_device_extension_names, m_errorMonitor)) {
4736 return;
4737 }
4738
4739 PFN_vkCmdBuildAccelerationStructureNV vkCmdBuildAccelerationStructureNV =
4740 reinterpret_cast<PFN_vkCmdBuildAccelerationStructureNV>(
4741 vkGetDeviceProcAddr(m_device->handle(), "vkCmdBuildAccelerationStructureNV"));
4742 assert(vkCmdBuildAccelerationStructureNV != nullptr);
4743
4744 VkBufferObj vbo;
4745 VkBufferObj ibo;
4746 VkGeometryNV geometry;
4747 GetSimpleGeometryForAccelerationStructureTests(*m_device, &vbo, &ibo, &geometry);
4748
4749 VkAccelerationStructureCreateInfoNV bot_level_as_create_info = {};
4750 bot_level_as_create_info.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_CREATE_INFO_NV;
4751 bot_level_as_create_info.info.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_INFO_NV;
4752 bot_level_as_create_info.info.type = VK_ACCELERATION_STRUCTURE_TYPE_BOTTOM_LEVEL_NV;
4753 bot_level_as_create_info.info.instanceCount = 0;
4754 bot_level_as_create_info.info.geometryCount = 1;
4755 bot_level_as_create_info.info.pGeometries = &geometry;
4756
4757 VkAccelerationStructureObj bot_level_as(*m_device, bot_level_as_create_info);
4758 m_errorMonitor->VerifyNotFound();
4759
4760 VkBufferObj bot_level_as_scratch;
4761 bot_level_as.create_scratch_buffer(*m_device, &bot_level_as_scratch);
4762
4763 // Command buffer must be in recording state
4764 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
4765 "VUID-vkCmdBuildAccelerationStructureNV-commandBuffer-recording");
4766 vkCmdBuildAccelerationStructureNV(m_commandBuffer->handle(), &bot_level_as_create_info.info, VK_NULL_HANDLE, 0, VK_FALSE,
4767 bot_level_as.handle(), VK_NULL_HANDLE, bot_level_as_scratch.handle(), 0);
4768 m_errorMonitor->VerifyFound();
4769
4770 m_commandBuffer->begin();
4771
4772 // Incompatible type
4773 VkAccelerationStructureInfoNV as_build_info_with_incompatible_type = bot_level_as_create_info.info;
4774 as_build_info_with_incompatible_type.type = VK_ACCELERATION_STRUCTURE_TYPE_TOP_LEVEL_NV;
4775 as_build_info_with_incompatible_type.instanceCount = 1;
4776 as_build_info_with_incompatible_type.geometryCount = 0;
4777
4778 // This is duplicated since it triggers one error for different types and one error for lower instance count - the
4779 // build info is incompatible but still needs to be valid to get past the stateless checks.
4780 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdBuildAccelerationStructureNV-dst-02488");
4781 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdBuildAccelerationStructureNV-dst-02488");
4782 vkCmdBuildAccelerationStructureNV(m_commandBuffer->handle(), &as_build_info_with_incompatible_type, VK_NULL_HANDLE, 0, VK_FALSE,
4783 bot_level_as.handle(), VK_NULL_HANDLE, bot_level_as_scratch.handle(), 0);
4784 m_errorMonitor->VerifyFound();
4785
4786 // Incompatible flags
4787 VkAccelerationStructureInfoNV as_build_info_with_incompatible_flags = bot_level_as_create_info.info;
4788 as_build_info_with_incompatible_flags.flags = VK_BUILD_ACCELERATION_STRUCTURE_LOW_MEMORY_BIT_NV;
4789 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdBuildAccelerationStructureNV-dst-02488");
4790 vkCmdBuildAccelerationStructureNV(m_commandBuffer->handle(), &as_build_info_with_incompatible_flags, VK_NULL_HANDLE, 0,
4791 VK_FALSE, bot_level_as.handle(), VK_NULL_HANDLE, bot_level_as_scratch.handle(), 0);
4792 m_errorMonitor->VerifyFound();
4793
4794 // Incompatible build size
4795 VkGeometryNV geometry_with_more_vertices = geometry;
4796 geometry_with_more_vertices.geometry.triangles.vertexCount += 1;
4797
4798 VkAccelerationStructureInfoNV as_build_info_with_incompatible_geometry = bot_level_as_create_info.info;
4799 as_build_info_with_incompatible_geometry.pGeometries = &geometry_with_more_vertices;
4800 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdBuildAccelerationStructureNV-dst-02488");
4801 vkCmdBuildAccelerationStructureNV(m_commandBuffer->handle(), &as_build_info_with_incompatible_geometry, VK_NULL_HANDLE, 0,
4802 VK_FALSE, bot_level_as.handle(), VK_NULL_HANDLE, bot_level_as_scratch.handle(), 0);
4803 m_errorMonitor->VerifyFound();
4804
4805 // Scratch buffer too small
4806 VkBufferCreateInfo too_small_scratch_buffer_info = {};
4807 too_small_scratch_buffer_info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
4808 too_small_scratch_buffer_info.usage = VK_BUFFER_USAGE_RAY_TRACING_BIT_NV;
4809 too_small_scratch_buffer_info.size = 1;
4810 VkBufferObj too_small_scratch_buffer(*m_device, too_small_scratch_buffer_info);
4811 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdBuildAccelerationStructureNV-update-02491");
4812 vkCmdBuildAccelerationStructureNV(m_commandBuffer->handle(), &bot_level_as_create_info.info, VK_NULL_HANDLE, 0, VK_FALSE,
4813 bot_level_as.handle(), VK_NULL_HANDLE, too_small_scratch_buffer.handle(), 0);
4814 m_errorMonitor->VerifyFound();
4815
4816 // Scratch buffer with offset too small
4817 VkDeviceSize scratch_buffer_offset = 5;
4818 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdBuildAccelerationStructureNV-update-02491");
4819 vkCmdBuildAccelerationStructureNV(m_commandBuffer->handle(), &bot_level_as_create_info.info, VK_NULL_HANDLE, 0, VK_FALSE,
4820 bot_level_as.handle(), VK_NULL_HANDLE, bot_level_as_scratch.handle(), scratch_buffer_offset);
4821 m_errorMonitor->VerifyFound();
4822
4823 // Src must have been built before
4824 VkAccelerationStructureObj bot_level_as_updated(*m_device, bot_level_as_create_info);
4825 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdBuildAccelerationStructureNV-update-02489");
4826 vkCmdBuildAccelerationStructureNV(m_commandBuffer->handle(), &bot_level_as_create_info.info, VK_NULL_HANDLE, 0, VK_TRUE,
4827 bot_level_as_updated.handle(), bot_level_as.handle(), bot_level_as_scratch.handle(), 0);
4828 m_errorMonitor->VerifyFound();
4829
4830 // Src must have been built before with the VK_BUILD_ACCELERATION_STRUCTURE_ALLOW_UPDATE_BIT_NV flag
4831 vkCmdBuildAccelerationStructureNV(m_commandBuffer->handle(), &bot_level_as_create_info.info, VK_NULL_HANDLE, 0, VK_FALSE,
4832 bot_level_as.handle(), VK_NULL_HANDLE, bot_level_as_scratch.handle(), 0);
4833 m_errorMonitor->VerifyNotFound();
4834 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdBuildAccelerationStructureNV-update-02489");
4835 vkCmdBuildAccelerationStructureNV(m_commandBuffer->handle(), &bot_level_as_create_info.info, VK_NULL_HANDLE, 0, VK_TRUE,
4836 bot_level_as_updated.handle(), bot_level_as.handle(), bot_level_as_scratch.handle(), 0);
4837 m_errorMonitor->VerifyFound();
4838 }
4839
TEST_F(VkLayerTest,ValidateGetAccelerationStructureHandleNV)4840 TEST_F(VkLayerTest, ValidateGetAccelerationStructureHandleNV) {
4841 TEST_DESCRIPTION("Validate acceleration structure handle querying.");
4842 if (!InitFrameworkForRayTracingTest(this, m_instance_extension_names, m_device_extension_names, m_errorMonitor)) {
4843 return;
4844 }
4845
4846 PFN_vkGetAccelerationStructureHandleNV vkGetAccelerationStructureHandleNV =
4847 reinterpret_cast<PFN_vkGetAccelerationStructureHandleNV>(
4848 vkGetDeviceProcAddr(m_device->handle(), "vkGetAccelerationStructureHandleNV"));
4849 assert(vkGetAccelerationStructureHandleNV != nullptr);
4850
4851 VkBufferObj vbo;
4852 VkBufferObj ibo;
4853 VkGeometryNV geometry;
4854 GetSimpleGeometryForAccelerationStructureTests(*m_device, &vbo, &ibo, &geometry);
4855
4856 VkAccelerationStructureCreateInfoNV bot_level_as_create_info = {};
4857 bot_level_as_create_info.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_CREATE_INFO_NV;
4858 bot_level_as_create_info.info.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_INFO_NV;
4859 bot_level_as_create_info.info.type = VK_ACCELERATION_STRUCTURE_TYPE_BOTTOM_LEVEL_NV;
4860 bot_level_as_create_info.info.instanceCount = 0;
4861 bot_level_as_create_info.info.geometryCount = 1;
4862 bot_level_as_create_info.info.pGeometries = &geometry;
4863
4864 // Not enough space for the handle
4865 {
4866 VkAccelerationStructureObj bot_level_as(*m_device, bot_level_as_create_info);
4867 m_errorMonitor->VerifyNotFound();
4868
4869 uint64_t handle = 0;
4870 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
4871 "VUID-vkGetAccelerationStructureHandleNV-dataSize-02240");
4872 vkGetAccelerationStructureHandleNV(m_device->handle(), bot_level_as.handle(), sizeof(uint8_t), &handle);
4873 m_errorMonitor->VerifyFound();
4874 }
4875
4876 // No memory bound to acceleration structure
4877 {
4878 VkAccelerationStructureObj bot_level_as(*m_device, bot_level_as_create_info, /*init_memory=*/false);
4879 m_errorMonitor->VerifyNotFound();
4880
4881 uint64_t handle = 0;
4882 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
4883 "UNASSIGNED-vkGetAccelerationStructureHandleNV-accelerationStructure-XXXX");
4884 vkGetAccelerationStructureHandleNV(m_device->handle(), bot_level_as.handle(), sizeof(uint64_t), &handle);
4885 m_errorMonitor->VerifyFound();
4886 }
4887 }
4888
TEST_F(VkLayerTest,ValidateCmdCopyAccelerationStructureNV)4889 TEST_F(VkLayerTest, ValidateCmdCopyAccelerationStructureNV) {
4890 TEST_DESCRIPTION("Validate acceleration structure copying.");
4891 if (!InitFrameworkForRayTracingTest(this, m_instance_extension_names, m_device_extension_names, m_errorMonitor)) {
4892 return;
4893 }
4894
4895 PFN_vkCmdCopyAccelerationStructureNV vkCmdCopyAccelerationStructureNV = reinterpret_cast<PFN_vkCmdCopyAccelerationStructureNV>(
4896 vkGetDeviceProcAddr(m_device->handle(), "vkCmdCopyAccelerationStructureNV"));
4897 assert(vkCmdCopyAccelerationStructureNV != nullptr);
4898
4899 VkBufferObj vbo;
4900 VkBufferObj ibo;
4901 VkGeometryNV geometry;
4902 GetSimpleGeometryForAccelerationStructureTests(*m_device, &vbo, &ibo, &geometry);
4903
4904 VkAccelerationStructureCreateInfoNV as_create_info = {};
4905 as_create_info.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_CREATE_INFO_NV;
4906 as_create_info.info.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_INFO_NV;
4907 as_create_info.info.type = VK_ACCELERATION_STRUCTURE_TYPE_BOTTOM_LEVEL_NV;
4908 as_create_info.info.instanceCount = 0;
4909 as_create_info.info.geometryCount = 1;
4910 as_create_info.info.pGeometries = &geometry;
4911
4912 VkAccelerationStructureObj src_as(*m_device, as_create_info);
4913 VkAccelerationStructureObj dst_as(*m_device, as_create_info);
4914 VkAccelerationStructureObj dst_as_without_mem(*m_device, as_create_info, false);
4915 m_errorMonitor->VerifyNotFound();
4916
4917 // Command buffer must be in recording state
4918 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
4919 "VUID-vkCmdCopyAccelerationStructureNV-commandBuffer-recording");
4920 vkCmdCopyAccelerationStructureNV(m_commandBuffer->handle(), dst_as.handle(), src_as.handle(),
4921 VK_COPY_ACCELERATION_STRUCTURE_MODE_CLONE_NV);
4922 m_errorMonitor->VerifyFound();
4923
4924 m_commandBuffer->begin();
4925
4926 // Src must have been created with allow compaction flag
4927 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdCopyAccelerationStructureNV-src-02497");
4928 vkCmdCopyAccelerationStructureNV(m_commandBuffer->handle(), dst_as.handle(), src_as.handle(),
4929 VK_COPY_ACCELERATION_STRUCTURE_MODE_COMPACT_NV);
4930 m_errorMonitor->VerifyFound();
4931
4932 // Dst must have been bound with memory
4933 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
4934 "UNASSIGNED-CoreValidation-DrawState-InvalidCommandBuffer-VkAccelerationStructureNV");
4935 vkCmdCopyAccelerationStructureNV(m_commandBuffer->handle(), dst_as_without_mem.handle(), src_as.handle(),
4936 VK_COPY_ACCELERATION_STRUCTURE_MODE_CLONE_NV);
4937 m_errorMonitor->VerifyFound();
4938 }
4939