• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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