1 /*
2  * Copyright (c) 2015-2021 The Khronos Group Inc.
3  * Copyright (c) 2015-2021 Valve Corporation
4  * Copyright (c) 2015-2021 LunarG, Inc.
5  * Copyright (c) 2015-2021 Google, Inc.
6  * Modifications Copyright (C) 2020-2021 Advanced Micro Devices, Inc. All rights reserved.
7  *
8  * Licensed under the Apache License, Version 2.0 (the "License");
9  * you may not use this file except in compliance with the License.
10  * You may obtain a copy of the License at
11  *
12  *     http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Author: Chia-I Wu <olvaffe@gmail.com>
15  * Author: Chris Forbes <chrisf@ijw.co.nz>
16  * Author: Courtney Goeltzenleuchter <courtney@LunarG.com>
17  * Author: Mark Lobodzinski <mark@lunarg.com>
18  * Author: Mike Stroyan <mike@LunarG.com>
19  * Author: Tobin Ehlis <tobine@google.com>
20  * Author: Tony Barbour <tony@LunarG.com>
21  * Author: Cody Northrop <cnorthrop@google.com>
22  * Author: Dave Houlton <daveh@lunarg.com>
23  * Author: Jeremy Kniager <jeremyk@lunarg.com>
24  * Author: Shannon McPherson <shannon@lunarg.com>
25  * Author: John Zulauf <jzulauf@lunarg.com>
26  * Author: Tobias Hector <tobias.hector@amd.com>
27  */
28 
29 #include "cast_utils.h"
30 #include "layer_validation_tests.h"
31 #include "core_validation_error_enums.h"
32 
33 class MessageIdFilter {
34   public:
MessageIdFilter(const char * filter_string)35     MessageIdFilter(const char *filter_string) {
36         local_string = filter_string;
37         filter_string_value.arrayString.pCharArray = local_string.data();
38         filter_string_value.arrayString.count = local_string.size();
39 
40         strncpy(filter_setting_val.name, "message_id_filter", sizeof(filter_setting_val.name));
41         filter_setting_val.type = VK_LAYER_SETTING_VALUE_TYPE_STRING_ARRAY_EXT;
42         filter_setting_val.data = filter_string_value;
43         filter_setting = {static_cast<VkStructureType>(VK_STRUCTURE_TYPE_INSTANCE_LAYER_SETTINGS_EXT), nullptr, 1,
44                           &filter_setting_val};
45     }
46     VkLayerSettingsEXT *pnext{&filter_setting};
47 
48   private:
49     VkLayerSettingValueDataEXT filter_string_value{};
50     VkLayerSettingValueEXT filter_setting_val;
51     VkLayerSettingsEXT filter_setting;
52     std::string local_string;
53 };
54 
55 class CustomStypeList {
56   public:
CustomStypeList(const char * stype_id_string)57     CustomStypeList(const char *stype_id_string) {
58         local_string = stype_id_string;
59         custom_stype_value.arrayString.pCharArray = local_string.data();
60         custom_stype_value.arrayString.count = local_string.size();
61 
62         strncpy(custom_stype_setting_val.name, "custom_stype_list", sizeof(custom_stype_setting_val.name));
63         custom_stype_setting_val.type = VK_LAYER_SETTING_VALUE_TYPE_STRING_ARRAY_EXT;
64         custom_stype_setting_val.data = custom_stype_value;
65         custom_stype_setting = {static_cast<VkStructureType>(VK_STRUCTURE_TYPE_INSTANCE_LAYER_SETTINGS_EXT), nullptr, 1,
66                                 &custom_stype_setting_val};
67     }
68 
CustomStypeList(const std::vector<uint32_t> & stype_id_array)69     CustomStypeList(const std::vector<uint32_t> &stype_id_array) {
70         local_vector = stype_id_array;
71         custom_stype_value.arrayInt32.pInt32Array = local_vector.data();
72         custom_stype_value.arrayInt32.count = local_vector.size();
73 
74         strncpy(custom_stype_setting_val.name, "custom_stype_list", sizeof(custom_stype_setting_val.name));
75         custom_stype_setting_val.type = VK_LAYER_SETTING_VALUE_TYPE_UINT32_ARRAY_EXT;
76         custom_stype_setting_val.data = custom_stype_value;
77         custom_stype_setting = {static_cast<VkStructureType>(VK_STRUCTURE_TYPE_INSTANCE_LAYER_SETTINGS_EXT), nullptr, 1,
78                                 &custom_stype_setting_val};
79     }
80     VkLayerSettingsEXT *pnext{&custom_stype_setting};
81 
82   private:
83     VkLayerSettingValueDataEXT custom_stype_value{};
84     VkLayerSettingValueEXT custom_stype_setting_val;
85     VkLayerSettingsEXT custom_stype_setting;
86     std::string local_string;
87     std::vector<uint32_t> local_vector;
88 };
89 
90 class DuplicateMsgLimit {
91   public:
DuplicateMsgLimit(const uint32_t limit)92     DuplicateMsgLimit(const uint32_t limit) {
93         limit_value.value32 = limit;
94 
95         strncpy(limit_setting_val.name, "duplicate_message_limit", sizeof(limit_setting_val.name));
96         limit_setting_val.type = VK_LAYER_SETTING_VALUE_TYPE_UINT32_EXT;
97         limit_setting_val.data = limit_value;
98         limit_setting = {static_cast<VkStructureType>(VK_STRUCTURE_TYPE_INSTANCE_LAYER_SETTINGS_EXT), nullptr, 1,
99                          &limit_setting_val};
100     }
101     VkLayerSettingsEXT *pnext{&limit_setting};
102 
103   private:
104     VkLayerSettingValueDataEXT limit_value{};
105     VkLayerSettingValueEXT limit_setting_val;
106     VkLayerSettingsEXT limit_setting;
107 };
108 
TEST_F(VkLayerTest,VersionCheckPromotedAPIs)109 TEST_F(VkLayerTest, VersionCheckPromotedAPIs) {
110     TEST_DESCRIPTION("Validate that promoted APIs are not valid in old versions.");
111     SetTargetApiVersion(VK_API_VERSION_1_0);
112 
113     ASSERT_NO_FATAL_FAILURE(Init());
114 
115     PFN_vkGetPhysicalDeviceProperties2 vkGetPhysicalDeviceProperties2 =
116         (PFN_vkGetPhysicalDeviceProperties2)vk::GetInstanceProcAddr(instance(), "vkGetPhysicalDeviceProperties2");
117     assert(vkGetPhysicalDeviceProperties2);
118 
119     VkPhysicalDeviceProperties2 phys_dev_props_2{};
120 
121     m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "UNASSIGNED-API-Version-Violation");
122     vkGetPhysicalDeviceProperties2(gpu(), &phys_dev_props_2);
123     m_errorMonitor->VerifyFound();
124 }
125 
TEST_F(VkLayerTest,UnsupportedPnextApiVersion)126 TEST_F(VkLayerTest, UnsupportedPnextApiVersion) {
127     TEST_DESCRIPTION("Validate that newer pnext structs are not valid for old Vulkan versions.");
128     SetTargetApiVersion(VK_API_VERSION_1_1);
129 
130     ASSERT_NO_FATAL_FAILURE(Init());
131     if (IsPlatform(kNexusPlayer)) {
132         printf("%s This test should not run on Nexus Player\n", kSkipPrefix);
133         return;
134     }
135 
136     auto phys_dev_props_2 = LvlInitStruct<VkPhysicalDeviceProperties2>();
137     auto bad_version_1_1_struct = LvlInitStruct<VkPhysicalDeviceVulkan12Properties>();
138     phys_dev_props_2.pNext = &bad_version_1_1_struct;
139 
140     // VkPhysDevVulkan12Props was introduced in 1.2, so try adding it to a 1.1 pNext chain
141     if (DeviceValidationVersion() >= VK_API_VERSION_1_1) {
142         m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkPhysicalDeviceProperties2-pNext-pNext");
143         vk::GetPhysicalDeviceProperties2(gpu(), &phys_dev_props_2);
144         m_errorMonitor->VerifyFound();
145     }
146 
147     // 1.1 context, VK_KHR_depth_stencil_resolve is NOT enabled, but using its struct is valid
148     if (DeviceExtensionSupported(VK_KHR_DEPTH_STENCIL_RESOLVE_EXTENSION_NAME)) {
149         auto unenabled_device_ext_struct = LvlInitStruct<VkPhysicalDeviceDepthStencilResolveProperties>();
150         phys_dev_props_2.pNext = &unenabled_device_ext_struct;
151         if (DeviceValidationVersion() >= VK_API_VERSION_1_1) {
152             m_errorMonitor->ExpectSuccess();
153             vk::GetPhysicalDeviceProperties2(gpu(), &phys_dev_props_2);
154             m_errorMonitor->VerifyNotFound();
155         } else {
156             m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "UNASSIGNED-API-Version-Violation");
157             vk::GetPhysicalDeviceProperties2(gpu(), &phys_dev_props_2);
158             m_errorMonitor->VerifyFound();
159         }
160     }
161 }
162 
TEST_F(VkLayerTest,PrivateDataExtTest)163 TEST_F(VkLayerTest, PrivateDataExtTest) {
164     TEST_DESCRIPTION("Test private data extension use.");
165 
166     if (InstanceExtensionSupported(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME)) {
167         m_instance_extension_names.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
168     } else {
169         printf("%s Did not find required instance extension %s; skipped.\n", kSkipPrefix,
170                VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
171         return;
172     }
173 
174     ASSERT_NO_FATAL_FAILURE(InitFramework());
175 
176     if (IsPlatform(kMockICD) || DeviceSimulation()) {
177         printf("%s Test not supported by MockICD, skipping.\n", kSkipPrefix);
178         return;
179     }
180 
181     if (DeviceExtensionSupported(gpu(), nullptr, VK_EXT_PRIVATE_DATA_EXTENSION_NAME)) {
182         m_device_extension_names.push_back(VK_EXT_PRIVATE_DATA_EXTENSION_NAME);
183     } else {
184         printf("%s Extension %s is not supported.\n", kSkipPrefix, VK_EXT_PRIVATE_DATA_EXTENSION_NAME);
185         return;
186     }
187 
188     PFN_vkGetPhysicalDeviceFeatures2KHR vkGetPhysicalDeviceFeatures2KHR =
189         (PFN_vkGetPhysicalDeviceFeatures2KHR)vk::GetInstanceProcAddr(instance(), "vkGetPhysicalDeviceFeatures2KHR");
190     ASSERT_TRUE(vkGetPhysicalDeviceFeatures2KHR != nullptr);
191 
192     auto private_data_features = LvlInitStruct<VkPhysicalDevicePrivateDataFeaturesEXT>();
193     auto features2 = LvlInitStruct<VkPhysicalDeviceFeatures2KHR>(&private_data_features);
194     vkGetPhysicalDeviceFeatures2KHR(gpu(), &features2);
195 
196     if (private_data_features.privateData == VK_FALSE) {
197         printf("%s privateData feature is not supported.\n", kSkipPrefix);
198         return;
199     }
200 
201     ASSERT_NO_FATAL_FAILURE(InitState(nullptr, &features2));
202 
203     PFN_vkDestroyPrivateDataSlotEXT pfn_vkDestroyPrivateDataSlotEXT =
204         (PFN_vkDestroyPrivateDataSlotEXT)vk::GetDeviceProcAddr(m_device->handle(), "vkDestroyPrivateDataSlotEXT");
205     PFN_vkCreatePrivateDataSlotEXT pfn_vkCreatePrivateDataSlotEXT =
206         (PFN_vkCreatePrivateDataSlotEXT)vk::GetDeviceProcAddr(m_device->handle(), "vkCreatePrivateDataSlotEXT");
207     PFN_vkGetPrivateDataEXT pfn_vkGetPrivateDataEXT =
208         (PFN_vkGetPrivateDataEXT)vk::GetDeviceProcAddr(m_device->handle(), "vkGetPrivateDataEXT");
209     PFN_vkSetPrivateDataEXT pfn_vkSetPrivateDataEXT =
210         (PFN_vkSetPrivateDataEXT)vk::GetDeviceProcAddr(m_device->handle(), "vkSetPrivateDataEXT");
211 
212     VkPrivateDataSlotEXT data_slot;
213     VkPrivateDataSlotCreateInfoEXT data_create_info;
214     data_create_info.sType = VK_STRUCTURE_TYPE_PRIVATE_DATA_SLOT_CREATE_INFO_EXT;
215     data_create_info.pNext = NULL;
216     data_create_info.flags = 0;
217     VkResult err = pfn_vkCreatePrivateDataSlotEXT(m_device->handle(), &data_create_info, NULL, &data_slot);
218     if (err != VK_SUCCESS) {
219         printf("%s Failed to create private data slot, VkResult %d.\n", kSkipPrefix, err);
220     }
221 
222     VkSampler sampler;
223     VkSamplerCreateInfo sampler_info;
224     sampler_info.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO;
225     sampler_info.pNext = NULL;
226     sampler_info.flags = 0;
227     sampler_info.magFilter = VK_FILTER_LINEAR;
228     sampler_info.minFilter = VK_FILTER_LINEAR;
229     sampler_info.mipmapMode = VK_SAMPLER_MIPMAP_MODE_LINEAR;
230     sampler_info.addressModeU = VK_SAMPLER_ADDRESS_MODE_REPEAT;
231     sampler_info.addressModeV = VK_SAMPLER_ADDRESS_MODE_REPEAT;
232     sampler_info.addressModeW = VK_SAMPLER_ADDRESS_MODE_REPEAT;
233     sampler_info.mipLodBias = 0.0f;
234     sampler_info.anisotropyEnable = VK_FALSE;
235     sampler_info.maxAnisotropy = 16;
236     sampler_info.compareEnable = VK_FALSE;
237     sampler_info.compareOp = VK_COMPARE_OP_ALWAYS;
238     sampler_info.minLod = 0.0f;
239     sampler_info.maxLod = 0.0f;
240     sampler_info.borderColor = VK_BORDER_COLOR_INT_OPAQUE_BLACK;
241     sampler_info.unnormalizedCoordinates = VK_FALSE;
242     vk::CreateSampler(m_device->handle(), &sampler_info, NULL, &sampler);
243 
244     static const uint64_t data_value = 0x70AD;
245     err = pfn_vkSetPrivateDataEXT(m_device->handle(), VK_OBJECT_TYPE_SAMPLER, (uint64_t)sampler, data_slot, data_value);
246     if (err != VK_SUCCESS) {
247         printf("%s Failed to set private data. VkResult = %d", kSkipPrefix, err);
248     }
249     m_errorMonitor->ExpectSuccess();
250     uint64_t data;
251     pfn_vkGetPrivateDataEXT(m_device->handle(), VK_OBJECT_TYPE_SAMPLER, (uint64_t)sampler, data_slot, &data);
252     if (data != data_value) {
253         m_errorMonitor->SetError("Got unexpected private data, %s.\n");
254     }
255     pfn_vkDestroyPrivateDataSlotEXT(m_device->handle(), data_slot, NULL);
256     vk::DestroySampler(m_device->handle(), sampler, NULL);
257     m_errorMonitor->VerifyNotFound();
258 }
259 
TEST_F(VkLayerTest,PrivateDataFeature)260 TEST_F(VkLayerTest, PrivateDataFeature) {
261     TEST_DESCRIPTION("Test privateData feature not being enabled.");
262 
263     ASSERT_NO_FATAL_FAILURE(InitFramework());
264 
265     if (IsPlatform(kMockICD) || DeviceSimulation()) {
266         printf("%s Test not supported by MockICD, skipping.\n", kSkipPrefix);
267         return;
268     }
269 
270     if (DeviceExtensionSupported(gpu(), nullptr, VK_EXT_PRIVATE_DATA_EXTENSION_NAME)) {
271         m_device_extension_names.push_back(VK_EXT_PRIVATE_DATA_EXTENSION_NAME);
272     } else {
273         printf("%s Extension %s is not supported.\n", kSkipPrefix, VK_EXT_PRIVATE_DATA_EXTENSION_NAME);
274         return;
275     }
276     // feature not enabled
277     ASSERT_NO_FATAL_FAILURE(InitState());
278 
279     PFN_vkCreatePrivateDataSlotEXT vkCreatePrivateDataSlotEXT =
280         (PFN_vkCreatePrivateDataSlotEXT)vk::GetDeviceProcAddr(m_device->handle(), "vkCreatePrivateDataSlotEXT");
281 
282     VkPrivateDataSlotEXT data_slot;
283     VkPrivateDataSlotCreateInfoEXT data_create_info;
284     data_create_info.sType = VK_STRUCTURE_TYPE_PRIVATE_DATA_SLOT_CREATE_INFO_EXT;
285     data_create_info.pNext = NULL;
286     data_create_info.flags = 0;
287     m_errorMonitor->SetUnexpectedError("VUID-vkCreatePrivateDataSlotEXT-privateData-04564");
288     vkCreatePrivateDataSlotEXT(m_device->handle(), &data_create_info, NULL, &data_slot);
289     m_errorMonitor->VerifyNotFound();
290 }
291 
TEST_F(VkLayerTest,CustomStypeStructString)292 TEST_F(VkLayerTest, CustomStypeStructString) {
293     TEST_DESCRIPTION("Positive Test for ability to specify custom pNext structs using a list (string)");
294 
295     // Create a custom structure
296     typedef struct CustomStruct {
297         VkStructureType sType;
298         const void *pNext;
299         uint32_t custom_data;
300     } CustomStruct;
301 
302     uint32_t custom_stype = 3000300000;
303     CustomStruct custom_struct;
304     custom_struct.pNext = nullptr;
305     custom_struct.sType = static_cast<VkStructureType>(custom_stype);
306     custom_struct.custom_data = 44;
307 
308     // Communicate list of structinfo pairs to layers
309     auto stype_list = CustomStypeList("3000300000,24");
310     ASSERT_NO_FATAL_FAILURE(InitFramework(m_errorMonitor, stype_list.pnext));
311     ASSERT_NO_FATAL_FAILURE(InitState());
312 
313     uint32_t queue_family_index = 0;
314     VkBufferCreateInfo buffer_create_info = {};
315     buffer_create_info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
316     buffer_create_info.size = 1024;
317     buffer_create_info.usage = VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT;
318     buffer_create_info.queueFamilyIndexCount = 1;
319     buffer_create_info.pQueueFamilyIndices = &queue_family_index;
320     VkBufferObj buffer;
321     buffer.init(*m_device, buffer_create_info);
322     VkBufferView buffer_view;
323     VkBufferViewCreateInfo bvci = {};
324     bvci.sType = VK_STRUCTURE_TYPE_BUFFER_VIEW_CREATE_INFO;
325     bvci.pNext = &custom_struct;  // Add custom struct through pNext
326     bvci.buffer = buffer.handle();
327     bvci.format = VK_FORMAT_R32_SFLOAT;
328     bvci.range = VK_WHOLE_SIZE;
329 
330     m_errorMonitor->ExpectSuccess(kErrorBit);
331     vk::CreateBufferView(m_device->device(), &bvci, NULL, &buffer_view);
332     m_errorMonitor->VerifyNotFound();
333 
334     vk::DestroyBufferView(m_device->device(), buffer_view, nullptr);
335 }
336 
TEST_F(VkLayerTest,CustomStypeStructArray)337 TEST_F(VkLayerTest, CustomStypeStructArray) {
338     TEST_DESCRIPTION("Positive Test for ability to specify custom pNext structs using a vector of integers");
339 
340     // Create a custom structure
341     typedef struct CustomStruct {
342         VkStructureType sType;
343         const void *pNext;
344         uint32_t custom_data;
345     } CustomStruct;
346 
347     const uint32_t custom_stype_a = 3000300000;
348     CustomStruct custom_struct_a;
349     custom_struct_a.pNext = nullptr;
350     custom_struct_a.sType = static_cast<VkStructureType>(custom_stype_a);
351     custom_struct_a.custom_data = 44;
352 
353     const uint32_t custom_stype_b = 3000300001;
354     CustomStruct custom_struct_b;
355     custom_struct_b.pNext = &custom_struct_a;
356     custom_struct_b.sType = static_cast<VkStructureType>(custom_stype_b);
357     custom_struct_b.custom_data = 88;
358 
359     // Communicate list of structinfo pairs to layers, including a duplicate which should get filtered out
360     std::vector<uint32_t> custom_struct_info = {custom_stype_a,       sizeof(CustomStruct), custom_stype_b,
361                                                 sizeof(CustomStruct), custom_stype_a,       sizeof(CustomStruct)};
362     auto stype_list = CustomStypeList(custom_struct_info);
363     ASSERT_NO_FATAL_FAILURE(InitFramework(m_errorMonitor, stype_list.pnext));
364     ASSERT_NO_FATAL_FAILURE(InitState());
365 
366     uint32_t queue_family_index = 0;
367     VkBufferCreateInfo buffer_create_info = {};
368     buffer_create_info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
369     buffer_create_info.size = 1024;
370     buffer_create_info.usage = VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT;
371     buffer_create_info.queueFamilyIndexCount = 1;
372     buffer_create_info.pQueueFamilyIndices = &queue_family_index;
373     VkBufferObj buffer;
374     buffer.init(*m_device, buffer_create_info);
375     VkBufferView buffer_view;
376     VkBufferViewCreateInfo bvci = {};
377     bvci.sType = VK_STRUCTURE_TYPE_BUFFER_VIEW_CREATE_INFO;
378     bvci.pNext = &custom_struct_b;  // Add custom struct through pNext
379     bvci.buffer = buffer.handle();
380     bvci.format = VK_FORMAT_R32_SFLOAT;
381     bvci.range = VK_WHOLE_SIZE;
382 
383     m_errorMonitor->ExpectSuccess(kErrorBit);
384     vk::CreateBufferView(m_device->device(), &bvci, NULL, &buffer_view);
385     m_errorMonitor->VerifyNotFound();
386 
387     vk::DestroyBufferView(m_device->device(), buffer_view, nullptr);
388 }
389 
TEST_F(VkLayerTest,DuplicateMessageLimit)390 TEST_F(VkLayerTest, DuplicateMessageLimit) {
391     TEST_DESCRIPTION("Use the duplicate_message_id setting and verify correct operation");
392 
393     if (InstanceExtensionSupported(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME)) {
394         m_instance_extension_names.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
395     } else {
396         printf("%s %s Extension not supported, skipping tests\n", kSkipPrefix,
397                VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
398         return;
399     }
400 
401     auto msg_limit = DuplicateMsgLimit(3);
402     ASSERT_NO_FATAL_FAILURE(InitFramework(m_errorMonitor, msg_limit.pnext));
403     ASSERT_NO_FATAL_FAILURE(InitState());
404     PFN_vkGetPhysicalDeviceProperties2KHR vkGetPhysicalDeviceProperties2KHR =
405         (PFN_vkGetPhysicalDeviceProperties2KHR)vk::GetInstanceProcAddr(instance(), "vkGetPhysicalDeviceProperties2KHR");
406     ASSERT_TRUE(vkGetPhysicalDeviceProperties2KHR != nullptr);
407 
408     // Create an invalid pNext structure to trigger the stateless validation warning
409     VkBaseOutStructure bogus_struct{};
410     bogus_struct.sType = static_cast<VkStructureType>(0x33333333);
411     auto properties2 = LvlInitStruct<VkPhysicalDeviceProperties2KHR>(&bogus_struct);
412 
413     // Should get the first three errors just fine
414     m_errorMonitor->SetDesiredFailureMsg((kErrorBit | kWarningBit), "VUID-VkPhysicalDeviceProperties2-pNext-pNext");
415     vkGetPhysicalDeviceProperties2KHR(gpu(), &properties2);
416     m_errorMonitor->VerifyFound();
417     m_errorMonitor->SetDesiredFailureMsg((kErrorBit | kWarningBit), "VUID-VkPhysicalDeviceProperties2-pNext-pNext");
418     vkGetPhysicalDeviceProperties2KHR(gpu(), &properties2);
419     m_errorMonitor->VerifyFound();
420     m_errorMonitor->SetDesiredFailureMsg((kErrorBit | kWarningBit), "VUID-VkPhysicalDeviceProperties2-pNext-pNext");
421     vkGetPhysicalDeviceProperties2KHR(gpu(), &properties2);
422     m_errorMonitor->VerifyFound();
423 
424     // Limit should prevent the message from coming through a fourth time
425     m_errorMonitor->ExpectSuccess(kErrorBit | kWarningBit);
426     vkGetPhysicalDeviceProperties2KHR(gpu(), &properties2);
427     m_errorMonitor->VerifyNotFound();
428 }
429 
TEST_F(VkLayerTest,MessageIdFilterString)430 TEST_F(VkLayerTest, MessageIdFilterString) {
431     TEST_DESCRIPTION("Validate that message id string filtering is working");
432 
433     // This test would normally produce an unexpected error or two.  Use the message filter instead of
434     // the error_monitor's SetUnexpectedError to test the filtering.
435     auto filter_setting = MessageIdFilter("VUID-VkRenderPassCreateInfo-pNext-01963");
436     ASSERT_NO_FATAL_FAILURE(InitFramework(m_errorMonitor, filter_setting.pnext));
437 
438     if (DeviceExtensionSupported(gpu(), nullptr, VK_KHR_MAINTENANCE_2_EXTENSION_NAME)) {
439         m_device_extension_names.push_back(VK_KHR_MAINTENANCE_2_EXTENSION_NAME);
440     } else {
441         printf("%s Extension %s is not supported.\n", kSkipPrefix, VK_KHR_MAINTENANCE_2_EXTENSION_NAME);
442         return;
443     }
444     ASSERT_NO_FATAL_FAILURE(InitState());
445     VkAttachmentDescription attach = {0,
446                                       VK_FORMAT_R8G8B8A8_UNORM,
447                                       VK_SAMPLE_COUNT_1_BIT,
448                                       VK_ATTACHMENT_LOAD_OP_DONT_CARE,
449                                       VK_ATTACHMENT_STORE_OP_DONT_CARE,
450                                       VK_ATTACHMENT_LOAD_OP_DONT_CARE,
451                                       VK_ATTACHMENT_STORE_OP_DONT_CARE,
452                                       VK_IMAGE_LAYOUT_UNDEFINED,
453                                       VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL};
454     VkAttachmentReference ref = {0, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL};
455     VkSubpassDescription subpass = {0, VK_PIPELINE_BIND_POINT_GRAPHICS, 1, &ref, 0, nullptr, nullptr, nullptr, 0, nullptr};
456     VkInputAttachmentAspectReference iaar = {0, 0, VK_IMAGE_ASPECT_METADATA_BIT};
457     VkRenderPassInputAttachmentAspectCreateInfo rpiaaci = {VK_STRUCTURE_TYPE_RENDER_PASS_INPUT_ATTACHMENT_ASPECT_CREATE_INFO,
458                                                            nullptr, 1, &iaar};
459     VkRenderPassCreateInfo rpci = {VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, &rpiaaci, 0, 1, &attach, 1, &subpass, 0, nullptr};
460     m_errorMonitor->SetUnexpectedError("VUID-VkRenderPassCreateInfo2-attachment-02525");
461     TestRenderPassCreate(m_errorMonitor, m_device->device(), &rpci, false, "VUID-VkInputAttachmentAspectReference-aspectMask-01964",
462                          nullptr);
463 }
464 
TEST_F(VkLayerTest,MessageIdFilterHexInt)465 TEST_F(VkLayerTest, MessageIdFilterHexInt) {
466     TEST_DESCRIPTION("Validate that message id hex int filtering is working");
467 
468     // This test would normally produce an unexpected error or two.  Use the message filter instead of
469     // the error_monitor's SetUnexpectedError to test the filtering.
470     auto filter_setting = MessageIdFilter("0xa19880e3");
471     ASSERT_NO_FATAL_FAILURE(InitFramework(m_errorMonitor, filter_setting.pnext));
472 
473     if (DeviceExtensionSupported(gpu(), nullptr, VK_KHR_MAINTENANCE_2_EXTENSION_NAME)) {
474         m_device_extension_names.push_back(VK_KHR_MAINTENANCE_2_EXTENSION_NAME);
475     } else {
476         printf("%s Extension %s is not supported.\n", kSkipPrefix, VK_KHR_MAINTENANCE_2_EXTENSION_NAME);
477         return;
478     }
479     ASSERT_NO_FATAL_FAILURE(InitState());
480     VkAttachmentDescription attach = {0,
481                                       VK_FORMAT_R8G8B8A8_UNORM,
482                                       VK_SAMPLE_COUNT_1_BIT,
483                                       VK_ATTACHMENT_LOAD_OP_DONT_CARE,
484                                       VK_ATTACHMENT_STORE_OP_DONT_CARE,
485                                       VK_ATTACHMENT_LOAD_OP_DONT_CARE,
486                                       VK_ATTACHMENT_STORE_OP_DONT_CARE,
487                                       VK_IMAGE_LAYOUT_UNDEFINED,
488                                       VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL};
489     VkAttachmentReference ref = {0, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL};
490     VkSubpassDescription subpass = {0, VK_PIPELINE_BIND_POINT_GRAPHICS, 1, &ref, 0, nullptr, nullptr, nullptr, 0, nullptr};
491     VkInputAttachmentAspectReference iaar = {0, 0, VK_IMAGE_ASPECT_METADATA_BIT};
492     VkRenderPassInputAttachmentAspectCreateInfo rpiaaci = {VK_STRUCTURE_TYPE_RENDER_PASS_INPUT_ATTACHMENT_ASPECT_CREATE_INFO,
493                                                            nullptr, 1, &iaar};
494     VkRenderPassCreateInfo rpci = {VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, &rpiaaci, 0, 1, &attach, 1, &subpass, 0, nullptr};
495     m_errorMonitor->SetUnexpectedError("VUID-VkRenderPassCreateInfo2-attachment-02525");
496     TestRenderPassCreate(m_errorMonitor, m_device->device(), &rpci, false, "VUID-VkInputAttachmentAspectReference-aspectMask-01964",
497                          nullptr);
498 }
499 
TEST_F(VkLayerTest,MessageIdFilterInt)500 TEST_F(VkLayerTest, MessageIdFilterInt) {
501     TEST_DESCRIPTION("Validate that message id decimal int filtering is working");
502 
503     // This test would normally produce an unexpected error or two.  Use the message filter instead of
504     // the error_monitor's SetUnexpectedError to test the filtering.
505     auto filter_setting = MessageIdFilter("2711126243");
506     ASSERT_NO_FATAL_FAILURE(InitFramework(m_errorMonitor, filter_setting.pnext));
507 
508     if (DeviceExtensionSupported(gpu(), nullptr, VK_KHR_MAINTENANCE_2_EXTENSION_NAME)) {
509         m_device_extension_names.push_back(VK_KHR_MAINTENANCE_2_EXTENSION_NAME);
510     } else {
511         printf("%s Extension %s is not supported.\n", kSkipPrefix, VK_KHR_MAINTENANCE_2_EXTENSION_NAME);
512         return;
513     }
514     ASSERT_NO_FATAL_FAILURE(InitState());
515     VkAttachmentDescription attach = {0,
516                                       VK_FORMAT_R8G8B8A8_UNORM,
517                                       VK_SAMPLE_COUNT_1_BIT,
518                                       VK_ATTACHMENT_LOAD_OP_DONT_CARE,
519                                       VK_ATTACHMENT_STORE_OP_DONT_CARE,
520                                       VK_ATTACHMENT_LOAD_OP_DONT_CARE,
521                                       VK_ATTACHMENT_STORE_OP_DONT_CARE,
522                                       VK_IMAGE_LAYOUT_UNDEFINED,
523                                       VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL};
524     VkAttachmentReference ref = {0, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL};
525     VkSubpassDescription subpass = {0, VK_PIPELINE_BIND_POINT_GRAPHICS, 1, &ref, 0, nullptr, nullptr, nullptr, 0, nullptr};
526     VkInputAttachmentAspectReference iaar = {0, 0, VK_IMAGE_ASPECT_METADATA_BIT};
527     VkRenderPassInputAttachmentAspectCreateInfo rpiaaci = {VK_STRUCTURE_TYPE_RENDER_PASS_INPUT_ATTACHMENT_ASPECT_CREATE_INFO,
528                                                            nullptr, 1, &iaar};
529     VkRenderPassCreateInfo rpci = {VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, &rpiaaci, 0, 1, &attach, 1, &subpass, 0, nullptr};
530     m_errorMonitor->SetUnexpectedError("VUID-VkRenderPassCreateInfo2-attachment-02525");
531     TestRenderPassCreate(m_errorMonitor, m_device->device(), &rpci, false, "VUID-VkInputAttachmentAspectReference-aspectMask-01964",
532                          nullptr);
533 }
534 
535 struct LayerStatusCheckData {
536     std::function<void(const VkDebugUtilsMessengerCallbackDataEXT *pCallbackData, LayerStatusCheckData *)> callback;
537     ErrorMonitor *error_monitor;
538 };
539 
TEST_F(VkLayerTest,LayerInfoMessages)540 TEST_F(VkLayerTest, LayerInfoMessages) {
541     TEST_DESCRIPTION("Ensure layer prints startup status messages.");
542 
543     auto ici = GetInstanceCreateInfo();
544     LayerStatusCheckData callback_data;
545     auto local_callback = [](const VkDebugUtilsMessengerCallbackDataEXT *pCallbackData, LayerStatusCheckData *data) {
546         std::string message(pCallbackData->pMessage);
547         if ((data->error_monitor->GetMessageFlags() & kInformationBit) &&
548             (message.find("UNASSIGNED-khronos-validation-createinstance-status-message") == std::string::npos)) {
549             data->error_monitor->SetError("UNASSIGNED-Khronos-validation-createinstance-status-message-not-found");
550         } else if ((data->error_monitor->GetMessageFlags() & kPerformanceWarningBit) &&
551                    (message.find("UNASSIGNED-khronos-Validation-debug-build-warning-message") == std::string::npos)) {
552             data->error_monitor->SetError("UNASSIGNED-khronos-validation-createinstance-debug-warning-message-not-found");
553         }
554     };
555     callback_data.error_monitor = m_errorMonitor;
556     callback_data.callback = local_callback;
557 
558     VkInstance local_instance;
559 
560     auto callback_create_info = LvlInitStruct<VkDebugUtilsMessengerCreateInfoEXT>();
561     callback_create_info.messageSeverity = VK_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT;
562     callback_create_info.messageType = VK_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT;
563     callback_create_info.pfnUserCallback = DebugUtilsCallback;
564     callback_create_info.pUserData = &callback_data;
565     ici.pNext = &callback_create_info;
566 
567     // Create an instance, error if layer status INFO message not found
568     m_errorMonitor->ExpectSuccess();
569     ASSERT_VK_SUCCESS(vk::CreateInstance(&ici, nullptr, &local_instance));
570     m_errorMonitor->VerifyNotFound();
571     vk::DestroyInstance(local_instance, nullptr);
572 
573 #ifndef NDEBUG
574     // Create an instance, error if layer DEBUG_BUILD warning message not found
575     callback_create_info.messageSeverity = VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT;
576     callback_create_info.messageType = VK_DEBUG_UTILS_MESSAGE_TYPE_PERFORMANCE_BIT_EXT;
577     m_errorMonitor->ExpectSuccess();
578     ASSERT_VK_SUCCESS(vk::CreateInstance(&ici, nullptr, &local_instance));
579     m_errorMonitor->VerifyNotFound();
580     vk::DestroyInstance(local_instance, nullptr);
581 #endif
582 }
583 
TEST_F(VkLayerTest,RequiredParameter)584 TEST_F(VkLayerTest, RequiredParameter) {
585     TEST_DESCRIPTION("Specify VK_NULL_HANDLE, NULL, and 0 for required handle, pointer, array, and array count parameters");
586 
587     ASSERT_NO_FATAL_FAILURE(Init());
588 
589     m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "required parameter pFeatures specified as NULL");
590     // Specify NULL for a pointer to a handle
591     // Expected to trigger an error with
592     // parameter_validation::validate_required_pointer
593     vk::GetPhysicalDeviceFeatures(gpu(), NULL);
594     m_errorMonitor->VerifyFound();
595 
596     m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "required parameter pQueueFamilyPropertyCount specified as NULL");
597     // Specify NULL for pointer to array count
598     // Expected to trigger an error with parameter_validation::validate_array
599     vk::GetPhysicalDeviceQueueFamilyProperties(gpu(), NULL, NULL);
600     m_errorMonitor->VerifyFound();
601 
602     m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdSetViewport-viewportCount-arraylength");
603     // Specify 0 for a required array count
604     // Expected to trigger an error with parameter_validation::validate_array
605     VkViewport viewport = {0.0f, 0.0f, 64.0f, 64.0f, 0.0f, 1.0f};
606     m_commandBuffer->SetViewport(0, 0, &viewport);
607     m_errorMonitor->VerifyFound();
608 
609     m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCreateImage-pCreateInfo-parameter");
610     // Specify a null pImageCreateInfo struct pointer
611     VkImage test_image;
612     vk::CreateImage(device(), NULL, NULL, &test_image);
613     m_errorMonitor->VerifyFound();
614 
615     m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdSetViewport-pViewports-parameter");
616     // Specify NULL for a required array
617     // Expected to trigger an error with parameter_validation::validate_array
618     m_commandBuffer->SetViewport(0, 1, NULL);
619     m_errorMonitor->VerifyFound();
620 
621     m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "required parameter memory specified as VK_NULL_HANDLE");
622     // Specify VK_NULL_HANDLE for a required handle
623     // Expected to trigger an error with
624     // parameter_validation::validate_required_handle
625     vk::UnmapMemory(device(), VK_NULL_HANDLE);
626     m_errorMonitor->VerifyFound();
627 
628     m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "required parameter pFences[0] specified as VK_NULL_HANDLE");
629     // Specify VK_NULL_HANDLE for a required handle array entry
630     // Expected to trigger an error with
631     // parameter_validation::validate_required_handle_array
632     VkFence fence = VK_NULL_HANDLE;
633     vk::ResetFences(device(), 1, &fence);
634     m_errorMonitor->VerifyFound();
635 
636     m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "required parameter pAllocateInfo specified as NULL");
637     // Specify NULL for a required struct pointer
638     // Expected to trigger an error with
639     // parameter_validation::validate_struct_type
640     VkDeviceMemory memory = VK_NULL_HANDLE;
641     vk::AllocateMemory(device(), NULL, NULL, &memory);
642     m_errorMonitor->VerifyFound();
643 
644     m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "value of faceMask must not be 0");
645     // Specify 0 for a required VkFlags parameter
646     // Expected to trigger an error with parameter_validation::validate_flags
647     m_commandBuffer->SetStencilReference(0, 0);
648     m_errorMonitor->VerifyFound();
649 
650     m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "value of pSubmits[0].pWaitDstStageMask[0] must not be 0");
651     // Specify 0 for a required VkFlags array entry
652     // Expected to trigger an error with
653     // parameter_validation::validate_flags_array
654     VkSemaphore semaphore = VK_NULL_HANDLE;
655     VkPipelineStageFlags stageFlags = 0;
656     VkSubmitInfo submitInfo = {};
657     submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
658     submitInfo.waitSemaphoreCount = 1;
659     submitInfo.pWaitSemaphores = &semaphore;
660     submitInfo.pWaitDstStageMask = &stageFlags;
661     vk::QueueSubmit(m_device->m_queue, 1, &submitInfo, VK_NULL_HANDLE);
662     m_errorMonitor->VerifyFound();
663 
664     m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkSubmitInfo-sType-sType");
665     stageFlags = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT;
666     // Set a bogus sType and see what happens
667     submitInfo.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
668     submitInfo.waitSemaphoreCount = 1;
669     submitInfo.pWaitSemaphores = &semaphore;
670     submitInfo.pWaitDstStageMask = &stageFlags;
671     vk::QueueSubmit(m_device->m_queue, 1, &submitInfo, VK_NULL_HANDLE);
672     m_errorMonitor->VerifyFound();
673 
674     m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkSubmitInfo-pWaitSemaphores-parameter");
675     stageFlags = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT;
676     submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
677     submitInfo.waitSemaphoreCount = 1;
678     // Set a null pointer for pWaitSemaphores
679     submitInfo.pWaitSemaphores = NULL;
680     submitInfo.pWaitDstStageMask = &stageFlags;
681     vk::QueueSubmit(m_device->m_queue, 1, &submitInfo, VK_NULL_HANDLE);
682     m_errorMonitor->VerifyFound();
683 
684     m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCreateRenderPass-pCreateInfo-parameter");
685     VkRenderPass render_pass;
686     vk::CreateRenderPass(device(), nullptr, nullptr, &render_pass);
687     m_errorMonitor->VerifyFound();
688 }
689 
TEST_F(VkLayerTest,SpecLinks)690 TEST_F(VkLayerTest, SpecLinks) {
691     TEST_DESCRIPTION("Test that spec links in a typical error message are well-formed");
692     ASSERT_NO_FATAL_FAILURE(InitFramework());
693 
694     if (DeviceExtensionSupported(gpu(), nullptr, VK_KHR_MAINTENANCE_2_EXTENSION_NAME)) {
695         m_device_extension_names.push_back(VK_KHR_MAINTENANCE_2_EXTENSION_NAME);
696     }
697     ASSERT_NO_FATAL_FAILURE(InitState());
698 
699 #ifdef ANNOTATED_SPEC_LINK
700     bool test_annotated_spec_link = true;
701 #else   // ANNOTATED_SPEC_LINK
702     bool test_annotated_spec_link = false;
703 #endif  // ANNOTATED_SPEC_LINK
704 
705     std::string spec_version;
706     if (test_annotated_spec_link) {
707         std::string major_version = std::to_string(VK_VERSION_MAJOR(VK_HEADER_VERSION_COMPLETE));
708         std::string minor_version = std::to_string(VK_VERSION_MINOR(VK_HEADER_VERSION_COMPLETE));
709         std::string patch_version = std::to_string(VK_VERSION_PATCH(VK_HEADER_VERSION_COMPLETE));
710         spec_version = "doc/view/" + major_version + "." + minor_version + "." + patch_version + ".0/windows";
711     } else {
712         spec_version = "registry/vulkan/specs";
713     }
714 
715     m_errorMonitor->SetDesiredFailureMsg(kErrorBit, spec_version);
716     vk::GetPhysicalDeviceFeatures(gpu(), NULL);
717     m_errorMonitor->VerifyFound();
718 
719     // Now generate a 'default' message and check the link
720     bool ycbcr_support = (DeviceExtensionEnabled(VK_KHR_SAMPLER_YCBCR_CONVERSION_EXTENSION_NAME) ||
721                           (DeviceValidationVersion() >= VK_API_VERSION_1_1));
722     bool maintenance2_support =
723         (DeviceExtensionEnabled(VK_KHR_MAINTENANCE_2_EXTENSION_NAME) || (DeviceValidationVersion() >= VK_API_VERSION_1_1));
724 
725     if (!((m_device->format_properties(VK_FORMAT_R8_UINT).optimalTilingFeatures & VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT) &&
726           (ycbcr_support ^ maintenance2_support))) {
727         printf("%s Device does not support format and extensions required, skipping test case", kSkipPrefix);
728         return;
729     }
730 
731     VkImageCreateInfo imageInfo = {VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
732                                    nullptr,
733                                    0,
734                                    VK_IMAGE_TYPE_2D,
735                                    VK_FORMAT_R8_UINT,
736                                    {128, 128, 1},
737                                    1,
738                                    1,
739                                    VK_SAMPLE_COUNT_1_BIT,
740                                    VK_IMAGE_TILING_OPTIMAL,
741                                    VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT,
742                                    VK_SHARING_MODE_EXCLUSIVE,
743                                    0,
744                                    nullptr,
745                                    VK_IMAGE_LAYOUT_UNDEFINED};
746     imageInfo.flags = VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT;
747     VkImageObj mutImage(m_device);
748     mutImage.init(&imageInfo);
749     ASSERT_TRUE(mutImage.initialized());
750 
751     VkImageViewCreateInfo imgViewInfo = {};
752     imgViewInfo.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
753     imgViewInfo.viewType = VK_IMAGE_VIEW_TYPE_2D;
754     imgViewInfo.format = VK_FORMAT_B8G8R8A8_UNORM;  // different than createImage
755     imgViewInfo.subresourceRange.layerCount = 1;
756     imgViewInfo.subresourceRange.baseMipLevel = 0;
757     imgViewInfo.subresourceRange.levelCount = 1;
758     imgViewInfo.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
759     imgViewInfo.image = mutImage.handle();
760 
761     // VUIDs 01759 and 01760 should generate 'default' spec URLs, to search the registry
762     CreateImageViewTest(*this, &imgViewInfo, "Vulkan-Docs/search");
763 }
764 
TEST_F(VkLayerTest,UsePnextOnlyStructWithoutExtensionEnabled)765 TEST_F(VkLayerTest, UsePnextOnlyStructWithoutExtensionEnabled) {
766     TEST_DESCRIPTION(
767         "Validate that using VkPipelineTessellationDomainOriginStateCreateInfo in VkPipelineTessellationStateCreateInfo.pNext "
768         "in a 1.0 context will generate an error message.");
769 
770     SetTargetApiVersion(VK_API_VERSION_1_0);
771 
772     ASSERT_NO_FATAL_FAILURE(Init());
773     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
774 
775     if (!m_device->phy().features().tessellationShader) {
776         printf("%s Device does not support tessellation shaders; skipped.\n", kSkipPrefix);
777         return;
778     }
779     VkShaderObj vs(m_device, bindStateVertShaderText, VK_SHADER_STAGE_VERTEX_BIT, this);
780     VkShaderObj tcs(m_device, bindStateTscShaderText, VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT, this);
781     VkShaderObj tes(m_device, bindStateTeshaderText, VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT, this);
782     VkShaderObj fs(m_device, bindStateFragShaderText, VK_SHADER_STAGE_FRAGMENT_BIT, this);
783     VkPipelineInputAssemblyStateCreateInfo iasci{VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO, nullptr, 0,
784                                                  VK_PRIMITIVE_TOPOLOGY_PATCH_LIST, VK_FALSE};
785     VkPipelineTessellationDomainOriginStateCreateInfo tessellationDomainOriginStateInfo = {
786         VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_DOMAIN_ORIGIN_STATE_CREATE_INFO, VK_NULL_HANDLE,
787         VK_TESSELLATION_DOMAIN_ORIGIN_UPPER_LEFT};
788     VkPipelineTessellationStateCreateInfo tsci{VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_STATE_CREATE_INFO,
789                                                &tessellationDomainOriginStateInfo, 0, 3};
790     CreatePipelineHelper pipe(*this);
791     pipe.InitInfo();
792     pipe.gp_ci_.pTessellationState = &tsci;
793     pipe.gp_ci_.pInputAssemblyState = &iasci;
794     pipe.shader_stages_ = {vs.GetStageCreateInfo(), tcs.GetStageCreateInfo(), tes.GetStageCreateInfo(), fs.GetStageCreateInfo()};
795     pipe.InitState();
796     m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkGraphicsPipelineCreateInfo-pNext-pNext");
797     m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkPipelineTessellationStateCreateInfo-pNext-pNext");
798     pipe.CreateGraphicsPipeline();
799     m_errorMonitor->VerifyFound();
800 }
801 
TEST_F(VkLayerTest,PnextOnlyStructValidation)802 TEST_F(VkLayerTest, PnextOnlyStructValidation) {
803     TEST_DESCRIPTION("See if checks occur on structs ONLY used in pnext chains.");
804 
805     if (!(CheckDescriptorIndexingSupportAndInitFramework(this, m_instance_extension_names, m_device_extension_names, NULL,
806                                                          m_errorMonitor))) {
807         printf("Descriptor indexing or one of its dependencies not supported, skipping tests\n");
808         return;
809     }
810 
811     PFN_vkGetPhysicalDeviceFeatures2KHR vkGetPhysicalDeviceFeatures2KHR =
812         (PFN_vkGetPhysicalDeviceFeatures2KHR)vk::GetInstanceProcAddr(instance(), "vkGetPhysicalDeviceFeatures2KHR");
813     ASSERT_TRUE(vkGetPhysicalDeviceFeatures2KHR != nullptr);
814 
815     // Create a device passing in a bad PdevFeatures2 value
816     auto indexing_features = LvlInitStruct<VkPhysicalDeviceDescriptorIndexingFeaturesEXT>();
817     auto features2 = LvlInitStruct<VkPhysicalDeviceFeatures2KHR>(&indexing_features);
818     vkGetPhysicalDeviceFeatures2KHR(gpu(), &features2);
819     // Set one of the features values to an invalid boolean value
820     indexing_features.descriptorBindingUniformBufferUpdateAfterBind = 800;
821 
822     uint32_t queue_node_count;
823     vk::GetPhysicalDeviceQueueFamilyProperties(gpu(), &queue_node_count, NULL);
824     VkQueueFamilyProperties *queue_props = new VkQueueFamilyProperties[queue_node_count];
825     vk::GetPhysicalDeviceQueueFamilyProperties(gpu(), &queue_node_count, queue_props);
826     float priorities[] = {1.0f};
827     VkDeviceQueueCreateInfo queue_info{};
828     queue_info.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
829     queue_info.pNext = NULL;
830     queue_info.flags = 0;
831     queue_info.queueFamilyIndex = 0;
832     queue_info.queueCount = 1;
833     queue_info.pQueuePriorities = &priorities[0];
834     VkDeviceCreateInfo dev_info = {};
835     dev_info.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
836     dev_info.pNext = NULL;
837     dev_info.queueCreateInfoCount = 1;
838     dev_info.pQueueCreateInfos = &queue_info;
839     dev_info.enabledLayerCount = 0;
840     dev_info.ppEnabledLayerNames = NULL;
841     dev_info.enabledExtensionCount = m_device_extension_names.size();
842     dev_info.ppEnabledExtensionNames = m_device_extension_names.data();
843     dev_info.pNext = &features2;
844     VkDevice dev;
845     m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "is neither VK_TRUE nor VK_FALSE");
846     m_errorMonitor->SetUnexpectedError("Failed to create");
847     vk::CreateDevice(gpu(), &dev_info, NULL, &dev);
848     m_errorMonitor->VerifyFound();
849 }
850 
TEST_F(VkLayerTest,ReservedParameter)851 TEST_F(VkLayerTest, ReservedParameter) {
852     TEST_DESCRIPTION("Specify a non-zero value for a reserved parameter");
853 
854     ASSERT_NO_FATAL_FAILURE(Init());
855 
856     m_errorMonitor->SetDesiredFailureMsg(kErrorBit, " must be 0");
857     // Specify 0 for a reserved VkFlags parameter
858     // Expected to trigger an error with
859     // parameter_validation::validate_reserved_flags
860     VkSemaphore sem_handle = VK_NULL_HANDLE;
861     VkSemaphoreCreateInfo sem_info = {};
862     sem_info.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO;
863     sem_info.flags = 1;
864     vk::CreateSemaphore(device(), &sem_info, NULL, &sem_handle);
865     m_errorMonitor->VerifyFound();
866 }
867 
TEST_F(VkLayerTest,DebugMarkerNameTest)868 TEST_F(VkLayerTest, DebugMarkerNameTest) {
869     TEST_DESCRIPTION("Ensure debug marker object names are printed in debug report output");
870 
871     if (InstanceExtensionSupported(VK_EXT_DEBUG_REPORT_EXTENSION_NAME)) {
872         m_instance_extension_names.push_back(VK_EXT_DEBUG_REPORT_EXTENSION_NAME);
873     } else {
874         printf("%s Did not find required instance extension %s; skipped.\n", kSkipPrefix,
875                VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
876         return;
877     }
878 
879     ASSERT_NO_FATAL_FAILURE(InitFramework(m_errorMonitor));
880     if (DeviceExtensionSupported(gpu(), kValidationLayerName, VK_EXT_DEBUG_MARKER_EXTENSION_NAME)) {
881         m_device_extension_names.push_back(VK_EXT_DEBUG_MARKER_EXTENSION_NAME);
882     } else {
883         printf("%s Debug Marker Extension not supported, skipping test\n", kSkipPrefix);
884         return;
885     }
886     ASSERT_NO_FATAL_FAILURE(InitState());
887 
888     PFN_vkDebugMarkerSetObjectNameEXT fpvkDebugMarkerSetObjectNameEXT =
889         (PFN_vkDebugMarkerSetObjectNameEXT)vk::GetInstanceProcAddr(instance(), "vkDebugMarkerSetObjectNameEXT");
890     if (!(fpvkDebugMarkerSetObjectNameEXT)) {
891         printf("%s Can't find fpvkDebugMarkerSetObjectNameEXT; skipped.\n", kSkipPrefix);
892         return;
893     }
894 
895     if (DeviceSimulation()) {
896         printf("%sSkipping object naming test.\n", kSkipPrefix);
897         return;
898     }
899 
900     VkBuffer buffer;
901     VkDeviceMemory memory_1, memory_2;
902     std::string memory_name = "memory_name";
903 
904     VkBufferCreateInfo buffer_create_info = {};
905     buffer_create_info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
906     buffer_create_info.usage = VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT;
907     buffer_create_info.size = 1;
908 
909     vk::CreateBuffer(device(), &buffer_create_info, nullptr, &buffer);
910 
911     VkMemoryRequirements memRequirements;
912     vk::GetBufferMemoryRequirements(device(), buffer, &memRequirements);
913 
914     VkMemoryAllocateInfo memory_allocate_info = {};
915     memory_allocate_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
916     memory_allocate_info.allocationSize = memRequirements.size;
917     memory_allocate_info.memoryTypeIndex = 0;
918 
919     vk::AllocateMemory(device(), &memory_allocate_info, nullptr, &memory_1);
920     vk::AllocateMemory(device(), &memory_allocate_info, nullptr, &memory_2);
921 
922     VkDebugMarkerObjectNameInfoEXT name_info = {};
923     name_info.sType = VK_STRUCTURE_TYPE_DEBUG_MARKER_OBJECT_NAME_INFO_EXT;
924     name_info.pNext = nullptr;
925     name_info.object = (uint64_t)memory_2;
926     name_info.objectType = VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_MEMORY_EXT;
927     name_info.pObjectName = memory_name.c_str();
928     fpvkDebugMarkerSetObjectNameEXT(device(), &name_info);
929 
930     vk::BindBufferMemory(device(), buffer, memory_1, 0);
931 
932     // Test core_validation layer
933     m_errorMonitor->SetDesiredFailureMsg(kErrorBit, memory_name);
934     vk::BindBufferMemory(device(), buffer, memory_2, 0);
935     m_errorMonitor->VerifyFound();
936 
937     vk::FreeMemory(device(), memory_1, nullptr);
938     memory_1 = VK_NULL_HANDLE;
939     vk::FreeMemory(device(), memory_2, nullptr);
940     memory_2 = VK_NULL_HANDLE;
941     vk::DestroyBuffer(device(), buffer, nullptr);
942     buffer = VK_NULL_HANDLE;
943 
944     VkCommandBuffer commandBuffer;
945     std::string commandBuffer_name = "command_buffer_name";
946     VkCommandPool commandpool_1;
947     VkCommandPool commandpool_2;
948     VkCommandPoolCreateInfo pool_create_info{};
949     pool_create_info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
950     pool_create_info.queueFamilyIndex = m_device->graphics_queue_node_index_;
951     pool_create_info.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT;
952     vk::CreateCommandPool(device(), &pool_create_info, nullptr, &commandpool_1);
953     vk::CreateCommandPool(device(), &pool_create_info, nullptr, &commandpool_2);
954 
955     VkCommandBufferAllocateInfo command_buffer_allocate_info{};
956     command_buffer_allocate_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
957     command_buffer_allocate_info.commandPool = commandpool_1;
958     command_buffer_allocate_info.commandBufferCount = 1;
959     command_buffer_allocate_info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
960     vk::AllocateCommandBuffers(device(), &command_buffer_allocate_info, &commandBuffer);
961 
962     name_info.object = (uint64_t)commandBuffer;
963     name_info.objectType = VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT;
964     name_info.pObjectName = commandBuffer_name.c_str();
965     fpvkDebugMarkerSetObjectNameEXT(device(), &name_info);
966 
967     VkCommandBufferBeginInfo cb_begin_Info = {};
968     cb_begin_Info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
969     cb_begin_Info.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT;
970     vk::BeginCommandBuffer(commandBuffer, &cb_begin_Info);
971 
972     const VkRect2D scissor = {{-1, 0}, {16, 16}};
973     const VkRect2D scissors[] = {scissor, scissor};
974 
975     // Test parameter_validation layer
976     m_errorMonitor->SetDesiredFailureMsg(kErrorBit, commandBuffer_name);
977     vk::CmdSetScissor(commandBuffer, 0, 1, scissors);
978     m_errorMonitor->VerifyFound();
979 
980     // Test object_tracker layer
981     m_errorMonitor->SetDesiredFailureMsg(kErrorBit, commandBuffer_name);
982     vk::FreeCommandBuffers(device(), commandpool_2, 1, &commandBuffer);
983     m_errorMonitor->VerifyFound();
984 
985     vk::DestroyCommandPool(device(), commandpool_1, NULL);
986     vk::DestroyCommandPool(device(), commandpool_2, NULL);
987 }
988 
TEST_F(VkLayerTest,DebugUtilsNameTest)989 TEST_F(VkLayerTest, DebugUtilsNameTest) {
990     TEST_DESCRIPTION("Ensure debug utils object names are printed in debug messenger output");
991 
992     // Skip test if extension not supported
993     if (InstanceExtensionSupported(VK_EXT_DEBUG_UTILS_EXTENSION_NAME)) {
994         m_instance_extension_names.push_back(VK_EXT_DEBUG_UTILS_EXTENSION_NAME);
995     } else {
996         printf("%s Debug Utils Extension not supported, skipping test\n", kSkipPrefix);
997         return;
998     }
999 
1000     ASSERT_NO_FATAL_FAILURE(InitFramework(m_errorMonitor));
1001     ASSERT_NO_FATAL_FAILURE(InitState());
1002 
1003     PFN_vkSetDebugUtilsObjectNameEXT fpvkSetDebugUtilsObjectNameEXT =
1004         (PFN_vkSetDebugUtilsObjectNameEXT)vk::GetInstanceProcAddr(instance(), "vkSetDebugUtilsObjectNameEXT");
1005     ASSERT_TRUE(fpvkSetDebugUtilsObjectNameEXT);  // Must be extant if extension is enabled
1006     PFN_vkCreateDebugUtilsMessengerEXT fpvkCreateDebugUtilsMessengerEXT =
1007         (PFN_vkCreateDebugUtilsMessengerEXT)vk::GetInstanceProcAddr(instance(), "vkCreateDebugUtilsMessengerEXT");
1008     ASSERT_TRUE(fpvkCreateDebugUtilsMessengerEXT);  // Must be extant if extension is enabled
1009     PFN_vkDestroyDebugUtilsMessengerEXT fpvkDestroyDebugUtilsMessengerEXT =
1010         (PFN_vkDestroyDebugUtilsMessengerEXT)vk::GetInstanceProcAddr(instance(), "vkDestroyDebugUtilsMessengerEXT");
1011     ASSERT_TRUE(fpvkDestroyDebugUtilsMessengerEXT);  // Must be extant if extension is enabled
1012     PFN_vkCmdInsertDebugUtilsLabelEXT fpvkCmdInsertDebugUtilsLabelEXT =
1013         (PFN_vkCmdInsertDebugUtilsLabelEXT)vk::GetInstanceProcAddr(instance(), "vkCmdInsertDebugUtilsLabelEXT");
1014     ASSERT_TRUE(fpvkCmdInsertDebugUtilsLabelEXT);  // Must be extant if extension is enabled
1015 
1016     if (DeviceSimulation()) {
1017         printf("%sSkipping object naming test.\n", kSkipPrefix);
1018         return;
1019     }
1020 
1021     DebugUtilsLabelCheckData callback_data;
1022     auto empty_callback = [](const VkDebugUtilsMessengerCallbackDataEXT *pCallbackData, DebugUtilsLabelCheckData *data) {
1023         data->count++;
1024     };
1025     callback_data.count = 0;
1026     callback_data.callback = empty_callback;
1027 
1028     auto callback_create_info = LvlInitStruct<VkDebugUtilsMessengerCreateInfoEXT>();
1029     callback_create_info.messageSeverity =
1030         VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT | VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT;
1031     callback_create_info.messageType = VK_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT;
1032     callback_create_info.pfnUserCallback = DebugUtilsCallback;
1033     callback_create_info.pUserData = &callback_data;
1034     VkDebugUtilsMessengerEXT my_messenger = VK_NULL_HANDLE;
1035     fpvkCreateDebugUtilsMessengerEXT(instance(), &callback_create_info, nullptr, &my_messenger);
1036 
1037     VkBuffer buffer;
1038     VkDeviceMemory memory_1, memory_2;
1039     std::string memory_name = "memory_name";
1040 
1041     VkBufferCreateInfo buffer_create_info = {};
1042     buffer_create_info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
1043     buffer_create_info.usage = VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT;
1044     buffer_create_info.size = 1;
1045 
1046     vk::CreateBuffer(device(), &buffer_create_info, nullptr, &buffer);
1047 
1048     VkMemoryRequirements memRequirements;
1049     vk::GetBufferMemoryRequirements(device(), buffer, &memRequirements);
1050 
1051     VkMemoryAllocateInfo memory_allocate_info = {};
1052     memory_allocate_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
1053     memory_allocate_info.allocationSize = memRequirements.size;
1054     memory_allocate_info.memoryTypeIndex = 0;
1055 
1056     vk::AllocateMemory(device(), &memory_allocate_info, nullptr, &memory_1);
1057     vk::AllocateMemory(device(), &memory_allocate_info, nullptr, &memory_2);
1058 
1059     VkDebugUtilsObjectNameInfoEXT name_info = {};
1060     name_info.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_OBJECT_NAME_INFO_EXT;
1061     name_info.pNext = nullptr;
1062     name_info.objectType = VK_OBJECT_TYPE_DEVICE_MEMORY;
1063     name_info.pObjectName = memory_name.c_str();
1064 
1065     // Pass in bad handle make sure ObjectTracker catches it
1066     m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkDebugUtilsObjectNameInfoEXT-objectType-02590");
1067     name_info.objectHandle = (uint64_t)0xcadecade;
1068     fpvkSetDebugUtilsObjectNameEXT(device(), &name_info);
1069     m_errorMonitor->VerifyFound();
1070 
1071     // Pass in 'unknown' object type and see if parameter validation catches it
1072     m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkDebugUtilsObjectNameInfoEXT-objectType-02589");
1073     name_info.objectHandle = (uint64_t)memory_2;
1074     name_info.objectType = VK_OBJECT_TYPE_UNKNOWN;
1075     fpvkSetDebugUtilsObjectNameEXT(device(), &name_info);
1076     m_errorMonitor->VerifyFound();
1077 
1078     name_info.objectType = VK_OBJECT_TYPE_DEVICE_MEMORY;
1079     fpvkSetDebugUtilsObjectNameEXT(device(), &name_info);
1080 
1081     vk::BindBufferMemory(device(), buffer, memory_1, 0);
1082 
1083     // Test core_validation layer
1084     m_errorMonitor->SetDesiredFailureMsg(kErrorBit, memory_name);
1085     vk::BindBufferMemory(device(), buffer, memory_2, 0);
1086     m_errorMonitor->VerifyFound();
1087 
1088     vk::FreeMemory(device(), memory_1, nullptr);
1089     memory_1 = VK_NULL_HANDLE;
1090     vk::FreeMemory(device(), memory_2, nullptr);
1091     memory_2 = VK_NULL_HANDLE;
1092     vk::DestroyBuffer(device(), buffer, nullptr);
1093     buffer = VK_NULL_HANDLE;
1094 
1095     VkCommandBuffer commandBuffer;
1096     std::string commandBuffer_name = "command_buffer_name";
1097     VkCommandPool commandpool_1;
1098     VkCommandPool commandpool_2;
1099     VkCommandPoolCreateInfo pool_create_info{};
1100     pool_create_info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
1101     pool_create_info.queueFamilyIndex = m_device->graphics_queue_node_index_;
1102     pool_create_info.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT;
1103     vk::CreateCommandPool(device(), &pool_create_info, nullptr, &commandpool_1);
1104     vk::CreateCommandPool(device(), &pool_create_info, nullptr, &commandpool_2);
1105 
1106     VkCommandBufferAllocateInfo command_buffer_allocate_info{};
1107     command_buffer_allocate_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
1108     command_buffer_allocate_info.commandPool = commandpool_1;
1109     command_buffer_allocate_info.commandBufferCount = 1;
1110     command_buffer_allocate_info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
1111     vk::AllocateCommandBuffers(device(), &command_buffer_allocate_info, &commandBuffer);
1112 
1113     name_info.objectHandle = (uint64_t)commandBuffer;
1114     name_info.objectType = VK_OBJECT_TYPE_COMMAND_BUFFER;
1115     name_info.pObjectName = commandBuffer_name.c_str();
1116     fpvkSetDebugUtilsObjectNameEXT(device(), &name_info);
1117 
1118     VkCommandBufferBeginInfo cb_begin_Info = {};
1119     cb_begin_Info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
1120     cb_begin_Info.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT;
1121     vk::BeginCommandBuffer(commandBuffer, &cb_begin_Info);
1122 
1123     const VkRect2D scissor = {{-1, 0}, {16, 16}};
1124     const VkRect2D scissors[] = {scissor, scissor};
1125 
1126     auto command_label = LvlInitStruct<VkDebugUtilsLabelEXT>();
1127     command_label.pLabelName = "Command Label 0123";
1128     command_label.color[0] = 0.;
1129     command_label.color[1] = 1.;
1130     command_label.color[2] = 2.;
1131     command_label.color[3] = 3.0;
1132     bool command_label_test = false;
1133     auto command_label_callback = [command_label, &command_label_test](const VkDebugUtilsMessengerCallbackDataEXT *pCallbackData,
1134                                                                        DebugUtilsLabelCheckData *data) {
1135         data->count++;
1136         command_label_test = false;
1137         if (pCallbackData->cmdBufLabelCount == 1) {
1138             command_label_test = pCallbackData->pCmdBufLabels[0] == command_label;
1139         }
1140     };
1141     callback_data.callback = command_label_callback;
1142 
1143     fpvkCmdInsertDebugUtilsLabelEXT(commandBuffer, &command_label);
1144     // Test parameter_validation layer
1145     m_errorMonitor->SetDesiredFailureMsg(kErrorBit, commandBuffer_name);
1146     vk::CmdSetScissor(commandBuffer, 0, 1, scissors);
1147     m_errorMonitor->VerifyFound();
1148 
1149     // Check the label test
1150     if (!command_label_test) {
1151         ADD_FAILURE() << "Command label '" << command_label.pLabelName << "' not passed to callback.";
1152     }
1153 
1154     // Test object_tracker layer
1155     m_errorMonitor->SetDesiredFailureMsg(kErrorBit, commandBuffer_name);
1156     vk::FreeCommandBuffers(device(), commandpool_2, 1, &commandBuffer);
1157     m_errorMonitor->VerifyFound();
1158 
1159     vk::DestroyCommandPool(device(), commandpool_1, NULL);
1160     vk::DestroyCommandPool(device(), commandpool_2, NULL);
1161     fpvkDestroyDebugUtilsMessengerEXT(instance(), my_messenger, nullptr);
1162 }
1163 
TEST_F(VkLayerTest,InvalidStructSType)1164 TEST_F(VkLayerTest, InvalidStructSType) {
1165     TEST_DESCRIPTION("Specify an invalid VkStructureType for a Vulkan structure's sType field");
1166 
1167     ASSERT_NO_FATAL_FAILURE(Init());
1168 
1169     m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "parameter pAllocateInfo->sType must be");
1170     // Zero struct memory, effectively setting sType to
1171     // VK_STRUCTURE_TYPE_APPLICATION_INFO
1172     // Expected to trigger an error with
1173     // parameter_validation::validate_struct_type
1174     VkMemoryAllocateInfo alloc_info = {};
1175     VkDeviceMemory memory = VK_NULL_HANDLE;
1176     vk::AllocateMemory(device(), &alloc_info, NULL, &memory);
1177     m_errorMonitor->VerifyFound();
1178 
1179     m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "parameter pSubmits[0].sType must be");
1180     // Zero struct memory, effectively setting sType to
1181     // VK_STRUCTURE_TYPE_APPLICATION_INFO
1182     // Expected to trigger an error with
1183     // parameter_validation::validate_struct_type_array
1184     VkSubmitInfo submit_info = {};
1185     vk::QueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
1186     m_errorMonitor->VerifyFound();
1187 }
1188 
TEST_F(VkLayerTest,InvalidStructPNext)1189 TEST_F(VkLayerTest, InvalidStructPNext) {
1190     TEST_DESCRIPTION("Specify an invalid value for a Vulkan structure's pNext field");
1191 
1192     if (InstanceExtensionSupported(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME)) {
1193         m_instance_extension_names.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
1194     } else {
1195         printf("%s Extension %s is not supported.\n", kSkipPrefix, VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
1196         return;
1197     }
1198     ASSERT_NO_FATAL_FAILURE(Init());
1199 
1200     PFN_vkGetPhysicalDeviceProperties2KHR vkGetPhysicalDeviceProperties2KHR =
1201         (PFN_vkGetPhysicalDeviceProperties2KHR)vk::GetInstanceProcAddr(instance(), "vkGetPhysicalDeviceProperties2KHR");
1202     ASSERT_TRUE(vkGetPhysicalDeviceProperties2KHR != nullptr);
1203 
1204     m_errorMonitor->SetDesiredFailureMsg((kErrorBit | kWarningBit), "value of pCreateInfo->pNext must be NULL");
1205     // Set VkMemoryAllocateInfo::pNext to a non-NULL value, when pNext must be NULL.
1206     // Need to pick a function that has no allowed pNext structure types.
1207     // Expected to trigger an error with parameter_validation::validate_struct_pnext
1208     VkEvent event = VK_NULL_HANDLE;
1209     VkEventCreateInfo event_alloc_info = {};
1210     // Zero-initialization will provide the correct sType
1211     VkApplicationInfo app_info = {};
1212     event_alloc_info.sType = VK_STRUCTURE_TYPE_EVENT_CREATE_INFO;
1213     event_alloc_info.pNext = &app_info;
1214     vk::CreateEvent(device(), &event_alloc_info, NULL, &event);
1215     m_errorMonitor->VerifyFound();
1216 
1217     m_errorMonitor->SetDesiredFailureMsg((kErrorBit | kWarningBit), " chain includes a structure with unexpected VkStructureType ");
1218     // Set VkMemoryAllocateInfo::pNext to a non-NULL value, but use
1219     // a function that has allowed pNext structure types and specify
1220     // a structure type that is not allowed.
1221     // Expected to trigger an error with parameter_validation::validate_struct_pnext
1222     VkDeviceMemory memory = VK_NULL_HANDLE;
1223     VkMemoryAllocateInfo memory_alloc_info = {};
1224     memory_alloc_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
1225     memory_alloc_info.pNext = &app_info;
1226     vk::AllocateMemory(device(), &memory_alloc_info, NULL, &memory);
1227     m_errorMonitor->VerifyFound();
1228 
1229     m_errorMonitor->SetDesiredFailureMsg((kErrorBit | kWarningBit), " chain includes a structure with unexpected VkStructureType ");
1230     // Same concept as above, but unlike vkAllocateMemory where VkMemoryAllocateInfo is a const
1231     // in vkGetPhysicalDeviceProperties2, VkPhysicalDeviceProperties2 is not a const
1232     VkPhysicalDeviceProperties2 physical_device_properties2 = {};
1233     physical_device_properties2.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2;
1234     physical_device_properties2.pNext = &app_info;
1235 
1236     vkGetPhysicalDeviceProperties2KHR(gpu(), &physical_device_properties2);
1237     m_errorMonitor->VerifyFound();
1238 }
1239 
TEST_F(VkLayerTest,UnrecognizedValueOutOfRange)1240 TEST_F(VkLayerTest, UnrecognizedValueOutOfRange) {
1241     ASSERT_NO_FATAL_FAILURE(Init());
1242 
1243     m_errorMonitor->SetDesiredFailureMsg(kErrorBit,
1244                                          "does not fall within the begin..end range of the core VkFormat enumeration tokens");
1245     // Specify an invalid VkFormat value
1246     // Expected to trigger an error with
1247     // parameter_validation::validate_ranged_enum
1248     VkFormatProperties format_properties;
1249     vk::GetPhysicalDeviceFormatProperties(gpu(), static_cast<VkFormat>(8000), &format_properties);
1250     m_errorMonitor->VerifyFound();
1251 }
1252 
TEST_F(VkLayerTest,UnrecognizedValueBadMask)1253 TEST_F(VkLayerTest, UnrecognizedValueBadMask) {
1254     ASSERT_NO_FATAL_FAILURE(Init());
1255 
1256     m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "contains flag bits that are not recognized members of");
1257     // Specify an invalid VkFlags bitmask value
1258     // Expected to trigger an error with parameter_validation::validate_flags
1259     VkImageFormatProperties image_format_properties;
1260     vk::GetPhysicalDeviceImageFormatProperties(gpu(), VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_TYPE_2D, VK_IMAGE_TILING_OPTIMAL,
1261                                                static_cast<VkImageUsageFlags>(1 << 25), 0, &image_format_properties);
1262     m_errorMonitor->VerifyFound();
1263 }
1264 
TEST_F(VkLayerTest,UnrecognizedValueBadFlag)1265 TEST_F(VkLayerTest, UnrecognizedValueBadFlag) {
1266     ASSERT_NO_FATAL_FAILURE(Init());
1267 
1268     m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "contains flag bits that are not recognized members of");
1269     // Specify an invalid VkFlags array entry
1270     // Expected to trigger an error with parameter_validation::validate_flags_array
1271     VkSemaphore semaphore;
1272     VkSemaphoreCreateInfo semaphore_create_info{};
1273     semaphore_create_info.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO;
1274     vk::CreateSemaphore(m_device->device(), &semaphore_create_info, nullptr, &semaphore);
1275     // `stage_flags` is set to a value which, currently, is not a defined stage flag
1276     // `VK_IMAGE_ASPECT_FLAG_BITS_MAX_ENUM` works well for this
1277     VkPipelineStageFlags stage_flags = VK_IMAGE_ASPECT_FLAG_BITS_MAX_ENUM;
1278     // `waitSemaphoreCount` *must* be greater than 0 to perform this check
1279     VkSubmitInfo submit_info = {};
1280     submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
1281     submit_info.waitSemaphoreCount = 1;
1282     submit_info.pWaitSemaphores = &semaphore;
1283     submit_info.pWaitDstStageMask = &stage_flags;
1284     vk::QueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
1285     vk::DestroySemaphore(m_device->device(), semaphore, nullptr);
1286 
1287     m_errorMonitor->VerifyFound();
1288 }
1289 
TEST_F(VkLayerTest,UnrecognizedValueBadBool)1290 TEST_F(VkLayerTest, UnrecognizedValueBadBool) {
1291     // Make sure using VK_SAMPLER_ADDRESS_MODE_MIRROR_CLAMP_TO_EDGE doesn't trigger a false positive.
1292     ASSERT_NO_FATAL_FAILURE(InitFramework(m_errorMonitor));
1293     if (DeviceExtensionSupported(gpu(), nullptr, VK_KHR_SAMPLER_MIRROR_CLAMP_TO_EDGE_EXTENSION_NAME)) {
1294         m_device_extension_names.push_back(VK_KHR_SAMPLER_MIRROR_CLAMP_TO_EDGE_EXTENSION_NAME);
1295     } else {
1296         printf("%s VK_KHR_sampler_mirror_clamp_to_edge extension not supported, skipping test\n", kSkipPrefix);
1297         return;
1298     }
1299     ASSERT_NO_FATAL_FAILURE(InitState());
1300 
1301     // Specify an invalid VkBool32 value, expecting a warning with parameter_validation::validate_bool32
1302     VkSamplerCreateInfo sampler_info = SafeSaneSamplerCreateInfo();
1303     sampler_info.addressModeU = VK_SAMPLER_ADDRESS_MODE_MIRROR_CLAMP_TO_EDGE;
1304     sampler_info.addressModeV = VK_SAMPLER_ADDRESS_MODE_MIRROR_CLAMP_TO_EDGE;
1305     sampler_info.addressModeW = VK_SAMPLER_ADDRESS_MODE_MIRROR_CLAMP_TO_EDGE;
1306 
1307     // Not VK_TRUE or VK_FALSE
1308     sampler_info.anisotropyEnable = 3;
1309     CreateSamplerTest(*this, &sampler_info, "is neither VK_TRUE nor VK_FALSE");
1310 }
1311 
TEST_F(VkLayerTest,UnrecognizedValueMaxEnum)1312 TEST_F(VkLayerTest, UnrecognizedValueMaxEnum) {
1313     ASSERT_NO_FATAL_FAILURE(Init());
1314 
1315     // Specify MAX_ENUM
1316     VkFormatProperties format_properties;
1317     m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "does not fall within the begin..end range");
1318     vk::GetPhysicalDeviceFormatProperties(gpu(), VK_FORMAT_MAX_ENUM, &format_properties);
1319     m_errorMonitor->VerifyFound();
1320 }
1321 
TEST_F(VkLayerTest,SubmitSignaledFence)1322 TEST_F(VkLayerTest, SubmitSignaledFence) {
1323     vk_testing::Fence testFence;
1324 
1325     m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "submitted in SIGNALED state.  Fences must be reset before being submitted");
1326 
1327     VkFenceCreateInfo fenceInfo = {};
1328     fenceInfo.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
1329     fenceInfo.pNext = NULL;
1330     fenceInfo.flags = VK_FENCE_CREATE_SIGNALED_BIT;
1331 
1332     ASSERT_NO_FATAL_FAILURE(Init());
1333     ASSERT_NO_FATAL_FAILURE(InitViewport());
1334     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
1335 
1336     m_commandBuffer->begin();
1337     m_commandBuffer->ClearAllBuffers(m_renderTargets, m_clear_color, nullptr, m_depth_clear_color, m_stencil_clear_color);
1338     m_commandBuffer->end();
1339 
1340     testFence.init(*m_device, fenceInfo);
1341 
1342     VkSubmitInfo submit_info;
1343     submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
1344     submit_info.pNext = NULL;
1345     submit_info.waitSemaphoreCount = 0;
1346     submit_info.pWaitSemaphores = NULL;
1347     submit_info.pWaitDstStageMask = NULL;
1348     submit_info.commandBufferCount = 1;
1349     submit_info.pCommandBuffers = &m_commandBuffer->handle();
1350     submit_info.signalSemaphoreCount = 0;
1351     submit_info.pSignalSemaphores = NULL;
1352 
1353     vk::QueueSubmit(m_device->m_queue, 1, &submit_info, testFence.handle());
1354     vk::QueueWaitIdle(m_device->m_queue);
1355 
1356     m_errorMonitor->VerifyFound();
1357 }
1358 
TEST_F(VkLayerTest,LeakAnObject)1359 TEST_F(VkLayerTest, LeakAnObject) {
1360     TEST_DESCRIPTION("Create a fence and destroy its device without first destroying the fence.");
1361 
1362     ASSERT_NO_FATAL_FAILURE(InitFramework(m_errorMonitor));
1363     if (!IsPlatform(kMockICD)) {
1364         // This test leaks a fence (on purpose) and should not be run on a real driver
1365         printf("%s This test only runs on the mock ICD\n", kSkipPrefix);
1366         return;
1367     }
1368 
1369     // Workaround for overzealous layers checking even the guaranteed 0th queue family
1370     const auto q_props = vk_testing::PhysicalDevice(gpu()).queue_properties();
1371     ASSERT_TRUE(q_props.size() > 0);
1372     ASSERT_TRUE(q_props[0].queueCount > 0);
1373 
1374     const float q_priority[] = {1.0f};
1375     VkDeviceQueueCreateInfo queue_ci = {};
1376     queue_ci.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
1377     queue_ci.queueFamilyIndex = 0;
1378     queue_ci.queueCount = 1;
1379     queue_ci.pQueuePriorities = q_priority;
1380 
1381     VkDeviceCreateInfo device_ci = {};
1382     device_ci.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
1383     device_ci.queueCreateInfoCount = 1;
1384     device_ci.pQueueCreateInfos = &queue_ci;
1385 
1386     VkDevice leaky_device;
1387     ASSERT_VK_SUCCESS(vk::CreateDevice(gpu(), &device_ci, nullptr, &leaky_device));
1388 
1389     const VkFenceCreateInfo fence_ci = {VK_STRUCTURE_TYPE_FENCE_CREATE_INFO};
1390     VkFence leaked_fence;
1391     ASSERT_VK_SUCCESS(vk::CreateFence(leaky_device, &fence_ci, nullptr, &leaked_fence));
1392 
1393     m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkDestroyDevice-device-00378");
1394     vk::DestroyDevice(leaky_device, nullptr);
1395     m_errorMonitor->VerifyFound();
1396 }
1397 
TEST_F(VkLayerTest,UseObjectWithWrongDevice)1398 TEST_F(VkLayerTest, UseObjectWithWrongDevice) {
1399     TEST_DESCRIPTION(
1400         "Try to destroy a render pass object using a device other than the one it was created on. This should generate a distinct "
1401         "error from the invalid handle error.");
1402     // Create first device and renderpass
1403     ASSERT_NO_FATAL_FAILURE(Init());
1404     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
1405 
1406     // Create second device
1407     float priorities[] = {1.0f};
1408     VkDeviceQueueCreateInfo queue_info{};
1409     queue_info.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
1410     queue_info.pNext = NULL;
1411     queue_info.flags = 0;
1412     queue_info.queueFamilyIndex = 0;
1413     queue_info.queueCount = 1;
1414     queue_info.pQueuePriorities = &priorities[0];
1415 
1416     VkDeviceCreateInfo device_create_info = {};
1417     auto features = m_device->phy().features();
1418     device_create_info.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
1419     device_create_info.pNext = NULL;
1420     device_create_info.queueCreateInfoCount = 1;
1421     device_create_info.pQueueCreateInfos = &queue_info;
1422     device_create_info.enabledLayerCount = 0;
1423     device_create_info.ppEnabledLayerNames = NULL;
1424     device_create_info.pEnabledFeatures = &features;
1425 
1426     VkDevice second_device;
1427     ASSERT_VK_SUCCESS(vk::CreateDevice(gpu(), &device_create_info, NULL, &second_device));
1428 
1429     // Try to destroy the renderpass from the first device using the second device
1430     m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkDestroyRenderPass-renderPass-parent");
1431     vk::DestroyRenderPass(second_device, m_renderPass, NULL);
1432     m_errorMonitor->VerifyFound();
1433 
1434     vk::DestroyDevice(second_device, NULL);
1435 }
1436 
TEST_F(VkLayerTest,InvalidAllocationCallbacks)1437 TEST_F(VkLayerTest, InvalidAllocationCallbacks) {
1438     TEST_DESCRIPTION("Test with invalid VkAllocationCallbacks");
1439 
1440     ASSERT_NO_FATAL_FAILURE(Init());
1441 
1442     // vk::CreateInstance, and vk::CreateDevice tend to crash in the Loader Trampoline ATM, so choosing vk::CreateCommandPool
1443     const VkCommandPoolCreateInfo cpci = {VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO, nullptr, 0,
1444                                           DeviceObj()->QueueFamilyMatching(0, 0, true)};
1445     VkCommandPool cmdPool;
1446 
1447     struct Alloc {
1448         static VKAPI_ATTR void *VKAPI_CALL alloc(void *, size_t, size_t, VkSystemAllocationScope) { return nullptr; };
1449         static VKAPI_ATTR void *VKAPI_CALL realloc(void *, void *, size_t, size_t, VkSystemAllocationScope) { return nullptr; };
1450         static VKAPI_ATTR void VKAPI_CALL free(void *, void *){};
1451         static VKAPI_ATTR void VKAPI_CALL internalAlloc(void *, size_t, VkInternalAllocationType, VkSystemAllocationScope){};
1452         static VKAPI_ATTR void VKAPI_CALL internalFree(void *, size_t, VkInternalAllocationType, VkSystemAllocationScope){};
1453     };
1454 
1455     {
1456         m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkAllocationCallbacks-pfnAllocation-00632");
1457         const VkAllocationCallbacks allocator = {nullptr, nullptr, Alloc::realloc, Alloc::free, nullptr, nullptr};
1458         vk::CreateCommandPool(device(), &cpci, &allocator, &cmdPool);
1459         m_errorMonitor->VerifyFound();
1460     }
1461 
1462     {
1463         m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkAllocationCallbacks-pfnReallocation-00633");
1464         const VkAllocationCallbacks allocator = {nullptr, Alloc::alloc, nullptr, Alloc::free, nullptr, nullptr};
1465         vk::CreateCommandPool(device(), &cpci, &allocator, &cmdPool);
1466         m_errorMonitor->VerifyFound();
1467     }
1468 
1469     {
1470         m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkAllocationCallbacks-pfnFree-00634");
1471         const VkAllocationCallbacks allocator = {nullptr, Alloc::alloc, Alloc::realloc, nullptr, nullptr, nullptr};
1472         vk::CreateCommandPool(device(), &cpci, &allocator, &cmdPool);
1473         m_errorMonitor->VerifyFound();
1474     }
1475 
1476     {
1477         m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkAllocationCallbacks-pfnInternalAllocation-00635");
1478         const VkAllocationCallbacks allocator = {nullptr, Alloc::alloc, Alloc::realloc, Alloc::free, nullptr, Alloc::internalFree};
1479         vk::CreateCommandPool(device(), &cpci, &allocator, &cmdPool);
1480         m_errorMonitor->VerifyFound();
1481     }
1482 
1483     {
1484         m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkAllocationCallbacks-pfnInternalAllocation-00635");
1485         const VkAllocationCallbacks allocator = {nullptr, Alloc::alloc, Alloc::realloc, Alloc::free, Alloc::internalAlloc, nullptr};
1486         vk::CreateCommandPool(device(), &cpci, &allocator, &cmdPool);
1487         m_errorMonitor->VerifyFound();
1488     }
1489 }
1490 
TEST_F(VkLayerTest,MismatchedQueueFamiliesOnSubmit)1491 TEST_F(VkLayerTest, MismatchedQueueFamiliesOnSubmit) {
1492     TEST_DESCRIPTION(
1493         "Submit command buffer created using one queue family and attempt to submit them on a queue created in a different queue "
1494         "family.");
1495 
1496     ASSERT_NO_FATAL_FAILURE(Init());  // assumes it initializes all queue families on vk::CreateDevice
1497 
1498     // This test is meaningless unless we have multiple queue families
1499     auto queue_family_properties = m_device->phy().queue_properties();
1500     std::vector<uint32_t> queue_families;
1501     for (uint32_t i = 0; i < queue_family_properties.size(); ++i)
1502         if (queue_family_properties[i].queueCount > 0) queue_families.push_back(i);
1503 
1504     if (queue_families.size() < 2) {
1505         printf("%s Device only has one queue family; skipped.\n", kSkipPrefix);
1506         return;
1507     }
1508 
1509     const uint32_t queue_family = queue_families[0];
1510 
1511     const uint32_t other_queue_family = queue_families[1];
1512     VkQueue other_queue;
1513     vk::GetDeviceQueue(m_device->device(), other_queue_family, 0, &other_queue);
1514 
1515     VkCommandPoolObj cmd_pool(m_device, queue_family);
1516     VkCommandBufferObj cmd_buff(m_device, &cmd_pool);
1517 
1518     cmd_buff.begin();
1519     cmd_buff.end();
1520 
1521     // Submit on the wrong queue
1522     VkSubmitInfo submit_info = {};
1523     submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
1524     submit_info.commandBufferCount = 1;
1525     submit_info.pCommandBuffers = &cmd_buff.handle();
1526 
1527     m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkQueueSubmit-pCommandBuffers-00074");
1528     vk::QueueSubmit(other_queue, 1, &submit_info, VK_NULL_HANDLE);
1529     m_errorMonitor->VerifyFound();
1530 }
1531 
TEST_F(VkLayerTest,TemporaryExternalSemaphore)1532 TEST_F(VkLayerTest, TemporaryExternalSemaphore) {
1533 #ifdef _WIN32
1534     const auto extension_name = VK_KHR_EXTERNAL_SEMAPHORE_WIN32_EXTENSION_NAME;
1535     const auto handle_type = VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT_KHR;
1536 #else
1537     const auto extension_name = VK_KHR_EXTERNAL_SEMAPHORE_FD_EXTENSION_NAME;
1538     const auto handle_type = VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_FD_BIT_KHR;
1539 #endif
1540     // Check for external semaphore instance extensions
1541     if (InstanceExtensionSupported(VK_KHR_EXTERNAL_SEMAPHORE_CAPABILITIES_EXTENSION_NAME)) {
1542         m_instance_extension_names.push_back(VK_KHR_EXTERNAL_SEMAPHORE_CAPABILITIES_EXTENSION_NAME);
1543         m_instance_extension_names.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
1544     } else {
1545         printf("%s External semaphore extension not supported, skipping test\n", kSkipPrefix);
1546         return;
1547     }
1548     ASSERT_NO_FATAL_FAILURE(InitFramework(m_errorMonitor));
1549 
1550     // Check for external semaphore device extensions
1551     if (DeviceExtensionSupported(gpu(), nullptr, extension_name)) {
1552         m_device_extension_names.push_back(extension_name);
1553         m_device_extension_names.push_back(VK_KHR_EXTERNAL_SEMAPHORE_EXTENSION_NAME);
1554     } else {
1555         printf("%s External semaphore extension not supported, skipping test\n", kSkipPrefix);
1556         return;
1557     }
1558     ASSERT_NO_FATAL_FAILURE(InitState());
1559 
1560     // Check for external semaphore import and export capability
1561     VkPhysicalDeviceExternalSemaphoreInfoKHR esi = {VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_SEMAPHORE_INFO_KHR, nullptr,
1562                                                     handle_type};
1563     VkExternalSemaphorePropertiesKHR esp = {VK_STRUCTURE_TYPE_EXTERNAL_SEMAPHORE_PROPERTIES_KHR, nullptr};
1564     auto vkGetPhysicalDeviceExternalSemaphorePropertiesKHR =
1565         (PFN_vkGetPhysicalDeviceExternalSemaphorePropertiesKHR)vk::GetInstanceProcAddr(
1566             instance(), "vkGetPhysicalDeviceExternalSemaphorePropertiesKHR");
1567     vkGetPhysicalDeviceExternalSemaphorePropertiesKHR(gpu(), &esi, &esp);
1568 
1569     if (!(esp.externalSemaphoreFeatures & VK_EXTERNAL_SEMAPHORE_FEATURE_EXPORTABLE_BIT_KHR) ||
1570         !(esp.externalSemaphoreFeatures & VK_EXTERNAL_SEMAPHORE_FEATURE_IMPORTABLE_BIT_KHR)) {
1571         printf("%s External semaphore does not support importing and exporting, skipping test\n", kSkipPrefix);
1572         return;
1573     }
1574 
1575     VkResult err;
1576 
1577     // Create a semaphore to export payload from
1578     VkExportSemaphoreCreateInfoKHR esci = {VK_STRUCTURE_TYPE_EXPORT_SEMAPHORE_CREATE_INFO_KHR, nullptr, handle_type};
1579     VkSemaphoreCreateInfo sci = {VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO, &esci, 0};
1580 
1581     VkSemaphore export_semaphore;
1582     err = vk::CreateSemaphore(m_device->device(), &sci, nullptr, &export_semaphore);
1583     ASSERT_VK_SUCCESS(err);
1584 
1585     // Create a semaphore to import payload into
1586     sci.pNext = nullptr;
1587     VkSemaphore import_semaphore;
1588     err = vk::CreateSemaphore(m_device->device(), &sci, nullptr, &import_semaphore);
1589     ASSERT_VK_SUCCESS(err);
1590 
1591 #ifdef _WIN32
1592     // Export semaphore payload to an opaque handle
1593     HANDLE handle = nullptr;
1594     VkSemaphoreGetWin32HandleInfoKHR ghi = {VK_STRUCTURE_TYPE_SEMAPHORE_GET_WIN32_HANDLE_INFO_KHR, nullptr, export_semaphore,
1595                                             handle_type};
1596     auto vkGetSemaphoreWin32HandleKHR =
1597         (PFN_vkGetSemaphoreWin32HandleKHR)vk::GetDeviceProcAddr(m_device->device(), "vkGetSemaphoreWin32HandleKHR");
1598     err = vkGetSemaphoreWin32HandleKHR(m_device->device(), &ghi, &handle);
1599     ASSERT_VK_SUCCESS(err);
1600 
1601     // Import opaque handle exported above *temporarily*
1602     VkImportSemaphoreWin32HandleInfoKHR ihi = {VK_STRUCTURE_TYPE_IMPORT_SEMAPHORE_WIN32_HANDLE_INFO_KHR,
1603                                                nullptr,
1604                                                import_semaphore,
1605                                                VK_SEMAPHORE_IMPORT_TEMPORARY_BIT_KHR,
1606                                                handle_type,
1607                                                handle,
1608                                                nullptr};
1609     auto vkImportSemaphoreWin32HandleKHR =
1610         (PFN_vkImportSemaphoreWin32HandleKHR)vk::GetDeviceProcAddr(m_device->device(), "vkImportSemaphoreWin32HandleKHR");
1611     err = vkImportSemaphoreWin32HandleKHR(m_device->device(), &ihi);
1612     ASSERT_VK_SUCCESS(err);
1613 #else
1614     // Export semaphore payload to an opaque handle
1615     int fd = 0;
1616     VkSemaphoreGetFdInfoKHR ghi = {VK_STRUCTURE_TYPE_SEMAPHORE_GET_FD_INFO_KHR, nullptr, export_semaphore, handle_type};
1617     auto vkGetSemaphoreFdKHR = (PFN_vkGetSemaphoreFdKHR)vk::GetDeviceProcAddr(m_device->device(), "vkGetSemaphoreFdKHR");
1618     err = vkGetSemaphoreFdKHR(m_device->device(), &ghi, &fd);
1619     ASSERT_VK_SUCCESS(err);
1620 
1621     // Import opaque handle exported above *temporarily*
1622     VkImportSemaphoreFdInfoKHR ihi = {VK_STRUCTURE_TYPE_IMPORT_SEMAPHORE_FD_INFO_KHR, nullptr,     import_semaphore,
1623                                       VK_SEMAPHORE_IMPORT_TEMPORARY_BIT_KHR,          handle_type, fd};
1624     auto vkImportSemaphoreFdKHR = (PFN_vkImportSemaphoreFdKHR)vk::GetDeviceProcAddr(m_device->device(), "vkImportSemaphoreFdKHR");
1625     err = vkImportSemaphoreFdKHR(m_device->device(), &ihi);
1626     ASSERT_VK_SUCCESS(err);
1627 #endif
1628 
1629     // Wait on the imported semaphore twice in vk::QueueSubmit, the second wait should be an error
1630     VkPipelineStageFlags flags = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT;
1631     VkSubmitInfo si[] = {
1632         {VK_STRUCTURE_TYPE_SUBMIT_INFO, nullptr, 0, nullptr, &flags, 0, nullptr, 1, &export_semaphore},
1633         {VK_STRUCTURE_TYPE_SUBMIT_INFO, nullptr, 1, &import_semaphore, &flags, 0, nullptr, 0, nullptr},
1634         {VK_STRUCTURE_TYPE_SUBMIT_INFO, nullptr, 0, nullptr, &flags, 0, nullptr, 1, &export_semaphore},
1635         {VK_STRUCTURE_TYPE_SUBMIT_INFO, nullptr, 1, &import_semaphore, &flags, 0, nullptr, 0, nullptr},
1636     };
1637     m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "has no way to be signaled");
1638     vk::QueueSubmit(m_device->m_queue, 4, si, VK_NULL_HANDLE);
1639     m_errorMonitor->VerifyFound();
1640 
1641     auto index = m_device->graphics_queue_node_index_;
1642     if (m_device->queue_props[index].queueFlags & VK_QUEUE_SPARSE_BINDING_BIT) {
1643         // Wait on the imported semaphore twice in vk::QueueBindSparse, the second wait should be an error
1644         VkBindSparseInfo bi[] = {
1645             {VK_STRUCTURE_TYPE_BIND_SPARSE_INFO, nullptr, 0, nullptr, 0, nullptr, 0, nullptr, 0, nullptr, 1, &export_semaphore},
1646             {VK_STRUCTURE_TYPE_BIND_SPARSE_INFO, nullptr, 1, &import_semaphore, 0, nullptr, 0, nullptr, 0, nullptr, 0, nullptr},
1647             {VK_STRUCTURE_TYPE_BIND_SPARSE_INFO, nullptr, 0, nullptr, 0, nullptr, 0, nullptr, 0, nullptr, 1, &export_semaphore},
1648             {VK_STRUCTURE_TYPE_BIND_SPARSE_INFO, nullptr, 1, &import_semaphore, 0, nullptr, 0, nullptr, 0, nullptr, 0, nullptr},
1649         };
1650         m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "has no way to be signaled");
1651         vk::QueueBindSparse(m_device->m_queue, 4, bi, VK_NULL_HANDLE);
1652         m_errorMonitor->VerifyFound();
1653     }
1654 
1655     // Cleanup
1656     err = vk::QueueWaitIdle(m_device->m_queue);
1657     ASSERT_VK_SUCCESS(err);
1658     vk::DestroySemaphore(m_device->device(), export_semaphore, nullptr);
1659     vk::DestroySemaphore(m_device->device(), import_semaphore, nullptr);
1660 }
1661 
TEST_F(VkLayerTest,TemporaryExternalFence)1662 TEST_F(VkLayerTest, TemporaryExternalFence) {
1663 #ifdef _WIN32
1664     const auto extension_name = VK_KHR_EXTERNAL_FENCE_WIN32_EXTENSION_NAME;
1665     const auto handle_type = VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_WIN32_BIT_KHR;
1666 #else
1667     const auto extension_name = VK_KHR_EXTERNAL_FENCE_FD_EXTENSION_NAME;
1668     const auto handle_type = VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_FD_BIT_KHR;
1669 #endif
1670     // Check for external fence instance extensions
1671     if (InstanceExtensionSupported(VK_KHR_EXTERNAL_FENCE_CAPABILITIES_EXTENSION_NAME)) {
1672         m_instance_extension_names.push_back(VK_KHR_EXTERNAL_FENCE_CAPABILITIES_EXTENSION_NAME);
1673         m_instance_extension_names.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
1674     } else {
1675         printf("%s External fence extension not supported, skipping test\n", kSkipPrefix);
1676         return;
1677     }
1678     ASSERT_NO_FATAL_FAILURE(InitFramework(m_errorMonitor));
1679 
1680     // Check for external fence device extensions
1681     if (DeviceExtensionSupported(gpu(), nullptr, extension_name)) {
1682         m_device_extension_names.push_back(extension_name);
1683         m_device_extension_names.push_back(VK_KHR_EXTERNAL_FENCE_EXTENSION_NAME);
1684     } else {
1685         printf("%s External fence extension not supported, skipping test\n", kSkipPrefix);
1686         return;
1687     }
1688     ASSERT_NO_FATAL_FAILURE(InitState());
1689 
1690     // Check for external fence import and export capability
1691     VkPhysicalDeviceExternalFenceInfoKHR efi = {VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_FENCE_INFO_KHR, nullptr, handle_type};
1692     VkExternalFencePropertiesKHR efp = {VK_STRUCTURE_TYPE_EXTERNAL_FENCE_PROPERTIES_KHR, nullptr};
1693     auto vkGetPhysicalDeviceExternalFencePropertiesKHR = (PFN_vkGetPhysicalDeviceExternalFencePropertiesKHR)vk::GetInstanceProcAddr(
1694         instance(), "vkGetPhysicalDeviceExternalFencePropertiesKHR");
1695     vkGetPhysicalDeviceExternalFencePropertiesKHR(gpu(), &efi, &efp);
1696 
1697     if (!(efp.externalFenceFeatures & VK_EXTERNAL_FENCE_FEATURE_EXPORTABLE_BIT_KHR) ||
1698         !(efp.externalFenceFeatures & VK_EXTERNAL_FENCE_FEATURE_IMPORTABLE_BIT_KHR)) {
1699         printf("%s External fence does not support importing and exporting, skipping test\n", kSkipPrefix);
1700         return;
1701     }
1702 
1703     VkResult err;
1704 
1705     // Create a fence to export payload from
1706     VkFence export_fence;
1707     {
1708         VkExportFenceCreateInfoKHR efci = {VK_STRUCTURE_TYPE_EXPORT_FENCE_CREATE_INFO_KHR, nullptr, handle_type};
1709         VkFenceCreateInfo fci = {VK_STRUCTURE_TYPE_FENCE_CREATE_INFO, &efci, 0};
1710         err = vk::CreateFence(m_device->device(), &fci, nullptr, &export_fence);
1711         ASSERT_VK_SUCCESS(err);
1712     }
1713 
1714     // Create a fence to import payload into
1715     VkFence import_fence;
1716     {
1717         VkFenceCreateInfo fci = {VK_STRUCTURE_TYPE_FENCE_CREATE_INFO, nullptr, 0};
1718         err = vk::CreateFence(m_device->device(), &fci, nullptr, &import_fence);
1719         ASSERT_VK_SUCCESS(err);
1720     }
1721 
1722 #ifdef _WIN32
1723     // Export fence payload to an opaque handle
1724     HANDLE handle = nullptr;
1725     {
1726         VkFenceGetWin32HandleInfoKHR ghi = {VK_STRUCTURE_TYPE_FENCE_GET_WIN32_HANDLE_INFO_KHR, nullptr, export_fence, handle_type};
1727         auto vkGetFenceWin32HandleKHR =
1728             (PFN_vkGetFenceWin32HandleKHR)vk::GetDeviceProcAddr(m_device->device(), "vkGetFenceWin32HandleKHR");
1729         err = vkGetFenceWin32HandleKHR(m_device->device(), &ghi, &handle);
1730         ASSERT_VK_SUCCESS(err);
1731     }
1732 
1733     // Import opaque handle exported above
1734     {
1735         VkImportFenceWin32HandleInfoKHR ifi = {VK_STRUCTURE_TYPE_IMPORT_FENCE_WIN32_HANDLE_INFO_KHR,
1736                                                nullptr,
1737                                                import_fence,
1738                                                VK_FENCE_IMPORT_TEMPORARY_BIT_KHR,
1739                                                handle_type,
1740                                                handle,
1741                                                nullptr};
1742         auto vkImportFenceWin32HandleKHR =
1743             (PFN_vkImportFenceWin32HandleKHR)vk::GetDeviceProcAddr(m_device->device(), "vkImportFenceWin32HandleKHR");
1744         err = vkImportFenceWin32HandleKHR(m_device->device(), &ifi);
1745         ASSERT_VK_SUCCESS(err);
1746     }
1747 #else
1748     // Export fence payload to an opaque handle
1749     int fd = 0;
1750     {
1751         VkFenceGetFdInfoKHR gfi = {VK_STRUCTURE_TYPE_FENCE_GET_FD_INFO_KHR, nullptr, export_fence, handle_type};
1752         auto vkGetFenceFdKHR = (PFN_vkGetFenceFdKHR)vk::GetDeviceProcAddr(m_device->device(), "vkGetFenceFdKHR");
1753         err = vkGetFenceFdKHR(m_device->device(), &gfi, &fd);
1754         ASSERT_VK_SUCCESS(err);
1755     }
1756 
1757     // Import opaque handle exported above
1758     {
1759         VkImportFenceFdInfoKHR ifi = {VK_STRUCTURE_TYPE_IMPORT_FENCE_FD_INFO_KHR, nullptr,     import_fence,
1760                                       VK_FENCE_IMPORT_TEMPORARY_BIT_KHR,          handle_type, fd};
1761         auto vkImportFenceFdKHR = (PFN_vkImportFenceFdKHR)vk::GetDeviceProcAddr(m_device->device(), "vkImportFenceFdKHR");
1762         err = vkImportFenceFdKHR(m_device->device(), &ifi);
1763         ASSERT_VK_SUCCESS(err);
1764     }
1765 #endif
1766 
1767     // Undo the temporary import
1768     vk::ResetFences(m_device->device(), 1, &import_fence);
1769 
1770     // Signal the previously imported fence twice, the second signal should produce a validation error
1771     vk::QueueSubmit(m_device->m_queue, 0, nullptr, import_fence);
1772     m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "is already in use by another submission.");
1773     vk::QueueSubmit(m_device->m_queue, 0, nullptr, import_fence);
1774     m_errorMonitor->VerifyFound();
1775 
1776     // Cleanup
1777     err = vk::QueueWaitIdle(m_device->m_queue);
1778     ASSERT_VK_SUCCESS(err);
1779     vk::DestroyFence(m_device->device(), export_fence, nullptr);
1780     vk::DestroyFence(m_device->device(), import_fence, nullptr);
1781 }
1782 
TEST_F(VkLayerTest,InvalidCmdBufferEventDestroyed)1783 TEST_F(VkLayerTest, InvalidCmdBufferEventDestroyed) {
1784     TEST_DESCRIPTION("Attempt to draw with a command buffer that is invalid due to an event dependency being destroyed.");
1785     ASSERT_NO_FATAL_FAILURE(Init());
1786 
1787     VkEvent event;
1788     VkEventCreateInfo evci = {};
1789     evci.sType = VK_STRUCTURE_TYPE_EVENT_CREATE_INFO;
1790     VkResult result = vk::CreateEvent(m_device->device(), &evci, NULL, &event);
1791     ASSERT_VK_SUCCESS(result);
1792 
1793     m_commandBuffer->begin();
1794     vk::CmdSetEvent(m_commandBuffer->handle(), event, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT);
1795     m_commandBuffer->end();
1796 
1797     m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "UNASSIGNED-CoreValidation-DrawState-InvalidCommandBuffer-VkEvent");
1798     // Destroy event dependency prior to submit to cause ERROR
1799     vk::DestroyEvent(m_device->device(), event, NULL);
1800 
1801     VkSubmitInfo submit_info = {};
1802     submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
1803     submit_info.commandBufferCount = 1;
1804     submit_info.pCommandBuffers = &m_commandBuffer->handle();
1805     vk::QueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
1806 
1807     m_errorMonitor->VerifyFound();
1808 }
1809 
TEST_F(VkLayerTest,InvalidCmdBufferQueryPoolDestroyed)1810 TEST_F(VkLayerTest, InvalidCmdBufferQueryPoolDestroyed) {
1811     TEST_DESCRIPTION("Attempt to draw with a command buffer that is invalid due to a query pool dependency being destroyed.");
1812     ASSERT_NO_FATAL_FAILURE(Init());
1813 
1814     VkQueryPool query_pool;
1815     VkQueryPoolCreateInfo qpci{};
1816     qpci.sType = VK_STRUCTURE_TYPE_QUERY_POOL_CREATE_INFO;
1817     qpci.queryType = VK_QUERY_TYPE_TIMESTAMP;
1818     qpci.queryCount = 1;
1819     VkResult result = vk::CreateQueryPool(m_device->device(), &qpci, nullptr, &query_pool);
1820     ASSERT_VK_SUCCESS(result);
1821 
1822     m_commandBuffer->begin();
1823     vk::CmdResetQueryPool(m_commandBuffer->handle(), query_pool, 0, 1);
1824     m_commandBuffer->end();
1825 
1826     m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "UNASSIGNED-CoreValidation-DrawState-InvalidCommandBuffer-VkQueryPool");
1827     // Destroy query pool dependency prior to submit to cause ERROR
1828     vk::DestroyQueryPool(m_device->device(), query_pool, NULL);
1829 
1830     VkSubmitInfo submit_info = {};
1831     submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
1832     submit_info.commandBufferCount = 1;
1833     submit_info.pCommandBuffers = &m_commandBuffer->handle();
1834     vk::QueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
1835 
1836     m_errorMonitor->VerifyFound();
1837 }
1838 
TEST_F(VkLayerTest,DeviceFeature2AndVertexAttributeDivisorExtensionUnenabled)1839 TEST_F(VkLayerTest, DeviceFeature2AndVertexAttributeDivisorExtensionUnenabled) {
1840     TEST_DESCRIPTION(
1841         "Test unenabled VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME & "
1842         "VK_EXT_VERTEX_ATTRIBUTE_DIVISOR_EXTENSION_NAME.");
1843 
1844     VkPhysicalDeviceFeatures2 pd_features2 = {};
1845     pd_features2.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2;
1846     pd_features2.pNext = nullptr;
1847 
1848     ASSERT_NO_FATAL_FAILURE(Init());
1849     vk_testing::QueueCreateInfoArray queue_info(m_device->queue_props);
1850     VkDeviceCreateInfo device_create_info = {};
1851     device_create_info.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
1852     device_create_info.pNext = &pd_features2;
1853     device_create_info.queueCreateInfoCount = queue_info.size();
1854     device_create_info.pQueueCreateInfos = queue_info.data();
1855     VkDevice testDevice;
1856     m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkDeviceCreateInfo-pNext-pNext");
1857     m_errorMonitor->SetUnexpectedError("Failed to create device chain");
1858     vk::CreateDevice(gpu(), &device_create_info, NULL, &testDevice);
1859     m_errorMonitor->VerifyFound();
1860 
1861     VkPhysicalDeviceVertexAttributeDivisorFeaturesEXT vadf = {};
1862     vadf.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VERTEX_ATTRIBUTE_DIVISOR_FEATURES_EXT;
1863     vadf.pNext = nullptr;
1864     device_create_info.pNext = &vadf;
1865     m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VK_EXT_vertex_attribute_divisor must be enabled when it creates a device");
1866     m_errorMonitor->SetUnexpectedError("Failed to create device chain");
1867     vk::CreateDevice(gpu(), &device_create_info, NULL, &testDevice);
1868     m_errorMonitor->VerifyFound();
1869 }
1870 
TEST_F(VkLayerTest,Features12AndpNext)1871 TEST_F(VkLayerTest, Features12AndpNext) {
1872     TEST_DESCRIPTION("Test VkPhysicalDeviceVulkan12Features and illegal struct in pNext");
1873 
1874     SetTargetApiVersion(VK_API_VERSION_1_2);
1875     if (InstanceExtensionSupported(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME)) {
1876         m_instance_extension_names.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
1877     } else {
1878         printf("%s %s Extension not supported, skipping tests\n", kSkipPrefix,
1879                VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
1880         return;
1881     }
1882     ASSERT_NO_FATAL_FAILURE(InitFramework(m_errorMonitor));
1883     if (DeviceValidationVersion() < VK_API_VERSION_1_2) {
1884         printf("%s Vulkan12Struct requires Vulkan 1.2+, skipping test\n", kSkipPrefix);
1885         return;
1886     }
1887     if (!DeviceExtensionSupported(gpu(), nullptr, VK_KHR_STORAGE_BUFFER_STORAGE_CLASS_EXTENSION_NAME) ||
1888         !DeviceExtensionSupported(gpu(), nullptr, VK_KHR_8BIT_STORAGE_EXTENSION_NAME) ||
1889         !DeviceExtensionSupported(gpu(), nullptr, VK_KHR_16BIT_STORAGE_EXTENSION_NAME)) {
1890         printf("%s Storage Extension(s) not supported, skipping tests\n", kSkipPrefix);
1891         return;
1892     }
1893     VkPhysicalDevice16BitStorageFeatures sixteen_bit = {};
1894     sixteen_bit.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_16BIT_STORAGE_FEATURES;
1895     sixteen_bit.storageBuffer16BitAccess = true;
1896     VkPhysicalDeviceVulkan11Features features11 = {};
1897     features11.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_1_FEATURES;
1898     features11.pNext = &sixteen_bit;
1899     features11.storageBuffer16BitAccess = true;
1900 
1901     VkPhysicalDevice8BitStorageFeatures eight_bit = {};
1902     eight_bit.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_8BIT_STORAGE_FEATURES;
1903     eight_bit.pNext = &features11;
1904     eight_bit.storageBuffer8BitAccess = true;
1905     VkPhysicalDeviceVulkan12Features features12 = {};
1906     features12.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_2_FEATURES;
1907     features12.pNext = &eight_bit;
1908     features12.storageBuffer8BitAccess = true;
1909 
1910     vk_testing::PhysicalDevice physical_device(gpu());
1911     vk_testing::QueueCreateInfoArray queue_info(physical_device.queue_properties());
1912     std::vector<VkDeviceQueueCreateInfo> create_queue_infos;
1913     auto qci = queue_info.data();
1914     for (uint32_t i = 0; i < queue_info.size(); ++i) {
1915         if (qci[i].queueCount) {
1916             create_queue_infos.push_back(qci[i]);
1917         }
1918     }
1919 
1920     VkDeviceCreateInfo device_create_info = {};
1921     device_create_info.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
1922     device_create_info.pNext = &features12;
1923     device_create_info.queueCreateInfoCount = queue_info.size();
1924     device_create_info.pQueueCreateInfos = queue_info.data();
1925     VkDevice testDevice;
1926 
1927     m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkDeviceCreateInfo-pNext-02829");
1928     m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkDeviceCreateInfo-pNext-02830");
1929     m_errorMonitor->SetUnexpectedError("Failed to create device chain");
1930     vk::CreateDevice(gpu(), &device_create_info, NULL, &testDevice);
1931     m_errorMonitor->VerifyFound();
1932 }
1933 
TEST_F(VkLayerTest,RequiredPromotedFeaturesExtensions)1934 TEST_F(VkLayerTest, RequiredPromotedFeaturesExtensions) {
1935     TEST_DESCRIPTION("Checks that features are enabled if extension is passed in for promoted extensions with requirement.");
1936 
1937     // targets  each possible version
1938     SetTargetApiVersion(VK_API_VERSION_1_1);
1939     SetTargetApiVersion(VK_API_VERSION_1_2);
1940     if (InstanceExtensionSupported(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME)) {
1941         m_instance_extension_names.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
1942     } else {
1943         printf("%s %s Extension not supported, skipping tests\n", kSkipPrefix,
1944                VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
1945         return;
1946     }
1947     ASSERT_NO_FATAL_FAILURE(InitFramework(m_errorMonitor));
1948 
1949     if (DeviceValidationVersion() < VK_API_VERSION_1_1) {
1950         printf("%s Test does not run on Vulkan 1.0, skipping test\n", kSkipPrefix);
1951         return;
1952     }
1953     const bool test_1_2 = (DeviceValidationVersion() >= VK_API_VERSION_1_2);
1954 
1955     vk_testing::PhysicalDevice physical_device(gpu());
1956     vk_testing::QueueCreateInfoArray queue_info(physical_device.queue_properties());
1957     std::vector<VkDeviceQueueCreateInfo> create_queue_infos;
1958     auto qci = queue_info.data();
1959     for (uint32_t i = 0; i < queue_info.size(); ++i) {
1960         if (qci[i].queueCount) {
1961             create_queue_infos.push_back(qci[i]);
1962         }
1963     }
1964 
1965     // Explicity set all tested features to false
1966     VkPhysicalDeviceVulkan12Features features12 = {};
1967     features12.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_2_FEATURES;
1968     features12.pNext = nullptr;
1969     features12.drawIndirectCount = VK_FALSE;
1970     features12.samplerMirrorClampToEdge = VK_FALSE;
1971     features12.descriptorIndexing = VK_FALSE;
1972     features12.samplerFilterMinmax = VK_FALSE;
1973     features12.shaderOutputViewportIndex = VK_FALSE;
1974     features12.shaderOutputLayer = VK_TRUE;  // Set true since both shader_viewport features need to true
1975 
1976     VkPhysicalDeviceVulkan11Features features11 = {};
1977     features11.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_1_FEATURES;
1978     features11.pNext = (test_1_2 == true) ? &features12 : nullptr;
1979     features11.shaderDrawParameters = VK_FALSE;
1980 
1981     std::vector<const char *> device_extensions;
1982 
1983     // Go through each extension and if supported add to list and add failure to check for
1984     if (DeviceExtensionSupported(gpu(), nullptr, VK_KHR_SHADER_DRAW_PARAMETERS_EXTENSION_NAME)) {
1985         device_extensions.push_back(VK_KHR_SHADER_DRAW_PARAMETERS_EXTENSION_NAME);
1986         m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkDeviceCreateInfo-ppEnabledExtensionNames-04476");
1987     }
1988     if (test_1_2 == true) {
1989         if (DeviceExtensionSupported(gpu(), nullptr, VK_KHR_DRAW_INDIRECT_COUNT_EXTENSION_NAME)) {
1990             device_extensions.push_back(VK_KHR_DRAW_INDIRECT_COUNT_EXTENSION_NAME);
1991             m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkDeviceCreateInfo-ppEnabledExtensionNames-02831");
1992         }
1993         if (DeviceExtensionSupported(gpu(), nullptr, VK_KHR_SAMPLER_MIRROR_CLAMP_TO_EDGE_EXTENSION_NAME)) {
1994             device_extensions.push_back(VK_KHR_SAMPLER_MIRROR_CLAMP_TO_EDGE_EXTENSION_NAME);
1995             m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkDeviceCreateInfo-ppEnabledExtensionNames-02832");
1996         }
1997         if (DeviceExtensionSupported(gpu(), nullptr, VK_EXT_DESCRIPTOR_INDEXING_EXTENSION_NAME)) {
1998             device_extensions.push_back(VK_EXT_DESCRIPTOR_INDEXING_EXTENSION_NAME);
1999             device_extensions.push_back(VK_KHR_MAINTENANCE_3_EXTENSION_NAME);
2000             m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkDeviceCreateInfo-ppEnabledExtensionNames-02833");
2001         }
2002         if (DeviceExtensionSupported(gpu(), nullptr, VK_EXT_SAMPLER_FILTER_MINMAX_EXTENSION_NAME)) {
2003             device_extensions.push_back(VK_EXT_SAMPLER_FILTER_MINMAX_EXTENSION_NAME);
2004             m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkDeviceCreateInfo-ppEnabledExtensionNames-02834");
2005         }
2006         if (DeviceExtensionSupported(gpu(), nullptr, VK_EXT_SHADER_VIEWPORT_INDEX_LAYER_EXTENSION_NAME)) {
2007             device_extensions.push_back(VK_EXT_SHADER_VIEWPORT_INDEX_LAYER_EXTENSION_NAME);
2008             m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkDeviceCreateInfo-ppEnabledExtensionNames-02835");
2009         }
2010     } else {
2011         // VkPhysicalDeviceVulkan11Features was not added until Vulkan 1.2
2012         m_errorMonitor->SetUnexpectedError("VUID-VkDeviceCreateInfo-pNext-pNext");
2013     }
2014 
2015     VkDeviceCreateInfo device_create_info = {};
2016     device_create_info.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
2017     device_create_info.pNext = &features11;
2018     device_create_info.queueCreateInfoCount = queue_info.size();
2019     device_create_info.pQueueCreateInfos = queue_info.data();
2020     device_create_info.ppEnabledExtensionNames = device_extensions.data();
2021     device_create_info.enabledExtensionCount = device_extensions.size();
2022     VkDevice testDevice;
2023 
2024     m_errorMonitor->SetUnexpectedError("Failed to create device chain");
2025     vk::CreateDevice(gpu(), &device_create_info, NULL, &testDevice);
2026     m_errorMonitor->VerifyFound();
2027 }
2028 
TEST_F(VkLayerTest,FeaturesVariablePointer)2029 TEST_F(VkLayerTest, FeaturesVariablePointer) {
2030     TEST_DESCRIPTION("Checks VK_KHR_variable_pointers features.");
2031 
2032     if (InstanceExtensionSupported(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME)) {
2033         m_instance_extension_names.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
2034     } else {
2035         printf("%s %s Extension not supported, skipping tests\n", kSkipPrefix,
2036                VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
2037         return;
2038     }
2039     ASSERT_NO_FATAL_FAILURE(InitFramework(m_errorMonitor));
2040     std::vector<const char *> device_extensions;
2041     if (DeviceExtensionSupported(gpu(), nullptr, VK_KHR_VARIABLE_POINTERS_EXTENSION_NAME) &&
2042         DeviceExtensionSupported(gpu(), nullptr, VK_KHR_STORAGE_BUFFER_STORAGE_CLASS_EXTENSION_NAME)) {
2043         device_extensions.push_back(VK_KHR_VARIABLE_POINTERS_EXTENSION_NAME);
2044         device_extensions.push_back(VK_KHR_STORAGE_BUFFER_STORAGE_CLASS_EXTENSION_NAME);
2045     } else {
2046         printf("%s VariablePointer Extension not supported, skipping tests\n", kSkipPrefix);
2047         return;
2048     }
2049 
2050     PFN_vkGetPhysicalDeviceFeatures2KHR vkGetPhysicalDeviceFeatures2KHR =
2051         (PFN_vkGetPhysicalDeviceFeatures2KHR)vk::GetInstanceProcAddr(instance(), "vkGetPhysicalDeviceFeatures2KHR");
2052     ASSERT_TRUE(vkGetPhysicalDeviceFeatures2KHR != nullptr);
2053 
2054     // Create a device that enables variablePointers but not variablePointersStorageBuffer
2055     auto variable_features = LvlInitStruct<VkPhysicalDeviceVariablePointersFeatures>();
2056     auto features2 = LvlInitStruct<VkPhysicalDeviceFeatures2KHR>(&variable_features);
2057     vkGetPhysicalDeviceFeatures2KHR(gpu(), &features2);
2058 
2059     if (variable_features.variablePointers == VK_FALSE) {
2060         printf("%s variablePointer feature not supported, skipping tests\n", kSkipPrefix);
2061         return;
2062     }
2063 
2064     variable_features.variablePointersStorageBuffer = VK_FALSE;
2065 
2066     vk_testing::PhysicalDevice physical_device(gpu());
2067     vk_testing::QueueCreateInfoArray queue_info(physical_device.queue_properties());
2068     std::vector<VkDeviceQueueCreateInfo> create_queue_infos;
2069     auto qci = queue_info.data();
2070     for (uint32_t i = 0; i < queue_info.size(); ++i) {
2071         if (qci[i].queueCount) {
2072             create_queue_infos.push_back(qci[i]);
2073         }
2074     }
2075 
2076     VkDeviceCreateInfo device_create_info = {};
2077     device_create_info.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
2078     device_create_info.pNext = &features2;
2079     device_create_info.queueCreateInfoCount = queue_info.size();
2080     device_create_info.pQueueCreateInfos = queue_info.data();
2081     device_create_info.ppEnabledExtensionNames = device_extensions.data();
2082     device_create_info.enabledExtensionCount = device_extensions.size();
2083     VkDevice testDevice;
2084 
2085     m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkPhysicalDeviceVariablePointersFeatures-variablePointers-01431");
2086     vk::CreateDevice(gpu(), &device_create_info, NULL, &testDevice);
2087     m_errorMonitor->VerifyFound();
2088 }
2089 
TEST_F(VkLayerTest,FeaturesMultiview)2090 TEST_F(VkLayerTest, FeaturesMultiview) {
2091     TEST_DESCRIPTION("Checks VK_KHR_multiview features.");
2092 
2093     if (InstanceExtensionSupported(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME)) {
2094         m_instance_extension_names.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
2095     } else {
2096         printf("%s %s Extension not supported, skipping tests\n", kSkipPrefix,
2097                VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
2098         return;
2099     }
2100     ASSERT_NO_FATAL_FAILURE(InitFramework(m_errorMonitor));
2101     std::vector<const char *> device_extensions;
2102     if (DeviceExtensionSupported(gpu(), nullptr, VK_KHR_MULTIVIEW_EXTENSION_NAME)) {
2103         device_extensions.push_back(VK_KHR_MULTIVIEW_EXTENSION_NAME);
2104     } else {
2105         printf("%s Multiview Extension not supported, skipping tests\n", kSkipPrefix);
2106         return;
2107     }
2108 
2109     PFN_vkGetPhysicalDeviceFeatures2KHR vkGetPhysicalDeviceFeatures2KHR =
2110         (PFN_vkGetPhysicalDeviceFeatures2KHR)vk::GetInstanceProcAddr(instance(), "vkGetPhysicalDeviceFeatures2KHR");
2111     ASSERT_TRUE(vkGetPhysicalDeviceFeatures2KHR != nullptr);
2112 
2113     auto multiview_features = LvlInitStruct<VkPhysicalDeviceMultiviewFeatures>();
2114     auto features2 = LvlInitStruct<VkPhysicalDeviceFeatures2KHR>(&multiview_features);
2115     vkGetPhysicalDeviceFeatures2KHR(gpu(), &features2);
2116 
2117     // Set false to trigger VUs
2118     multiview_features.multiview = VK_FALSE;
2119 
2120     vk_testing::PhysicalDevice physical_device(gpu());
2121     vk_testing::QueueCreateInfoArray queue_info(physical_device.queue_properties());
2122     std::vector<VkDeviceQueueCreateInfo> create_queue_infos;
2123     auto qci = queue_info.data();
2124     for (uint32_t i = 0; i < queue_info.size(); ++i) {
2125         if (qci[i].queueCount) {
2126             create_queue_infos.push_back(qci[i]);
2127         }
2128     }
2129 
2130     VkDeviceCreateInfo device_create_info = {};
2131     device_create_info.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
2132     device_create_info.pNext = &features2;
2133     device_create_info.queueCreateInfoCount = queue_info.size();
2134     device_create_info.pQueueCreateInfos = queue_info.data();
2135     device_create_info.ppEnabledExtensionNames = device_extensions.data();
2136     device_create_info.enabledExtensionCount = device_extensions.size();
2137     VkDevice testDevice;
2138 
2139     if ((multiview_features.multiviewGeometryShader == VK_FALSE) && (multiview_features.multiviewTessellationShader == VK_FALSE)) {
2140         printf("%s multiviewGeometryShader and  multiviewTessellationShader feature not supported, skipping tests\n", kSkipPrefix);
2141         return;
2142     }
2143 
2144     if (multiview_features.multiviewGeometryShader == VK_TRUE) {
2145         m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkPhysicalDeviceMultiviewFeatures-multiviewGeometryShader-00580");
2146     }
2147     if (multiview_features.multiviewTessellationShader == VK_TRUE) {
2148         m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkPhysicalDeviceMultiviewFeatures-multiviewTessellationShader-00581");
2149     }
2150     vk::CreateDevice(gpu(), &device_create_info, NULL, &testDevice);
2151     m_errorMonitor->VerifyFound();
2152 }
2153 
TEST_F(VkLayerTest,BeginQueryOnTimestampPool)2154 TEST_F(VkLayerTest, BeginQueryOnTimestampPool) {
2155     TEST_DESCRIPTION("Call CmdBeginQuery on a TIMESTAMP query pool.");
2156 
2157     ASSERT_NO_FATAL_FAILURE(Init());
2158 
2159     VkQueryPool query_pool;
2160     VkQueryPoolCreateInfo query_pool_create_info{};
2161     query_pool_create_info.sType = VK_STRUCTURE_TYPE_QUERY_POOL_CREATE_INFO;
2162     query_pool_create_info.queryType = VK_QUERY_TYPE_TIMESTAMP;
2163     query_pool_create_info.queryCount = 1;
2164     vk::CreateQueryPool(m_device->device(), &query_pool_create_info, nullptr, &query_pool);
2165 
2166     m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdBeginQuery-queryType-02804");
2167     VkCommandBufferBeginInfo begin_info{};
2168     begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
2169 
2170     vk::BeginCommandBuffer(m_commandBuffer->handle(), &begin_info);
2171     vk::CmdResetQueryPool(m_commandBuffer->handle(), query_pool, 0, 1);
2172     vk::CmdBeginQuery(m_commandBuffer->handle(), query_pool, 0, 0);
2173     vk::EndCommandBuffer(m_commandBuffer->handle());
2174     m_errorMonitor->VerifyFound();
2175 
2176     vk::DestroyQueryPool(m_device->device(), query_pool, nullptr);
2177 }
2178 
TEST_F(VkLayerTest,ValidationCacheTestBadMerge)2179 TEST_F(VkLayerTest, ValidationCacheTestBadMerge) {
2180     ASSERT_NO_FATAL_FAILURE(InitFramework(m_errorMonitor));
2181     if (DeviceExtensionSupported(gpu(), kValidationLayerName, VK_EXT_VALIDATION_CACHE_EXTENSION_NAME)) {
2182         m_device_extension_names.push_back(VK_EXT_VALIDATION_CACHE_EXTENSION_NAME);
2183     } else {
2184         printf("%s %s not supported, skipping test\n", kSkipPrefix, VK_EXT_VALIDATION_CACHE_EXTENSION_NAME);
2185         return;
2186     }
2187     ASSERT_NO_FATAL_FAILURE(InitState());
2188 
2189     // Load extension functions
2190     auto fpCreateValidationCache =
2191         (PFN_vkCreateValidationCacheEXT)vk::GetDeviceProcAddr(m_device->device(), "vkCreateValidationCacheEXT");
2192     auto fpDestroyValidationCache =
2193         (PFN_vkDestroyValidationCacheEXT)vk::GetDeviceProcAddr(m_device->device(), "vkDestroyValidationCacheEXT");
2194     auto fpMergeValidationCaches =
2195         (PFN_vkMergeValidationCachesEXT)vk::GetDeviceProcAddr(m_device->device(), "vkMergeValidationCachesEXT");
2196     if (!fpCreateValidationCache || !fpDestroyValidationCache || !fpMergeValidationCaches) {
2197         printf("%s Failed to load function pointers for %s\n", kSkipPrefix, VK_EXT_VALIDATION_CACHE_EXTENSION_NAME);
2198         return;
2199     }
2200 
2201     VkValidationCacheCreateInfoEXT validationCacheCreateInfo;
2202     validationCacheCreateInfo.sType = VK_STRUCTURE_TYPE_VALIDATION_CACHE_CREATE_INFO_EXT;
2203     validationCacheCreateInfo.pNext = NULL;
2204     validationCacheCreateInfo.initialDataSize = 0;
2205     validationCacheCreateInfo.pInitialData = NULL;
2206     validationCacheCreateInfo.flags = 0;
2207     VkValidationCacheEXT validationCache = VK_NULL_HANDLE;
2208     VkResult res = fpCreateValidationCache(m_device->device(), &validationCacheCreateInfo, nullptr, &validationCache);
2209     ASSERT_VK_SUCCESS(res);
2210 
2211     m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkMergeValidationCachesEXT-dstCache-01536");
2212     res = fpMergeValidationCaches(m_device->device(), validationCache, 1, &validationCache);
2213     m_errorMonitor->VerifyFound();
2214 
2215     fpDestroyValidationCache(m_device->device(), validationCache, nullptr);
2216 }
2217 
TEST_F(VkLayerTest,InvalidQueueFamilyIndex)2218 TEST_F(VkLayerTest, InvalidQueueFamilyIndex) {
2219     // Miscellaneous queueFamilyIndex validation tests
2220     bool get_physical_device_properties2 = InstanceExtensionSupported(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
2221     if (get_physical_device_properties2) {
2222         m_instance_extension_names.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
2223     }
2224 
2225     ASSERT_NO_FATAL_FAILURE(Init());
2226     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
2227     VkBufferCreateInfo buffCI = {};
2228     buffCI.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
2229     buffCI.size = 1024;
2230     buffCI.usage = VK_BUFFER_USAGE_TRANSFER_DST_BIT;
2231     buffCI.queueFamilyIndexCount = 2;
2232     // Introduce failure by specifying invalid queue_family_index
2233     uint32_t qfi[2];
2234     qfi[0] = 777;
2235     qfi[1] = 0;
2236 
2237     buffCI.pQueueFamilyIndices = qfi;
2238     buffCI.sharingMode = VK_SHARING_MODE_CONCURRENT;  // qfi only matters in CONCURRENT mode
2239 
2240     const char *vuid = (get_physical_device_properties2) ? "VUID-VkBufferCreateInfo-sharingMode-01419"
2241                                                          : "VUID-VkBufferCreateInfo-sharingMode-01391";
2242     // Test for queue family index out of range
2243     CreateBufferTest(*this, &buffCI, vuid);
2244 
2245     // Test for non-unique QFI in array
2246     qfi[0] = 0;
2247     CreateBufferTest(*this, &buffCI, vuid);
2248 
2249     if (m_device->queue_props.size() > 2) {
2250         m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkQueueSubmit-pSubmits-04626");
2251 
2252         // Create buffer shared to queue families 1 and 2, but submitted on queue family 0
2253         buffCI.queueFamilyIndexCount = 2;
2254         qfi[0] = 1;
2255         qfi[1] = 2;
2256         VkBufferObj ib;
2257         ib.init(*m_device, buffCI);
2258 
2259         m_commandBuffer->begin();
2260         vk::CmdFillBuffer(m_commandBuffer->handle(), ib.handle(), 0, 16, 5);
2261         m_commandBuffer->end();
2262         m_commandBuffer->QueueCommandBuffer(false);
2263         m_errorMonitor->VerifyFound();
2264     }
2265 
2266     // If there is more than one queue family, create a device with a single queue family, then create a buffer
2267     // with SHARING_MODE_CONCURRENT that uses a non-device PDEV queue family.
2268     uint32_t queue_count;
2269     vk::GetPhysicalDeviceQueueFamilyProperties(gpu(), &queue_count, NULL);
2270     VkQueueFamilyProperties *queue_props = new VkQueueFamilyProperties[queue_count];
2271     vk::GetPhysicalDeviceQueueFamilyProperties(gpu(), &queue_count, queue_props);
2272 
2273     if (queue_count < 3) {
2274         printf("%s Multiple queue families are required to run this test.\n", kSkipPrefix);
2275         return;
2276     }
2277     std::vector<float> priorities(queue_props->queueCount, 1.0f);
2278     VkDeviceQueueCreateInfo queue_info = {};
2279     queue_info.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
2280     queue_info.queueFamilyIndex = 0;
2281     queue_info.queueCount = queue_props->queueCount;
2282     queue_info.pQueuePriorities = priorities.data();
2283     VkDeviceCreateInfo dev_info{};
2284     dev_info.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
2285     dev_info.queueCreateInfoCount = 1;
2286     dev_info.pQueueCreateInfos = &queue_info;
2287     dev_info.enabledLayerCount = 0;
2288     dev_info.enabledExtensionCount = m_device_extension_names.size();
2289     dev_info.ppEnabledExtensionNames = m_device_extension_names.data();
2290 
2291     // Create a device with a single queue family
2292     VkDevice second_device;
2293     ASSERT_VK_SUCCESS(vk::CreateDevice(gpu(), &dev_info, nullptr, &second_device));
2294 
2295     // Select Queue family for CONCURRENT buffer that is not owned by device
2296     buffCI.queueFamilyIndexCount = 2;
2297     qfi[1] = 2;
2298     VkBuffer buffer = VK_NULL_HANDLE;
2299     m_errorMonitor->ExpectSuccess();
2300     vk::CreateBuffer(second_device, &buffCI, NULL, &buffer);
2301     m_errorMonitor->VerifyNotFound();
2302     vk::DestroyDevice(second_device, nullptr);
2303 }
2304 
TEST_F(VkLayerTest,InvalidQueryPoolCreate)2305 TEST_F(VkLayerTest, InvalidQueryPoolCreate) {
2306     TEST_DESCRIPTION("Attempt to create a query pool for PIPELINE_STATISTICS without enabling pipeline stats for the device.");
2307 
2308     ASSERT_NO_FATAL_FAILURE(Init());
2309 
2310     vk_testing::QueueCreateInfoArray queue_info(m_device->queue_props);
2311 
2312     VkDevice local_device;
2313     VkDeviceCreateInfo device_create_info = {};
2314     auto features = m_device->phy().features();
2315     // Intentionally disable pipeline stats
2316     features.pipelineStatisticsQuery = VK_FALSE;
2317     device_create_info.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
2318     device_create_info.pNext = NULL;
2319     device_create_info.queueCreateInfoCount = queue_info.size();
2320     device_create_info.pQueueCreateInfos = queue_info.data();
2321     device_create_info.enabledLayerCount = 0;
2322     device_create_info.ppEnabledLayerNames = NULL;
2323     device_create_info.pEnabledFeatures = &features;
2324     VkResult err = vk::CreateDevice(gpu(), &device_create_info, nullptr, &local_device);
2325     ASSERT_VK_SUCCESS(err);
2326 
2327     VkQueryPoolCreateInfo qpci{};
2328     qpci.sType = VK_STRUCTURE_TYPE_QUERY_POOL_CREATE_INFO;
2329     qpci.queryType = VK_QUERY_TYPE_PIPELINE_STATISTICS;
2330     qpci.queryCount = 1;
2331     VkQueryPool query_pool;
2332 
2333     m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkQueryPoolCreateInfo-queryType-00791");
2334     vk::CreateQueryPool(local_device, &qpci, nullptr, &query_pool);
2335     m_errorMonitor->VerifyFound();
2336 
2337     qpci.queryType = VK_QUERY_TYPE_OCCLUSION;
2338     qpci.queryCount = 0;
2339     m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkQueryPoolCreateInfo-queryCount-02763");
2340     vk::CreateQueryPool(local_device, &qpci, nullptr, &query_pool);
2341     m_errorMonitor->VerifyFound();
2342 
2343     vk::DestroyDevice(local_device, nullptr);
2344 }
2345 
TEST_F(VkLayerTest,InvalidQuerySizes)2346 TEST_F(VkLayerTest, InvalidQuerySizes) {
2347     TEST_DESCRIPTION("Invalid size of using queries commands.");
2348 
2349     ASSERT_NO_FATAL_FAILURE(Init());
2350 
2351     if (IsPlatform(kPixel2XL)) {
2352         printf("%s This test should not run on Pixel 2 XL\n", kSkipPrefix);
2353         return;
2354     }
2355 
2356     uint32_t queue_count;
2357     vk::GetPhysicalDeviceQueueFamilyProperties(gpu(), &queue_count, NULL);
2358     std::vector<VkQueueFamilyProperties> queue_props(queue_count);
2359     vk::GetPhysicalDeviceQueueFamilyProperties(gpu(), &queue_count, queue_props.data());
2360     const uint32_t timestampValidBits = queue_props[m_device->graphics_queue_node_index_].timestampValidBits;
2361 
2362     VkBufferObj buffer;
2363     buffer.init(*m_device, 128, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, VK_BUFFER_USAGE_TRANSFER_DST_BIT);
2364     VkMemoryRequirements mem_reqs = {};
2365     vk::GetBufferMemoryRequirements(m_device->device(), buffer.handle(), &mem_reqs);
2366     const VkDeviceSize buffer_size = mem_reqs.size;
2367 
2368     const uint32_t query_pool_size = 4;
2369     VkQueryPool occlusion_query_pool;
2370     VkQueryPoolCreateInfo query_pool_create_info{};
2371     query_pool_create_info.sType = VK_STRUCTURE_TYPE_QUERY_POOL_CREATE_INFO;
2372     query_pool_create_info.queryType = VK_QUERY_TYPE_OCCLUSION;
2373     query_pool_create_info.queryCount = query_pool_size;
2374     vk::CreateQueryPool(m_device->device(), &query_pool_create_info, nullptr, &occlusion_query_pool);
2375 
2376     m_commandBuffer->begin();
2377 
2378     // FirstQuery is too large
2379     m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdResetQueryPool-firstQuery-00796");
2380     m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdResetQueryPool-firstQuery-00797");
2381     vk::CmdResetQueryPool(m_commandBuffer->handle(), occlusion_query_pool, query_pool_size, 1);
2382     m_errorMonitor->VerifyFound();
2383 
2384     // Sum of firstQuery and queryCount is too large
2385     m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdResetQueryPool-firstQuery-00797");
2386     vk::CmdResetQueryPool(m_commandBuffer->handle(), occlusion_query_pool, 1, query_pool_size);
2387     m_errorMonitor->VerifyFound();
2388 
2389     // Actually reset all queries so they can be used
2390     m_errorMonitor->ExpectSuccess();
2391     vk::CmdResetQueryPool(m_commandBuffer->handle(), occlusion_query_pool, 0, query_pool_size);
2392     m_errorMonitor->VerifyNotFound();
2393 
2394     vk::CmdBeginQuery(m_commandBuffer->handle(), occlusion_query_pool, 0, 0);
2395 
2396     // Query index to large
2397     m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdEndQuery-query-00810");
2398     vk::CmdEndQuery(m_commandBuffer->handle(), occlusion_query_pool, query_pool_size);
2399     m_errorMonitor->VerifyFound();
2400 
2401     vk::CmdEndQuery(m_commandBuffer->handle(), occlusion_query_pool, 0);
2402 
2403     // FirstQuery is too large
2404     m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdCopyQueryPoolResults-firstQuery-00820");
2405     m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdCopyQueryPoolResults-firstQuery-00821");
2406     vk::CmdCopyQueryPoolResults(m_commandBuffer->handle(), occlusion_query_pool, query_pool_size, 1, buffer.handle(), 0, 0, 0);
2407     m_errorMonitor->VerifyFound();
2408 
2409     // sum of firstQuery and queryCount is too large
2410     m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdCopyQueryPoolResults-firstQuery-00821");
2411     vk::CmdCopyQueryPoolResults(m_commandBuffer->handle(), occlusion_query_pool, 1, query_pool_size, buffer.handle(), 0, 0, 0);
2412     m_errorMonitor->VerifyFound();
2413 
2414     // Offset larger than buffer size
2415     m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdCopyQueryPoolResults-dstOffset-00819");
2416     vk::CmdCopyQueryPoolResults(m_commandBuffer->handle(), occlusion_query_pool, 0, 1, buffer.handle(), buffer_size + 4, 0, 0);
2417     m_errorMonitor->VerifyFound();
2418 
2419     // Buffer does not have enough storage from offset to contain result of each query
2420     m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdCopyQueryPoolResults-dstBuffer-00824");
2421     vk::CmdCopyQueryPoolResults(m_commandBuffer->handle(), occlusion_query_pool, 0, 2, buffer.handle(), buffer_size - 4, 4, 0);
2422     m_errorMonitor->VerifyFound();
2423 
2424     // Query is not a timestamp type
2425     if (timestampValidBits == 0) {
2426         m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdWriteTimestamp-timestampValidBits-00829");
2427     }
2428     m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdWriteTimestamp-queryPool-01416");
2429     vk::CmdWriteTimestamp(m_commandBuffer->handle(), VK_PIPELINE_STAGE_VERTEX_INPUT_BIT, occlusion_query_pool, 0);
2430     m_errorMonitor->VerifyFound();
2431 
2432     m_commandBuffer->end();
2433 
2434     const size_t out_data_size = 16;
2435     uint8_t data[out_data_size];
2436 
2437     // FirstQuery is too large
2438     m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkGetQueryPoolResults-firstQuery-00813");
2439     m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkGetQueryPoolResults-firstQuery-00816");
2440     vk::GetQueryPoolResults(m_device->device(), occlusion_query_pool, query_pool_size, 1, out_data_size, &data, 4, 0);
2441     m_errorMonitor->VerifyFound();
2442 
2443     // Sum of firstQuery and queryCount is too large
2444     m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkGetQueryPoolResults-firstQuery-00816");
2445     vk::GetQueryPoolResults(m_device->device(), occlusion_query_pool, 1, query_pool_size, out_data_size, &data, 4, 0);
2446     m_errorMonitor->VerifyFound();
2447 
2448     vk::DestroyQueryPool(m_device->device(), occlusion_query_pool, nullptr);
2449 }
2450 
TEST_F(VkLayerTest,UnclosedAndDuplicateQueries)2451 TEST_F(VkLayerTest, UnclosedAndDuplicateQueries) {
2452     TEST_DESCRIPTION("End a command buffer with a query still in progress, create nested queries.");
2453 
2454     ASSERT_NO_FATAL_FAILURE(Init());
2455 
2456     VkQueue queue = VK_NULL_HANDLE;
2457     vk::GetDeviceQueue(m_device->device(), m_device->graphics_queue_node_index_, 0, &queue);
2458 
2459     VkQueryPool query_pool;
2460     VkQueryPoolCreateInfo query_pool_create_info = {};
2461     query_pool_create_info.sType = VK_STRUCTURE_TYPE_QUERY_POOL_CREATE_INFO;
2462     query_pool_create_info.queryType = VK_QUERY_TYPE_OCCLUSION;
2463     query_pool_create_info.queryCount = 5;
2464     vk::CreateQueryPool(m_device->device(), &query_pool_create_info, nullptr, &query_pool);
2465     m_commandBuffer->begin();
2466     vk::CmdResetQueryPool(m_commandBuffer->handle(), query_pool, 0, 5);
2467 
2468     m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdBeginQuery-queryPool-01922");
2469     vk::CmdBeginQuery(m_commandBuffer->handle(), query_pool, 1, 0);
2470     // Attempt to begin a query that has the same type as an active query
2471     vk::CmdBeginQuery(m_commandBuffer->handle(), query_pool, 3, 0);
2472     vk::CmdEndQuery(m_commandBuffer->handle(), query_pool, 1);
2473     m_errorMonitor->VerifyFound();
2474 
2475     m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkEndCommandBuffer-commandBuffer-00061");
2476     vk::CmdBeginQuery(m_commandBuffer->handle(), query_pool, 0, 0);
2477     vk::EndCommandBuffer(m_commandBuffer->handle());
2478     m_errorMonitor->VerifyFound();
2479 
2480     vk::DestroyQueryPool(m_device->device(), query_pool, nullptr);
2481 }
2482 
TEST_F(VkLayerTest,QueryPreciseBit)2483 TEST_F(VkLayerTest, QueryPreciseBit) {
2484     TEST_DESCRIPTION("Check for correct Query Precise Bit circumstances.");
2485     ASSERT_NO_FATAL_FAILURE(Init());
2486 
2487     // These tests require that the device support pipeline statistics query
2488     VkPhysicalDeviceFeatures device_features = {};
2489     ASSERT_NO_FATAL_FAILURE(GetPhysicalDeviceFeatures(&device_features));
2490     if (VK_TRUE != device_features.pipelineStatisticsQuery) {
2491         printf("%s Test requires unsupported pipelineStatisticsQuery feature. Skipped.\n", kSkipPrefix);
2492         return;
2493     }
2494 
2495     std::vector<const char *> device_extension_names;
2496     auto features = m_device->phy().features();
2497 
2498     // Test for precise bit when query type is not OCCLUSION
2499     if (features.occlusionQueryPrecise) {
2500         VkEvent event;
2501         VkEventCreateInfo event_create_info{};
2502         event_create_info.sType = VK_STRUCTURE_TYPE_EVENT_CREATE_INFO;
2503         vk::CreateEvent(m_device->handle(), &event_create_info, nullptr, &event);
2504 
2505         m_commandBuffer->begin();
2506         m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdBeginQuery-queryType-00800");
2507 
2508         VkQueryPool query_pool;
2509         VkQueryPoolCreateInfo query_pool_create_info = {};
2510         query_pool_create_info.sType = VK_STRUCTURE_TYPE_QUERY_POOL_CREATE_INFO;
2511         query_pool_create_info.queryType = VK_QUERY_TYPE_PIPELINE_STATISTICS;
2512         query_pool_create_info.queryCount = 3;
2513         query_pool_create_info.pipelineStatistics = VK_QUERY_PIPELINE_STATISTIC_INPUT_ASSEMBLY_VERTICES_BIT |
2514                                                     VK_QUERY_PIPELINE_STATISTIC_INPUT_ASSEMBLY_PRIMITIVES_BIT |
2515                                                     VK_QUERY_PIPELINE_STATISTIC_VERTEX_SHADER_INVOCATIONS_BIT;
2516         vk::CreateQueryPool(m_device->handle(), &query_pool_create_info, nullptr, &query_pool);
2517 
2518         vk::CmdResetQueryPool(m_commandBuffer->handle(), query_pool, 0, 1);
2519         vk::CmdBeginQuery(m_commandBuffer->handle(), query_pool, 0, VK_QUERY_CONTROL_PRECISE_BIT);
2520         m_errorMonitor->VerifyFound();
2521         // vk::CmdBeginQuery(m_commandBuffer->handle(), query_pool, 0, VK_QUERY_CONTROL_PRECISE_BIT);
2522         m_commandBuffer->end();
2523 
2524         const size_t out_data_size = 64;
2525         uint8_t data[out_data_size];
2526         // The dataSize is too small to return the data
2527         m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkGetQueryPoolResults-dataSize-00817");
2528         vk::GetQueryPoolResults(m_device->device(), query_pool, 0, 3, 8, &data, 12, 0);
2529         m_errorMonitor->VerifyFound();
2530 
2531         vk::DestroyQueryPool(m_device->handle(), query_pool, nullptr);
2532         vk::DestroyEvent(m_device->handle(), event, nullptr);
2533     }
2534 
2535     // Test for precise bit when precise feature is not available
2536     features.occlusionQueryPrecise = false;
2537     VkDeviceObj test_device(0, gpu(), device_extension_names, &features);
2538 
2539     VkCommandPoolCreateInfo pool_create_info{};
2540     pool_create_info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
2541     pool_create_info.queueFamilyIndex = test_device.graphics_queue_node_index_;
2542 
2543     VkCommandPool command_pool;
2544     vk::CreateCommandPool(test_device.handle(), &pool_create_info, nullptr, &command_pool);
2545 
2546     VkCommandBufferAllocateInfo cmd = {};
2547     cmd.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
2548     cmd.pNext = NULL;
2549     cmd.commandPool = command_pool;
2550     cmd.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
2551     cmd.commandBufferCount = 1;
2552 
2553     VkCommandBuffer cmd_buffer;
2554     VkResult err = vk::AllocateCommandBuffers(test_device.handle(), &cmd, &cmd_buffer);
2555     ASSERT_VK_SUCCESS(err);
2556 
2557     VkEvent event;
2558     VkEventCreateInfo event_create_info{};
2559     event_create_info.sType = VK_STRUCTURE_TYPE_EVENT_CREATE_INFO;
2560     vk::CreateEvent(test_device.handle(), &event_create_info, nullptr, &event);
2561 
2562     VkCommandBufferBeginInfo begin_info = {VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, nullptr,
2563                                            VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT, nullptr};
2564 
2565     vk::BeginCommandBuffer(cmd_buffer, &begin_info);
2566     m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdBeginQuery-queryType-00800");
2567 
2568     VkQueryPool query_pool;
2569     VkQueryPoolCreateInfo query_pool_create_info = {};
2570     query_pool_create_info.sType = VK_STRUCTURE_TYPE_QUERY_POOL_CREATE_INFO;
2571     query_pool_create_info.queryType = VK_QUERY_TYPE_OCCLUSION;
2572     query_pool_create_info.queryCount = 2;
2573     vk::CreateQueryPool(test_device.handle(), &query_pool_create_info, nullptr, &query_pool);
2574 
2575     vk::CmdResetQueryPool(cmd_buffer, query_pool, 0, 2);
2576     vk::CmdBeginQuery(cmd_buffer, query_pool, 0, VK_QUERY_CONTROL_PRECISE_BIT);
2577     m_errorMonitor->VerifyFound();
2578     vk::EndCommandBuffer(cmd_buffer);
2579 
2580     const size_t out_data_size = 16;
2581     uint8_t data[out_data_size];
2582     // The dataSize is too small to return the data
2583     m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkGetQueryPoolResults-dataSize-00817");
2584     vk::GetQueryPoolResults(test_device.handle(), query_pool, 0, 2, 8, &data, out_data_size / 2, 0);
2585     m_errorMonitor->VerifyFound();
2586 
2587     vk::DestroyQueryPool(test_device.handle(), query_pool, nullptr);
2588     vk::DestroyEvent(test_device.handle(), event, nullptr);
2589     vk::DestroyCommandPool(test_device.handle(), command_pool, nullptr);
2590 }
2591 
TEST_F(VkLayerTest,StageMaskGsTsEnabled)2592 TEST_F(VkLayerTest, StageMaskGsTsEnabled) {
2593     TEST_DESCRIPTION(
2594         "Attempt to use a stageMask w/ geometry shader and tesselation shader bits enabled when those features are disabled on the "
2595         "device.");
2596 
2597     ASSERT_NO_FATAL_FAILURE(Init());
2598     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
2599 
2600     std::vector<const char *> device_extension_names;
2601     auto features = m_device->phy().features();
2602     // Make sure gs & ts are disabled
2603     features.geometryShader = false;
2604     features.tessellationShader = false;
2605     // The sacrificial device object
2606     VkDeviceObj test_device(0, gpu(), device_extension_names, &features);
2607 
2608     VkCommandPoolCreateInfo pool_create_info{};
2609     pool_create_info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
2610     pool_create_info.queueFamilyIndex = test_device.graphics_queue_node_index_;
2611 
2612     VkCommandPool command_pool;
2613     vk::CreateCommandPool(test_device.handle(), &pool_create_info, nullptr, &command_pool);
2614 
2615     VkCommandBufferAllocateInfo cmd = {};
2616     cmd.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
2617     cmd.pNext = NULL;
2618     cmd.commandPool = command_pool;
2619     cmd.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
2620     cmd.commandBufferCount = 1;
2621 
2622     VkCommandBuffer cmd_buffer;
2623     VkResult err = vk::AllocateCommandBuffers(test_device.handle(), &cmd, &cmd_buffer);
2624     ASSERT_VK_SUCCESS(err);
2625 
2626     VkEvent event;
2627     VkEventCreateInfo evci = {};
2628     evci.sType = VK_STRUCTURE_TYPE_EVENT_CREATE_INFO;
2629     VkResult result = vk::CreateEvent(test_device.handle(), &evci, NULL, &event);
2630     ASSERT_VK_SUCCESS(result);
2631 
2632     VkCommandBufferBeginInfo cbbi = {};
2633     cbbi.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
2634     vk::BeginCommandBuffer(cmd_buffer, &cbbi);
2635     m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdSetEvent-stageMask-04090");
2636     vk::CmdSetEvent(cmd_buffer, event, VK_PIPELINE_STAGE_GEOMETRY_SHADER_BIT);
2637     m_errorMonitor->VerifyFound();
2638 
2639     m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdSetEvent-stageMask-04091");
2640     vk::CmdSetEvent(cmd_buffer, event, VK_PIPELINE_STAGE_TESSELLATION_CONTROL_SHADER_BIT);
2641     m_errorMonitor->VerifyFound();
2642 
2643     vk::DestroyEvent(test_device.handle(), event, NULL);
2644     vk::DestroyCommandPool(test_device.handle(), command_pool, NULL);
2645 }
2646 
TEST_F(VkLayerTest,StageMaskHost)2647 TEST_F(VkLayerTest, StageMaskHost) {
2648     TEST_DESCRIPTION("Test invalid usage of VK_PIPELINE_STAGE_HOST_BIT.");
2649     ASSERT_NO_FATAL_FAILURE(Init());
2650     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
2651 
2652     VkEvent event;
2653     VkEventCreateInfo event_create_info{};
2654     event_create_info.sType = VK_STRUCTURE_TYPE_EVENT_CREATE_INFO;
2655     vk::CreateEvent(m_device->device(), &event_create_info, nullptr, &event);
2656 
2657     m_commandBuffer->begin();
2658 
2659     m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdSetEvent-stageMask-01149");
2660     vk::CmdSetEvent(m_commandBuffer->handle(), event, VK_PIPELINE_STAGE_HOST_BIT);
2661     m_errorMonitor->VerifyFound();
2662 
2663     m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdResetEvent-stageMask-01153");
2664     vk::CmdResetEvent(m_commandBuffer->handle(), event, VK_PIPELINE_STAGE_HOST_BIT);
2665     m_errorMonitor->VerifyFound();
2666 
2667     m_commandBuffer->end();
2668 
2669     VkSemaphoreCreateInfo semaphore_create_info = {};
2670     semaphore_create_info.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO;
2671     VkSemaphore semaphore;
2672     ASSERT_VK_SUCCESS(vk::CreateSemaphore(m_device->device(), &semaphore_create_info, nullptr, &semaphore));
2673 
2674     VkPipelineStageFlags stage_flags = VK_PIPELINE_STAGE_HOST_BIT;
2675     VkSubmitInfo submit_info = {};
2676 
2677     // Signal the semaphore so the next test can wait on it.
2678     submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
2679     submit_info.signalSemaphoreCount = 1;
2680     submit_info.pSignalSemaphores = &semaphore;
2681     vk::QueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
2682     m_errorMonitor->VerifyNotFound();
2683 
2684     submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
2685     submit_info.signalSemaphoreCount = 0;
2686     submit_info.pSignalSemaphores = nullptr;
2687     submit_info.waitSemaphoreCount = 1;
2688     submit_info.pWaitSemaphores = &semaphore;
2689     submit_info.pWaitDstStageMask = &stage_flags;
2690 
2691     m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkSubmitInfo-pWaitDstStageMask-00078");
2692     vk::QueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
2693     m_errorMonitor->VerifyFound();
2694 
2695     vk::DestroyEvent(m_device->device(), event, nullptr);
2696     vk::DestroySemaphore(m_device->device(), semaphore, nullptr);
2697 }
2698 
TEST_F(VkLayerTest,DescriptorPoolInUseDestroyedSignaled)2699 TEST_F(VkLayerTest, DescriptorPoolInUseDestroyedSignaled) {
2700     TEST_DESCRIPTION("Delete a DescriptorPool with a DescriptorSet that is in use.");
2701     ASSERT_NO_FATAL_FAILURE(Init());
2702     ASSERT_NO_FATAL_FAILURE(InitViewport());
2703     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
2704 
2705     // Create image to update the descriptor with
2706     VkImageObj image(m_device);
2707     image.Init(32, 32, 1, VK_FORMAT_B8G8R8A8_UNORM, VK_IMAGE_USAGE_SAMPLED_BIT, VK_IMAGE_TILING_OPTIMAL, 0);
2708     ASSERT_TRUE(image.initialized());
2709 
2710     VkImageView view = image.targetView(VK_FORMAT_B8G8R8A8_UNORM);
2711     // Create Sampler
2712     VkSamplerCreateInfo sampler_ci = SafeSaneSamplerCreateInfo();
2713     VkSampler sampler;
2714     VkResult err = vk::CreateSampler(m_device->device(), &sampler_ci, NULL, &sampler);
2715     ASSERT_VK_SUCCESS(err);
2716 
2717     // Create PSO to be used for draw-time errors below
2718     VkShaderObj fs(m_device, bindStateFragSamplerShaderText, VK_SHADER_STAGE_FRAGMENT_BIT, this);
2719 
2720     CreatePipelineHelper pipe(*this);
2721     pipe.InitInfo();
2722     pipe.shader_stages_ = {pipe.vs_->GetStageCreateInfo(), fs.GetStageCreateInfo()};
2723     pipe.dsl_bindings_ = {
2724         {0, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_ALL, nullptr},
2725     };
2726     const VkDynamicState dyn_states[] = {VK_DYNAMIC_STATE_VIEWPORT, VK_DYNAMIC_STATE_SCISSOR};
2727     VkPipelineDynamicStateCreateInfo dyn_state_ci = {};
2728     dyn_state_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO;
2729     dyn_state_ci.dynamicStateCount = size(dyn_states);
2730     dyn_state_ci.pDynamicStates = dyn_states;
2731     pipe.dyn_state_ci_ = dyn_state_ci;
2732     pipe.InitState();
2733     pipe.CreateGraphicsPipeline();
2734 
2735     // Update descriptor with image and sampler
2736     pipe.descriptor_set_->WriteDescriptorImageInfo(0, view, sampler, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER);
2737     pipe.descriptor_set_->UpdateDescriptorSets();
2738 
2739     m_commandBuffer->begin();
2740     m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
2741     vk::CmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.pipeline_);
2742     vk::CmdBindDescriptorSets(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.pipeline_layout_.handle(), 0, 1,
2743                               &pipe.descriptor_set_->set_, 0, NULL);
2744 
2745     VkViewport viewport = {0, 0, 16, 16, 0, 1};
2746     VkRect2D scissor = {{0, 0}, {16, 16}};
2747     vk::CmdSetViewport(m_commandBuffer->handle(), 0, 1, &viewport);
2748     vk::CmdSetScissor(m_commandBuffer->handle(), 0, 1, &scissor);
2749 
2750     m_commandBuffer->Draw(1, 0, 0, 0);
2751     m_commandBuffer->EndRenderPass();
2752     m_commandBuffer->end();
2753     // Submit cmd buffer to put pool in-flight
2754     VkSubmitInfo submit_info = {};
2755     submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
2756     submit_info.commandBufferCount = 1;
2757     submit_info.pCommandBuffers = &m_commandBuffer->handle();
2758     vk::QueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
2759     // Destroy pool while in-flight, causing error
2760     m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkDestroyDescriptorPool-descriptorPool-00303");
2761     vk::DestroyDescriptorPool(m_device->device(), pipe.descriptor_set_->pool_, NULL);
2762     m_errorMonitor->VerifyFound();
2763     vk::QueueWaitIdle(m_device->m_queue);
2764     // Cleanup
2765     vk::DestroySampler(m_device->device(), sampler, NULL);
2766     m_errorMonitor->SetUnexpectedError(
2767         "If descriptorPool is not VK_NULL_HANDLE, descriptorPool must be a valid VkDescriptorPool handle");
2768     m_errorMonitor->SetUnexpectedError("Unable to remove DescriptorPool obj");
2769     // TODO : It seems Validation layers think ds_pool was already destroyed, even though it wasn't?
2770 }
2771 
TEST_F(VkLayerTest,FramebufferInUseDestroyedSignaled)2772 TEST_F(VkLayerTest, FramebufferInUseDestroyedSignaled) {
2773     TEST_DESCRIPTION("Delete in-use framebuffer.");
2774     ASSERT_NO_FATAL_FAILURE(Init());
2775     VkFormatProperties format_properties;
2776     VkResult err = VK_SUCCESS;
2777     vk::GetPhysicalDeviceFormatProperties(gpu(), VK_FORMAT_B8G8R8A8_UNORM, &format_properties);
2778 
2779     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
2780 
2781     VkImageObj image(m_device);
2782     image.Init(256, 256, 1, VK_FORMAT_B8G8R8A8_UNORM, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, VK_IMAGE_TILING_OPTIMAL, 0);
2783     ASSERT_TRUE(image.initialized());
2784     VkImageView view = image.targetView(VK_FORMAT_B8G8R8A8_UNORM);
2785 
2786     VkFramebufferCreateInfo fci = {VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, nullptr, 0, m_renderPass, 1, &view, 256, 256, 1};
2787     VkFramebuffer fb;
2788     err = vk::CreateFramebuffer(m_device->device(), &fci, nullptr, &fb);
2789     ASSERT_VK_SUCCESS(err);
2790 
2791     // Just use default renderpass with our framebuffer
2792     m_renderPassBeginInfo.framebuffer = fb;
2793     // Create Null cmd buffer for submit
2794     m_commandBuffer->begin();
2795     m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
2796     m_commandBuffer->EndRenderPass();
2797     m_commandBuffer->end();
2798     // Submit cmd buffer to put it in-flight
2799     VkSubmitInfo submit_info = {};
2800     submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
2801     submit_info.commandBufferCount = 1;
2802     submit_info.pCommandBuffers = &m_commandBuffer->handle();
2803     vk::QueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
2804     // Destroy framebuffer while in-flight
2805     m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkDestroyFramebuffer-framebuffer-00892");
2806     vk::DestroyFramebuffer(m_device->device(), fb, NULL);
2807     m_errorMonitor->VerifyFound();
2808     // Wait for queue to complete so we can safely destroy everything
2809     vk::QueueWaitIdle(m_device->m_queue);
2810     m_errorMonitor->SetUnexpectedError("If framebuffer is not VK_NULL_HANDLE, framebuffer must be a valid VkFramebuffer handle");
2811     m_errorMonitor->SetUnexpectedError("Unable to remove Framebuffer obj");
2812     vk::DestroyFramebuffer(m_device->device(), fb, nullptr);
2813 }
2814 
TEST_F(VkLayerTest,FramebufferImageInUseDestroyedSignaled)2815 TEST_F(VkLayerTest, FramebufferImageInUseDestroyedSignaled) {
2816     TEST_DESCRIPTION("Delete in-use image that's child of framebuffer.");
2817     ASSERT_NO_FATAL_FAILURE(Init());
2818     VkFormatProperties format_properties;
2819     VkResult err = VK_SUCCESS;
2820     vk::GetPhysicalDeviceFormatProperties(gpu(), VK_FORMAT_B8G8R8A8_UNORM, &format_properties);
2821 
2822     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
2823 
2824     VkImageCreateInfo image_ci = {};
2825     image_ci.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
2826     image_ci.pNext = NULL;
2827     image_ci.imageType = VK_IMAGE_TYPE_2D;
2828     image_ci.format = VK_FORMAT_B8G8R8A8_UNORM;
2829     image_ci.extent.width = 256;
2830     image_ci.extent.height = 256;
2831     image_ci.extent.depth = 1;
2832     image_ci.mipLevels = 1;
2833     image_ci.arrayLayers = 1;
2834     image_ci.samples = VK_SAMPLE_COUNT_1_BIT;
2835     image_ci.tiling = VK_IMAGE_TILING_OPTIMAL;
2836     image_ci.usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
2837     image_ci.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
2838     image_ci.flags = 0;
2839     VkImageObj image(m_device);
2840     image.init(&image_ci);
2841 
2842     VkImageView view = image.targetView(VK_FORMAT_B8G8R8A8_UNORM);
2843 
2844     VkFramebufferCreateInfo fci = {VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, nullptr, 0, m_renderPass, 1, &view, 256, 256, 1};
2845     VkFramebuffer fb;
2846     err = vk::CreateFramebuffer(m_device->device(), &fci, nullptr, &fb);
2847     ASSERT_VK_SUCCESS(err);
2848 
2849     // Just use default renderpass with our framebuffer
2850     m_renderPassBeginInfo.framebuffer = fb;
2851     // Create Null cmd buffer for submit
2852     m_commandBuffer->begin();
2853     m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
2854     m_commandBuffer->EndRenderPass();
2855     m_commandBuffer->end();
2856     // Submit cmd buffer to put it (and attached imageView) in-flight
2857     VkSubmitInfo submit_info = {};
2858     submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
2859     submit_info.commandBufferCount = 1;
2860     submit_info.pCommandBuffers = &m_commandBuffer->handle();
2861     // Submit cmd buffer to put framebuffer and children in-flight
2862     vk::QueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
2863     // Destroy image attached to framebuffer while in-flight
2864     m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkDestroyImage-image-01000");
2865     vk::DestroyImage(m_device->device(), image.handle(), NULL);
2866     m_errorMonitor->VerifyFound();
2867     // Wait for queue to complete so we can safely destroy image and other objects
2868     vk::QueueWaitIdle(m_device->m_queue);
2869     m_errorMonitor->SetUnexpectedError("If image is not VK_NULL_HANDLE, image must be a valid VkImage handle");
2870     m_errorMonitor->SetUnexpectedError("Unable to remove Image obj");
2871     vk::DestroyFramebuffer(m_device->device(), fb, nullptr);
2872 }
2873 
TEST_F(VkLayerTest,EventInUseDestroyedSignaled)2874 TEST_F(VkLayerTest, EventInUseDestroyedSignaled) {
2875     ASSERT_NO_FATAL_FAILURE(Init());
2876     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
2877 
2878     m_commandBuffer->begin();
2879 
2880     VkEvent event;
2881     VkEventCreateInfo event_create_info = {};
2882     event_create_info.sType = VK_STRUCTURE_TYPE_EVENT_CREATE_INFO;
2883     vk::CreateEvent(m_device->device(), &event_create_info, nullptr, &event);
2884     vk::CmdSetEvent(m_commandBuffer->handle(), event, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT);
2885 
2886     m_commandBuffer->end();
2887     vk::DestroyEvent(m_device->device(), event, nullptr);
2888 
2889     VkSubmitInfo submit_info = {};
2890     submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
2891     submit_info.commandBufferCount = 1;
2892     submit_info.pCommandBuffers = &m_commandBuffer->handle();
2893     m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "that is invalid because bound");
2894     vk::QueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
2895     m_errorMonitor->VerifyFound();
2896 }
2897 
TEST_F(VkLayerTest,InUseDestroyedSignaled)2898 TEST_F(VkLayerTest, InUseDestroyedSignaled) {
2899     TEST_DESCRIPTION(
2900         "Use vkCmdExecuteCommands with invalid state in primary and secondary command buffers. Delete objects that are in use. "
2901         "Call VkQueueSubmit with an event that has been deleted.");
2902 
2903     ASSERT_NO_FATAL_FAILURE(Init());
2904     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
2905 
2906     m_errorMonitor->ExpectSuccess();
2907 
2908     VkSemaphoreCreateInfo semaphore_create_info = {};
2909     semaphore_create_info.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO;
2910     VkSemaphore semaphore;
2911     ASSERT_VK_SUCCESS(vk::CreateSemaphore(m_device->device(), &semaphore_create_info, nullptr, &semaphore));
2912     VkFenceCreateInfo fence_create_info = {};
2913     fence_create_info.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
2914     VkFence fence;
2915     ASSERT_VK_SUCCESS(vk::CreateFence(m_device->device(), &fence_create_info, nullptr, &fence));
2916 
2917     VkBufferTest buffer_test(m_device, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT);
2918 
2919     CreatePipelineHelper pipe(*this);
2920     pipe.InitInfo();
2921     pipe.InitState();
2922     pipe.CreateGraphicsPipeline();
2923 
2924     pipe.descriptor_set_->WriteDescriptorBufferInfo(0, buffer_test.GetBuffer(), 0, 1024, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER);
2925     pipe.descriptor_set_->UpdateDescriptorSets();
2926 
2927     VkEvent event;
2928     VkEventCreateInfo event_create_info = {};
2929     event_create_info.sType = VK_STRUCTURE_TYPE_EVENT_CREATE_INFO;
2930     vk::CreateEvent(m_device->device(), &event_create_info, nullptr, &event);
2931 
2932     m_commandBuffer->begin();
2933 
2934     vk::CmdSetEvent(m_commandBuffer->handle(), event, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT);
2935 
2936     vk::CmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.pipeline_);
2937     vk::CmdBindDescriptorSets(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.pipeline_layout_.handle(), 0, 1,
2938                               &pipe.descriptor_set_->set_, 0, NULL);
2939 
2940     m_commandBuffer->end();
2941 
2942     VkSubmitInfo submit_info = {};
2943     submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
2944     submit_info.commandBufferCount = 1;
2945     submit_info.pCommandBuffers = &m_commandBuffer->handle();
2946     submit_info.signalSemaphoreCount = 1;
2947     submit_info.pSignalSemaphores = &semaphore;
2948     vk::QueueSubmit(m_device->m_queue, 1, &submit_info, fence);
2949     m_errorMonitor->Reset();  // resume logmsg processing
2950 
2951     m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkDestroyEvent-event-01145");
2952     vk::DestroyEvent(m_device->device(), event, nullptr);
2953     m_errorMonitor->VerifyFound();
2954 
2955     m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkDestroySemaphore-semaphore-01137");
2956     vk::DestroySemaphore(m_device->device(), semaphore, nullptr);
2957     m_errorMonitor->VerifyFound();
2958 
2959     m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkDestroyFence-fence-01120");
2960     vk::DestroyFence(m_device->device(), fence, nullptr);
2961     m_errorMonitor->VerifyFound();
2962 
2963     vk::QueueWaitIdle(m_device->m_queue);
2964     m_errorMonitor->SetUnexpectedError("If semaphore is not VK_NULL_HANDLE, semaphore must be a valid VkSemaphore handle");
2965     m_errorMonitor->SetUnexpectedError("Unable to remove Semaphore obj");
2966     vk::DestroySemaphore(m_device->device(), semaphore, nullptr);
2967     m_errorMonitor->SetUnexpectedError("If fence is not VK_NULL_HANDLE, fence must be a valid VkFence handle");
2968     m_errorMonitor->SetUnexpectedError("Unable to remove Fence obj");
2969     vk::DestroyFence(m_device->device(), fence, nullptr);
2970     m_errorMonitor->SetUnexpectedError("If event is not VK_NULL_HANDLE, event must be a valid VkEvent handle");
2971     m_errorMonitor->SetUnexpectedError("Unable to remove Event obj");
2972     vk::DestroyEvent(m_device->device(), event, nullptr);
2973 }
2974 
TEST_F(VkLayerTest,EventStageMaskOneCommandBufferPass)2975 TEST_F(VkLayerTest, EventStageMaskOneCommandBufferPass) {
2976     ASSERT_NO_FATAL_FAILURE(Init());
2977     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
2978 
2979     VkCommandBufferObj commandBuffer1(m_device, m_commandPool);
2980     VkCommandBufferObj commandBuffer2(m_device, m_commandPool);
2981 
2982     VkEvent event;
2983     VkEventCreateInfo event_create_info = {};
2984     event_create_info.sType = VK_STRUCTURE_TYPE_EVENT_CREATE_INFO;
2985     vk::CreateEvent(m_device->device(), &event_create_info, nullptr, &event);
2986 
2987     commandBuffer1.begin();
2988     vk::CmdSetEvent(commandBuffer1.handle(), event, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT);
2989     vk::CmdWaitEvents(commandBuffer1.handle(), 1, &event, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT,
2990                       VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, 0, nullptr, 0, nullptr, 0, nullptr);
2991     commandBuffer1.end();
2992 
2993     VkSubmitInfo submit_info = {};
2994     submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
2995     submit_info.commandBufferCount = 1;
2996     submit_info.pCommandBuffers = &commandBuffer1.handle();
2997     m_errorMonitor->ExpectSuccess();
2998     vk::QueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
2999     m_errorMonitor->VerifyNotFound();
3000     vk::QueueWaitIdle(m_device->m_queue);
3001 
3002     vk::DestroyEvent(m_device->device(), event, nullptr);
3003 }
3004 
TEST_F(VkLayerTest,EventStageMaskOneCommandBufferFail)3005 TEST_F(VkLayerTest, EventStageMaskOneCommandBufferFail) {
3006     ASSERT_NO_FATAL_FAILURE(Init());
3007     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
3008 
3009     VkCommandBufferObj commandBuffer1(m_device, m_commandPool);
3010     VkCommandBufferObj commandBuffer2(m_device, m_commandPool);
3011 
3012     VkEvent event;
3013     VkEventCreateInfo event_create_info = {};
3014     event_create_info.sType = VK_STRUCTURE_TYPE_EVENT_CREATE_INFO;
3015     vk::CreateEvent(m_device->device(), &event_create_info, nullptr, &event);
3016 
3017     commandBuffer1.begin();
3018     vk::CmdSetEvent(commandBuffer1.handle(), event, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT);
3019     // wrong srcStageMask
3020     vk::CmdWaitEvents(commandBuffer1.handle(), 1, &event, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT,
3021                       0, nullptr, 0, nullptr, 0, nullptr);
3022     commandBuffer1.end();
3023 
3024     VkSubmitInfo submit_info = {};
3025     submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
3026     submit_info.commandBufferCount = 1;
3027     submit_info.pCommandBuffers = &commandBuffer1.handle();
3028     m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdWaitEvents-srcStageMask-parameter");
3029     vk::QueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
3030     m_errorMonitor->VerifyFound();
3031     vk::QueueWaitIdle(m_device->m_queue);
3032 
3033     vk::DestroyEvent(m_device->device(), event, nullptr);
3034 }
3035 
TEST_F(VkLayerTest,EventStageMaskTwoCommandBufferPass)3036 TEST_F(VkLayerTest, EventStageMaskTwoCommandBufferPass) {
3037     ASSERT_NO_FATAL_FAILURE(Init());
3038     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
3039 
3040     VkCommandBufferObj commandBuffer1(m_device, m_commandPool);
3041     VkCommandBufferObj commandBuffer2(m_device, m_commandPool);
3042 
3043     VkEvent event;
3044     VkEventCreateInfo event_create_info = {};
3045     event_create_info.sType = VK_STRUCTURE_TYPE_EVENT_CREATE_INFO;
3046     vk::CreateEvent(m_device->device(), &event_create_info, nullptr, &event);
3047 
3048     commandBuffer1.begin();
3049     vk::CmdSetEvent(commandBuffer1.handle(), event, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT);
3050     commandBuffer1.end();
3051 
3052     VkSubmitInfo submit_info = {};
3053     submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
3054     submit_info.commandBufferCount = 1;
3055     submit_info.pCommandBuffers = &commandBuffer1.handle();
3056     vk::QueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
3057 
3058     commandBuffer2.begin();
3059     vk::CmdWaitEvents(commandBuffer2.handle(), 1, &event, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT,
3060                       VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, 0, nullptr, 0, nullptr, 0, nullptr);
3061     commandBuffer2.end();
3062 
3063     submit_info.pCommandBuffers = &commandBuffer2.handle();
3064     m_errorMonitor->ExpectSuccess();
3065     vk::QueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
3066     m_errorMonitor->VerifyNotFound();
3067     vk::QueueWaitIdle(m_device->m_queue);
3068 
3069     vk::DestroyEvent(m_device->device(), event, nullptr);
3070 }
3071 
TEST_F(VkLayerTest,EventStageMaskTwoCommandBufferFail)3072 TEST_F(VkLayerTest, EventStageMaskTwoCommandBufferFail) {
3073     ASSERT_NO_FATAL_FAILURE(Init());
3074     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
3075 
3076     VkCommandBufferObj commandBuffer1(m_device, m_commandPool);
3077     VkCommandBufferObj commandBuffer2(m_device, m_commandPool);
3078 
3079     VkEvent event;
3080     VkEventCreateInfo event_create_info = {};
3081     event_create_info.sType = VK_STRUCTURE_TYPE_EVENT_CREATE_INFO;
3082     vk::CreateEvent(m_device->device(), &event_create_info, nullptr, &event);
3083 
3084     commandBuffer1.begin();
3085     vk::CmdSetEvent(commandBuffer1.handle(), event, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT);
3086     commandBuffer1.end();
3087 
3088     VkSubmitInfo submit_info = {};
3089     submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
3090     submit_info.commandBufferCount = 1;
3091     submit_info.pCommandBuffers = &commandBuffer1.handle();
3092     vk::QueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
3093 
3094     commandBuffer2.begin();
3095     // wrong srcStageMask
3096     vk::CmdWaitEvents(commandBuffer2.handle(), 1, &event, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT,
3097                       0, nullptr, 0, nullptr, 0, nullptr);
3098     commandBuffer2.end();
3099 
3100     submit_info.pCommandBuffers = &commandBuffer2.handle();
3101     m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdWaitEvents-srcStageMask-parameter");
3102     vk::QueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
3103     m_errorMonitor->VerifyFound();
3104     vk::QueueWaitIdle(m_device->m_queue);
3105 
3106     vk::DestroyEvent(m_device->device(), event, nullptr);
3107 }
3108 
TEST_F(VkLayerTest,QueryPoolPartialTimestamp)3109 TEST_F(VkLayerTest, QueryPoolPartialTimestamp) {
3110     TEST_DESCRIPTION("Request partial result on timestamp query.");
3111 
3112     ASSERT_NO_FATAL_FAILURE(Init());
3113     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
3114 
3115     uint32_t queue_count;
3116     vk::GetPhysicalDeviceQueueFamilyProperties(gpu(), &queue_count, NULL);
3117     std::vector<VkQueueFamilyProperties> queue_props(queue_count);
3118     vk::GetPhysicalDeviceQueueFamilyProperties(gpu(), &queue_count, queue_props.data());
3119     if (queue_props[m_device->graphics_queue_node_index_].timestampValidBits == 0) {
3120         printf("%s Device graphic queue has timestampValidBits of 0, skipping.\n", kSkipPrefix);
3121         return;
3122     }
3123 
3124     VkBufferObj buffer;
3125     buffer.init(*m_device, 128, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, VK_BUFFER_USAGE_TRANSFER_DST_BIT);
3126 
3127     VkQueryPool query_pool;
3128     VkQueryPoolCreateInfo query_pool_ci{};
3129     query_pool_ci.sType = VK_STRUCTURE_TYPE_QUERY_POOL_CREATE_INFO;
3130     query_pool_ci.queryType = VK_QUERY_TYPE_TIMESTAMP;
3131     query_pool_ci.queryCount = 1;
3132     vk::CreateQueryPool(m_device->device(), &query_pool_ci, nullptr, &query_pool);
3133 
3134     // Use setup as a positive test...
3135     m_errorMonitor->ExpectSuccess();
3136     m_commandBuffer->begin();
3137     vk::CmdResetQueryPool(m_commandBuffer->handle(), query_pool, 0, 1);
3138     vk::CmdWriteTimestamp(m_commandBuffer->handle(), VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, query_pool, 0);
3139     m_errorMonitor->VerifyNotFound();
3140 
3141     m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdCopyQueryPoolResults-queryType-00827");
3142     vk::CmdCopyQueryPoolResults(m_commandBuffer->handle(), query_pool, 0, 1, buffer.handle(), 0, 8, VK_QUERY_RESULT_PARTIAL_BIT);
3143     m_errorMonitor->VerifyFound();
3144 
3145     m_errorMonitor->ExpectSuccess();
3146     m_commandBuffer->end();
3147 
3148     // Submit cmd buffer and wait for it.
3149     VkSubmitInfo submit_info = {};
3150     submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
3151     submit_info.commandBufferCount = 1;
3152     submit_info.pCommandBuffers = &m_commandBuffer->handle();
3153     vk::QueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
3154     vk::QueueWaitIdle(m_device->m_queue);
3155     m_errorMonitor->VerifyNotFound();
3156 
3157     // Attempt to obtain partial results.
3158     m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkGetQueryPoolResults-queryType-00818");
3159     uint32_t data_space[16];
3160     m_errorMonitor->SetUnexpectedError("Cannot get query results on queryPool");
3161     vk::GetQueryPoolResults(m_device->handle(), query_pool, 0, 1, sizeof(data_space), &data_space, sizeof(uint32_t),
3162                             VK_QUERY_RESULT_PARTIAL_BIT);
3163     m_errorMonitor->VerifyFound();
3164 
3165     // Destroy query pool.
3166     vk::DestroyQueryPool(m_device->handle(), query_pool, NULL);
3167 }
3168 
TEST_F(VkLayerTest,PerformanceQueryIntel)3169 TEST_F(VkLayerTest, PerformanceQueryIntel) {
3170     TEST_DESCRIPTION("Call CmdCopyQueryPoolResults for an Intel performance query.");
3171 
3172     ASSERT_NO_FATAL_FAILURE(InitFramework());
3173     if (DeviceExtensionSupported(gpu(), nullptr, VK_INTEL_PERFORMANCE_QUERY_EXTENSION_NAME)) {
3174         m_device_extension_names.push_back(VK_INTEL_PERFORMANCE_QUERY_EXTENSION_NAME);
3175     } else {
3176         printf("%s Intel Performance Query Extension not supported, skipping tests\n", kSkipPrefix);
3177         return;
3178     }
3179     ASSERT_NO_FATAL_FAILURE(InitState());
3180 
3181     auto performance_api_info_intel = LvlInitStruct<VkInitializePerformanceApiInfoINTEL>();
3182     PFN_vkInitializePerformanceApiINTEL vkInitializePerformanceApiINTEL =
3183         (PFN_vkInitializePerformanceApiINTEL)vk::GetDeviceProcAddr(m_device->device(), "vkInitializePerformanceApiINTEL");
3184     vkInitializePerformanceApiINTEL(m_device->device(), &performance_api_info_intel);
3185 
3186     VkBufferObj buffer;
3187     buffer.init(*m_device, 128, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, VK_BUFFER_USAGE_TRANSFER_DST_BIT);
3188 
3189     VkQueryPool query_pool;
3190     VkQueryPoolCreateInfo query_pool_ci{};
3191     query_pool_ci.sType = VK_STRUCTURE_TYPE_QUERY_POOL_CREATE_INFO;
3192     query_pool_ci.queryType = VK_QUERY_TYPE_PERFORMANCE_QUERY_INTEL;
3193     query_pool_ci.queryCount = 1;
3194     vk::CreateQueryPool(m_device->device(), &query_pool_ci, nullptr, &query_pool);
3195 
3196     m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdCopyQueryPoolResults-queryType-02734");
3197     m_commandBuffer->begin();
3198     vk::CmdCopyQueryPoolResults(m_commandBuffer->handle(), query_pool, 0, 1, buffer.handle(), 0, 8, 0);
3199     m_commandBuffer->end();
3200     m_errorMonitor->VerifyFound();
3201 
3202     // Destroy query pool.
3203     vk::DestroyQueryPool(m_device->handle(), query_pool, NULL);
3204 }
3205 
TEST_F(VkLayerTest,QueryPoolInUseDestroyedSignaled)3206 TEST_F(VkLayerTest, QueryPoolInUseDestroyedSignaled) {
3207     TEST_DESCRIPTION("Delete in-use query pool.");
3208 
3209     ASSERT_NO_FATAL_FAILURE(Init());
3210     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
3211 
3212     VkQueryPool query_pool;
3213     VkQueryPoolCreateInfo query_pool_ci{};
3214     query_pool_ci.sType = VK_STRUCTURE_TYPE_QUERY_POOL_CREATE_INFO;
3215     query_pool_ci.queryType = VK_QUERY_TYPE_TIMESTAMP;
3216     query_pool_ci.queryCount = 1;
3217     vk::CreateQueryPool(m_device->device(), &query_pool_ci, nullptr, &query_pool);
3218 
3219     m_commandBuffer->begin();
3220     // Use query pool to create binding with cmd buffer
3221     vk::CmdResetQueryPool(m_commandBuffer->handle(), query_pool, 0, 1);
3222     vk::CmdWriteTimestamp(m_commandBuffer->handle(), VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, query_pool, 0);
3223     m_commandBuffer->end();
3224 
3225     // Submit cmd buffer and then destroy query pool while in-flight
3226     VkSubmitInfo submit_info = {};
3227     submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
3228     submit_info.commandBufferCount = 1;
3229     submit_info.pCommandBuffers = &m_commandBuffer->handle();
3230     vk::QueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
3231 
3232     m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkDestroyQueryPool-queryPool-00793");
3233     vk::DestroyQueryPool(m_device->handle(), query_pool, NULL);
3234     m_errorMonitor->VerifyFound();
3235 
3236     vk::QueueWaitIdle(m_device->m_queue);
3237     // Now that cmd buffer done we can safely destroy query_pool
3238     m_errorMonitor->SetUnexpectedError("If queryPool is not VK_NULL_HANDLE, queryPool must be a valid VkQueryPool handle");
3239     m_errorMonitor->SetUnexpectedError("Unable to remove QueryPool obj");
3240     vk::DestroyQueryPool(m_device->handle(), query_pool, NULL);
3241 }
3242 
TEST_F(VkLayerTest,PipelineInUseDestroyedSignaled)3243 TEST_F(VkLayerTest, PipelineInUseDestroyedSignaled) {
3244     TEST_DESCRIPTION("Delete in-use pipeline.");
3245 
3246     ASSERT_NO_FATAL_FAILURE(Init());
3247     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
3248 
3249     const VkPipelineLayoutObj pipeline_layout(m_device);
3250 
3251     m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkDestroyPipeline-pipeline-00765");
3252     // Create PSO to be used for draw-time errors below
3253 
3254     // Store pipeline handle so we can actually delete it before test finishes
3255     VkPipeline delete_this_pipeline;
3256     {  // Scope pipeline so it will be auto-deleted
3257         CreatePipelineHelper pipe(*this);
3258         pipe.InitInfo();
3259         pipe.InitState();
3260         pipe.CreateGraphicsPipeline();
3261 
3262         delete_this_pipeline = pipe.pipeline_;
3263 
3264         m_commandBuffer->begin();
3265         // Bind pipeline to cmd buffer
3266         vk::CmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.pipeline_);
3267 
3268         m_commandBuffer->end();
3269 
3270         VkSubmitInfo submit_info = {};
3271         submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
3272         submit_info.commandBufferCount = 1;
3273         submit_info.pCommandBuffers = &m_commandBuffer->handle();
3274         // Submit cmd buffer and then pipeline destroyed while in-flight
3275         vk::QueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
3276     }  // Pipeline deletion triggered here
3277     m_errorMonitor->VerifyFound();
3278     // Make sure queue finished and then actually delete pipeline
3279     vk::QueueWaitIdle(m_device->m_queue);
3280     m_errorMonitor->SetUnexpectedError("If pipeline is not VK_NULL_HANDLE, pipeline must be a valid VkPipeline handle");
3281     m_errorMonitor->SetUnexpectedError("Unable to remove Pipeline obj");
3282     vk::DestroyPipeline(m_device->handle(), delete_this_pipeline, nullptr);
3283 }
3284 
TEST_F(VkLayerTest,ImageViewInUseDestroyedSignaled)3285 TEST_F(VkLayerTest, ImageViewInUseDestroyedSignaled) {
3286     TEST_DESCRIPTION("Delete in-use imageView.");
3287 
3288     ASSERT_NO_FATAL_FAILURE(Init());
3289     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
3290 
3291     VkSamplerCreateInfo sampler_ci = SafeSaneSamplerCreateInfo();
3292     VkSampler sampler;
3293 
3294     VkResult err;
3295     err = vk::CreateSampler(m_device->device(), &sampler_ci, NULL, &sampler);
3296     ASSERT_VK_SUCCESS(err);
3297 
3298     VkImageObj image(m_device);
3299     image.Init(128, 128, 1, VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_USAGE_SAMPLED_BIT, VK_IMAGE_TILING_OPTIMAL, 0);
3300     ASSERT_TRUE(image.initialized());
3301 
3302     VkImageView view = image.targetView(VK_FORMAT_R8G8B8A8_UNORM);
3303 
3304     // Create PSO to use the sampler
3305     VkShaderObj fs(m_device, bindStateFragSamplerShaderText, VK_SHADER_STAGE_FRAGMENT_BIT, this);
3306 
3307     CreatePipelineHelper pipe(*this);
3308     pipe.InitInfo();
3309     pipe.shader_stages_ = {pipe.vs_->GetStageCreateInfo(), fs.GetStageCreateInfo()};
3310     pipe.dsl_bindings_ = {
3311         {0, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_ALL, nullptr},
3312     };
3313     const VkDynamicState dyn_states[] = {VK_DYNAMIC_STATE_VIEWPORT, VK_DYNAMIC_STATE_SCISSOR};
3314     VkPipelineDynamicStateCreateInfo dyn_state_ci = {};
3315     dyn_state_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO;
3316     dyn_state_ci.dynamicStateCount = size(dyn_states);
3317     dyn_state_ci.pDynamicStates = dyn_states;
3318     pipe.dyn_state_ci_ = dyn_state_ci;
3319     pipe.InitState();
3320     pipe.CreateGraphicsPipeline();
3321 
3322     pipe.descriptor_set_->WriteDescriptorImageInfo(0, view, sampler, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER);
3323     pipe.descriptor_set_->UpdateDescriptorSets();
3324 
3325     m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkDestroyImageView-imageView-01026");
3326 
3327     m_commandBuffer->begin();
3328     m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
3329     // Bind pipeline to cmd buffer
3330     vk::CmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.pipeline_);
3331     vk::CmdBindDescriptorSets(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.pipeline_layout_.handle(), 0, 1,
3332                               &pipe.descriptor_set_->set_, 0, nullptr);
3333 
3334     VkViewport viewport = {0, 0, 16, 16, 0, 1};
3335     VkRect2D scissor = {{0, 0}, {16, 16}};
3336     vk::CmdSetViewport(m_commandBuffer->handle(), 0, 1, &viewport);
3337     vk::CmdSetScissor(m_commandBuffer->handle(), 0, 1, &scissor);
3338 
3339     m_commandBuffer->Draw(1, 0, 0, 0);
3340     m_commandBuffer->EndRenderPass();
3341     m_commandBuffer->end();
3342     // Submit cmd buffer then destroy sampler
3343     VkSubmitInfo submit_info = {};
3344     submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
3345     submit_info.commandBufferCount = 1;
3346     submit_info.pCommandBuffers = &m_commandBuffer->handle();
3347     // Submit cmd buffer and then destroy imageView while in-flight
3348     vk::QueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
3349 
3350     vk::DestroyImageView(m_device->device(), view, nullptr);
3351     m_errorMonitor->VerifyFound();
3352     vk::QueueWaitIdle(m_device->m_queue);
3353     // Now we can actually destroy imageView
3354     m_errorMonitor->SetUnexpectedError("If imageView is not VK_NULL_HANDLE, imageView must be a valid VkImageView handle");
3355     m_errorMonitor->SetUnexpectedError("Unable to remove ImageView obj");
3356     vk::DestroySampler(m_device->device(), sampler, nullptr);
3357 }
3358 
TEST_F(VkLayerTest,BufferViewInUseDestroyedSignaled)3359 TEST_F(VkLayerTest, BufferViewInUseDestroyedSignaled) {
3360     TEST_DESCRIPTION("Delete in-use bufferView.");
3361 
3362     ASSERT_NO_FATAL_FAILURE(Init());
3363     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
3364 
3365     uint32_t queue_family_index = 0;
3366     VkBufferCreateInfo buffer_create_info = {};
3367     buffer_create_info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
3368     buffer_create_info.size = 1024;
3369     buffer_create_info.usage = VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT;
3370     buffer_create_info.queueFamilyIndexCount = 1;
3371     buffer_create_info.pQueueFamilyIndices = &queue_family_index;
3372     VkBufferObj buffer;
3373     buffer.init(*m_device, buffer_create_info);
3374 
3375     VkBufferView view;
3376     VkBufferViewCreateInfo bvci = {};
3377     bvci.sType = VK_STRUCTURE_TYPE_BUFFER_VIEW_CREATE_INFO;
3378     bvci.buffer = buffer.handle();
3379     bvci.format = VK_FORMAT_R32_SFLOAT;
3380     bvci.range = VK_WHOLE_SIZE;
3381 
3382     VkResult err = vk::CreateBufferView(m_device->device(), &bvci, NULL, &view);
3383     ASSERT_VK_SUCCESS(err);
3384 
3385     char const *fsSource = R"glsl(
3386         #version 450
3387         layout(set=0, binding=0, r32f) uniform readonly imageBuffer s;
3388         layout(location=0) out vec4 x;
3389         void main(){
3390            x = imageLoad(s, 0);
3391         }
3392     )glsl";
3393     VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
3394 
3395     CreatePipelineHelper pipe(*this);
3396     pipe.InitInfo();
3397     pipe.shader_stages_ = {pipe.vs_->GetStageCreateInfo(), fs.GetStageCreateInfo()};
3398     pipe.dsl_bindings_ = {
3399         {0, VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER, 1, VK_SHADER_STAGE_ALL, nullptr},
3400     };
3401     const VkDynamicState dyn_states[] = {VK_DYNAMIC_STATE_VIEWPORT, VK_DYNAMIC_STATE_SCISSOR};
3402     VkPipelineDynamicStateCreateInfo dyn_state_ci = {};
3403     dyn_state_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO;
3404     dyn_state_ci.dynamicStateCount = size(dyn_states);
3405     dyn_state_ci.pDynamicStates = dyn_states;
3406     pipe.dyn_state_ci_ = dyn_state_ci;
3407     pipe.InitState();
3408     err = pipe.CreateGraphicsPipeline();
3409     if (err != VK_SUCCESS) {
3410         printf("%s Unable to compile shader, skipping.\n", kSkipPrefix);
3411         return;
3412     }
3413 
3414     pipe.descriptor_set_->WriteDescriptorBufferView(0, view, VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER);
3415     pipe.descriptor_set_->UpdateDescriptorSets();
3416 
3417     m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkDestroyBufferView-bufferView-00936");
3418 
3419     m_commandBuffer->begin();
3420     m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
3421     VkViewport viewport = {0, 0, 16, 16, 0, 1};
3422     vk::CmdSetViewport(m_commandBuffer->handle(), 0, 1, &viewport);
3423     VkRect2D scissor = {{0, 0}, {16, 16}};
3424     vk::CmdSetScissor(m_commandBuffer->handle(), 0, 1, &scissor);
3425     // Bind pipeline to cmd buffer
3426     vk::CmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.pipeline_);
3427     vk::CmdBindDescriptorSets(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.pipeline_layout_.handle(), 0, 1,
3428                               &pipe.descriptor_set_->set_, 0, nullptr);
3429     m_commandBuffer->Draw(1, 0, 0, 0);
3430     m_commandBuffer->EndRenderPass();
3431     m_commandBuffer->end();
3432 
3433     VkSubmitInfo submit_info = {};
3434     submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
3435     submit_info.commandBufferCount = 1;
3436     submit_info.pCommandBuffers = &m_commandBuffer->handle();
3437     // Submit cmd buffer and then destroy bufferView while in-flight
3438     vk::QueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
3439 
3440     vk::DestroyBufferView(m_device->device(), view, nullptr);
3441     m_errorMonitor->VerifyFound();
3442     vk::QueueWaitIdle(m_device->m_queue);
3443     // Now we can actually destroy bufferView
3444     m_errorMonitor->SetUnexpectedError("If bufferView is not VK_NULL_HANDLE, bufferView must be a valid VkBufferView handle");
3445     m_errorMonitor->SetUnexpectedError("Unable to remove BufferView obj");
3446     vk::DestroyBufferView(m_device->device(), view, NULL);
3447 }
3448 
TEST_F(VkLayerTest,SamplerInUseDestroyedSignaled)3449 TEST_F(VkLayerTest, SamplerInUseDestroyedSignaled) {
3450     TEST_DESCRIPTION("Delete in-use sampler.");
3451 
3452     ASSERT_NO_FATAL_FAILURE(Init());
3453     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
3454 
3455     VkSamplerCreateInfo sampler_ci = SafeSaneSamplerCreateInfo();
3456     VkSampler sampler;
3457 
3458     VkResult err;
3459     err = vk::CreateSampler(m_device->device(), &sampler_ci, NULL, &sampler);
3460     ASSERT_VK_SUCCESS(err);
3461 
3462     VkImageObj image(m_device);
3463     image.Init(128, 128, 1, VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_USAGE_SAMPLED_BIT, VK_IMAGE_TILING_OPTIMAL, 0);
3464     ASSERT_TRUE(image.initialized());
3465 
3466     VkImageView view = image.targetView(VK_FORMAT_R8G8B8A8_UNORM);
3467 
3468     // Create PSO to use the sampler
3469     VkShaderObj fs(m_device, bindStateFragSamplerShaderText, VK_SHADER_STAGE_FRAGMENT_BIT, this);
3470 
3471     CreatePipelineHelper pipe(*this);
3472     pipe.InitInfo();
3473     pipe.shader_stages_ = {pipe.vs_->GetStageCreateInfo(), fs.GetStageCreateInfo()};
3474     pipe.dsl_bindings_ = {
3475         {0, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_ALL, nullptr},
3476     };
3477     const VkDynamicState dyn_states[] = {VK_DYNAMIC_STATE_VIEWPORT, VK_DYNAMIC_STATE_SCISSOR};
3478     VkPipelineDynamicStateCreateInfo dyn_state_ci = {};
3479     dyn_state_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO;
3480     dyn_state_ci.dynamicStateCount = size(dyn_states);
3481     dyn_state_ci.pDynamicStates = dyn_states;
3482     pipe.dyn_state_ci_ = dyn_state_ci;
3483     pipe.InitState();
3484     pipe.CreateGraphicsPipeline();
3485 
3486     pipe.descriptor_set_->WriteDescriptorImageInfo(0, view, sampler, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER);
3487     pipe.descriptor_set_->UpdateDescriptorSets();
3488 
3489     m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkDestroySampler-sampler-01082");
3490 
3491     m_commandBuffer->begin();
3492     m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
3493     // Bind pipeline to cmd buffer
3494     vk::CmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.pipeline_);
3495     vk::CmdBindDescriptorSets(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.pipeline_layout_.handle(), 0, 1,
3496                               &pipe.descriptor_set_->set_, 0, nullptr);
3497 
3498     VkViewport viewport = {0, 0, 16, 16, 0, 1};
3499     VkRect2D scissor = {{0, 0}, {16, 16}};
3500     vk::CmdSetViewport(m_commandBuffer->handle(), 0, 1, &viewport);
3501     vk::CmdSetScissor(m_commandBuffer->handle(), 0, 1, &scissor);
3502 
3503     m_commandBuffer->Draw(1, 0, 0, 0);
3504     m_commandBuffer->EndRenderPass();
3505     m_commandBuffer->end();
3506     // Submit cmd buffer then destroy sampler
3507     VkSubmitInfo submit_info = {};
3508     submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
3509     submit_info.commandBufferCount = 1;
3510     submit_info.pCommandBuffers = &m_commandBuffer->handle();
3511     // Submit cmd buffer and then destroy sampler while in-flight
3512     vk::QueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
3513 
3514     vk::DestroySampler(m_device->device(), sampler, nullptr);  // Destroyed too soon
3515     m_errorMonitor->VerifyFound();
3516     vk::QueueWaitIdle(m_device->m_queue);
3517 
3518     // Now we can actually destroy sampler
3519     m_errorMonitor->SetUnexpectedError("If sampler is not VK_NULL_HANDLE, sampler must be a valid VkSampler handle");
3520     m_errorMonitor->SetUnexpectedError("Unable to remove Sampler obj");
3521     vk::DestroySampler(m_device->device(), sampler, NULL);  // Destroyed for real
3522 }
3523 
TEST_F(VkLayerTest,QueueForwardProgressFenceWait)3524 TEST_F(VkLayerTest, QueueForwardProgressFenceWait) {
3525     TEST_DESCRIPTION("Call VkQueueSubmit with a semaphore that is already signaled but not waited on by the queue.");
3526 
3527     ASSERT_NO_FATAL_FAILURE(Init());
3528     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
3529 
3530     const char *queue_forward_progress_message = "UNASSIGNED-CoreValidation-DrawState-QueueForwardProgress";
3531 
3532     VkCommandBufferObj cb1(m_device, m_commandPool);
3533     cb1.begin();
3534     cb1.end();
3535 
3536     VkSemaphoreCreateInfo semaphore_create_info = {};
3537     semaphore_create_info.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO;
3538     VkSemaphore semaphore;
3539     ASSERT_VK_SUCCESS(vk::CreateSemaphore(m_device->device(), &semaphore_create_info, nullptr, &semaphore));
3540     VkSubmitInfo submit_info = {};
3541     submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
3542     submit_info.commandBufferCount = 1;
3543     submit_info.pCommandBuffers = &cb1.handle();
3544     submit_info.signalSemaphoreCount = 1;
3545     submit_info.pSignalSemaphores = &semaphore;
3546     vk::QueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
3547 
3548     m_commandBuffer->begin();
3549     m_commandBuffer->end();
3550     submit_info.pCommandBuffers = &m_commandBuffer->handle();
3551     m_errorMonitor->SetDesiredFailureMsg(kErrorBit, queue_forward_progress_message);
3552     vk::QueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
3553     m_errorMonitor->VerifyFound();
3554 
3555     vk::DeviceWaitIdle(m_device->device());
3556     vk::DestroySemaphore(m_device->device(), semaphore, nullptr);
3557 }
3558 
3559 #if GTEST_IS_THREADSAFE
TEST_F(VkLayerTest,ThreadCommandBufferCollision)3560 TEST_F(VkLayerTest, ThreadCommandBufferCollision) {
3561     test_platform_thread thread;
3562 
3563     m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "THREADING ERROR");
3564     m_errorMonitor->SetAllowedFailureMsg("THREADING ERROR");  // Ignore any extra threading errors found beyond the first one
3565 
3566     ASSERT_NO_FATAL_FAILURE(Init());
3567     ASSERT_NO_FATAL_FAILURE(InitViewport());
3568     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
3569 
3570     // Test takes magnitude of time longer for devsim and slows down testing
3571     if (IsPlatform(kMockICD) || DeviceSimulation()) {
3572         printf("%s Test not supported by MockICD, skipping tests\n", kSkipPrefix);
3573         return;
3574     }
3575 
3576     // Calls AllocateCommandBuffers
3577     VkCommandBufferObj commandBuffer(m_device, m_commandPool);
3578 
3579     commandBuffer.begin();
3580 
3581     VkEventCreateInfo event_info;
3582     VkEvent event;
3583     VkResult err;
3584 
3585     memset(&event_info, 0, sizeof(event_info));
3586     event_info.sType = VK_STRUCTURE_TYPE_EVENT_CREATE_INFO;
3587 
3588     err = vk::CreateEvent(device(), &event_info, NULL, &event);
3589     ASSERT_VK_SUCCESS(err);
3590 
3591     err = vk::ResetEvent(device(), event);
3592     ASSERT_VK_SUCCESS(err);
3593 
3594     struct thread_data_struct data;
3595     data.commandBuffer = commandBuffer.handle();
3596     data.event = event;
3597     bool bailout = false;
3598     data.bailout = &bailout;
3599     m_errorMonitor->SetBailout(data.bailout);
3600 
3601     // First do some correct operations using multiple threads.
3602     // Add many entries to command buffer from another thread.
3603     test_platform_thread_create(&thread, AddToCommandBuffer, (void *)&data);
3604     // Make non-conflicting calls from this thread at the same time.
3605     for (int i = 0; i < 80000; i++) {
3606         uint32_t count;
3607         vk::EnumeratePhysicalDevices(instance(), &count, NULL);
3608     }
3609     test_platform_thread_join(thread, NULL);
3610 
3611     // Then do some incorrect operations using multiple threads.
3612     // Add many entries to command buffer from another thread.
3613     test_platform_thread_create(&thread, AddToCommandBuffer, (void *)&data);
3614     // Add many entries to command buffer from this thread at the same time.
3615     AddToCommandBuffer(&data);
3616 
3617     test_platform_thread_join(thread, NULL);
3618     commandBuffer.end();
3619 
3620     m_errorMonitor->SetBailout(NULL);
3621 
3622     m_errorMonitor->VerifyFound();
3623 
3624     vk::DestroyEvent(device(), event, NULL);
3625 }
3626 
TEST_F(VkLayerTest,ThreadUpdateDescriptorCollision)3627 TEST_F(VkLayerTest, ThreadUpdateDescriptorCollision) {
3628     TEST_DESCRIPTION("Two threads updating the same descriptor set, expected to generate a threading error");
3629     test_platform_thread thread;
3630 
3631     m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "THREADING ERROR : vkUpdateDescriptorSets");
3632     m_errorMonitor->SetAllowedFailureMsg("THREADING ERROR");  // Ignore any extra threading errors found beyond the first one
3633 
3634     ASSERT_NO_FATAL_FAILURE(Init());
3635     ASSERT_NO_FATAL_FAILURE(InitViewport());
3636     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
3637 
3638     OneOffDescriptorSet normal_descriptor_set(m_device,
3639                                               {
3640                                                   {0, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1, VK_SHADER_STAGE_COMPUTE_BIT, nullptr},
3641                                                   {1, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1, VK_SHADER_STAGE_COMPUTE_BIT, nullptr},
3642                                               },
3643                                               0);
3644 
3645     VkBufferObj buffer;
3646     buffer.init(*m_device, 256, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT);
3647 
3648     struct thread_data_struct data;
3649     data.device = device();
3650     data.descriptorSet = normal_descriptor_set.set_;
3651     data.binding = 0;
3652     data.buffer = buffer.handle();
3653     bool bailout = false;
3654     data.bailout = &bailout;
3655     m_errorMonitor->SetBailout(data.bailout);
3656 
3657     // Update descriptors from another thread.
3658     test_platform_thread_create(&thread, UpdateDescriptor, (void *)&data);
3659     // Update descriptors from this thread at the same time.
3660 
3661     struct thread_data_struct data2;
3662     data2.device = device();
3663     data2.descriptorSet = normal_descriptor_set.set_;
3664     data2.binding = 1;
3665     data2.buffer = buffer.handle();
3666     data2.bailout = &bailout;
3667 
3668     UpdateDescriptor(&data2);
3669 
3670     test_platform_thread_join(thread, NULL);
3671 
3672     m_errorMonitor->SetBailout(NULL);
3673 
3674     m_errorMonitor->VerifyFound();
3675 }
3676 
TEST_F(VkLayerTest,ThreadUpdateDescriptorUpdateAfterBindNoCollision)3677 TEST_F(VkLayerTest, ThreadUpdateDescriptorUpdateAfterBindNoCollision) {
3678     TEST_DESCRIPTION("Two threads updating the same UAB descriptor set, expected not to generate a threading error");
3679     test_platform_thread thread;
3680     m_errorMonitor->ExpectSuccess();
3681 
3682     if (InstanceExtensionSupported(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME)) {
3683         m_instance_extension_names.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
3684     } else {
3685         printf("%s %s Extension not supported, skipping tests\n", kSkipPrefix,
3686                VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
3687         return;
3688     }
3689 
3690     ASSERT_NO_FATAL_FAILURE(InitFramework(m_errorMonitor));
3691     if (DeviceExtensionSupported(gpu(), nullptr, VK_EXT_DESCRIPTOR_INDEXING_EXTENSION_NAME) &&
3692         DeviceExtensionSupported(gpu(), nullptr, VK_KHR_MAINTENANCE_3_EXTENSION_NAME)) {
3693         m_device_extension_names.push_back(VK_EXT_DESCRIPTOR_INDEXING_EXTENSION_NAME);
3694         m_device_extension_names.push_back(VK_KHR_MAINTENANCE_3_EXTENSION_NAME);
3695     } else {
3696         printf("%s Descriptor Indexing or Maintenance3 Extension not supported, skipping tests\n", kSkipPrefix);
3697         return;
3698     }
3699 
3700     PFN_vkGetPhysicalDeviceFeatures2KHR vkGetPhysicalDeviceFeatures2KHR =
3701         (PFN_vkGetPhysicalDeviceFeatures2KHR)vk::GetInstanceProcAddr(instance(), "vkGetPhysicalDeviceFeatures2KHR");
3702     ASSERT_TRUE(vkGetPhysicalDeviceFeatures2KHR != nullptr);
3703 
3704     // Create a device that enables descriptorBindingStorageBufferUpdateAfterBind
3705     auto indexing_features = LvlInitStruct<VkPhysicalDeviceDescriptorIndexingFeaturesEXT>();
3706     auto features2 = LvlInitStruct<VkPhysicalDeviceFeatures2KHR>(&indexing_features);
3707     vkGetPhysicalDeviceFeatures2KHR(gpu(), &features2);
3708 
3709     if (VK_FALSE == indexing_features.descriptorBindingStorageBufferUpdateAfterBind) {
3710         printf("%s Test requires (unsupported) descriptorBindingStorageBufferUpdateAfterBind, skipping\n", kSkipPrefix);
3711         return;
3712     }
3713 
3714     ASSERT_NO_FATAL_FAILURE(InitState(nullptr, &features2, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT));
3715     ASSERT_NO_FATAL_FAILURE(InitViewport());
3716     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
3717 
3718     std::array<VkDescriptorBindingFlagsEXT, 2> flags = {
3719         {VK_DESCRIPTOR_BINDING_UPDATE_AFTER_BIND_BIT_EXT, VK_DESCRIPTOR_BINDING_UPDATE_AFTER_BIND_BIT_EXT}};
3720     auto flags_create_info = LvlInitStruct<VkDescriptorSetLayoutBindingFlagsCreateInfoEXT>();
3721     flags_create_info.bindingCount = (uint32_t)flags.size();
3722     flags_create_info.pBindingFlags = flags.data();
3723 
3724     OneOffDescriptorSet normal_descriptor_set(m_device,
3725                                               {
3726                                                   {0, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1, VK_SHADER_STAGE_COMPUTE_BIT, nullptr},
3727                                                   {1, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1, VK_SHADER_STAGE_COMPUTE_BIT, nullptr},
3728                                               },
3729                                               VK_DESCRIPTOR_SET_LAYOUT_CREATE_UPDATE_AFTER_BIND_POOL_BIT_EXT, &flags_create_info,
3730                                               VK_DESCRIPTOR_POOL_CREATE_UPDATE_AFTER_BIND_BIT_EXT);
3731 
3732     VkBufferObj buffer;
3733     buffer.init(*m_device, 256, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT);
3734 
3735     struct thread_data_struct data;
3736     data.device = device();
3737     data.descriptorSet = normal_descriptor_set.set_;
3738     data.binding = 0;
3739     data.buffer = buffer.handle();
3740     bool bailout = false;
3741     data.bailout = &bailout;
3742     m_errorMonitor->SetBailout(data.bailout);
3743 
3744     // Update descriptors from another thread.
3745     test_platform_thread_create(&thread, UpdateDescriptor, (void *)&data);
3746     // Update descriptors from this thread at the same time.
3747 
3748     struct thread_data_struct data2;
3749     data2.device = device();
3750     data2.descriptorSet = normal_descriptor_set.set_;
3751     data2.binding = 1;
3752     data2.buffer = buffer.handle();
3753     data2.bailout = &bailout;
3754 
3755     UpdateDescriptor(&data2);
3756 
3757     test_platform_thread_join(thread, NULL);
3758 
3759     m_errorMonitor->SetBailout(NULL);
3760 
3761     m_errorMonitor->VerifyNotFound();
3762 }
3763 #endif  // GTEST_IS_THREADSAFE
3764 
TEST_F(VkLayerTest,ExecuteUnrecordedPrimaryCB)3765 TEST_F(VkLayerTest, ExecuteUnrecordedPrimaryCB) {
3766     TEST_DESCRIPTION("Attempt vkQueueSubmit with a CB in the initial state");
3767     ASSERT_NO_FATAL_FAILURE(Init());
3768     // never record m_commandBuffer
3769 
3770     VkSubmitInfo si = {};
3771     si.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
3772     si.commandBufferCount = 1;
3773     si.pCommandBuffers = &m_commandBuffer->handle();
3774 
3775     m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkQueueSubmit-pCommandBuffers-00072");
3776     vk::QueueSubmit(m_device->m_queue, 1, &si, VK_NULL_HANDLE);
3777     m_errorMonitor->VerifyFound();
3778 }
3779 
TEST_F(VkLayerTest,Maintenance1AndNegativeViewport)3780 TEST_F(VkLayerTest, Maintenance1AndNegativeViewport) {
3781     TEST_DESCRIPTION("Attempt to enable AMD_negative_viewport_height and Maintenance1_KHR extension simultaneously");
3782 
3783     ASSERT_NO_FATAL_FAILURE(InitFramework(m_errorMonitor));
3784     if (!((DeviceExtensionSupported(gpu(), nullptr, VK_KHR_MAINTENANCE_1_EXTENSION_NAME)) &&
3785           (DeviceExtensionSupported(gpu(), nullptr, VK_AMD_NEGATIVE_VIEWPORT_HEIGHT_EXTENSION_NAME)))) {
3786         printf("%s Maintenance1 and AMD_negative viewport height extensions not supported, skipping test\n", kSkipPrefix);
3787         return;
3788     }
3789     ASSERT_NO_FATAL_FAILURE(InitState());
3790 
3791     vk_testing::QueueCreateInfoArray queue_info(m_device->queue_props);
3792     const char *extension_names[2] = {"VK_KHR_maintenance1", "VK_AMD_negative_viewport_height"};
3793     VkDevice testDevice;
3794     VkDeviceCreateInfo device_create_info = {};
3795     auto features = m_device->phy().features();
3796     device_create_info.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
3797     device_create_info.pNext = NULL;
3798     device_create_info.queueCreateInfoCount = queue_info.size();
3799     device_create_info.pQueueCreateInfos = queue_info.data();
3800     device_create_info.enabledLayerCount = 0;
3801     device_create_info.ppEnabledLayerNames = NULL;
3802     device_create_info.enabledExtensionCount = 2;
3803     device_create_info.ppEnabledExtensionNames = (const char *const *)extension_names;
3804     device_create_info.pEnabledFeatures = &features;
3805 
3806     m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkDeviceCreateInfo-ppEnabledExtensionNames-00374");
3807     // The following unexpected error is coming from the LunarG loader. Do not make it a desired message because platforms that do
3808     // not use the LunarG loader (e.g. Android) will not see the message and the test will fail.
3809     m_errorMonitor->SetUnexpectedError("Failed to create device chain.");
3810     vk::CreateDevice(gpu(), &device_create_info, NULL, &testDevice);
3811     m_errorMonitor->VerifyFound();
3812 }
3813 
TEST_F(VkLayerTest,HostQueryResetNotEnabled)3814 TEST_F(VkLayerTest, HostQueryResetNotEnabled) {
3815     TEST_DESCRIPTION("Use vkResetQueryPoolEXT without enabling the feature");
3816 
3817     if (!InstanceExtensionSupported(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME)) {
3818         printf("%s Did not find required instance extension %s; skipped.\n", kSkipPrefix,
3819                VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
3820         return;
3821     }
3822 
3823     m_instance_extension_names.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
3824     ASSERT_NO_FATAL_FAILURE(InitFramework(m_errorMonitor));
3825 
3826     if (!DeviceExtensionSupported(gpu(), nullptr, VK_EXT_HOST_QUERY_RESET_EXTENSION_NAME)) {
3827         printf("%s Extension %s not supported by device; skipped.\n", kSkipPrefix, VK_EXT_HOST_QUERY_RESET_EXTENSION_NAME);
3828         return;
3829     }
3830 
3831     m_device_extension_names.push_back(VK_EXT_HOST_QUERY_RESET_EXTENSION_NAME);
3832     ASSERT_NO_FATAL_FAILURE(InitState());
3833 
3834     auto fpvkResetQueryPoolEXT = (PFN_vkResetQueryPoolEXT)vk::GetDeviceProcAddr(m_device->device(), "vkResetQueryPoolEXT");
3835 
3836     VkQueryPool query_pool;
3837     VkQueryPoolCreateInfo query_pool_create_info{};
3838     query_pool_create_info.sType = VK_STRUCTURE_TYPE_QUERY_POOL_CREATE_INFO;
3839     query_pool_create_info.queryType = VK_QUERY_TYPE_TIMESTAMP;
3840     query_pool_create_info.queryCount = 1;
3841     vk::CreateQueryPool(m_device->device(), &query_pool_create_info, nullptr, &query_pool);
3842 
3843     m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkResetQueryPool-None-02665");
3844     fpvkResetQueryPoolEXT(m_device->device(), query_pool, 0, 1);
3845     m_errorMonitor->VerifyFound();
3846 
3847     vk::DestroyQueryPool(m_device->device(), query_pool, nullptr);
3848 }
3849 
TEST_F(VkLayerTest,HostQueryResetBadFirstQuery)3850 TEST_F(VkLayerTest, HostQueryResetBadFirstQuery) {
3851     TEST_DESCRIPTION("Bad firstQuery in vkResetQueryPoolEXT");
3852 
3853     if (!InstanceExtensionSupported(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME)) {
3854         printf("%s Did not find required instance extension %s; skipped.\n", kSkipPrefix,
3855                VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
3856         return;
3857     }
3858 
3859     m_instance_extension_names.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
3860     SetTargetApiVersion(VK_API_VERSION_1_2);
3861     ASSERT_NO_FATAL_FAILURE(InitFramework(m_errorMonitor));
3862 
3863     if (!DeviceExtensionSupported(gpu(), nullptr, VK_EXT_HOST_QUERY_RESET_EXTENSION_NAME)) {
3864         printf("%s Extension %s not supported by device; skipped.\n", kSkipPrefix, VK_EXT_HOST_QUERY_RESET_EXTENSION_NAME);
3865         return;
3866     }
3867 
3868     m_device_extension_names.push_back(VK_EXT_HOST_QUERY_RESET_EXTENSION_NAME);
3869 
3870     VkPhysicalDeviceHostQueryResetFeaturesEXT host_query_reset_features{};
3871     host_query_reset_features.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_HOST_QUERY_RESET_FEATURES_EXT;
3872     host_query_reset_features.hostQueryReset = VK_TRUE;
3873 
3874     VkPhysicalDeviceFeatures2 pd_features2{};
3875     pd_features2.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2;
3876     pd_features2.pNext = &host_query_reset_features;
3877 
3878     ASSERT_NO_FATAL_FAILURE(InitState(nullptr, &pd_features2));
3879 
3880     auto fpvkResetQueryPoolEXT = (PFN_vkResetQueryPoolEXT)vk::GetDeviceProcAddr(m_device->device(), "vkResetQueryPoolEXT");
3881 
3882     VkQueryPool query_pool;
3883     VkQueryPoolCreateInfo query_pool_create_info{};
3884     query_pool_create_info.sType = VK_STRUCTURE_TYPE_QUERY_POOL_CREATE_INFO;
3885     query_pool_create_info.queryType = VK_QUERY_TYPE_TIMESTAMP;
3886     query_pool_create_info.queryCount = 1;
3887     vk::CreateQueryPool(m_device->device(), &query_pool_create_info, nullptr, &query_pool);
3888 
3889     m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkResetQueryPool-firstQuery-02666");
3890     fpvkResetQueryPoolEXT(m_device->device(), query_pool, 1, 0);
3891     m_errorMonitor->VerifyFound();
3892 
3893     if (DeviceValidationVersion() >= VK_API_VERSION_1_2) {
3894         auto fpvkResetQueryPool = (PFN_vkResetQueryPool)vk::GetDeviceProcAddr(m_device->device(), "vkResetQueryPool");
3895         if (nullptr == fpvkResetQueryPool) {
3896             m_errorMonitor->ExpectSuccess();
3897             m_errorMonitor->SetError("No ProcAddr for 1.2 core vkResetQueryPool");
3898             m_errorMonitor->VerifyNotFound();
3899         } else {
3900             m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkResetQueryPool-firstQuery-02666");
3901             fpvkResetQueryPool(m_device->device(), query_pool, 1, 0);
3902             m_errorMonitor->VerifyFound();
3903         }
3904     }
3905 
3906     vk::DestroyQueryPool(m_device->device(), query_pool, nullptr);
3907 }
3908 
TEST_F(VkLayerTest,HostQueryResetBadRange)3909 TEST_F(VkLayerTest, HostQueryResetBadRange) {
3910     TEST_DESCRIPTION("Bad range in vkResetQueryPoolEXT");
3911 
3912     if (!InstanceExtensionSupported(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME)) {
3913         printf("%s Did not find required instance extension %s; skipped.\n", kSkipPrefix,
3914                VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
3915         return;
3916     }
3917 
3918     m_instance_extension_names.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
3919     ASSERT_NO_FATAL_FAILURE(InitFramework(m_errorMonitor));
3920 
3921     if (!DeviceExtensionSupported(gpu(), nullptr, VK_EXT_HOST_QUERY_RESET_EXTENSION_NAME)) {
3922         printf("%s Extension %s not supported by device; skipped.\n", kSkipPrefix, VK_EXT_HOST_QUERY_RESET_EXTENSION_NAME);
3923         return;
3924     }
3925 
3926     m_device_extension_names.push_back(VK_EXT_HOST_QUERY_RESET_EXTENSION_NAME);
3927 
3928     VkPhysicalDeviceHostQueryResetFeaturesEXT host_query_reset_features{};
3929     host_query_reset_features.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_HOST_QUERY_RESET_FEATURES_EXT;
3930     host_query_reset_features.hostQueryReset = VK_TRUE;
3931 
3932     VkPhysicalDeviceFeatures2 pd_features2{};
3933     pd_features2.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2;
3934     pd_features2.pNext = &host_query_reset_features;
3935 
3936     ASSERT_NO_FATAL_FAILURE(InitState(nullptr, &pd_features2));
3937 
3938     auto fpvkResetQueryPoolEXT = (PFN_vkResetQueryPoolEXT)vk::GetDeviceProcAddr(m_device->device(), "vkResetQueryPoolEXT");
3939 
3940     VkQueryPool query_pool;
3941     VkQueryPoolCreateInfo query_pool_create_info{};
3942     query_pool_create_info.sType = VK_STRUCTURE_TYPE_QUERY_POOL_CREATE_INFO;
3943     query_pool_create_info.queryType = VK_QUERY_TYPE_TIMESTAMP;
3944     query_pool_create_info.queryCount = 1;
3945     vk::CreateQueryPool(m_device->device(), &query_pool_create_info, nullptr, &query_pool);
3946 
3947     m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkResetQueryPool-firstQuery-02667");
3948     fpvkResetQueryPoolEXT(m_device->device(), query_pool, 0, 2);
3949     m_errorMonitor->VerifyFound();
3950 
3951     vk::DestroyQueryPool(m_device->device(), query_pool, nullptr);
3952 }
3953 
TEST_F(VkLayerTest,HostQueryResetInvalidQueryPool)3954 TEST_F(VkLayerTest, HostQueryResetInvalidQueryPool) {
3955     TEST_DESCRIPTION("Invalid queryPool in vkResetQueryPoolEXT");
3956 
3957     if (!InstanceExtensionSupported(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME)) {
3958         printf("%s Did not find required instance extension %s; skipped.\n", kSkipPrefix,
3959                VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
3960         return;
3961     }
3962 
3963     m_instance_extension_names.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
3964     ASSERT_NO_FATAL_FAILURE(InitFramework(m_errorMonitor));
3965 
3966     if (!DeviceExtensionSupported(gpu(), nullptr, VK_EXT_HOST_QUERY_RESET_EXTENSION_NAME)) {
3967         printf("%s Extension %s not supported by device; skipped.\n", kSkipPrefix, VK_EXT_HOST_QUERY_RESET_EXTENSION_NAME);
3968         return;
3969     }
3970 
3971     m_device_extension_names.push_back(VK_EXT_HOST_QUERY_RESET_EXTENSION_NAME);
3972 
3973     VkPhysicalDeviceHostQueryResetFeaturesEXT host_query_reset_features{};
3974     host_query_reset_features.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_HOST_QUERY_RESET_FEATURES_EXT;
3975     host_query_reset_features.hostQueryReset = VK_TRUE;
3976 
3977     VkPhysicalDeviceFeatures2 pd_features2{};
3978     pd_features2.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2;
3979     pd_features2.pNext = &host_query_reset_features;
3980 
3981     ASSERT_NO_FATAL_FAILURE(InitState(nullptr, &pd_features2));
3982 
3983     auto fpvkResetQueryPoolEXT = (PFN_vkResetQueryPoolEXT)vk::GetDeviceProcAddr(m_device->device(), "vkResetQueryPoolEXT");
3984 
3985     // Create and destroy a query pool.
3986     VkQueryPool query_pool;
3987     VkQueryPoolCreateInfo query_pool_create_info{};
3988     query_pool_create_info.sType = VK_STRUCTURE_TYPE_QUERY_POOL_CREATE_INFO;
3989     query_pool_create_info.queryType = VK_QUERY_TYPE_TIMESTAMP;
3990     query_pool_create_info.queryCount = 1;
3991     vk::CreateQueryPool(m_device->device(), &query_pool_create_info, nullptr, &query_pool);
3992     vk::DestroyQueryPool(m_device->device(), query_pool, nullptr);
3993 
3994     // Attempt to reuse the query pool handle.
3995     m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkResetQueryPool-queryPool-parameter");
3996     fpvkResetQueryPoolEXT(m_device->device(), query_pool, 0, 1);
3997     m_errorMonitor->VerifyFound();
3998 }
3999 
TEST_F(VkLayerTest,HostQueryResetWrongDevice)4000 TEST_F(VkLayerTest, HostQueryResetWrongDevice) {
4001     TEST_DESCRIPTION("Device not matching queryPool in vkResetQueryPoolEXT");
4002 
4003     if (!InstanceExtensionSupported(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME)) {
4004         printf("%s Did not find required instance extension %s; skipped.\n", kSkipPrefix,
4005                VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
4006         return;
4007     }
4008 
4009     m_instance_extension_names.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
4010     ASSERT_NO_FATAL_FAILURE(InitFramework(m_errorMonitor));
4011 
4012     if (!DeviceExtensionSupported(gpu(), nullptr, VK_EXT_HOST_QUERY_RESET_EXTENSION_NAME)) {
4013         printf("%s Extension %s not supported by device; skipped.\n", kSkipPrefix, VK_EXT_HOST_QUERY_RESET_EXTENSION_NAME);
4014         return;
4015     }
4016 
4017     m_device_extension_names.push_back(VK_EXT_HOST_QUERY_RESET_EXTENSION_NAME);
4018 
4019     VkPhysicalDeviceHostQueryResetFeaturesEXT host_query_reset_features{};
4020     host_query_reset_features.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_HOST_QUERY_RESET_FEATURES_EXT;
4021     host_query_reset_features.hostQueryReset = VK_TRUE;
4022 
4023     VkPhysicalDeviceFeatures2 pd_features2{};
4024     pd_features2.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2;
4025     pd_features2.pNext = &host_query_reset_features;
4026 
4027     ASSERT_NO_FATAL_FAILURE(InitState(nullptr, &pd_features2));
4028 
4029     auto fpvkResetQueryPoolEXT = (PFN_vkResetQueryPoolEXT)vk::GetDeviceProcAddr(m_device->device(), "vkResetQueryPoolEXT");
4030 
4031     VkQueryPool query_pool;
4032     VkQueryPoolCreateInfo query_pool_create_info{};
4033     query_pool_create_info.sType = VK_STRUCTURE_TYPE_QUERY_POOL_CREATE_INFO;
4034     query_pool_create_info.queryType = VK_QUERY_TYPE_TIMESTAMP;
4035     query_pool_create_info.queryCount = 1;
4036     vk::CreateQueryPool(m_device->device(), &query_pool_create_info, nullptr, &query_pool);
4037 
4038     // Create a second device with the feature enabled.
4039     vk_testing::QueueCreateInfoArray queue_info(m_device->queue_props);
4040     auto features = m_device->phy().features();
4041 
4042     VkDeviceCreateInfo device_create_info = {};
4043     device_create_info.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
4044     device_create_info.pNext = &host_query_reset_features;
4045     device_create_info.queueCreateInfoCount = queue_info.size();
4046     device_create_info.pQueueCreateInfos = queue_info.data();
4047     device_create_info.pEnabledFeatures = &features;
4048     device_create_info.enabledExtensionCount = m_device_extension_names.size();
4049     device_create_info.ppEnabledExtensionNames = m_device_extension_names.data();
4050 
4051     VkDevice second_device;
4052     ASSERT_VK_SUCCESS(vk::CreateDevice(gpu(), &device_create_info, nullptr, &second_device));
4053 
4054     m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkResetQueryPool-queryPool-parent");
4055     // Run vk::ResetQueryPoolExt on the wrong device.
4056     fpvkResetQueryPoolEXT(second_device, query_pool, 0, 1);
4057     m_errorMonitor->VerifyFound();
4058 
4059     vk::DestroyQueryPool(m_device->device(), query_pool, nullptr);
4060     vk::DestroyDevice(second_device, nullptr);
4061 }
4062 
TEST_F(VkLayerTest,ResetEventThenSet)4063 TEST_F(VkLayerTest, ResetEventThenSet) {
4064     TEST_DESCRIPTION("Reset an event then set it after the reset has been submitted.");
4065 
4066     ASSERT_NO_FATAL_FAILURE(Init());
4067     VkEvent event;
4068     VkEventCreateInfo event_create_info{};
4069     event_create_info.sType = VK_STRUCTURE_TYPE_EVENT_CREATE_INFO;
4070     vk::CreateEvent(m_device->device(), &event_create_info, nullptr, &event);
4071 
4072     VkCommandPool command_pool;
4073     VkCommandPoolCreateInfo pool_create_info{};
4074     pool_create_info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
4075     pool_create_info.queueFamilyIndex = m_device->graphics_queue_node_index_;
4076     pool_create_info.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT;
4077     vk::CreateCommandPool(m_device->device(), &pool_create_info, nullptr, &command_pool);
4078 
4079     VkCommandBuffer command_buffer;
4080     VkCommandBufferAllocateInfo command_buffer_allocate_info{};
4081     command_buffer_allocate_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
4082     command_buffer_allocate_info.commandPool = command_pool;
4083     command_buffer_allocate_info.commandBufferCount = 1;
4084     command_buffer_allocate_info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
4085     vk::AllocateCommandBuffers(m_device->device(), &command_buffer_allocate_info, &command_buffer);
4086 
4087     VkQueue queue = VK_NULL_HANDLE;
4088     vk::GetDeviceQueue(m_device->device(), m_device->graphics_queue_node_index_, 0, &queue);
4089 
4090     {
4091         VkCommandBufferBeginInfo begin_info{};
4092         begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
4093         vk::BeginCommandBuffer(command_buffer, &begin_info);
4094 
4095         vk::CmdResetEvent(command_buffer, event, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT);
4096         vk::EndCommandBuffer(command_buffer);
4097     }
4098     {
4099         VkSubmitInfo submit_info{};
4100         submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
4101         submit_info.commandBufferCount = 1;
4102         submit_info.pCommandBuffers = &command_buffer;
4103         submit_info.signalSemaphoreCount = 0;
4104         submit_info.pSignalSemaphores = nullptr;
4105         vk::QueueSubmit(queue, 1, &submit_info, VK_NULL_HANDLE);
4106     }
4107     {
4108         m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "that is already in use by a command buffer.");
4109         vk::SetEvent(m_device->device(), event);
4110         m_errorMonitor->VerifyFound();
4111     }
4112 
4113     vk::QueueWaitIdle(queue);
4114 
4115     vk::DestroyEvent(m_device->device(), event, nullptr);
4116     vk::FreeCommandBuffers(m_device->device(), command_pool, 1, &command_buffer);
4117     vk::DestroyCommandPool(m_device->device(), command_pool, NULL);
4118 }
4119 
TEST_F(VkLayerTest,ShadingRateImageNV)4120 TEST_F(VkLayerTest, ShadingRateImageNV) {
4121     TEST_DESCRIPTION("Test VK_NV_shading_rate_image.");
4122 
4123     if (InstanceExtensionSupported(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME)) {
4124         m_instance_extension_names.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
4125     } else {
4126         printf("%s Did not find required instance extension %s; skipped.\n", kSkipPrefix,
4127                VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
4128         return;
4129     }
4130     ASSERT_NO_FATAL_FAILURE(InitFramework(m_errorMonitor));
4131     std::array<const char *, 1> required_device_extensions = {{VK_NV_SHADING_RATE_IMAGE_EXTENSION_NAME}};
4132     for (auto device_extension : required_device_extensions) {
4133         if (DeviceExtensionSupported(gpu(), nullptr, device_extension)) {
4134             m_device_extension_names.push_back(device_extension);
4135         } else {
4136             printf("%s %s Extension not supported, skipping tests\n", kSkipPrefix, device_extension);
4137             return;
4138         }
4139     }
4140 
4141     if (IsPlatform(kMockICD) || DeviceSimulation()) {
4142         printf("%s Test not supported by MockICD, skipping tests\n", kSkipPrefix);
4143         return;
4144     }
4145 
4146     PFN_vkGetPhysicalDeviceFeatures2KHR vkGetPhysicalDeviceFeatures2KHR =
4147         (PFN_vkGetPhysicalDeviceFeatures2KHR)vk::GetInstanceProcAddr(instance(), "vkGetPhysicalDeviceFeatures2KHR");
4148     ASSERT_TRUE(vkGetPhysicalDeviceFeatures2KHR != nullptr);
4149 
4150     // Create a device that enables shading_rate_image but disables multiViewport
4151     auto shading_rate_image_features = LvlInitStruct<VkPhysicalDeviceShadingRateImageFeaturesNV>();
4152     auto features2 = LvlInitStruct<VkPhysicalDeviceFeatures2KHR>(&shading_rate_image_features);
4153     vkGetPhysicalDeviceFeatures2KHR(gpu(), &features2);
4154 
4155     features2.features.multiViewport = VK_FALSE;
4156 
4157     ASSERT_NO_FATAL_FAILURE(InitState(nullptr, &features2));
4158     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
4159 
4160     // Test shading rate image creation
4161     VkResult result = VK_RESULT_MAX_ENUM;
4162     VkImageCreateInfo image_create_info = {};
4163     image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
4164     image_create_info.pNext = NULL;
4165     image_create_info.imageType = VK_IMAGE_TYPE_2D;
4166     image_create_info.format = VK_FORMAT_R8_UINT;
4167     image_create_info.extent.width = 4;
4168     image_create_info.extent.height = 4;
4169     image_create_info.extent.depth = 1;
4170     image_create_info.mipLevels = 1;
4171     image_create_info.arrayLayers = 1;
4172     image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
4173     image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL;
4174     image_create_info.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
4175     image_create_info.usage = VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SHADING_RATE_IMAGE_BIT_NV;
4176     image_create_info.queueFamilyIndexCount = 0;
4177     image_create_info.pQueueFamilyIndices = NULL;
4178     image_create_info.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
4179     image_create_info.flags = VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT;
4180 
4181     // image type must be 2D
4182     image_create_info.imageType = VK_IMAGE_TYPE_3D;
4183     CreateImageTest(*this, &image_create_info, "VUID-VkImageCreateInfo-imageType-02082");
4184 
4185     image_create_info.imageType = VK_IMAGE_TYPE_2D;
4186     image_create_info.arrayLayers = 6;
4187 
4188     // must be single sample
4189     image_create_info.samples = VK_SAMPLE_COUNT_2_BIT;
4190     CreateImageTest(*this, &image_create_info, "VUID-VkImageCreateInfo-samples-02083");
4191 
4192     image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
4193 
4194     // tiling must be optimal
4195     image_create_info.tiling = VK_IMAGE_TILING_LINEAR;
4196     CreateImageTest(*this, &image_create_info, "VUID-VkImageCreateInfo-tiling-02084");
4197 
4198     image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL;
4199 
4200     // Should succeed.
4201     VkImageObj image(m_device);
4202     image.init(&image_create_info);
4203 
4204     // Test image view creation
4205     VkImageView view;
4206     VkImageViewCreateInfo ivci = {};
4207     ivci.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
4208     ivci.image = image.handle();
4209     ivci.viewType = VK_IMAGE_VIEW_TYPE_2D;
4210     ivci.format = VK_FORMAT_R8_UINT;
4211     ivci.subresourceRange.layerCount = 1;
4212     ivci.subresourceRange.baseMipLevel = 0;
4213     ivci.subresourceRange.levelCount = 1;
4214     ivci.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
4215 
4216     // view type must be 2D or 2D_ARRAY
4217     ivci.viewType = VK_IMAGE_VIEW_TYPE_CUBE;
4218     ivci.subresourceRange.layerCount = 6;
4219     m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkImageViewCreateInfo-image-02086");
4220     m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkImageViewCreateInfo-image-01003");
4221     result = vk::CreateImageView(m_device->device(), &ivci, nullptr, &view);
4222     m_errorMonitor->VerifyFound();
4223     if (VK_SUCCESS == result) {
4224         vk::DestroyImageView(m_device->device(), view, NULL);
4225         view = VK_NULL_HANDLE;
4226     }
4227     ivci.viewType = VK_IMAGE_VIEW_TYPE_2D;
4228     ivci.subresourceRange.layerCount = 1;
4229 
4230     // format must be R8_UINT
4231     ivci.format = VK_FORMAT_R8_UNORM;
4232     m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkImageViewCreateInfo-image-02087");
4233     result = vk::CreateImageView(m_device->device(), &ivci, nullptr, &view);
4234     m_errorMonitor->VerifyFound();
4235     if (VK_SUCCESS == result) {
4236         vk::DestroyImageView(m_device->device(), view, NULL);
4237         view = VK_NULL_HANDLE;
4238     }
4239     ivci.format = VK_FORMAT_R8_UINT;
4240 
4241     vk::CreateImageView(m_device->device(), &ivci, nullptr, &view);
4242     m_errorMonitor->VerifyNotFound();
4243 
4244     // Test pipeline creation
4245     VkPipelineViewportShadingRateImageStateCreateInfoNV vsrisci = {
4246         VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_SHADING_RATE_IMAGE_STATE_CREATE_INFO_NV};
4247 
4248     VkViewport viewport = {0.0f, 0.0f, 64.0f, 64.0f, 0.0f, 1.0f};
4249     VkViewport viewports[20] = {viewport, viewport};
4250     VkRect2D scissor = {{0, 0}, {64, 64}};
4251     VkRect2D scissors[20] = {scissor, scissor};
4252     VkDynamicState dynPalette = VK_DYNAMIC_STATE_VIEWPORT_SHADING_RATE_PALETTE_NV;
4253     VkPipelineDynamicStateCreateInfo dyn = {VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO, nullptr, 0, 1, &dynPalette};
4254 
4255     // viewportCount must be 0 or 1 when multiViewport is disabled
4256     {
4257         const auto break_vp = [&](CreatePipelineHelper &helper) {
4258             helper.vp_state_ci_.viewportCount = 2;
4259             helper.vp_state_ci_.pViewports = viewports;
4260             helper.vp_state_ci_.scissorCount = 2;
4261             helper.vp_state_ci_.pScissors = scissors;
4262             helper.vp_state_ci_.pNext = &vsrisci;
4263             helper.dyn_state_ci_ = dyn;
4264 
4265             vsrisci.shadingRateImageEnable = VK_TRUE;
4266             vsrisci.viewportCount = 2;
4267         };
4268         CreatePipelineHelper::OneshotTest(
4269             *this, break_vp, kErrorBit,
4270             vector<std::string>({"VUID-VkPipelineViewportShadingRateImageStateCreateInfoNV-viewportCount-02054",
4271                                  "VUID-VkPipelineViewportStateCreateInfo-viewportCount-01216",
4272                                  "VUID-VkPipelineViewportStateCreateInfo-scissorCount-01217"}));
4273     }
4274 
4275     // viewportCounts must match
4276     {
4277         const auto break_vp = [&](CreatePipelineHelper &helper) {
4278             helper.vp_state_ci_.viewportCount = 1;
4279             helper.vp_state_ci_.pViewports = viewports;
4280             helper.vp_state_ci_.scissorCount = 1;
4281             helper.vp_state_ci_.pScissors = scissors;
4282             helper.vp_state_ci_.pNext = &vsrisci;
4283             helper.dyn_state_ci_ = dyn;
4284 
4285             vsrisci.shadingRateImageEnable = VK_TRUE;
4286             vsrisci.viewportCount = 0;
4287         };
4288         CreatePipelineHelper::OneshotTest(
4289             *this, break_vp, kErrorBit,
4290             vector<std::string>({"VUID-VkPipelineViewportShadingRateImageStateCreateInfoNV-shadingRateImageEnable-02056"}));
4291     }
4292 
4293     // pShadingRatePalettes must not be NULL.
4294     {
4295         const auto break_vp = [&](CreatePipelineHelper &helper) {
4296             helper.vp_state_ci_.viewportCount = 1;
4297             helper.vp_state_ci_.pViewports = viewports;
4298             helper.vp_state_ci_.scissorCount = 1;
4299             helper.vp_state_ci_.pScissors = scissors;
4300             helper.vp_state_ci_.pNext = &vsrisci;
4301 
4302             vsrisci.shadingRateImageEnable = VK_TRUE;
4303             vsrisci.viewportCount = 1;
4304         };
4305         CreatePipelineHelper::OneshotTest(*this, break_vp, kErrorBit,
4306                                           vector<std::string>({"VUID-VkGraphicsPipelineCreateInfo-pDynamicStates-04057"}));
4307     }
4308 
4309     // Create an image without the SRI bit
4310     VkImageObj nonSRIimage(m_device);
4311     nonSRIimage.Init(256, 256, 1, VK_FORMAT_B8G8R8A8_UNORM, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, VK_IMAGE_TILING_OPTIMAL, 0);
4312     ASSERT_TRUE(nonSRIimage.initialized());
4313     VkImageView nonSRIview = nonSRIimage.targetView(VK_FORMAT_B8G8R8A8_UNORM);
4314 
4315     // Test SRI layout on non-SRI image
4316     VkImageMemoryBarrier img_barrier = {};
4317     img_barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
4318     img_barrier.pNext = nullptr;
4319     img_barrier.srcAccessMask = 0;
4320     img_barrier.dstAccessMask = 0;
4321     img_barrier.oldLayout = VK_IMAGE_LAYOUT_GENERAL;
4322     img_barrier.newLayout = VK_IMAGE_LAYOUT_SHADING_RATE_OPTIMAL_NV;
4323     img_barrier.image = nonSRIimage.handle();
4324     img_barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
4325     img_barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
4326     img_barrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
4327     img_barrier.subresourceRange.baseArrayLayer = 0;
4328     img_barrier.subresourceRange.baseMipLevel = 0;
4329     img_barrier.subresourceRange.layerCount = 1;
4330     img_barrier.subresourceRange.levelCount = 1;
4331 
4332     m_commandBuffer->begin();
4333 
4334     // Error trying to convert it to SRI layout
4335     m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkImageMemoryBarrier-oldLayout-02088");
4336     vk::CmdPipelineBarrier(m_commandBuffer->handle(), VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, 0, 0,
4337                            nullptr, 0, nullptr, 1, &img_barrier);
4338     m_errorMonitor->VerifyFound();
4339 
4340     // succeed converting it to GENERAL
4341     img_barrier.newLayout = VK_IMAGE_LAYOUT_GENERAL;
4342     vk::CmdPipelineBarrier(m_commandBuffer->handle(), VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, 0, 0,
4343                            nullptr, 0, nullptr, 1, &img_barrier);
4344     m_errorMonitor->VerifyNotFound();
4345 
4346     // Test vk::CmdBindShadingRateImageNV errors
4347     auto vkCmdBindShadingRateImageNV =
4348         (PFN_vkCmdBindShadingRateImageNV)vk::GetDeviceProcAddr(m_device->device(), "vkCmdBindShadingRateImageNV");
4349 
4350     // if the view is non-NULL, it must be R8_UINT, USAGE_SRI, image layout must match, layout must be valid
4351     m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdBindShadingRateImageNV-imageView-02060");
4352     m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdBindShadingRateImageNV-imageView-02061");
4353     m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdBindShadingRateImageNV-imageView-02062");
4354     m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdBindShadingRateImageNV-imageLayout-02063");
4355     vkCmdBindShadingRateImageNV(m_commandBuffer->handle(), nonSRIview, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
4356     m_errorMonitor->VerifyFound();
4357 
4358     // Test vk::CmdSetViewportShadingRatePaletteNV errors
4359     auto vkCmdSetViewportShadingRatePaletteNV =
4360         (PFN_vkCmdSetViewportShadingRatePaletteNV)vk::GetDeviceProcAddr(m_device->device(), "vkCmdSetViewportShadingRatePaletteNV");
4361 
4362     VkShadingRatePaletteEntryNV paletteEntries[100] = {};
4363     VkShadingRatePaletteNV palette = {100, paletteEntries};
4364     VkShadingRatePaletteNV palettes[] = {palette, palette};
4365 
4366     // errors on firstViewport/viewportCount
4367     m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdSetViewportShadingRatePaletteNV-firstViewport-02067");
4368     m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdSetViewportShadingRatePaletteNV-firstViewport-02068");
4369     m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdSetViewportShadingRatePaletteNV-viewportCount-02069");
4370     vkCmdSetViewportShadingRatePaletteNV(m_commandBuffer->handle(), 20, 2, palettes);
4371     m_errorMonitor->VerifyFound();
4372 
4373     // shadingRatePaletteEntryCount must be in range
4374     m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkShadingRatePaletteNV-shadingRatePaletteEntryCount-02071");
4375     vkCmdSetViewportShadingRatePaletteNV(m_commandBuffer->handle(), 0, 1, palettes);
4376     m_errorMonitor->VerifyFound();
4377 
4378     VkCoarseSampleLocationNV locations[100] = {
4379         {0, 0, 0},    {0, 0, 1}, {0, 1, 0}, {0, 1, 1}, {0, 1, 1},  // duplicate
4380         {1000, 0, 0},                                              // pixelX too large
4381         {0, 1000, 0},                                              // pixelY too large
4382         {0, 0, 1000},                                              // sample too large
4383     };
4384 
4385     // Test custom sample orders, both via pipeline state and via dynamic state
4386     {
4387         VkCoarseSampleOrderCustomNV sampOrdBadShadingRate = {VK_SHADING_RATE_PALETTE_ENTRY_1_INVOCATION_PER_PIXEL_NV, 1, 1,
4388                                                              locations};
4389         VkCoarseSampleOrderCustomNV sampOrdBadSampleCount = {VK_SHADING_RATE_PALETTE_ENTRY_1_INVOCATION_PER_1X2_PIXELS_NV, 3, 1,
4390                                                              locations};
4391         VkCoarseSampleOrderCustomNV sampOrdBadSampleLocationCount = {VK_SHADING_RATE_PALETTE_ENTRY_1_INVOCATION_PER_1X2_PIXELS_NV,
4392                                                                      2, 2, locations};
4393         VkCoarseSampleOrderCustomNV sampOrdDuplicateLocations = {VK_SHADING_RATE_PALETTE_ENTRY_1_INVOCATION_PER_1X2_PIXELS_NV, 2,
4394                                                                  1 * 2 * 2, &locations[1]};
4395         VkCoarseSampleOrderCustomNV sampOrdOutOfRangeLocations = {VK_SHADING_RATE_PALETTE_ENTRY_1_INVOCATION_PER_1X2_PIXELS_NV, 2,
4396                                                                   1 * 2 * 2, &locations[4]};
4397         VkCoarseSampleOrderCustomNV sampOrdTooLargeSampleLocationCount = {
4398             VK_SHADING_RATE_PALETTE_ENTRY_1_INVOCATION_PER_4X4_PIXELS_NV, 4, 64, &locations[8]};
4399         VkCoarseSampleOrderCustomNV sampOrdGood = {VK_SHADING_RATE_PALETTE_ENTRY_1_INVOCATION_PER_1X2_PIXELS_NV, 2, 1 * 2 * 2,
4400                                                    &locations[0]};
4401 
4402         VkPipelineViewportCoarseSampleOrderStateCreateInfoNV csosci = {
4403             VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_COARSE_SAMPLE_ORDER_STATE_CREATE_INFO_NV};
4404         csosci.sampleOrderType = VK_COARSE_SAMPLE_ORDER_TYPE_CUSTOM_NV;
4405         csosci.customSampleOrderCount = 1;
4406 
4407         using std::vector;
4408         struct TestCase {
4409             const VkCoarseSampleOrderCustomNV *order;
4410             vector<std::string> vuids;
4411         };
4412 
4413         vector<TestCase> test_cases = {
4414             {&sampOrdBadShadingRate, {"VUID-VkCoarseSampleOrderCustomNV-shadingRate-02073"}},
4415             {&sampOrdBadSampleCount,
4416              {"VUID-VkCoarseSampleOrderCustomNV-sampleCount-02074", "VUID-VkCoarseSampleOrderCustomNV-sampleLocationCount-02075"}},
4417             {&sampOrdBadSampleLocationCount, {"VUID-VkCoarseSampleOrderCustomNV-sampleLocationCount-02075"}},
4418             {&sampOrdDuplicateLocations, {"VUID-VkCoarseSampleOrderCustomNV-pSampleLocations-02077"}},
4419             {&sampOrdOutOfRangeLocations,
4420              {"VUID-VkCoarseSampleOrderCustomNV-pSampleLocations-02077", "VUID-VkCoarseSampleLocationNV-pixelX-02078",
4421               "VUID-VkCoarseSampleLocationNV-pixelY-02079", "VUID-VkCoarseSampleLocationNV-sample-02080"}},
4422             {&sampOrdTooLargeSampleLocationCount,
4423              {"VUID-VkCoarseSampleOrderCustomNV-sampleLocationCount-02076",
4424               "VUID-VkCoarseSampleOrderCustomNV-pSampleLocations-02077"}},
4425             {&sampOrdGood, {}},
4426         };
4427 
4428         for (const auto &test_case : test_cases) {
4429             const auto break_vp = [&](CreatePipelineHelper &helper) {
4430                 helper.vp_state_ci_.pNext = &csosci;
4431                 csosci.pCustomSampleOrders = test_case.order;
4432             };
4433             CreatePipelineHelper::OneshotTest(*this, break_vp, kErrorBit, test_case.vuids);
4434         }
4435 
4436         // Test vk::CmdSetCoarseSampleOrderNV errors
4437         auto vkCmdSetCoarseSampleOrderNV =
4438             (PFN_vkCmdSetCoarseSampleOrderNV)vk::GetDeviceProcAddr(m_device->device(), "vkCmdSetCoarseSampleOrderNV");
4439 
4440         for (const auto &test_case : test_cases) {
4441             for (uint32_t i = 0; i < test_case.vuids.size(); ++i) {
4442                 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, test_case.vuids[i]);
4443             }
4444             vkCmdSetCoarseSampleOrderNV(m_commandBuffer->handle(), VK_COARSE_SAMPLE_ORDER_TYPE_CUSTOM_NV, 1, test_case.order);
4445             if (test_case.vuids.size()) {
4446                 m_errorMonitor->VerifyFound();
4447             } else {
4448                 m_errorMonitor->VerifyNotFound();
4449             }
4450         }
4451 
4452         m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdSetCoarseSampleOrderNV-sampleOrderType-02081");
4453         vkCmdSetCoarseSampleOrderNV(m_commandBuffer->handle(), VK_COARSE_SAMPLE_ORDER_TYPE_PIXEL_MAJOR_NV, 1, &sampOrdGood);
4454         m_errorMonitor->VerifyFound();
4455     }
4456 
4457     m_commandBuffer->end();
4458 
4459     vk::DestroyImageView(m_device->device(), view, NULL);
4460 }
4461 
4462 #include "android_ndk_types.h"
4463 #ifdef AHB_VALIDATION_SUPPORT
4464 
TEST_F(VkLayerTest,AndroidHardwareBufferImageCreate)4465 TEST_F(VkLayerTest, AndroidHardwareBufferImageCreate) {
4466     TEST_DESCRIPTION("Verify AndroidHardwareBuffer image create info.");
4467 
4468     SetTargetApiVersion(VK_API_VERSION_1_1);
4469     ASSERT_NO_FATAL_FAILURE(InitFramework(m_errorMonitor));
4470 
4471     if ((DeviceExtensionSupported(gpu(), nullptr, VK_ANDROID_EXTERNAL_MEMORY_ANDROID_HARDWARE_BUFFER_EXTENSION_NAME)) &&
4472         // Also skip on devices that advertise AHB, but not the pre-requisite foreign_queue extension
4473         (DeviceExtensionSupported(gpu(), nullptr, VK_EXT_QUEUE_FAMILY_FOREIGN_EXTENSION_NAME))) {
4474         m_device_extension_names.push_back(VK_ANDROID_EXTERNAL_MEMORY_ANDROID_HARDWARE_BUFFER_EXTENSION_NAME);
4475         m_device_extension_names.push_back(VK_KHR_SAMPLER_YCBCR_CONVERSION_EXTENSION_NAME);
4476         m_device_extension_names.push_back(VK_KHR_MAINTENANCE_1_EXTENSION_NAME);
4477         m_device_extension_names.push_back(VK_KHR_BIND_MEMORY_2_EXTENSION_NAME);
4478         m_device_extension_names.push_back(VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME);
4479         m_device_extension_names.push_back(VK_KHR_EXTERNAL_MEMORY_EXTENSION_NAME);
4480         m_device_extension_names.push_back(VK_EXT_QUEUE_FAMILY_FOREIGN_EXTENSION_NAME);
4481     } else {
4482         printf("%s %s extension not supported, skipping tests\n", kSkipPrefix,
4483                VK_ANDROID_EXTERNAL_MEMORY_ANDROID_HARDWARE_BUFFER_EXTENSION_NAME);
4484         return;
4485     }
4486 
4487     ASSERT_NO_FATAL_FAILURE(InitState());
4488     VkDevice dev = m_device->device();
4489 
4490     VkImage img = VK_NULL_HANDLE;
4491     auto reset_img = [&img, dev]() {
4492         if (VK_NULL_HANDLE != img) vk::DestroyImage(dev, img, NULL);
4493         img = VK_NULL_HANDLE;
4494     };
4495 
4496     VkImageCreateInfo ici = LvlInitStruct<VkImageCreateInfo>();
4497     ici.imageType = VK_IMAGE_TYPE_2D;
4498     ici.arrayLayers = 1;
4499     ici.extent = {64, 64, 1};
4500     ici.format = VK_FORMAT_UNDEFINED;
4501     ici.mipLevels = 1;
4502     ici.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
4503     ici.samples = VK_SAMPLE_COUNT_1_BIT;
4504     ici.tiling = VK_IMAGE_TILING_OPTIMAL;
4505     ici.usage = VK_IMAGE_USAGE_SAMPLED_BIT;
4506 
4507     // undefined format
4508     m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkImageCreateInfo-pNext-01975");
4509     // Various extra errors for having VK_FORMAT_UNDEFINED without VkExternalFormatANDROID
4510     m_errorMonitor->SetUnexpectedError("VUID_Undefined");
4511     m_errorMonitor->SetUnexpectedError("VUID-VkImageCreateInfo-imageCreateMaxMipLevels-02251");
4512     vk::CreateImage(dev, &ici, NULL, &img);
4513     m_errorMonitor->VerifyFound();
4514     reset_img();
4515 
4516     // also undefined format
4517     VkExternalFormatANDROID efa = LvlInitStruct<VkExternalFormatANDROID>();
4518     efa.externalFormat = 0;
4519     ici.pNext = &efa;
4520     m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkImageCreateInfo-pNext-01975");
4521     vk::CreateImage(dev, &ici, NULL, &img);
4522     m_errorMonitor->VerifyFound();
4523     reset_img();
4524 
4525     // undefined format with an unknown external format
4526     efa.externalFormat = 0xBADC0DE;
4527     m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkExternalFormatANDROID-externalFormat-01894");
4528     vk::CreateImage(dev, &ici, NULL, &img);
4529     m_errorMonitor->VerifyFound();
4530     reset_img();
4531 
4532     AHardwareBuffer *ahb;
4533     AHardwareBuffer_Desc ahb_desc = {};
4534     ahb_desc.format = AHARDWAREBUFFER_FORMAT_R8G8B8X8_UNORM;
4535     ahb_desc.usage = AHARDWAREBUFFER_USAGE_GPU_SAMPLED_IMAGE;
4536     ahb_desc.width = 64;
4537     ahb_desc.height = 64;
4538     ahb_desc.layers = 1;
4539     // Allocate an AHardwareBuffer
4540     AHardwareBuffer_allocate(&ahb_desc, &ahb);
4541 
4542     // Retrieve it's properties to make it's external format 'known' (AHARDWAREBUFFER_FORMAT_R8G8B8X8_UNORM)
4543     VkAndroidHardwareBufferFormatPropertiesANDROID ahb_fmt_props = LvlInitStruct<VkAndroidHardwareBufferFormatPropertiesANDROID>();
4544     VkAndroidHardwareBufferPropertiesANDROID ahb_props = LvlInitStruct<VkAndroidHardwareBufferPropertiesANDROID>(&ahb_fmt_props);
4545     PFN_vkGetAndroidHardwareBufferPropertiesANDROID pfn_GetAHBProps =
4546         (PFN_vkGetAndroidHardwareBufferPropertiesANDROID)vk::GetDeviceProcAddr(dev, "vkGetAndroidHardwareBufferPropertiesANDROID");
4547     ASSERT_TRUE(pfn_GetAHBProps != nullptr);
4548     pfn_GetAHBProps(dev, ahb, &ahb_props);
4549 
4550     // a defined image format with a non-zero external format
4551     ici.format = VK_FORMAT_R8G8B8A8_UNORM;
4552     efa.externalFormat = ahb_fmt_props.externalFormat;
4553     m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkImageCreateInfo-pNext-01974");
4554     vk::CreateImage(dev, &ici, NULL, &img);
4555     m_errorMonitor->VerifyFound();
4556     reset_img();
4557     ici.format = VK_FORMAT_UNDEFINED;
4558 
4559     // external format while MUTABLE
4560     ici.flags = VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT;
4561     m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkImageCreateInfo-pNext-02396");
4562     vk::CreateImage(dev, &ici, NULL, &img);
4563     m_errorMonitor->VerifyFound();
4564     reset_img();
4565     ici.flags = 0;
4566 
4567     // external format while usage other than SAMPLED
4568     ici.usage |= VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT;
4569     m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkImageCreateInfo-pNext-02397");
4570     vk::CreateImage(dev, &ici, NULL, &img);
4571     m_errorMonitor->VerifyFound();
4572     reset_img();
4573     ici.usage = VK_IMAGE_USAGE_SAMPLED_BIT;
4574 
4575     // external format while tiline other than OPTIMAL
4576     ici.tiling = VK_IMAGE_TILING_LINEAR;
4577     m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkImageCreateInfo-pNext-02398");
4578     vk::CreateImage(dev, &ici, NULL, &img);
4579     m_errorMonitor->VerifyFound();
4580     reset_img();
4581     ici.tiling = VK_IMAGE_TILING_OPTIMAL;
4582 
4583     // imageType
4584     VkExternalMemoryImageCreateInfo emici = LvlInitStruct<VkExternalMemoryImageCreateInfo>();
4585     emici.handleTypes = VK_EXTERNAL_MEMORY_HANDLE_TYPE_ANDROID_HARDWARE_BUFFER_BIT_ANDROID;
4586     ici.pNext = &emici;  // remove efa from chain, insert emici
4587     ici.format = VK_FORMAT_R8G8B8A8_UNORM;
4588     ici.imageType = VK_IMAGE_TYPE_3D;
4589     ici.extent = {64, 64, 64};
4590 
4591     m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkImageCreateInfo-pNext-02393");
4592     vk::CreateImage(dev, &ici, NULL, &img);
4593     m_errorMonitor->VerifyFound();
4594     reset_img();
4595 
4596     // wrong mipLevels
4597     ici.imageType = VK_IMAGE_TYPE_2D;
4598     ici.extent = {64, 64, 1};
4599     ici.mipLevels = 6;  // should be 7
4600     m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkImageCreateInfo-pNext-02394");
4601     vk::CreateImage(dev, &ici, NULL, &img);
4602     m_errorMonitor->VerifyFound();
4603     reset_img();
4604 }
4605 
TEST_F(VkLayerTest,AndroidHardwareBufferFetchUnboundImageInfo)4606 TEST_F(VkLayerTest, AndroidHardwareBufferFetchUnboundImageInfo) {
4607     TEST_DESCRIPTION("Verify AndroidHardwareBuffer retreive image properties while memory unbound.");
4608 
4609     SetTargetApiVersion(VK_API_VERSION_1_1);
4610     ASSERT_NO_FATAL_FAILURE(InitFramework(m_errorMonitor));
4611 
4612     if ((DeviceExtensionSupported(gpu(), nullptr, VK_ANDROID_EXTERNAL_MEMORY_ANDROID_HARDWARE_BUFFER_EXTENSION_NAME)) &&
4613         // Also skip on devices that advertise AHB, but not the pre-requisite foreign_queue extension
4614         (DeviceExtensionSupported(gpu(), nullptr, VK_EXT_QUEUE_FAMILY_FOREIGN_EXTENSION_NAME))) {
4615         m_device_extension_names.push_back(VK_ANDROID_EXTERNAL_MEMORY_ANDROID_HARDWARE_BUFFER_EXTENSION_NAME);
4616         m_device_extension_names.push_back(VK_KHR_SAMPLER_YCBCR_CONVERSION_EXTENSION_NAME);
4617         m_device_extension_names.push_back(VK_KHR_MAINTENANCE_1_EXTENSION_NAME);
4618         m_device_extension_names.push_back(VK_KHR_BIND_MEMORY_2_EXTENSION_NAME);
4619         m_device_extension_names.push_back(VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME);
4620         m_device_extension_names.push_back(VK_KHR_EXTERNAL_MEMORY_EXTENSION_NAME);
4621         m_device_extension_names.push_back(VK_EXT_QUEUE_FAMILY_FOREIGN_EXTENSION_NAME);
4622     } else {
4623         printf("%s %s extension not supported, skipping tests\n", kSkipPrefix,
4624                VK_ANDROID_EXTERNAL_MEMORY_ANDROID_HARDWARE_BUFFER_EXTENSION_NAME);
4625         return;
4626     }
4627 
4628     ASSERT_NO_FATAL_FAILURE(InitState());
4629     VkDevice dev = m_device->device();
4630 
4631     VkImage img = VK_NULL_HANDLE;
4632     auto reset_img = [&img, dev]() {
4633         if (VK_NULL_HANDLE != img) vk::DestroyImage(dev, img, NULL);
4634         img = VK_NULL_HANDLE;
4635     };
4636 
4637     VkImageCreateInfo ici = LvlInitStruct<VkImageCreateInfo>();
4638     ici.imageType = VK_IMAGE_TYPE_2D;
4639     ici.arrayLayers = 1;
4640     ici.extent = {64, 64, 1};
4641     ici.format = VK_FORMAT_R8G8B8A8_UNORM;
4642     ici.mipLevels = 1;
4643     ici.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
4644     ici.samples = VK_SAMPLE_COUNT_1_BIT;
4645     ici.tiling = VK_IMAGE_TILING_LINEAR;
4646     ici.usage = VK_IMAGE_USAGE_SAMPLED_BIT;
4647 
4648     VkExternalMemoryImageCreateInfo emici = LvlInitStruct<VkExternalMemoryImageCreateInfo>();
4649     emici.handleTypes = VK_EXTERNAL_MEMORY_HANDLE_TYPE_ANDROID_HARDWARE_BUFFER_BIT_ANDROID;
4650     ici.pNext = &emici;
4651 
4652     m_errorMonitor->ExpectSuccess();
4653     vk::CreateImage(dev, &ici, NULL, &img);
4654     m_errorMonitor->VerifyNotFound();
4655 
4656     // attempt to fetch layout from unbound image
4657     VkImageSubresource sub_rsrc = {};
4658     sub_rsrc.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
4659     VkSubresourceLayout sub_layout = {};
4660     m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkGetImageSubresourceLayout-image-01895");
4661     vk::GetImageSubresourceLayout(dev, img, &sub_rsrc, &sub_layout);
4662     m_errorMonitor->VerifyFound();
4663 
4664     // attempt to get memory reqs from unbound image
4665     VkImageMemoryRequirementsInfo2 imri = LvlInitStruct<VkImageMemoryRequirementsInfo2>();
4666     imri.image = img;
4667     VkMemoryRequirements2 mem_reqs = LvlInitStruct<VkMemoryRequirements2>();
4668     m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkImageMemoryRequirementsInfo2-image-01897");
4669     vk::GetImageMemoryRequirements2(dev, &imri, &mem_reqs);
4670     m_errorMonitor->VerifyFound();
4671 
4672     reset_img();
4673 }
4674 
TEST_F(VkLayerTest,AndroidHardwareBufferMemoryAllocation)4675 TEST_F(VkLayerTest, AndroidHardwareBufferMemoryAllocation) {
4676     TEST_DESCRIPTION("Verify AndroidHardwareBuffer memory allocation.");
4677 
4678     SetTargetApiVersion(VK_API_VERSION_1_1);
4679     ASSERT_NO_FATAL_FAILURE(InitFramework(m_errorMonitor));
4680 
4681     if (IsPlatform(kGalaxyS10)) {
4682         printf("%s This test should not run on Galaxy S10\n", kSkipPrefix);
4683         return;
4684     }
4685 
4686     if ((DeviceExtensionSupported(gpu(), nullptr, VK_ANDROID_EXTERNAL_MEMORY_ANDROID_HARDWARE_BUFFER_EXTENSION_NAME)) &&
4687         // Also skip on devices that advertise AHB, but not the pre-requisite foreign_queue extension
4688         (DeviceExtensionSupported(gpu(), nullptr, VK_EXT_QUEUE_FAMILY_FOREIGN_EXTENSION_NAME))) {
4689         m_device_extension_names.push_back(VK_ANDROID_EXTERNAL_MEMORY_ANDROID_HARDWARE_BUFFER_EXTENSION_NAME);
4690         m_device_extension_names.push_back(VK_KHR_SAMPLER_YCBCR_CONVERSION_EXTENSION_NAME);
4691         m_device_extension_names.push_back(VK_KHR_MAINTENANCE_1_EXTENSION_NAME);
4692         m_device_extension_names.push_back(VK_KHR_BIND_MEMORY_2_EXTENSION_NAME);
4693         m_device_extension_names.push_back(VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME);
4694         m_device_extension_names.push_back(VK_KHR_EXTERNAL_MEMORY_EXTENSION_NAME);
4695         m_device_extension_names.push_back(VK_EXT_QUEUE_FAMILY_FOREIGN_EXTENSION_NAME);
4696     } else {
4697         printf("%s %s extension not supported, skipping tests\n", kSkipPrefix,
4698                VK_ANDROID_EXTERNAL_MEMORY_ANDROID_HARDWARE_BUFFER_EXTENSION_NAME);
4699         return;
4700     }
4701 
4702     ASSERT_NO_FATAL_FAILURE(InitState());
4703     VkDevice dev = m_device->device();
4704 
4705     VkImage img = VK_NULL_HANDLE;
4706     auto reset_img = [&img, dev]() {
4707         if (VK_NULL_HANDLE != img) vk::DestroyImage(dev, img, NULL);
4708         img = VK_NULL_HANDLE;
4709     };
4710     VkDeviceMemory mem_handle = VK_NULL_HANDLE;
4711     auto reset_mem = [&mem_handle, dev]() {
4712         if (VK_NULL_HANDLE != mem_handle) vk::FreeMemory(dev, mem_handle, NULL);
4713         mem_handle = VK_NULL_HANDLE;
4714     };
4715 
4716     PFN_vkGetAndroidHardwareBufferPropertiesANDROID pfn_GetAHBProps =
4717         (PFN_vkGetAndroidHardwareBufferPropertiesANDROID)vk::GetDeviceProcAddr(dev, "vkGetAndroidHardwareBufferPropertiesANDROID");
4718     ASSERT_TRUE(pfn_GetAHBProps != nullptr);
4719 
4720     // AHB structs
4721     AHardwareBuffer *ahb = nullptr;
4722     AHardwareBuffer_Desc ahb_desc = {};
4723     VkAndroidHardwareBufferFormatPropertiesANDROID ahb_fmt_props = LvlInitStruct<VkAndroidHardwareBufferFormatPropertiesANDROID>();
4724     VkAndroidHardwareBufferPropertiesANDROID ahb_props = LvlInitStruct<VkAndroidHardwareBufferPropertiesANDROID>(&ahb_fmt_props);
4725     VkImportAndroidHardwareBufferInfoANDROID iahbi = LvlInitStruct<VkImportAndroidHardwareBufferInfoANDROID>();
4726 
4727     // destroy and re-acquire an AHB, and fetch it's properties
4728     auto recreate_ahb = [&ahb, &iahbi, &ahb_desc, &ahb_props, dev, pfn_GetAHBProps]() {
4729         if (ahb) AHardwareBuffer_release(ahb);
4730         ahb = nullptr;
4731         AHardwareBuffer_allocate(&ahb_desc, &ahb);
4732         if (ahb) {
4733             pfn_GetAHBProps(dev, ahb, &ahb_props);
4734             iahbi.buffer = ahb;
4735         }
4736     };
4737 
4738     // Allocate an AHardwareBuffer
4739     ahb_desc.format = AHARDWAREBUFFER_FORMAT_R8G8B8X8_UNORM;
4740     ahb_desc.usage = AHARDWAREBUFFER_USAGE_GPU_SAMPLED_IMAGE;
4741     ahb_desc.width = 64;
4742     ahb_desc.height = 64;
4743     ahb_desc.layers = 1;
4744     recreate_ahb();
4745 
4746     // Create an image w/ external format
4747     VkExternalFormatANDROID efa = LvlInitStruct<VkExternalFormatANDROID>();
4748     efa.externalFormat = ahb_fmt_props.externalFormat;
4749 
4750     VkImageCreateInfo ici = LvlInitStruct<VkImageCreateInfo>(&efa);
4751     ici.imageType = VK_IMAGE_TYPE_2D;
4752     ici.arrayLayers = 1;
4753     ici.extent = {64, 64, 1};
4754     ici.format = VK_FORMAT_UNDEFINED;
4755     ici.mipLevels = 1;
4756     ici.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
4757     ici.samples = VK_SAMPLE_COUNT_1_BIT;
4758     ici.tiling = VK_IMAGE_TILING_OPTIMAL;
4759     ici.usage = VK_IMAGE_USAGE_SAMPLED_BIT;
4760     VkResult res = vk::CreateImage(dev, &ici, NULL, &img);
4761     ASSERT_VK_SUCCESS(res);
4762 
4763     // Chained import struct
4764     VkMemoryAllocateInfo mai = LvlInitStruct<VkMemoryAllocateInfo>(&iahbi);
4765     mai.allocationSize = ahb_props.allocationSize;
4766     mai.memoryTypeIndex = 32;
4767     // Set index to match one of the bits in ahb_props
4768     for (int i = 0; i < 32; i++) {
4769         if (ahb_props.memoryTypeBits & (1 << i)) {
4770             mai.memoryTypeIndex = i;
4771             break;
4772         }
4773     }
4774     ASSERT_NE(32, mai.memoryTypeIndex);
4775 
4776     // Import w/ non-dedicated memory allocation
4777 
4778     // Import requires format AHB_FMT_BLOB and usage AHB_USAGE_GPU_DATA_BUFFER
4779     m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkMemoryAllocateInfo-pNext-02384");
4780     vk::AllocateMemory(dev, &mai, NULL, &mem_handle);
4781     m_errorMonitor->VerifyFound();
4782     reset_mem();
4783 
4784     // Allocation size mismatch
4785     ahb_desc.format = AHARDWAREBUFFER_FORMAT_BLOB;
4786     ahb_desc.usage = AHARDWAREBUFFER_USAGE_GPU_DATA_BUFFER;
4787     ahb_desc.height = 1;
4788     recreate_ahb();
4789     mai.allocationSize = ahb_props.allocationSize + 1;
4790     m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkMemoryAllocateInfo-allocationSize-02383");
4791     vk::AllocateMemory(dev, &mai, NULL, &mem_handle);
4792     m_errorMonitor->VerifyFound();
4793     mai.allocationSize = ahb_props.allocationSize;
4794     reset_mem();
4795 
4796     // memoryTypeIndex mismatch
4797     mai.memoryTypeIndex++;
4798     m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkMemoryAllocateInfo-memoryTypeIndex-02385");
4799     vk::AllocateMemory(dev, &mai, NULL, &mem_handle);
4800     m_errorMonitor->VerifyFound();
4801     mai.memoryTypeIndex--;
4802     reset_mem();
4803 
4804     // Insert dedicated image memory allocation to mai chain
4805     VkMemoryDedicatedAllocateInfo mdai = LvlInitStruct<VkMemoryDedicatedAllocateInfo>();
4806     mdai.image = img;
4807     mdai.buffer = VK_NULL_HANDLE;
4808     mdai.pNext = mai.pNext;
4809     mai.pNext = &mdai;
4810 
4811     // Dedicated allocation with unmatched usage bits for Color
4812     ahb_desc.format = AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM;
4813     ahb_desc.usage = AHARDWAREBUFFER_USAGE_GPU_FRAMEBUFFER;
4814     ahb_desc.height = 64;
4815     recreate_ahb();
4816     mai.allocationSize = ahb_props.allocationSize;
4817     m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkMemoryAllocateInfo-pNext-02390");
4818     vk::AllocateMemory(dev, &mai, NULL, &mem_handle);
4819     m_errorMonitor->VerifyFound();
4820     reset_mem();
4821 
4822     // Dedicated allocation with unmatched usage bits for Depth/Stencil
4823     ahb_desc.format = AHARDWAREBUFFER_FORMAT_S8_UINT;
4824     ahb_desc.usage = AHARDWAREBUFFER_USAGE_GPU_FRAMEBUFFER;
4825     ahb_desc.height = 64;
4826     recreate_ahb();
4827     mai.allocationSize = ahb_props.allocationSize;
4828     m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkMemoryAllocateInfo-pNext-02390");
4829     vk::AllocateMemory(dev, &mai, NULL, &mem_handle);
4830     m_errorMonitor->VerifyFound();
4831     reset_mem();
4832 
4833     // Dedicated allocation with incomplete mip chain
4834     reset_img();
4835     ici.mipLevels = 2;
4836     vk::CreateImage(dev, &ici, NULL, &img);
4837     mdai.image = img;
4838     ahb_desc.usage = AHARDWAREBUFFER_USAGE_GPU_SAMPLED_IMAGE | AHARDWAREBUFFER_USAGE_GPU_MIPMAP_COMPLETE;
4839     recreate_ahb();
4840 
4841     if (ahb) {
4842         mai.allocationSize = ahb_props.allocationSize;
4843         for (int i = 0; i < 32; i++) {
4844             if (ahb_props.memoryTypeBits & (1 << i)) {
4845                 mai.memoryTypeIndex = i;
4846                 break;
4847             }
4848         }
4849         m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkMemoryAllocateInfo-pNext-02389");
4850         vk::AllocateMemory(dev, &mai, NULL, &mem_handle);
4851         m_errorMonitor->VerifyFound();
4852         reset_mem();
4853     } else {
4854         // ERROR: AHardwareBuffer_allocate() with MIPMAP_COMPLETE fails. It returns -12, NO_MEMORY.
4855         // The problem seems to happen in Pixel 2, not Pixel 3.
4856         printf("%s AHARDWAREBUFFER_USAGE_GPU_MIPMAP_COMPLETE not supported, skipping tests\n", kSkipPrefix);
4857         return;
4858     }
4859 
4860     // Dedicated allocation with mis-matched dimension
4861     ahb_desc.usage = AHARDWAREBUFFER_USAGE_GPU_SAMPLED_IMAGE;
4862     ahb_desc.height = 32;
4863     ahb_desc.width = 128;
4864     recreate_ahb();
4865     mai.allocationSize = ahb_props.allocationSize;
4866     m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkMemoryAllocateInfo-pNext-02388");
4867     vk::AllocateMemory(dev, &mai, NULL, &mem_handle);
4868     m_errorMonitor->VerifyFound();
4869     reset_mem();
4870 
4871     // Dedicated allocation with mis-matched VkFormat
4872     ahb_desc.usage = AHARDWAREBUFFER_USAGE_GPU_SAMPLED_IMAGE;
4873     ahb_desc.height = 64;
4874     ahb_desc.width = 64;
4875     recreate_ahb();
4876     mai.allocationSize = ahb_props.allocationSize;
4877     ici.mipLevels = 1;
4878     ici.format = VK_FORMAT_B8G8R8A8_UNORM;
4879     ici.pNext = NULL;
4880     VkImage img2;
4881     vk::CreateImage(dev, &ici, NULL, &img2);
4882     mdai.image = img2;
4883     m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkMemoryAllocateInfo-pNext-02387");
4884     vk::AllocateMemory(dev, &mai, NULL, &mem_handle);
4885     m_errorMonitor->VerifyFound();
4886     vk::DestroyImage(dev, img2, NULL);
4887     mdai.image = img;
4888     reset_mem();
4889 
4890     // Missing required ahb usage
4891     ahb_desc.usage = AHARDWAREBUFFER_USAGE_PROTECTED_CONTENT;
4892     m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkGetAndroidHardwareBufferPropertiesANDROID-buffer-01884");
4893     recreate_ahb();
4894     m_errorMonitor->VerifyFound();
4895 
4896     // Dedicated allocation with missing usage bits
4897     // Setting up this test also triggers a slew of others
4898     mai.allocationSize = ahb_props.allocationSize + 1;
4899     mai.memoryTypeIndex = 0;
4900     m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkMemoryAllocateInfo-pNext-02390");
4901     m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkMemoryAllocateInfo-memoryTypeIndex-02385");
4902     m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkMemoryAllocateInfo-allocationSize-02383");
4903     m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkMemoryAllocateInfo-pNext-02386");
4904     vk::AllocateMemory(dev, &mai, NULL, &mem_handle);
4905     m_errorMonitor->VerifyFound();
4906     reset_mem();
4907 
4908     // Non-import allocation - replace import struct in chain with export struct
4909     VkExportMemoryAllocateInfo emai = LvlInitStruct<VkExportMemoryAllocateInfo>();
4910     emai.handleTypes = VK_EXTERNAL_MEMORY_HANDLE_TYPE_ANDROID_HARDWARE_BUFFER_BIT_ANDROID;
4911     mai.pNext = &emai;
4912     emai.pNext = &mdai;  // still dedicated
4913     mdai.pNext = nullptr;
4914 
4915     // Export with allocation size non-zero
4916     ahb_desc.usage = AHARDWAREBUFFER_USAGE_GPU_SAMPLED_IMAGE;
4917     recreate_ahb();
4918     mai.allocationSize = ahb_props.allocationSize;
4919     m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkMemoryDedicatedAllocateInfo-image-02964");
4920     m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkMemoryAllocateInfo-pNext-01874");
4921     vk::AllocateMemory(dev, &mai, NULL, &mem_handle);
4922     m_errorMonitor->VerifyFound();
4923     reset_mem();
4924 
4925     AHardwareBuffer_release(ahb);
4926     reset_mem();
4927     reset_img();
4928 }
4929 
TEST_F(VkLayerTest,AndroidHardwareBufferCreateYCbCrSampler)4930 TEST_F(VkLayerTest, AndroidHardwareBufferCreateYCbCrSampler) {
4931     TEST_DESCRIPTION("Verify AndroidHardwareBuffer YCbCr sampler creation.");
4932 
4933     SetTargetApiVersion(VK_API_VERSION_1_1);
4934     ASSERT_NO_FATAL_FAILURE(InitFramework(m_errorMonitor));
4935 
4936     if ((DeviceExtensionSupported(gpu(), nullptr, VK_ANDROID_EXTERNAL_MEMORY_ANDROID_HARDWARE_BUFFER_EXTENSION_NAME)) &&
4937         // Also skip on devices that advertise AHB, but not the pre-requisite foreign_queue extension
4938         (DeviceExtensionSupported(gpu(), nullptr, VK_EXT_QUEUE_FAMILY_FOREIGN_EXTENSION_NAME))) {
4939         m_device_extension_names.push_back(VK_ANDROID_EXTERNAL_MEMORY_ANDROID_HARDWARE_BUFFER_EXTENSION_NAME);
4940         m_device_extension_names.push_back(VK_KHR_SAMPLER_YCBCR_CONVERSION_EXTENSION_NAME);
4941         m_device_extension_names.push_back(VK_KHR_MAINTENANCE_1_EXTENSION_NAME);
4942         m_device_extension_names.push_back(VK_KHR_BIND_MEMORY_2_EXTENSION_NAME);
4943         m_device_extension_names.push_back(VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME);
4944         m_device_extension_names.push_back(VK_KHR_EXTERNAL_MEMORY_EXTENSION_NAME);
4945         m_device_extension_names.push_back(VK_EXT_QUEUE_FAMILY_FOREIGN_EXTENSION_NAME);
4946     } else {
4947         printf("%s %s extension not supported, skipping tests\n", kSkipPrefix,
4948                VK_ANDROID_EXTERNAL_MEMORY_ANDROID_HARDWARE_BUFFER_EXTENSION_NAME);
4949         return;
4950     }
4951 
4952     // Enable Ycbcr Conversion Features
4953     VkPhysicalDeviceSamplerYcbcrConversionFeatures ycbcr_features = LvlInitStruct<VkPhysicalDeviceSamplerYcbcrConversionFeatures>();
4954     ycbcr_features.samplerYcbcrConversion = VK_TRUE;
4955     ASSERT_NO_FATAL_FAILURE(InitState(nullptr, &ycbcr_features));
4956     VkDevice dev = m_device->device();
4957 
4958     VkSamplerYcbcrConversion ycbcr_conv = VK_NULL_HANDLE;
4959     VkSamplerYcbcrConversionCreateInfo sycci = LvlInitStruct<VkSamplerYcbcrConversionCreateInfo>();
4960     sycci.format = VK_FORMAT_UNDEFINED;
4961     sycci.ycbcrModel = VK_SAMPLER_YCBCR_MODEL_CONVERSION_RGB_IDENTITY;
4962     sycci.ycbcrRange = VK_SAMPLER_YCBCR_RANGE_ITU_FULL;
4963 
4964     m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkSamplerYcbcrConversionCreateInfo-format-04061");
4965     m_errorMonitor->SetUnexpectedError("VUID-VkSamplerYcbcrConversionCreateInfo-xChromaOffset-01651");
4966     vk::CreateSamplerYcbcrConversion(dev, &sycci, NULL, &ycbcr_conv);
4967     m_errorMonitor->VerifyFound();
4968 
4969     VkExternalFormatANDROID efa = LvlInitStruct<VkExternalFormatANDROID>();
4970     efa.externalFormat = AHARDWAREBUFFER_FORMAT_R8G8B8X8_UNORM;
4971     sycci.format = VK_FORMAT_R8G8B8A8_UNORM;
4972     sycci.pNext = &efa;
4973     m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkSamplerYcbcrConversionCreateInfo-format-01904");
4974     m_errorMonitor->SetUnexpectedError("VUID-VkSamplerYcbcrConversionCreateInfo-xChromaOffset-01651");
4975     vk::CreateSamplerYcbcrConversion(dev, &sycci, NULL, &ycbcr_conv);
4976     m_errorMonitor->VerifyFound();
4977 
4978     m_errorMonitor->ExpectSuccess();
4979     efa.externalFormat = AHARDWAREBUFFER_FORMAT_Y8Cb8Cr8_420;
4980     sycci.format = VK_FORMAT_UNDEFINED;
4981     sycci.ycbcrModel = VK_SAMPLER_YCBCR_MODEL_CONVERSION_YCBCR_709;
4982     sycci.ycbcrRange = VK_SAMPLER_YCBCR_RANGE_ITU_NARROW;
4983     // Spec says if we use VkExternalFormatANDROID value of components is ignored.
4984     sycci.components = {VK_COMPONENT_SWIZZLE_ZERO, VK_COMPONENT_SWIZZLE_ZERO, VK_COMPONENT_SWIZZLE_ZERO, VK_COMPONENT_SWIZZLE_ZERO};
4985     vk::CreateSamplerYcbcrConversion(dev, &sycci, NULL, &ycbcr_conv);
4986     m_errorMonitor->VerifyNotFound();
4987     vk::DestroySamplerYcbcrConversion(dev, ycbcr_conv, nullptr);
4988 }
4989 
TEST_F(VkLayerTest,AndroidHardwareBufferPhysDevImageFormatProp2)4990 TEST_F(VkLayerTest, AndroidHardwareBufferPhysDevImageFormatProp2) {
4991     TEST_DESCRIPTION("Verify AndroidHardwareBuffer GetPhysicalDeviceImageFormatProperties.");
4992 
4993     SetTargetApiVersion(VK_API_VERSION_1_1);
4994     ASSERT_NO_FATAL_FAILURE(InitFramework(m_errorMonitor));
4995 
4996     if ((DeviceExtensionSupported(gpu(), nullptr, VK_ANDROID_EXTERNAL_MEMORY_ANDROID_HARDWARE_BUFFER_EXTENSION_NAME)) &&
4997         // Also skip on devices that advertise AHB, but not the pre-requisite foreign_queue extension
4998         (DeviceExtensionSupported(gpu(), nullptr, VK_EXT_QUEUE_FAMILY_FOREIGN_EXTENSION_NAME))) {
4999         m_device_extension_names.push_back(VK_ANDROID_EXTERNAL_MEMORY_ANDROID_HARDWARE_BUFFER_EXTENSION_NAME);
5000         m_device_extension_names.push_back(VK_KHR_SAMPLER_YCBCR_CONVERSION_EXTENSION_NAME);
5001         m_device_extension_names.push_back(VK_KHR_MAINTENANCE_1_EXTENSION_NAME);
5002         m_device_extension_names.push_back(VK_KHR_BIND_MEMORY_2_EXTENSION_NAME);
5003         m_device_extension_names.push_back(VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME);
5004         m_device_extension_names.push_back(VK_KHR_EXTERNAL_MEMORY_EXTENSION_NAME);
5005         m_device_extension_names.push_back(VK_EXT_QUEUE_FAMILY_FOREIGN_EXTENSION_NAME);
5006     } else {
5007         printf("%s %s extension not supported, skipping test\n", kSkipPrefix,
5008                VK_ANDROID_EXTERNAL_MEMORY_ANDROID_HARDWARE_BUFFER_EXTENSION_NAME);
5009         return;
5010     }
5011 
5012     ASSERT_NO_FATAL_FAILURE(InitState());
5013 
5014     if ((DeviceValidationVersion() < VK_API_VERSION_1_1) &&
5015         !InstanceExtensionEnabled(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME)) {
5016         printf("%s %s extension not supported, skipping test\n", kSkipPrefix,
5017                VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
5018         return;
5019     }
5020 
5021     VkImageFormatProperties2 ifp = LvlInitStruct<VkImageFormatProperties2>();
5022     VkPhysicalDeviceImageFormatInfo2 pdifi = LvlInitStruct<VkPhysicalDeviceImageFormatInfo2>();
5023     pdifi.format = VK_FORMAT_R8G8B8A8_UNORM;
5024     pdifi.tiling = VK_IMAGE_TILING_OPTIMAL;
5025     pdifi.type = VK_IMAGE_TYPE_2D;
5026     pdifi.usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
5027     VkAndroidHardwareBufferUsageANDROID ahbu = LvlInitStruct<VkAndroidHardwareBufferUsageANDROID>();
5028     ahbu.androidHardwareBufferUsage = AHARDWAREBUFFER_USAGE_GPU_SAMPLED_IMAGE;
5029     ifp.pNext = &ahbu;
5030 
5031     // AHB_usage chained to input without a matching external image format struc chained to output
5032     m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkGetPhysicalDeviceImageFormatProperties2-pNext-01868");
5033     vk::GetPhysicalDeviceImageFormatProperties2(m_device->phy().handle(), &pdifi, &ifp);
5034     m_errorMonitor->VerifyFound();
5035 
5036     // output struct chained, but does not include VK_EXTERNAL_MEMORY_HANDLE_TYPE_ANDROID_HARDWARE_BUFFER_BIT_ANDROID usage
5037     VkPhysicalDeviceExternalImageFormatInfo pdeifi = LvlInitStruct<VkPhysicalDeviceExternalImageFormatInfo>();
5038     pdeifi.handleType = VK_EXTERNAL_MEMORY_HANDLE_TYPE_HOST_ALLOCATION_BIT_EXT;
5039     pdifi.pNext = &pdeifi;
5040     m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkGetPhysicalDeviceImageFormatProperties2-pNext-01868");
5041     vk::GetPhysicalDeviceImageFormatProperties2(m_device->phy().handle(), &pdifi, &ifp);
5042     m_errorMonitor->VerifyFound();
5043 }
5044 
5045 #if DISABLEUNTILAHBWORKS
TEST_F(VkLayerTest,AndroidHardwareBufferCreateImageView)5046 TEST_F(VkLayerTest, AndroidHardwareBufferCreateImageView) {
5047     TEST_DESCRIPTION("Verify AndroidHardwareBuffer image view creation.");
5048 
5049     SetTargetApiVersion(VK_API_VERSION_1_1);
5050     ASSERT_NO_FATAL_FAILURE(InitFramework(m_errorMonitor));
5051 
5052     if (IsPlatform(kGalaxyS10)) {
5053         printf("%s This test should not run on Galaxy S10\n", kSkipPrefix);
5054         return;
5055     }
5056 
5057     if ((DeviceExtensionSupported(gpu(), nullptr, VK_ANDROID_EXTERNAL_MEMORY_ANDROID_HARDWARE_BUFFER_EXTENSION_NAME)) &&
5058         // Also skip on devices that advertise AHB, but not the pre-requisite foreign_queue extension
5059         (DeviceExtensionSupported(gpu(), nullptr, VK_EXT_QUEUE_FAMILY_FOREIGN_EXTENSION_NAME))) {
5060         m_device_extension_names.push_back(VK_ANDROID_EXTERNAL_MEMORY_ANDROID_HARDWARE_BUFFER_EXTENSION_NAME);
5061         m_device_extension_names.push_back(VK_KHR_SAMPLER_YCBCR_CONVERSION_EXTENSION_NAME);
5062         m_device_extension_names.push_back(VK_KHR_MAINTENANCE_1_EXTENSION_NAME);
5063         m_device_extension_names.push_back(VK_KHR_BIND_MEMORY_2_EXTENSION_NAME);
5064         m_device_extension_names.push_back(VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME);
5065         m_device_extension_names.push_back(VK_KHR_EXTERNAL_MEMORY_EXTENSION_NAME);
5066         m_device_extension_names.push_back(VK_EXT_QUEUE_FAMILY_FOREIGN_EXTENSION_NAME);
5067     } else {
5068         printf("%s %s extension not supported, skipping tests\n", kSkipPrefix,
5069                VK_ANDROID_EXTERNAL_MEMORY_ANDROID_HARDWARE_BUFFER_EXTENSION_NAME);
5070         return;
5071     }
5072 
5073     ASSERT_NO_FATAL_FAILURE(InitState());
5074     VkDevice dev = m_device->device();
5075 
5076     // Allocate an AHB and fetch its properties
5077     AHardwareBuffer *ahb = nullptr;
5078     AHardwareBuffer_Desc ahb_desc = {};
5079     ahb_desc.format = AHARDWAREBUFFER_FORMAT_R5G6B5_UNORM;
5080     ahb_desc.usage = AHARDWAREBUFFER_USAGE_GPU_SAMPLED_IMAGE;
5081     ahb_desc.width = 64;
5082     ahb_desc.height = 64;
5083     ahb_desc.layers = 1;
5084     AHardwareBuffer_allocate(&ahb_desc, &ahb);
5085 
5086     // Retrieve AHB properties to make it's external format 'known'
5087     VkAndroidHardwareBufferFormatPropertiesANDROID ahb_fmt_props = LvlInitStruct<VkAndroidHardwareBufferFormatPropertiesANDROID>();
5088     VkAndroidHardwareBufferPropertiesANDROID ahb_props = LvlInitStruct<VkAndroidHardwareBufferPropertiesANDROID>(&ahb_fmt_props);
5089     PFN_vkGetAndroidHardwareBufferPropertiesANDROID pfn_GetAHBProps =
5090         (PFN_vkGetAndroidHardwareBufferPropertiesANDROID)vk::GetDeviceProcAddr(dev, "vkGetAndroidHardwareBufferPropertiesANDROID");
5091     ASSERT_TRUE(pfn_GetAHBProps != nullptr);
5092     pfn_GetAHBProps(dev, ahb, &ahb_props);
5093     AHardwareBuffer_release(ahb);
5094 
5095     VkExternalMemoryImageCreateInfo emici = LvlInitStruct<VkExternalMemoryImageCreateInfo>();
5096     emici.handleTypes = VK_EXTERNAL_MEMORY_HANDLE_TYPE_ANDROID_HARDWARE_BUFFER_BIT_ANDROID;
5097 
5098     // Give image an external format
5099     VkExternalFormatANDROID efa = LvlInitStruct<VkExternalFormatANDROID>(&emici);
5100     efa.externalFormat = ahb_fmt_props.externalFormat;
5101 
5102     ahb_desc.format = AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM;
5103     ahb_desc.usage = AHARDWAREBUFFER_USAGE_GPU_SAMPLED_IMAGE;
5104     ahb_desc.width = 64;
5105     ahb_desc.height = 1;
5106     ahb_desc.layers = 1;
5107     AHardwareBuffer_allocate(&ahb_desc, &ahb);
5108 
5109     // Create another VkExternalFormatANDROID for test VUID-VkImageViewCreateInfo-image-02400
5110     VkAndroidHardwareBufferFormatPropertiesANDROID ahb_fmt_props_Ycbcr =
5111         LvlInitStruct<VkAndroidHardwareBufferFormatPropertiesANDROID>();
5112     VkAndroidHardwareBufferPropertiesANDROID ahb_props_Ycbcr =
5113         LvlInitStruct<VkAndroidHardwareBufferPropertiesANDROID>(&ahb_fmt_props_Ycbcr);
5114     pfn_GetAHBProps(dev, ahb, &ahb_props_Ycbcr);
5115     AHardwareBuffer_release(ahb);
5116 
5117     VkExternalFormatANDROID efa_Ycbcr = LvlInitStruct<VkExternalFormatANDROID>();
5118     efa_Ycbcr.externalFormat = ahb_fmt_props_Ycbcr.externalFormat;
5119 
5120     // Need to make sure format has sample bit needed for image usage
5121     if ((ahb_fmt_props_Ycbcr.formatFeatures & VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT) == 0) {
5122         printf("%s VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT feature bit not supported for format %" PRIu64 ".", kSkipPrefix,
5123                ahb_fmt_props_Ycbcr.externalFormat);
5124         return;
5125     }
5126 
5127     // Create the image
5128     VkImage img = VK_NULL_HANDLE;
5129     VkImageCreateInfo ici = LvlInitStruct<VkImageCreateInfo>(&efa);
5130     ici.imageType = VK_IMAGE_TYPE_2D;
5131     ici.arrayLayers = 1;
5132     ici.extent = {64, 64, 1};
5133     ici.format = VK_FORMAT_UNDEFINED;
5134     ici.mipLevels = 1;
5135     ici.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
5136     ici.samples = VK_SAMPLE_COUNT_1_BIT;
5137     ici.tiling = VK_IMAGE_TILING_OPTIMAL;
5138     ici.usage = VK_IMAGE_USAGE_SAMPLED_BIT;
5139     vk::CreateImage(dev, &ici, NULL, &img);
5140 
5141     // Set up memory allocation
5142     VkDeviceMemory img_mem = VK_NULL_HANDLE;
5143     VkMemoryAllocateInfo mai = LvlInitStruct<VkMemoryAllocateInfo>();
5144     mai.allocationSize = 64 * 64 * 4;
5145     mai.memoryTypeIndex = 0;
5146     vk::AllocateMemory(dev, &mai, NULL, &img_mem);
5147 
5148     // It shouldn't use vk::GetImageMemoryRequirements for imported AndroidHardwareBuffer when memory isn't bound yet
5149     m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkGetImageMemoryRequirements-image-04004");
5150     VkMemoryRequirements img_mem_reqs = {};
5151     vk::GetImageMemoryRequirements(m_device->device(), img, &img_mem_reqs);
5152     m_errorMonitor->VerifyFound();
5153     vk::BindImageMemory(dev, img, img_mem, 0);
5154 
5155     // Bind image to memory
5156     vk::DestroyImage(dev, img, NULL);
5157     vk::FreeMemory(dev, img_mem, NULL);
5158     vk::CreateImage(dev, &ici, NULL, &img);
5159     vk::AllocateMemory(dev, &mai, NULL, &img_mem);
5160     vk::BindImageMemory(dev, img, img_mem, 0);
5161 
5162     // Create a YCbCr conversion, with different external format, chain to view
5163     VkSamplerYcbcrConversion ycbcr_conv = VK_NULL_HANDLE;
5164     VkSamplerYcbcrConversionCreateInfo sycci = LvlInitStruct<VkSamplerYcbcrConversionCreateInfo>(&efa_Ycbcr);
5165     sycci.format = VK_FORMAT_UNDEFINED;
5166     sycci.ycbcrModel = VK_SAMPLER_YCBCR_MODEL_CONVERSION_RGB_IDENTITY;
5167     sycci.ycbcrRange = VK_SAMPLER_YCBCR_RANGE_ITU_FULL;
5168     vk::CreateSamplerYcbcrConversion(dev, &sycci, NULL, &ycbcr_conv);
5169     VkSamplerYcbcrConversionInfo syci = LvlInitStruct<VkSamplerYcbcrConversionInfo>();
5170     syci.conversion = ycbcr_conv;
5171 
5172     // Create a view
5173     VkImageView image_view = VK_NULL_HANDLE;
5174     VkImageViewCreateInfo ivci = LvlInitStruct<VkImageViewCreateInfo>(&syci);
5175     ivci.image = img;
5176     ivci.viewType = VK_IMAGE_VIEW_TYPE_2D;
5177     ivci.format = VK_FORMAT_UNDEFINED;
5178     ivci.subresourceRange = {VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1};
5179 
5180     auto reset_view = [&image_view, dev]() {
5181         if (VK_NULL_HANDLE != image_view) vk::DestroyImageView(dev, image_view, NULL);
5182         image_view = VK_NULL_HANDLE;
5183     };
5184 
5185     // Up to this point, no errors expected
5186     m_errorMonitor->VerifyNotFound();
5187 
5188     // Chained ycbcr conversion has different (external) format than image
5189     m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkImageViewCreateInfo-image-02400");
5190     // Also causes "unsupported format" - should be removed in future spec update
5191     m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkImageViewCreateInfo-None-02273");
5192     vk::CreateImageView(dev, &ivci, NULL, &image_view);
5193     m_errorMonitor->VerifyFound();
5194 
5195     reset_view();
5196     vk::DestroySamplerYcbcrConversion(dev, ycbcr_conv, NULL);
5197     sycci.pNext = &efa;
5198     vk::CreateSamplerYcbcrConversion(dev, &sycci, NULL, &ycbcr_conv);
5199     syci.conversion = ycbcr_conv;
5200 
5201     // View component swizzle not IDENTITY
5202     ivci.components.r = VK_COMPONENT_SWIZZLE_B;
5203     ivci.components.b = VK_COMPONENT_SWIZZLE_R;
5204     m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkImageViewCreateInfo-image-02401");
5205     // Also causes "unsupported format" - should be removed in future spec update
5206     m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkImageViewCreateInfo-None-02273");
5207     vk::CreateImageView(dev, &ivci, NULL, &image_view);
5208     m_errorMonitor->VerifyFound();
5209 
5210     reset_view();
5211     ivci.components.r = VK_COMPONENT_SWIZZLE_IDENTITY;
5212     ivci.components.b = VK_COMPONENT_SWIZZLE_IDENTITY;
5213 
5214     // View with external format, when format is not UNDEFINED
5215     ivci.format = VK_FORMAT_R5G6B5_UNORM_PACK16;
5216     m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkImageViewCreateInfo-image-02399");
5217     // Also causes "view format different from image format"
5218     m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkImageViewCreateInfo-image-01762");
5219     vk::CreateImageView(dev, &ivci, NULL, &image_view);
5220     m_errorMonitor->VerifyFound();
5221 
5222     reset_view();
5223     vk::DestroySamplerYcbcrConversion(dev, ycbcr_conv, NULL);
5224     vk::DestroyImageView(dev, image_view, NULL);
5225     vk::DestroyImage(dev, img, NULL);
5226     vk::FreeMemory(dev, img_mem, NULL);
5227 }
5228 #endif  // DISABLEUNTILAHBWORKS
5229 
TEST_F(VkLayerTest,AndroidHardwareBufferImportBuffer)5230 TEST_F(VkLayerTest, AndroidHardwareBufferImportBuffer) {
5231     TEST_DESCRIPTION("Verify AndroidHardwareBuffer import as buffer.");
5232 
5233     SetTargetApiVersion(VK_API_VERSION_1_1);
5234     ASSERT_NO_FATAL_FAILURE(InitFramework(m_errorMonitor));
5235 
5236     if (IsPlatform(kGalaxyS10)) {
5237         printf("%s This test should not run on Galaxy S10\n", kSkipPrefix);
5238         return;
5239     }
5240 
5241     if ((DeviceExtensionSupported(gpu(), nullptr, VK_ANDROID_EXTERNAL_MEMORY_ANDROID_HARDWARE_BUFFER_EXTENSION_NAME)) &&
5242         // Also skip on devices that advertise AHB, but not the pre-requisite foreign_queue extension
5243         (DeviceExtensionSupported(gpu(), nullptr, VK_EXT_QUEUE_FAMILY_FOREIGN_EXTENSION_NAME))) {
5244         m_device_extension_names.push_back(VK_ANDROID_EXTERNAL_MEMORY_ANDROID_HARDWARE_BUFFER_EXTENSION_NAME);
5245         m_device_extension_names.push_back(VK_KHR_SAMPLER_YCBCR_CONVERSION_EXTENSION_NAME);
5246         m_device_extension_names.push_back(VK_KHR_MAINTENANCE_1_EXTENSION_NAME);
5247         m_device_extension_names.push_back(VK_KHR_BIND_MEMORY_2_EXTENSION_NAME);
5248         m_device_extension_names.push_back(VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME);
5249         m_device_extension_names.push_back(VK_KHR_EXTERNAL_MEMORY_EXTENSION_NAME);
5250         m_device_extension_names.push_back(VK_EXT_QUEUE_FAMILY_FOREIGN_EXTENSION_NAME);
5251     } else {
5252         printf("%s %s extension not supported, skipping tests\n", kSkipPrefix,
5253                VK_ANDROID_EXTERNAL_MEMORY_ANDROID_HARDWARE_BUFFER_EXTENSION_NAME);
5254         return;
5255     }
5256 
5257     ASSERT_NO_FATAL_FAILURE(InitState());
5258     VkDevice dev = m_device->device();
5259 
5260     VkDeviceMemory mem_handle = VK_NULL_HANDLE;
5261     auto reset_mem = [&mem_handle, dev]() {
5262         if (VK_NULL_HANDLE != mem_handle) vk::FreeMemory(dev, mem_handle, NULL);
5263         mem_handle = VK_NULL_HANDLE;
5264     };
5265 
5266     PFN_vkGetAndroidHardwareBufferPropertiesANDROID pfn_GetAHBProps =
5267         (PFN_vkGetAndroidHardwareBufferPropertiesANDROID)vk::GetDeviceProcAddr(dev, "vkGetAndroidHardwareBufferPropertiesANDROID");
5268     ASSERT_TRUE(pfn_GetAHBProps != nullptr);
5269 
5270     // AHB structs
5271     AHardwareBuffer *ahb = nullptr;
5272     AHardwareBuffer_Desc ahb_desc = {};
5273     VkAndroidHardwareBufferPropertiesANDROID ahb_props = LvlInitStruct<VkAndroidHardwareBufferPropertiesANDROID>();
5274     VkImportAndroidHardwareBufferInfoANDROID iahbi = LvlInitStruct<VkImportAndroidHardwareBufferInfoANDROID>();
5275 
5276     // Allocate an AHardwareBuffer
5277     ahb_desc.format = AHARDWAREBUFFER_FORMAT_BLOB;
5278     ahb_desc.usage = AHARDWAREBUFFER_USAGE_SENSOR_DIRECT_DATA;  // non USAGE_GPU_*
5279     ahb_desc.width = 512;
5280     ahb_desc.height = 1;
5281     ahb_desc.layers = 1;
5282     AHardwareBuffer_allocate(&ahb_desc, &ahb);
5283     m_errorMonitor->SetUnexpectedError("VUID-vkGetAndroidHardwareBufferPropertiesANDROID-buffer-01884");
5284     pfn_GetAHBProps(dev, ahb, &ahb_props);
5285     iahbi.buffer = ahb;
5286 
5287     // Create export and import buffers
5288     VkExternalMemoryBufferCreateInfo ext_buf_info = LvlInitStruct<VkExternalMemoryBufferCreateInfo>();
5289     ext_buf_info.handleTypes = VK_EXTERNAL_MEMORY_HANDLE_TYPE_HOST_ALLOCATION_BIT_EXT;
5290 
5291     VkBufferCreateInfo bci = LvlInitStruct<VkBufferCreateInfo>(&ext_buf_info);
5292     bci.size = ahb_props.allocationSize;
5293     bci.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT;
5294 
5295     VkBuffer buf = VK_NULL_HANDLE;
5296     vk::CreateBuffer(dev, &bci, NULL, &buf);
5297     VkMemoryRequirements mem_reqs;
5298     vk::GetBufferMemoryRequirements(dev, buf, &mem_reqs);
5299 
5300     // Allocation info
5301     VkMemoryAllocateInfo mai = vk_testing::DeviceMemory::get_resource_alloc_info(*m_device, mem_reqs, 0);
5302     mai.pNext = &iahbi;  // Chained import struct
5303     VkPhysicalDeviceMemoryProperties memory_info;
5304     vk::GetPhysicalDeviceMemoryProperties(gpu(), &memory_info);
5305     unsigned int i;
5306     for (i = 0; i < memory_info.memoryTypeCount; i++) {
5307         if ((ahb_props.memoryTypeBits & (1 << i))) {
5308             mai.memoryTypeIndex = i;
5309             break;
5310         }
5311     }
5312     if (i >= memory_info.memoryTypeCount) {
5313         printf("%s No invalid memory type index could be found; skipped.\n", kSkipPrefix);
5314         AHardwareBuffer_release(ahb);
5315         reset_mem();
5316         vk::DestroyBuffer(dev, buf, NULL);
5317         return;
5318     }
5319 
5320     // Import as buffer requires usage AHB_USAGE_GPU_DATA_BUFFER
5321     m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkImportAndroidHardwareBufferInfoANDROID-buffer-01881");
5322     // Also causes "non-dedicated allocation format/usage" error
5323     m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkMemoryAllocateInfo-pNext-02384");
5324     vk::AllocateMemory(dev, &mai, NULL, &mem_handle);
5325     m_errorMonitor->VerifyFound();
5326 
5327     AHardwareBuffer_release(ahb);
5328     reset_mem();
5329     vk::DestroyBuffer(dev, buf, NULL);
5330 }
5331 
TEST_F(VkLayerTest,AndroidHardwareBufferExporttBuffer)5332 TEST_F(VkLayerTest, AndroidHardwareBufferExporttBuffer) {
5333     TEST_DESCRIPTION("Verify AndroidHardwareBuffer export memory as AHB.");
5334 
5335     SetTargetApiVersion(VK_API_VERSION_1_1);
5336     ASSERT_NO_FATAL_FAILURE(InitFramework(m_errorMonitor));
5337 
5338     if (IsPlatform(kGalaxyS10)) {
5339         printf("%s This test should not run on Galaxy S10\n", kSkipPrefix);
5340         return;
5341     }
5342 
5343     if ((DeviceExtensionSupported(gpu(), nullptr, VK_ANDROID_EXTERNAL_MEMORY_ANDROID_HARDWARE_BUFFER_EXTENSION_NAME)) &&
5344         // Also skip on devices that advertise AHB, but not the pre-requisite foreign_queue extension
5345         (DeviceExtensionSupported(gpu(), nullptr, VK_EXT_QUEUE_FAMILY_FOREIGN_EXTENSION_NAME))) {
5346         m_device_extension_names.push_back(VK_ANDROID_EXTERNAL_MEMORY_ANDROID_HARDWARE_BUFFER_EXTENSION_NAME);
5347         m_device_extension_names.push_back(VK_KHR_SAMPLER_YCBCR_CONVERSION_EXTENSION_NAME);
5348         m_device_extension_names.push_back(VK_KHR_MAINTENANCE_1_EXTENSION_NAME);
5349         m_device_extension_names.push_back(VK_KHR_BIND_MEMORY_2_EXTENSION_NAME);
5350         m_device_extension_names.push_back(VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME);
5351         m_device_extension_names.push_back(VK_KHR_EXTERNAL_MEMORY_EXTENSION_NAME);
5352         m_device_extension_names.push_back(VK_EXT_QUEUE_FAMILY_FOREIGN_EXTENSION_NAME);
5353     } else {
5354         printf("%s %s extension not supported, skipping tests\n", kSkipPrefix,
5355                VK_ANDROID_EXTERNAL_MEMORY_ANDROID_HARDWARE_BUFFER_EXTENSION_NAME);
5356         return;
5357     }
5358 
5359     ASSERT_NO_FATAL_FAILURE(InitState());
5360     VkDevice dev = m_device->device();
5361 
5362     VkDeviceMemory mem_handle = VK_NULL_HANDLE;
5363 
5364     // Allocate device memory, no linked export struct indicating AHB handle type
5365     VkMemoryAllocateInfo mai = LvlInitStruct<VkMemoryAllocateInfo>();
5366     mai.allocationSize = 65536;
5367     mai.memoryTypeIndex = 0;
5368     vk::AllocateMemory(dev, &mai, NULL, &mem_handle);
5369 
5370     PFN_vkGetMemoryAndroidHardwareBufferANDROID pfn_GetMemAHB =
5371         (PFN_vkGetMemoryAndroidHardwareBufferANDROID)vk::GetDeviceProcAddr(dev, "vkGetMemoryAndroidHardwareBufferANDROID");
5372     ASSERT_TRUE(pfn_GetMemAHB != nullptr);
5373 
5374     VkMemoryGetAndroidHardwareBufferInfoANDROID mgahbi = LvlInitStruct<VkMemoryGetAndroidHardwareBufferInfoANDROID>();
5375     mgahbi.memory = mem_handle;
5376     AHardwareBuffer *ahb = nullptr;
5377     m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkMemoryGetAndroidHardwareBufferInfoANDROID-handleTypes-01882");
5378     pfn_GetMemAHB(dev, &mgahbi, &ahb);
5379     m_errorMonitor->VerifyFound();
5380 
5381     if (ahb) AHardwareBuffer_release(ahb);
5382     ahb = nullptr;
5383     if (VK_NULL_HANDLE != mem_handle) vk::FreeMemory(dev, mem_handle, NULL);
5384     mem_handle = VK_NULL_HANDLE;
5385 
5386     // Add an export struct with AHB handle type to allocation info
5387     VkExportMemoryAllocateInfo emai = LvlInitStruct<VkExportMemoryAllocateInfo>();
5388     emai.handleTypes = VK_EXTERNAL_MEMORY_HANDLE_TYPE_ANDROID_HARDWARE_BUFFER_BIT_ANDROID;
5389     mai.pNext = &emai;
5390 
5391     // Create an image, do not bind memory
5392     VkImage img = VK_NULL_HANDLE;
5393     VkImageCreateInfo ici = LvlInitStruct<VkImageCreateInfo>();
5394     ici.imageType = VK_IMAGE_TYPE_2D;
5395     ici.arrayLayers = 1;
5396     ici.extent = {128, 128, 1};
5397     ici.format = VK_FORMAT_R8G8B8A8_UNORM;
5398     ici.mipLevels = 1;
5399     ici.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
5400     ici.samples = VK_SAMPLE_COUNT_1_BIT;
5401     ici.tiling = VK_IMAGE_TILING_OPTIMAL;
5402     ici.usage = VK_IMAGE_USAGE_SAMPLED_BIT;
5403     vk::CreateImage(dev, &ici, NULL, &img);
5404     ASSERT_TRUE(VK_NULL_HANDLE != img);
5405 
5406     // Add image to allocation chain as dedicated info, re-allocate
5407     VkMemoryDedicatedAllocateInfo mdai = {VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO};
5408     mdai.image = img;
5409     emai.pNext = &mdai;
5410     mai.allocationSize = 0;
5411     vk::AllocateMemory(dev, &mai, NULL, &mem_handle);
5412     mgahbi.memory = mem_handle;
5413 
5414     m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkMemoryGetAndroidHardwareBufferInfoANDROID-pNext-01883");
5415     pfn_GetMemAHB(dev, &mgahbi, &ahb);
5416     m_errorMonitor->VerifyFound();
5417 
5418     if (ahb) AHardwareBuffer_release(ahb);
5419     if (VK_NULL_HANDLE != mem_handle) vk::FreeMemory(dev, mem_handle, NULL);
5420     vk::DestroyImage(dev, img, NULL);
5421 }
5422 
TEST_F(VkLayerTest,AndroidHardwareBufferInvalidBindBufferMemory)5423 TEST_F(VkLayerTest, AndroidHardwareBufferInvalidBindBufferMemory) {
5424     TEST_DESCRIPTION("Validate binding AndroidHardwareBuffer VkBuffer act same as non-AHB buffers.");
5425 
5426     SetTargetApiVersion(VK_API_VERSION_1_1);
5427     ASSERT_NO_FATAL_FAILURE(InitFramework(m_errorMonitor));
5428 
5429     if (IsPlatform(kGalaxyS10)) {
5430         printf("%s This test should not run on Galaxy S10\n", kSkipPrefix);
5431         return;
5432     }
5433 
5434     if ((DeviceExtensionSupported(gpu(), nullptr, VK_ANDROID_EXTERNAL_MEMORY_ANDROID_HARDWARE_BUFFER_EXTENSION_NAME)) &&
5435         // Also skip on devices that advertise AHB, but not the pre-requisite foreign_queue extension
5436         (DeviceExtensionSupported(gpu(), nullptr, VK_EXT_QUEUE_FAMILY_FOREIGN_EXTENSION_NAME))) {
5437         m_device_extension_names.push_back(VK_ANDROID_EXTERNAL_MEMORY_ANDROID_HARDWARE_BUFFER_EXTENSION_NAME);
5438         m_device_extension_names.push_back(VK_KHR_SAMPLER_YCBCR_CONVERSION_EXTENSION_NAME);
5439         m_device_extension_names.push_back(VK_KHR_MAINTENANCE_1_EXTENSION_NAME);
5440         m_device_extension_names.push_back(VK_KHR_BIND_MEMORY_2_EXTENSION_NAME);
5441         m_device_extension_names.push_back(VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME);
5442         m_device_extension_names.push_back(VK_KHR_EXTERNAL_MEMORY_EXTENSION_NAME);
5443         m_device_extension_names.push_back(VK_EXT_QUEUE_FAMILY_FOREIGN_EXTENSION_NAME);
5444     } else {
5445         printf("%s %s extension not supported, skipping tests\n", kSkipPrefix,
5446                VK_ANDROID_EXTERNAL_MEMORY_ANDROID_HARDWARE_BUFFER_EXTENSION_NAME);
5447         return;
5448     }
5449 
5450     ASSERT_NO_FATAL_FAILURE(InitState());
5451 
5452     // Allocate an AHardwareBuffer
5453     AHardwareBuffer *ahb;
5454     AHardwareBuffer_Desc ahb_desc = {};
5455     ahb_desc.format = AHARDWAREBUFFER_FORMAT_BLOB;
5456     ahb_desc.usage = AHARDWAREBUFFER_USAGE_GPU_DATA_BUFFER;
5457     ahb_desc.width = 64;
5458     ahb_desc.height = 1;
5459     ahb_desc.layers = 1;
5460     ahb_desc.stride = 1;
5461     AHardwareBuffer_allocate(&ahb_desc, &ahb);
5462 
5463     VkExternalMemoryBufferCreateInfo ext_buf_info = LvlInitStruct<VkExternalMemoryBufferCreateInfo>();
5464     ext_buf_info.handleTypes = VK_EXTERNAL_MEMORY_HANDLE_TYPE_ANDROID_HARDWARE_BUFFER_BIT_ANDROID;
5465 
5466     VkBufferCreateInfo buffer_create_info = LvlInitStruct<VkBufferCreateInfo>(&ext_buf_info);
5467     buffer_create_info.size = 1 << 20;  // 1 MB
5468     buffer_create_info.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT;
5469 
5470     VkBuffer buffer = VK_NULL_HANDLE;
5471     vk::CreateBuffer(m_device->device(), &buffer_create_info, nullptr, &buffer);
5472 
5473     // Try to get memory requirements prior to binding memory
5474     VkMemoryRequirements mem_reqs;
5475     vk::GetBufferMemoryRequirements(m_device->device(), buffer, &mem_reqs);
5476 
5477     VkImportAndroidHardwareBufferInfoANDROID import_ahb_Info = LvlInitStruct<VkImportAndroidHardwareBufferInfoANDROID>();
5478     import_ahb_Info.buffer = ahb;
5479 
5480     VkMemoryAllocateInfo memory_info = LvlInitStruct<VkMemoryAllocateInfo>(&import_ahb_Info);
5481     memory_info.allocationSize = mem_reqs.size + mem_reqs.alignment;  // save room for offset
5482     bool has_memtype = m_device->phy().set_memory_type(mem_reqs.memoryTypeBits, &memory_info, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT);
5483     if (!has_memtype) {
5484         printf("%s No invalid memory type index could be found; skipped.\n", kSkipPrefix);
5485         AHardwareBuffer_release(ahb);
5486         vk::DestroyBuffer(m_device->device(), buffer, nullptr);
5487         return;
5488     }
5489 
5490     VkDeviceMemory memory = VK_NULL_HANDLE;
5491     VkResult result = vk::AllocateMemory(m_device->device(), &memory_info, NULL, &memory);
5492     if ((memory == VK_NULL_HANDLE) || (result != VK_SUCCESS)) {
5493         printf("%s This test failed to allocate memory for importing\n", kSkipPrefix);
5494         return;
5495     }
5496 
5497     if (mem_reqs.alignment > 1) {
5498         m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkBindBufferMemory-memoryOffset-01036");
5499         vk::BindBufferMemory(device(), buffer, memory, 1);
5500         m_errorMonitor->VerifyFound();
5501     }
5502 
5503     VkDeviceSize buffer_offset = (mem_reqs.size - 1) & ~(mem_reqs.alignment - 1);
5504     if (buffer_offset > 0) {
5505         m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkBindBufferMemory-size-01037");
5506         vk::BindBufferMemory(device(), buffer, memory, buffer_offset);
5507         m_errorMonitor->VerifyFound();
5508     }
5509 
5510     vk::DestroyBuffer(m_device->device(), buffer, nullptr);
5511     vk::FreeMemory(m_device->device(), memory, nullptr);
5512 }
5513 
TEST_F(VkLayerTest,AndroidHardwareBufferImportBufferHandleType)5514 TEST_F(VkLayerTest, AndroidHardwareBufferImportBufferHandleType) {
5515     TEST_DESCRIPTION("Don't use proper resource handleType for import buffer");
5516 
5517     ASSERT_NO_FATAL_FAILURE(InitFramework(m_errorMonitor));
5518 
5519     if (IsPlatform(kGalaxyS10)) {
5520         printf("%s This test should not run on Galaxy S10\n", kSkipPrefix);
5521         return;
5522     }
5523 
5524     if ((DeviceExtensionSupported(gpu(), nullptr, VK_ANDROID_EXTERNAL_MEMORY_ANDROID_HARDWARE_BUFFER_EXTENSION_NAME)) &&
5525         // Also skip on devices that advertise AHB, but not the pre-requisite foreign_queue extension
5526         (DeviceExtensionSupported(gpu(), nullptr, VK_EXT_QUEUE_FAMILY_FOREIGN_EXTENSION_NAME))) {
5527         m_device_extension_names.push_back(VK_ANDROID_EXTERNAL_MEMORY_ANDROID_HARDWARE_BUFFER_EXTENSION_NAME);
5528         m_device_extension_names.push_back(VK_KHR_SAMPLER_YCBCR_CONVERSION_EXTENSION_NAME);
5529         m_device_extension_names.push_back(VK_KHR_MAINTENANCE_1_EXTENSION_NAME);
5530         m_device_extension_names.push_back(VK_KHR_BIND_MEMORY_2_EXTENSION_NAME);
5531         m_device_extension_names.push_back(VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME);
5532         m_device_extension_names.push_back(VK_KHR_EXTERNAL_MEMORY_EXTENSION_NAME);
5533         m_device_extension_names.push_back(VK_EXT_QUEUE_FAMILY_FOREIGN_EXTENSION_NAME);
5534         m_device_extension_names.push_back(VK_KHR_DEDICATED_ALLOCATION_EXTENSION_NAME);
5535     } else {
5536         printf("%s %s extension not supported, skipping tests\n", kSkipPrefix,
5537                VK_ANDROID_EXTERNAL_MEMORY_ANDROID_HARDWARE_BUFFER_EXTENSION_NAME);
5538         return;
5539     }
5540 
5541     ASSERT_NO_FATAL_FAILURE(InitState());
5542 
5543     PFN_vkGetAndroidHardwareBufferPropertiesANDROID pfn_GetAHBProps =
5544         (PFN_vkGetAndroidHardwareBufferPropertiesANDROID)vk::GetDeviceProcAddr(m_device->device(),
5545                                                                                "vkGetAndroidHardwareBufferPropertiesANDROID");
5546     PFN_vkBindBufferMemory2KHR vkBindBufferMemory2Function =
5547         (PFN_vkBindBufferMemory2KHR)vk::GetDeviceProcAddr(m_device->handle(), "vkBindBufferMemory2KHR");
5548 
5549     m_errorMonitor->ExpectSuccess();
5550 
5551     AHardwareBuffer *ahb;
5552     AHardwareBuffer_Desc ahb_desc = {};
5553     ahb_desc.format = AHARDWAREBUFFER_FORMAT_BLOB;
5554     ahb_desc.usage = AHARDWAREBUFFER_USAGE_GPU_DATA_BUFFER;
5555     ahb_desc.width = 64;
5556     ahb_desc.height = 1;
5557     ahb_desc.layers = 1;
5558     ahb_desc.stride = 1;
5559     AHardwareBuffer_allocate(&ahb_desc, &ahb);
5560 
5561     // Create buffer without VkExternalMemoryBufferCreateInfo
5562     VkBuffer buffer = VK_NULL_HANDLE;
5563     VkBufferCreateInfo buffer_create_info = LvlInitStruct<VkBufferCreateInfo>();
5564     buffer_create_info.size = 512;
5565     buffer_create_info.usage = VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT;
5566     vk::CreateBuffer(m_device->device(), &buffer_create_info, nullptr, &buffer);
5567 
5568     VkImportAndroidHardwareBufferInfoANDROID import_ahb_Info = LvlInitStruct<VkImportAndroidHardwareBufferInfoANDROID>();
5569     import_ahb_Info.buffer = ahb;
5570 
5571     VkAndroidHardwareBufferPropertiesANDROID ahb_props = LvlInitStruct<VkAndroidHardwareBufferPropertiesANDROID>();
5572     pfn_GetAHBProps(m_device->device(), ahb, &ahb_props);
5573 
5574     VkMemoryAllocateInfo memory_allocate_info = LvlInitStruct<VkMemoryAllocateInfo>(&import_ahb_Info);
5575     memory_allocate_info.allocationSize = ahb_props.allocationSize;
5576     // driver won't expose correct memoryType since resource was not created as an import operation
5577     // so just need any valid memory type returned from GetAHBInfo
5578     for (int i = 0; i < 32; i++) {
5579         if (ahb_props.memoryTypeBits & (1 << i)) {
5580             memory_allocate_info.memoryTypeIndex = i;
5581             break;
5582         }
5583     }
5584 
5585     VkDeviceMemory memory;
5586     vk::AllocateMemory(m_device->device(), &memory_allocate_info, nullptr, &memory);
5587     m_errorMonitor->VerifyNotFound();
5588 
5589     m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkBindBufferMemory-memory-02986");
5590     m_errorMonitor->SetUnexpectedError("VUID-vkBindBufferMemory-memory-01035");
5591     vk::BindBufferMemory(m_device->device(), buffer, memory, 0);
5592     m_errorMonitor->VerifyFound();
5593 
5594     VkBindBufferMemoryInfo bind_buffer_info = LvlInitStruct<VkBindBufferMemoryInfo>();
5595     bind_buffer_info.buffer = buffer;
5596     bind_buffer_info.memory = memory;
5597     bind_buffer_info.memoryOffset = 0;
5598 
5599     m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkBindBufferMemoryInfo-memory-02986");
5600     m_errorMonitor->SetUnexpectedError("VUID-VkBindBufferMemoryInfo-memory-01035");
5601     vkBindBufferMemory2Function(m_device->device(), 1, &bind_buffer_info);
5602     m_errorMonitor->VerifyFound();
5603 
5604     vk::DestroyBuffer(m_device->device(), buffer, nullptr);
5605     vk::FreeMemory(m_device->device(), memory, nullptr);
5606 }
5607 
TEST_F(VkLayerTest,AndroidHardwareBufferImportImageHandleType)5608 TEST_F(VkLayerTest, AndroidHardwareBufferImportImageHandleType) {
5609     TEST_DESCRIPTION("Don't use proper resource handleType for import image");
5610 
5611     ASSERT_NO_FATAL_FAILURE(InitFramework(m_errorMonitor));
5612 
5613     if (IsPlatform(kGalaxyS10)) {
5614         printf("%s This test should not run on Galaxy S10\n", kSkipPrefix);
5615         return;
5616     }
5617 
5618     if ((DeviceExtensionSupported(gpu(), nullptr, VK_ANDROID_EXTERNAL_MEMORY_ANDROID_HARDWARE_BUFFER_EXTENSION_NAME)) &&
5619         // Also skip on devices that advertise AHB, but not the pre-requisite foreign_queue extension
5620         (DeviceExtensionSupported(gpu(), nullptr, VK_EXT_QUEUE_FAMILY_FOREIGN_EXTENSION_NAME))) {
5621         m_device_extension_names.push_back(VK_ANDROID_EXTERNAL_MEMORY_ANDROID_HARDWARE_BUFFER_EXTENSION_NAME);
5622         m_device_extension_names.push_back(VK_KHR_SAMPLER_YCBCR_CONVERSION_EXTENSION_NAME);
5623         m_device_extension_names.push_back(VK_KHR_MAINTENANCE_1_EXTENSION_NAME);
5624         m_device_extension_names.push_back(VK_KHR_BIND_MEMORY_2_EXTENSION_NAME);
5625         m_device_extension_names.push_back(VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME);
5626         m_device_extension_names.push_back(VK_KHR_EXTERNAL_MEMORY_EXTENSION_NAME);
5627         m_device_extension_names.push_back(VK_EXT_QUEUE_FAMILY_FOREIGN_EXTENSION_NAME);
5628         m_device_extension_names.push_back(VK_KHR_DEDICATED_ALLOCATION_EXTENSION_NAME);
5629     } else {
5630         printf("%s %s extension not supported, skipping tests\n", kSkipPrefix,
5631                VK_ANDROID_EXTERNAL_MEMORY_ANDROID_HARDWARE_BUFFER_EXTENSION_NAME);
5632         return;
5633     }
5634 
5635     ASSERT_NO_FATAL_FAILURE(InitState());
5636 
5637     PFN_vkGetAndroidHardwareBufferPropertiesANDROID pfn_GetAHBProps =
5638         (PFN_vkGetAndroidHardwareBufferPropertiesANDROID)vk::GetDeviceProcAddr(m_device->device(),
5639                                                                                "vkGetAndroidHardwareBufferPropertiesANDROID");
5640     PFN_vkBindImageMemory2KHR vkBindImageMemory2Function =
5641         (PFN_vkBindImageMemory2KHR)vk::GetDeviceProcAddr(m_device->handle(), "vkBindImageMemory2KHR");
5642 
5643     m_errorMonitor->ExpectSuccess();
5644 
5645     AHardwareBuffer *ahb;
5646     AHardwareBuffer_Desc ahb_desc = {};
5647     ahb_desc.format = AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM;
5648     ahb_desc.usage = AHARDWAREBUFFER_USAGE_GPU_SAMPLED_IMAGE;
5649     ahb_desc.width = 64;
5650     ahb_desc.height = 64;
5651     ahb_desc.layers = 1;
5652     ahb_desc.stride = 1;
5653     AHardwareBuffer_allocate(&ahb_desc, &ahb);
5654 
5655     // Create buffer without VkExternalMemoryImageCreateInfo
5656     VkImage image = VK_NULL_HANDLE;
5657     VkImageCreateInfo image_create_info = LvlInitStruct<VkImageCreateInfo>();
5658     image_create_info.flags = 0;
5659     image_create_info.imageType = VK_IMAGE_TYPE_2D;
5660     image_create_info.format = VK_FORMAT_R8G8B8A8_UNORM;
5661     image_create_info.extent = {64, 64, 1};
5662     image_create_info.mipLevels = 1;
5663     image_create_info.arrayLayers = 1;
5664     image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
5665     image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL;
5666     image_create_info.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
5667     image_create_info.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
5668     image_create_info.usage = VK_IMAGE_USAGE_SAMPLED_BIT;
5669     vk::CreateImage(m_device->device(), &image_create_info, nullptr, &image);
5670 
5671     VkMemoryDedicatedAllocateInfo memory_dedicated_info = LvlInitStruct<VkMemoryDedicatedAllocateInfo>();
5672     memory_dedicated_info.image = image;
5673     memory_dedicated_info.buffer = VK_NULL_HANDLE;
5674 
5675     VkImportAndroidHardwareBufferInfoANDROID import_ahb_Info =
5676         LvlInitStruct<VkImportAndroidHardwareBufferInfoANDROID>(&memory_dedicated_info);
5677     import_ahb_Info.buffer = ahb;
5678 
5679     VkAndroidHardwareBufferPropertiesANDROID ahb_props = LvlInitStruct<VkAndroidHardwareBufferPropertiesANDROID>();
5680     pfn_GetAHBProps(m_device->device(), ahb, &ahb_props);
5681 
5682     VkMemoryAllocateInfo memory_allocate_info = LvlInitStruct<VkMemoryAllocateInfo>(&import_ahb_Info);
5683     memory_allocate_info.allocationSize = ahb_props.allocationSize;
5684     // driver won't expose correct memoryType since resource was not created as an import operation
5685     // so just need any valid memory type returned from GetAHBInfo
5686     for (int i = 0; i < 32; i++) {
5687         if (ahb_props.memoryTypeBits & (1 << i)) {
5688             memory_allocate_info.memoryTypeIndex = i;
5689             break;
5690         }
5691     }
5692 
5693     VkDeviceMemory memory;
5694     vk::AllocateMemory(m_device->device(), &memory_allocate_info, nullptr, &memory);
5695     m_errorMonitor->VerifyNotFound();
5696 
5697     m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkBindImageMemory-memory-02990");
5698     m_errorMonitor->SetUnexpectedError("VUID-vkBindImageMemory-memory-01047");
5699     m_errorMonitor->SetUnexpectedError("VUID-vkBindImageMemory-size-01049");
5700     vk::BindImageMemory(m_device->device(), image, memory, 0);
5701     m_errorMonitor->VerifyFound();
5702 
5703     VkBindImageMemoryInfo bind_image_info = LvlInitStruct<VkBindImageMemoryInfo>();
5704     bind_image_info.image = image;
5705     bind_image_info.memory = memory;
5706     bind_image_info.memoryOffset = 0;
5707 
5708     m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkBindImageMemoryInfo-memory-02990");
5709     m_errorMonitor->SetUnexpectedError("VUID-VkBindImageMemoryInfo-pNext-01617");
5710     m_errorMonitor->SetUnexpectedError("VUID-VkBindImageMemoryInfo-pNext-01615");
5711     vkBindImageMemory2Function(m_device->device(), 1, &bind_image_info);
5712     m_errorMonitor->VerifyFound();
5713 
5714     vk::DestroyImage(m_device->device(), image, nullptr);
5715     vk::FreeMemory(m_device->device(), memory, nullptr);
5716 }
5717 
5718 #endif  // AHB_VALIDATION_SUPPORT
5719 
TEST_F(VkLayerTest,ValidateStride)5720 TEST_F(VkLayerTest, ValidateStride) {
5721     TEST_DESCRIPTION("Validate Stride.");
5722     ASSERT_NO_FATAL_FAILURE(Init(nullptr, nullptr, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT));
5723     if (IsPlatform(kPixelC)) {
5724         printf("%s This test should not run on Pixel C\n", kSkipPrefix);
5725         return;
5726     }
5727     ASSERT_NO_FATAL_FAILURE(InitViewport());
5728     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
5729 
5730     VkQueryPool query_pool;
5731     VkQueryPoolCreateInfo query_pool_ci{};
5732     query_pool_ci.sType = VK_STRUCTURE_TYPE_QUERY_POOL_CREATE_INFO;
5733     query_pool_ci.queryType = VK_QUERY_TYPE_TIMESTAMP;
5734     query_pool_ci.queryCount = 1;
5735     vk::CreateQueryPool(m_device->device(), &query_pool_ci, nullptr, &query_pool);
5736 
5737     m_commandBuffer->begin();
5738     vk::CmdResetQueryPool(m_commandBuffer->handle(), query_pool, 0, 1);
5739     vk::CmdWriteTimestamp(m_commandBuffer->handle(), VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, query_pool, 0);
5740     m_commandBuffer->end();
5741 
5742     VkSubmitInfo submit_info = {};
5743     submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
5744     submit_info.commandBufferCount = 1;
5745     submit_info.pCommandBuffers = &m_commandBuffer->handle();
5746     vk::QueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
5747     vk::QueueWaitIdle(m_device->m_queue);
5748 
5749     char data_space;
5750     m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkGetQueryPoolResults-flags-02827");
5751     vk::GetQueryPoolResults(m_device->handle(), query_pool, 0, 1, sizeof(data_space), &data_space, 1, VK_QUERY_RESULT_WAIT_BIT);
5752     m_errorMonitor->VerifyFound();
5753 
5754     m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkGetQueryPoolResults-flags-00815");
5755     vk::GetQueryPoolResults(m_device->handle(), query_pool, 0, 1, sizeof(data_space), &data_space, 1,
5756                             (VK_QUERY_RESULT_WAIT_BIT | VK_QUERY_RESULT_64_BIT));
5757     m_errorMonitor->VerifyFound();
5758 
5759     char data_space4[4] = "";
5760     m_errorMonitor->ExpectSuccess();
5761     vk::GetQueryPoolResults(m_device->handle(), query_pool, 0, 1, sizeof(data_space4), &data_space4, 4, VK_QUERY_RESULT_WAIT_BIT);
5762     m_errorMonitor->VerifyNotFound();
5763 
5764     char data_space8[8] = "";
5765     m_errorMonitor->ExpectSuccess();
5766     vk::GetQueryPoolResults(m_device->handle(), query_pool, 0, 1, sizeof(data_space8), &data_space8, 8,
5767                             (VK_QUERY_RESULT_WAIT_BIT | VK_QUERY_RESULT_64_BIT));
5768     m_errorMonitor->VerifyNotFound();
5769 
5770     uint32_t qfi = 0;
5771     VkBufferCreateInfo buff_create_info = {};
5772     buff_create_info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
5773     buff_create_info.size = 128;
5774     buff_create_info.usage =
5775         VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT | VK_BUFFER_USAGE_INDEX_BUFFER_BIT;
5776     buff_create_info.queueFamilyIndexCount = 1;
5777     buff_create_info.pQueueFamilyIndices = &qfi;
5778     VkBufferObj buffer;
5779     buffer.init(*m_device, buff_create_info);
5780 
5781     m_commandBuffer->reset();
5782     m_commandBuffer->begin();
5783     m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdCopyQueryPoolResults-flags-00822");
5784     vk::CmdCopyQueryPoolResults(m_commandBuffer->handle(), query_pool, 0, 1, buffer.handle(), 1, 1, 0);
5785     m_errorMonitor->VerifyFound();
5786 
5787     m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdCopyQueryPoolResults-flags-00823");
5788     vk::CmdCopyQueryPoolResults(m_commandBuffer->handle(), query_pool, 0, 1, buffer.handle(), 1, 1, VK_QUERY_RESULT_64_BIT);
5789     m_errorMonitor->VerifyFound();
5790 
5791     m_errorMonitor->ExpectSuccess();
5792     vk::CmdCopyQueryPoolResults(m_commandBuffer->handle(), query_pool, 0, 1, buffer.handle(), 4, 4, 0);
5793     m_errorMonitor->VerifyNotFound();
5794 
5795     m_errorMonitor->ExpectSuccess();
5796     vk::CmdCopyQueryPoolResults(m_commandBuffer->handle(), query_pool, 0, 1, buffer.handle(), 8, 8, VK_QUERY_RESULT_64_BIT);
5797     m_errorMonitor->VerifyNotFound();
5798 
5799     if (m_device->phy().features().multiDrawIndirect) {
5800         auto buffer_memory_barrier = buffer.buffer_memory_barrier(
5801             VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_INDIRECT_COMMAND_READ_BIT | VK_ACCESS_INDEX_READ_BIT, 0, VK_WHOLE_SIZE);
5802         m_commandBuffer->PipelineBarrier(VK_PIPELINE_STAGE_TRANSFER_BIT,
5803                                          VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT | VK_PIPELINE_STAGE_VERTEX_INPUT_BIT, 0, 0, nullptr, 1,
5804                                          &buffer_memory_barrier, 0, nullptr);
5805 
5806         CreatePipelineHelper helper(*this);
5807         helper.InitInfo();
5808         helper.InitState();
5809         helper.CreateGraphicsPipeline();
5810         m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
5811         vk::CmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, helper.pipeline_);
5812 
5813         m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdDrawIndirect-drawCount-00476");
5814         m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdDrawIndirect-drawCount-00488");
5815         vk::CmdDrawIndirect(m_commandBuffer->handle(), buffer.handle(), 0, 100, 2);
5816         m_errorMonitor->VerifyFound();
5817 
5818         m_errorMonitor->ExpectSuccess();
5819         vk::CmdDrawIndirect(m_commandBuffer->handle(), buffer.handle(), 0, 2, 24);
5820         m_errorMonitor->VerifyNotFound();
5821 
5822         vk::CmdBindIndexBuffer(m_commandBuffer->handle(), buffer.handle(), 0, VK_INDEX_TYPE_UINT16);
5823         m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdDrawIndexedIndirect-drawCount-00528");
5824         m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdDrawIndexedIndirect-drawCount-00540");
5825         vk::CmdDrawIndexedIndirect(m_commandBuffer->handle(), buffer.handle(), 0, 100, 2);
5826         m_errorMonitor->VerifyFound();
5827 
5828         auto draw_count = m_device->phy().properties().limits.maxDrawIndirectCount;
5829         if (draw_count != UINT32_MAX) {
5830             m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdDrawIndirect-drawCount-02719");
5831             vk::CmdDrawIndirect(m_commandBuffer->handle(), buffer.handle(), 0, draw_count + 1, 2);
5832             m_errorMonitor->VerifyFound();
5833         }
5834 
5835         m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdDrawIndirect-drawCount-00487");
5836         vk::CmdDrawIndirect(m_commandBuffer->handle(), buffer.handle(), buff_create_info.size, 1, 2);
5837         m_errorMonitor->VerifyFound();
5838 
5839         m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdDrawIndexedIndirect-drawCount-00539");
5840         vk::CmdDrawIndexedIndirect(m_commandBuffer->handle(), buffer.handle(), buff_create_info.size, 1, 2);
5841         m_errorMonitor->VerifyFound();
5842 
5843         m_errorMonitor->ExpectSuccess();
5844         vk::CmdDrawIndexedIndirect(m_commandBuffer->handle(), buffer.handle(), 0, 2, 24);
5845         m_errorMonitor->VerifyNotFound();
5846 
5847         vk::CmdEndRenderPass(m_commandBuffer->handle());
5848         m_commandBuffer->end();
5849 
5850     } else {
5851         printf("%s Test requires unsupported multiDrawIndirect feature. Skipped.\n", kSkipPrefix);
5852     }
5853     vk::DestroyQueryPool(m_device->handle(), query_pool, NULL);
5854 }
5855 
TEST_F(VkLayerTest,ValidateGeometryNV)5856 TEST_F(VkLayerTest, ValidateGeometryNV) {
5857     TEST_DESCRIPTION("Validate acceleration structure geometries.");
5858     if (!InitFrameworkForRayTracingTest(this, false, m_instance_extension_names, m_device_extension_names, m_errorMonitor)) {
5859         return;
5860     }
5861 
5862     VkBufferObj vbo;
5863     vbo.init(*m_device, 1024, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT,
5864              VK_BUFFER_USAGE_RAY_TRACING_BIT_NV);
5865 
5866     VkBufferObj ibo;
5867     ibo.init(*m_device, 1024, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT,
5868              VK_BUFFER_USAGE_RAY_TRACING_BIT_NV);
5869 
5870     VkBufferObj tbo;
5871     tbo.init(*m_device, 1024, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT,
5872              VK_BUFFER_USAGE_RAY_TRACING_BIT_NV);
5873 
5874     VkBufferObj aabbbo;
5875     aabbbo.init(*m_device, 1024, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT,
5876                 VK_BUFFER_USAGE_RAY_TRACING_BIT_NV);
5877 
5878     VkBufferCreateInfo unbound_buffer_ci = {};
5879     unbound_buffer_ci.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
5880     unbound_buffer_ci.size = 1024;
5881     unbound_buffer_ci.usage = VK_BUFFER_USAGE_RAY_TRACING_BIT_NV;
5882     VkBufferObj unbound_buffer;
5883     unbound_buffer.init_no_mem(*m_device, unbound_buffer_ci);
5884 
5885     const std::vector<float> vertices = {1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, -1.0f, 0.0f, 0.0f};
5886     const std::vector<uint32_t> indicies = {0, 1, 2};
5887     const std::vector<float> aabbs = {0.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f};
5888     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};
5889 
5890     uint8_t *mapped_vbo_buffer_data = (uint8_t *)vbo.memory().map();
5891     std::memcpy(mapped_vbo_buffer_data, (uint8_t *)vertices.data(), sizeof(float) * vertices.size());
5892     vbo.memory().unmap();
5893 
5894     uint8_t *mapped_ibo_buffer_data = (uint8_t *)ibo.memory().map();
5895     std::memcpy(mapped_ibo_buffer_data, (uint8_t *)indicies.data(), sizeof(uint32_t) * indicies.size());
5896     ibo.memory().unmap();
5897 
5898     uint8_t *mapped_tbo_buffer_data = (uint8_t *)tbo.memory().map();
5899     std::memcpy(mapped_tbo_buffer_data, (uint8_t *)transforms.data(), sizeof(float) * transforms.size());
5900     tbo.memory().unmap();
5901 
5902     uint8_t *mapped_aabbbo_buffer_data = (uint8_t *)aabbbo.memory().map();
5903     std::memcpy(mapped_aabbbo_buffer_data, (uint8_t *)aabbs.data(), sizeof(float) * aabbs.size());
5904     aabbbo.memory().unmap();
5905 
5906     VkGeometryNV valid_geometry_triangles = {};
5907     valid_geometry_triangles.sType = VK_STRUCTURE_TYPE_GEOMETRY_NV;
5908     valid_geometry_triangles.geometryType = VK_GEOMETRY_TYPE_TRIANGLES_NV;
5909     valid_geometry_triangles.geometry.triangles.sType = VK_STRUCTURE_TYPE_GEOMETRY_TRIANGLES_NV;
5910     valid_geometry_triangles.geometry.triangles.vertexData = vbo.handle();
5911     valid_geometry_triangles.geometry.triangles.vertexOffset = 0;
5912     valid_geometry_triangles.geometry.triangles.vertexCount = 3;
5913     valid_geometry_triangles.geometry.triangles.vertexStride = 12;
5914     valid_geometry_triangles.geometry.triangles.vertexFormat = VK_FORMAT_R32G32B32_SFLOAT;
5915     valid_geometry_triangles.geometry.triangles.indexData = ibo.handle();
5916     valid_geometry_triangles.geometry.triangles.indexOffset = 0;
5917     valid_geometry_triangles.geometry.triangles.indexCount = 3;
5918     valid_geometry_triangles.geometry.triangles.indexType = VK_INDEX_TYPE_UINT32;
5919     valid_geometry_triangles.geometry.triangles.transformData = tbo.handle();
5920     valid_geometry_triangles.geometry.triangles.transformOffset = 0;
5921     valid_geometry_triangles.geometry.aabbs = {};
5922     valid_geometry_triangles.geometry.aabbs.sType = VK_STRUCTURE_TYPE_GEOMETRY_AABB_NV;
5923 
5924     VkGeometryNV valid_geometry_aabbs = {};
5925     valid_geometry_aabbs.sType = VK_STRUCTURE_TYPE_GEOMETRY_NV;
5926     valid_geometry_aabbs.geometryType = VK_GEOMETRY_TYPE_AABBS_NV;
5927     valid_geometry_aabbs.geometry.triangles = {};
5928     valid_geometry_aabbs.geometry.triangles.sType = VK_STRUCTURE_TYPE_GEOMETRY_TRIANGLES_NV;
5929     valid_geometry_aabbs.geometry.aabbs = {};
5930     valid_geometry_aabbs.geometry.aabbs.sType = VK_STRUCTURE_TYPE_GEOMETRY_AABB_NV;
5931     valid_geometry_aabbs.geometry.aabbs.aabbData = aabbbo.handle();
5932     valid_geometry_aabbs.geometry.aabbs.numAABBs = 1;
5933     valid_geometry_aabbs.geometry.aabbs.offset = 0;
5934     valid_geometry_aabbs.geometry.aabbs.stride = 24;
5935 
5936     PFN_vkCreateAccelerationStructureNV vkCreateAccelerationStructureNV = reinterpret_cast<PFN_vkCreateAccelerationStructureNV>(
5937         vk::GetDeviceProcAddr(m_device->handle(), "vkCreateAccelerationStructureNV"));
5938     assert(vkCreateAccelerationStructureNV != nullptr);
5939 
5940     const auto GetCreateInfo = [](const VkGeometryNV &geometry) {
5941         VkAccelerationStructureCreateInfoNV as_create_info = {};
5942         as_create_info.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_CREATE_INFO_NV;
5943         as_create_info.info.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_INFO_NV;
5944         as_create_info.info.type = VK_ACCELERATION_STRUCTURE_TYPE_BOTTOM_LEVEL_NV;
5945         as_create_info.info.instanceCount = 0;
5946         as_create_info.info.geometryCount = 1;
5947         as_create_info.info.pGeometries = &geometry;
5948         return as_create_info;
5949     };
5950 
5951     VkAccelerationStructureNV as;
5952 
5953     // Invalid vertex format.
5954     {
5955         VkGeometryNV geometry = valid_geometry_triangles;
5956         geometry.geometry.triangles.vertexFormat = VK_FORMAT_R64_UINT;
5957 
5958         VkAccelerationStructureCreateInfoNV as_create_info = GetCreateInfo(geometry);
5959         m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkGeometryTrianglesNV-vertexFormat-02430");
5960         vkCreateAccelerationStructureNV(m_device->handle(), &as_create_info, nullptr, &as);
5961         m_errorMonitor->VerifyFound();
5962     }
5963     // Invalid vertex offset - not multiple of component size.
5964     {
5965         VkGeometryNV geometry = valid_geometry_triangles;
5966         geometry.geometry.triangles.vertexOffset = 1;
5967 
5968         VkAccelerationStructureCreateInfoNV as_create_info = GetCreateInfo(geometry);
5969         m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkGeometryTrianglesNV-vertexOffset-02429");
5970         vkCreateAccelerationStructureNV(m_device->handle(), &as_create_info, nullptr, &as);
5971         m_errorMonitor->VerifyFound();
5972     }
5973     // Invalid vertex offset - bigger than buffer.
5974     {
5975         VkGeometryNV geometry = valid_geometry_triangles;
5976         geometry.geometry.triangles.vertexOffset = 12 * 1024;
5977 
5978         VkAccelerationStructureCreateInfoNV as_create_info = GetCreateInfo(geometry);
5979         m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkGeometryTrianglesNV-vertexOffset-02428");
5980         vkCreateAccelerationStructureNV(m_device->handle(), &as_create_info, nullptr, &as);
5981         m_errorMonitor->VerifyFound();
5982     }
5983     // Invalid vertex buffer - no such buffer.
5984     {
5985         VkGeometryNV geometry = valid_geometry_triangles;
5986         geometry.geometry.triangles.vertexData = VkBuffer(123456789);
5987 
5988         VkAccelerationStructureCreateInfoNV as_create_info = GetCreateInfo(geometry);
5989         m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkGeometryTrianglesNV-vertexData-parameter");
5990         vkCreateAccelerationStructureNV(m_device->handle(), &as_create_info, nullptr, &as);
5991         m_errorMonitor->VerifyFound();
5992     }
5993 #if 0
5994     // XXX Subtest disabled because this is the wrong VUID.
5995     // No VUIDs currently exist to require memory is bound (spec bug).
5996     // Invalid vertex buffer - no memory bound.
5997     {
5998         VkGeometryNV geometry = valid_geometry_triangles;
5999         geometry.geometry.triangles.vertexData = unbound_buffer.handle();
6000 
6001         VkAccelerationStructureCreateInfoNV as_create_info = GetCreateInfo(geometry);
6002         m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkGeometryTrianglesNV-vertexOffset-02428");
6003         vkCreateAccelerationStructureNV(m_device->handle(), &as_create_info, nullptr, &as);
6004         m_errorMonitor->VerifyFound();
6005     }
6006 #endif
6007 
6008     // Invalid index offset - not multiple of index size.
6009     {
6010         VkGeometryNV geometry = valid_geometry_triangles;
6011         geometry.geometry.triangles.indexOffset = 1;
6012 
6013         VkAccelerationStructureCreateInfoNV as_create_info = GetCreateInfo(geometry);
6014         m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkGeometryTrianglesNV-indexOffset-02432");
6015         vkCreateAccelerationStructureNV(m_device->handle(), &as_create_info, nullptr, &as);
6016         m_errorMonitor->VerifyFound();
6017     }
6018     // Invalid index offset - bigger than buffer.
6019     {
6020         VkGeometryNV geometry = valid_geometry_triangles;
6021         geometry.geometry.triangles.indexOffset = 2048;
6022 
6023         VkAccelerationStructureCreateInfoNV as_create_info = GetCreateInfo(geometry);
6024         m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkGeometryTrianglesNV-indexOffset-02431");
6025         vkCreateAccelerationStructureNV(m_device->handle(), &as_create_info, nullptr, &as);
6026         m_errorMonitor->VerifyFound();
6027     }
6028     // Invalid index count - must be 0 if type is VK_INDEX_TYPE_NONE_NV.
6029     {
6030         VkGeometryNV geometry = valid_geometry_triangles;
6031         geometry.geometry.triangles.indexType = VK_INDEX_TYPE_NONE_NV;
6032         geometry.geometry.triangles.indexData = VK_NULL_HANDLE;
6033         geometry.geometry.triangles.indexCount = 1;
6034 
6035         VkAccelerationStructureCreateInfoNV as_create_info = GetCreateInfo(geometry);
6036         m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkGeometryTrianglesNV-indexCount-02436");
6037         vkCreateAccelerationStructureNV(m_device->handle(), &as_create_info, nullptr, &as);
6038         m_errorMonitor->VerifyFound();
6039     }
6040     // Invalid index data - must be VK_NULL_HANDLE if type is VK_INDEX_TYPE_NONE_NV.
6041     {
6042         VkGeometryNV geometry = valid_geometry_triangles;
6043         geometry.geometry.triangles.indexType = VK_INDEX_TYPE_NONE_NV;
6044         geometry.geometry.triangles.indexData = ibo.handle();
6045         geometry.geometry.triangles.indexCount = 0;
6046 
6047         VkAccelerationStructureCreateInfoNV as_create_info = GetCreateInfo(geometry);
6048         m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkGeometryTrianglesNV-indexData-02434");
6049         vkCreateAccelerationStructureNV(m_device->handle(), &as_create_info, nullptr, &as);
6050         m_errorMonitor->VerifyFound();
6051     }
6052 
6053     // Invalid transform offset - not multiple of 16.
6054     {
6055         VkGeometryNV geometry = valid_geometry_triangles;
6056         geometry.geometry.triangles.transformOffset = 1;
6057 
6058         VkAccelerationStructureCreateInfoNV as_create_info = GetCreateInfo(geometry);
6059         m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkGeometryTrianglesNV-transformOffset-02438");
6060         vkCreateAccelerationStructureNV(m_device->handle(), &as_create_info, nullptr, &as);
6061         m_errorMonitor->VerifyFound();
6062     }
6063     // Invalid transform offset - bigger than buffer.
6064     {
6065         VkGeometryNV geometry = valid_geometry_triangles;
6066         geometry.geometry.triangles.transformOffset = 2048;
6067 
6068         VkAccelerationStructureCreateInfoNV as_create_info = GetCreateInfo(geometry);
6069         m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkGeometryTrianglesNV-transformOffset-02437");
6070         vkCreateAccelerationStructureNV(m_device->handle(), &as_create_info, nullptr, &as);
6071         m_errorMonitor->VerifyFound();
6072     }
6073 
6074     // Invalid aabb offset - not multiple of 8.
6075     {
6076         VkGeometryNV geometry = valid_geometry_aabbs;
6077         geometry.geometry.aabbs.offset = 1;
6078 
6079         VkAccelerationStructureCreateInfoNV as_create_info = GetCreateInfo(geometry);
6080         m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkGeometryAABBNV-offset-02440");
6081         vkCreateAccelerationStructureNV(m_device->handle(), &as_create_info, nullptr, &as);
6082         m_errorMonitor->VerifyFound();
6083     }
6084     // Invalid aabb offset - bigger than buffer.
6085     {
6086         VkGeometryNV geometry = valid_geometry_aabbs;
6087         geometry.geometry.aabbs.offset = 8 * 1024;
6088 
6089         VkAccelerationStructureCreateInfoNV as_create_info = GetCreateInfo(geometry);
6090         m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkGeometryAABBNV-offset-02439");
6091         vkCreateAccelerationStructureNV(m_device->handle(), &as_create_info, nullptr, &as);
6092         m_errorMonitor->VerifyFound();
6093     }
6094     // Invalid aabb stride - not multiple of 8.
6095     {
6096         VkGeometryNV geometry = valid_geometry_aabbs;
6097         geometry.geometry.aabbs.stride = 1;
6098 
6099         VkAccelerationStructureCreateInfoNV as_create_info = GetCreateInfo(geometry);
6100         m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkGeometryAABBNV-stride-02441");
6101         vkCreateAccelerationStructureNV(m_device->handle(), &as_create_info, nullptr, &as);
6102         m_errorMonitor->VerifyFound();
6103     }
6104 
6105     // geometryType must be VK_GEOMETRY_TYPE_TRIANGLES_NV or VK_GEOMETRY_TYPE_AABBS_NV
6106     {
6107         VkGeometryNV geometry = valid_geometry_aabbs;
6108         geometry.geometry.aabbs.stride = 1;
6109         geometry.geometryType = VK_GEOMETRY_TYPE_INSTANCES_KHR;
6110 
6111         VkAccelerationStructureCreateInfoNV as_create_info = GetCreateInfo(geometry);
6112         m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkGeometryNV-geometryType-03503");
6113         m_errorMonitor->SetUnexpectedError("VUID-VkGeometryNV-geometryType-parameter");
6114         vkCreateAccelerationStructureNV(m_device->handle(), &as_create_info, nullptr, &as);
6115         m_errorMonitor->VerifyFound();
6116     }
6117 }
6118 
TEST_F(VkLayerTest,ValidateCreateAccelerationStructureNV)6119 TEST_F(VkLayerTest, ValidateCreateAccelerationStructureNV) {
6120     TEST_DESCRIPTION("Validate acceleration structure creation.");
6121     if (!InitFrameworkForRayTracingTest(this, false, m_instance_extension_names, m_device_extension_names, m_errorMonitor)) {
6122         return;
6123     }
6124 
6125     PFN_vkCreateAccelerationStructureNV vkCreateAccelerationStructureNV = reinterpret_cast<PFN_vkCreateAccelerationStructureNV>(
6126         vk::GetDeviceProcAddr(m_device->handle(), "vkCreateAccelerationStructureNV"));
6127     assert(vkCreateAccelerationStructureNV != nullptr);
6128 
6129     VkBufferObj vbo;
6130     VkBufferObj ibo;
6131     VkGeometryNV geometry;
6132     GetSimpleGeometryForAccelerationStructureTests(*m_device, &vbo, &ibo, &geometry);
6133 
6134     VkAccelerationStructureCreateInfoNV as_create_info = {};
6135     as_create_info.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_CREATE_INFO_NV;
6136     as_create_info.info.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_INFO_NV;
6137 
6138     VkAccelerationStructureNV as = VK_NULL_HANDLE;
6139 
6140     // Top level can not have geometry
6141     {
6142         VkAccelerationStructureCreateInfoNV bad_top_level_create_info = as_create_info;
6143         bad_top_level_create_info.info.type = VK_ACCELERATION_STRUCTURE_TYPE_TOP_LEVEL_NV;
6144         bad_top_level_create_info.info.instanceCount = 0;
6145         bad_top_level_create_info.info.geometryCount = 1;
6146         bad_top_level_create_info.info.pGeometries = &geometry;
6147         m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkAccelerationStructureInfoNV-type-02425");
6148         vkCreateAccelerationStructureNV(m_device->handle(), &bad_top_level_create_info, nullptr, &as);
6149         m_errorMonitor->VerifyFound();
6150     }
6151 
6152     // Bot level can not have instances
6153     {
6154         VkAccelerationStructureCreateInfoNV bad_bot_level_create_info = as_create_info;
6155         bad_bot_level_create_info.info.type = VK_ACCELERATION_STRUCTURE_TYPE_BOTTOM_LEVEL_NV;
6156         bad_bot_level_create_info.info.instanceCount = 1;
6157         bad_bot_level_create_info.info.geometryCount = 0;
6158         bad_bot_level_create_info.info.pGeometries = nullptr;
6159         m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkAccelerationStructureInfoNV-type-02426");
6160         vkCreateAccelerationStructureNV(m_device->handle(), &bad_bot_level_create_info, nullptr, &as);
6161         m_errorMonitor->VerifyFound();
6162     }
6163 
6164     // Type must not be VK_ACCELERATION_STRUCTURE_TYPE_GENERIC_KHR
6165     {
6166         VkAccelerationStructureCreateInfoNV bad_bot_level_create_info = as_create_info;
6167         bad_bot_level_create_info.info.type = VK_ACCELERATION_STRUCTURE_TYPE_GENERIC_KHR;
6168         bad_bot_level_create_info.info.instanceCount = 0;
6169         bad_bot_level_create_info.info.geometryCount = 0;
6170         bad_bot_level_create_info.info.pGeometries = nullptr;
6171         m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkAccelerationStructureInfoNV-type-04623");
6172         vkCreateAccelerationStructureNV(m_device->handle(), &bad_bot_level_create_info, nullptr, &as);
6173         m_errorMonitor->VerifyFound();
6174     }
6175 
6176     // Can not prefer both fast trace and fast build
6177     {
6178         VkAccelerationStructureCreateInfoNV bad_flags_level_create_info = as_create_info;
6179         bad_flags_level_create_info.info.type = VK_ACCELERATION_STRUCTURE_TYPE_BOTTOM_LEVEL_NV;
6180         bad_flags_level_create_info.info.instanceCount = 0;
6181         bad_flags_level_create_info.info.geometryCount = 1;
6182         bad_flags_level_create_info.info.pGeometries = &geometry;
6183         bad_flags_level_create_info.info.flags =
6184             VK_BUILD_ACCELERATION_STRUCTURE_PREFER_FAST_TRACE_BIT_NV | VK_BUILD_ACCELERATION_STRUCTURE_PREFER_FAST_BUILD_BIT_NV;
6185         m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkAccelerationStructureInfoNV-flags-02592");
6186         vkCreateAccelerationStructureNV(m_device->handle(), &bad_flags_level_create_info, nullptr, &as);
6187         m_errorMonitor->VerifyFound();
6188     }
6189 
6190     // Can not have geometry or instance for compacting
6191     {
6192         VkAccelerationStructureCreateInfoNV bad_compacting_as_create_info = as_create_info;
6193         bad_compacting_as_create_info.info.type = VK_ACCELERATION_STRUCTURE_TYPE_BOTTOM_LEVEL_NV;
6194         bad_compacting_as_create_info.info.instanceCount = 0;
6195         bad_compacting_as_create_info.info.geometryCount = 1;
6196         bad_compacting_as_create_info.info.pGeometries = &geometry;
6197         bad_compacting_as_create_info.info.flags = 0;
6198         bad_compacting_as_create_info.compactedSize = 1024;
6199         m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkAccelerationStructureCreateInfoNV-compactedSize-02421");
6200         vkCreateAccelerationStructureNV(m_device->handle(), &bad_compacting_as_create_info, nullptr, &as);
6201         m_errorMonitor->VerifyFound();
6202     }
6203 
6204     // Can not mix different geometry types into single bottom level acceleration structure
6205     {
6206         VkGeometryNV aabb_geometry = {};
6207         aabb_geometry.sType = VK_STRUCTURE_TYPE_GEOMETRY_NV;
6208         aabb_geometry.geometryType = VK_GEOMETRY_TYPE_AABBS_NV;
6209         aabb_geometry.geometry.triangles.sType = VK_STRUCTURE_TYPE_GEOMETRY_TRIANGLES_NV;
6210         aabb_geometry.geometry.aabbs = {};
6211         aabb_geometry.geometry.aabbs.sType = VK_STRUCTURE_TYPE_GEOMETRY_AABB_NV;
6212         // Buffer contents do not matter for this test.
6213         aabb_geometry.geometry.aabbs.aabbData = geometry.geometry.triangles.vertexData;
6214         aabb_geometry.geometry.aabbs.numAABBs = 1;
6215         aabb_geometry.geometry.aabbs.offset = 0;
6216         aabb_geometry.geometry.aabbs.stride = 24;
6217 
6218         std::vector<VkGeometryNV> geometries = {geometry, aabb_geometry};
6219 
6220         VkAccelerationStructureCreateInfoNV mix_geometry_types_as_create_info = as_create_info;
6221         mix_geometry_types_as_create_info.info.type = VK_ACCELERATION_STRUCTURE_TYPE_BOTTOM_LEVEL_NV;
6222         mix_geometry_types_as_create_info.info.instanceCount = 0;
6223         mix_geometry_types_as_create_info.info.geometryCount = static_cast<uint32_t>(geometries.size());
6224         mix_geometry_types_as_create_info.info.pGeometries = geometries.data();
6225         mix_geometry_types_as_create_info.info.flags = 0;
6226 
6227         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkAccelerationStructureInfoNV-type-02786");
6228         vkCreateAccelerationStructureNV(m_device->handle(), &mix_geometry_types_as_create_info, nullptr, &as);
6229         m_errorMonitor->VerifyFound();
6230     }
6231 }
6232 
TEST_F(VkLayerTest,ValidateCreateAccelerationStructureKHR)6233 TEST_F(VkLayerTest, ValidateCreateAccelerationStructureKHR) {
6234     TEST_DESCRIPTION("Validate acceleration structure creation.");
6235     if (!InitFrameworkForRayTracingTest(this, true, m_instance_extension_names, m_device_extension_names, m_errorMonitor, false,
6236                                         false, true)) {
6237         return;
6238     }
6239 
6240     PFN_vkGetPhysicalDeviceFeatures2KHR vkGetPhysicalDeviceFeatures2KHR =
6241         (PFN_vkGetPhysicalDeviceFeatures2KHR)vk::GetInstanceProcAddr(instance(), "vkGetPhysicalDeviceFeatures2KHR");
6242     VkPhysicalDeviceFeatures2KHR features2 = {};
6243     auto ray_tracing_features = LvlInitStruct<VkPhysicalDeviceRayTracingPipelineFeaturesKHR>();
6244     auto ray_query_features = LvlInitStruct<VkPhysicalDeviceRayQueryFeaturesKHR>(&ray_tracing_features);
6245     auto acc_struct_features = LvlInitStruct<VkPhysicalDeviceAccelerationStructureFeaturesKHR>(&ray_query_features);
6246     features2 = LvlInitStruct<VkPhysicalDeviceFeatures2KHR>(&acc_struct_features);
6247     vkGetPhysicalDeviceFeatures2KHR(gpu(), &features2);
6248     if (ray_query_features.rayQuery == VK_FALSE && ray_tracing_features.rayTracingPipeline == VK_FALSE) {
6249         printf("%s Both of the required features rayQuery and rayTracing are not supported, skipping test\n", kSkipPrefix);
6250         return;
6251     }
6252     ASSERT_NO_FATAL_FAILURE(InitState(nullptr, &acc_struct_features));
6253     PFN_vkCreateAccelerationStructureKHR vkCreateAccelerationStructureKHR = reinterpret_cast<PFN_vkCreateAccelerationStructureKHR>(
6254         vk::GetDeviceProcAddr(m_device->handle(), "vkCreateAccelerationStructureKHR"));
6255     assert(vkCreateAccelerationStructureKHR != nullptr);
6256 
6257     VkAccelerationStructureKHR as;
6258     VkAccelerationStructureCreateInfoKHR as_create_info = {};
6259     VkBufferObj buffer;
6260     buffer.init(*m_device, 4096, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, VK_BUFFER_USAGE_ACCELERATION_STRUCTURE_STORAGE_BIT_KHR);
6261     as_create_info.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_CREATE_INFO_KHR;
6262     as_create_info.pNext = NULL;
6263     as_create_info.buffer = buffer.handle();
6264     as_create_info.createFlags = 0;
6265     as_create_info.offset = 0;
6266     as_create_info.size = 0;
6267     as_create_info.type = VK_ACCELERATION_STRUCTURE_TYPE_BOTTOM_LEVEL_KHR;
6268     as_create_info.deviceAddress = 0;
6269     PFN_vkGetBufferDeviceAddressKHR vkGetBufferDeviceAddressKHR =
6270         (PFN_vkGetBufferDeviceAddressKHR)vk::GetDeviceProcAddr(device(), "vkGetBufferDeviceAddressKHR");
6271 
6272     VkBufferDeviceAddressInfo device_address_info = {VK_STRUCTURE_TYPE_BUFFER_DEVICE_ADDRESS_INFO, NULL, buffer.handle()};
6273     VkDeviceAddress device_address = vkGetBufferDeviceAddressKHR(m_device->handle(), &device_address_info);
6274     // invalid buffer;
6275     {
6276         VkBufferObj invalid_buffer;
6277         invalid_buffer.init(*m_device, 4096, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, VK_BUFFER_USAGE_SHADER_BINDING_TABLE_BIT_KHR);
6278         VkAccelerationStructureCreateInfoKHR invalid_as_create_info = as_create_info;
6279         invalid_as_create_info.buffer = invalid_buffer.handle();
6280         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
6281                                              "VUID-VkAccelerationStructureCreateInfoKHR-buffer-03614");
6282         vkCreateAccelerationStructureKHR(m_device->handle(), &invalid_as_create_info, nullptr, &as);
6283         m_errorMonitor->VerifyFound();
6284     }
6285 
6286     // invalid deviceAddress and flag;
6287     {
6288         VkAccelerationStructureCreateInfoKHR invalid_as_create_info = as_create_info;
6289         invalid_as_create_info.deviceAddress = device_address;
6290         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
6291                                              "VUID-VkAccelerationStructureCreateInfoKHR-deviceAddress-03612");
6292         vkCreateAccelerationStructureKHR(m_device->handle(), &invalid_as_create_info, nullptr, &as);
6293         m_errorMonitor->VerifyFound();
6294 
6295         invalid_as_create_info.deviceAddress = 0;
6296         invalid_as_create_info.createFlags = VK_ACCELERATION_STRUCTURE_CREATE_FLAG_BITS_MAX_ENUM_KHR;
6297         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
6298                                              "VUID-VkAccelerationStructureCreateInfoKHR-createFlags-parameter");
6299         vkCreateAccelerationStructureKHR(m_device->handle(), &invalid_as_create_info, nullptr, &as);
6300         m_errorMonitor->VerifyFound();
6301     }
6302 
6303     // invalid size and offset;
6304     {
6305         VkAccelerationStructureCreateInfoKHR invalid_as_create_info = as_create_info;
6306         invalid_as_create_info.size = 4097;  // buffer size is 4096
6307         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
6308                                              "VUID-VkAccelerationStructureCreateInfoKHR-offset-03616");
6309         vkCreateAccelerationStructureKHR(m_device->handle(), &invalid_as_create_info, nullptr, &as);
6310         m_errorMonitor->VerifyFound();
6311     }
6312 
6313     // invalid sType;
6314     {
6315         VkAccelerationStructureCreateInfoKHR invalid_as_create_info = as_create_info;
6316         invalid_as_create_info.sType = VK_STRUCTURE_TYPE_MAX_ENUM;
6317         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
6318                                              "VUID-VkAccelerationStructureCreateInfoKHR-sType-sType");
6319         vkCreateAccelerationStructureKHR(m_device->handle(), &invalid_as_create_info, nullptr, &as);
6320         m_errorMonitor->VerifyFound();
6321     }
6322 
6323     // invalid type;
6324     {
6325         VkAccelerationStructureCreateInfoKHR invalid_as_create_info = as_create_info;
6326         invalid_as_create_info.type = VK_ACCELERATION_STRUCTURE_TYPE_MAX_ENUM_KHR;
6327         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
6328                                              "VUID-VkAccelerationStructureCreateInfoKHR-type-parameter");
6329         vkCreateAccelerationStructureKHR(m_device->handle(), &invalid_as_create_info, nullptr, &as);
6330         m_errorMonitor->VerifyFound();
6331     }
6332 }
6333 
TEST_F(VkLayerTest,ValidateCreateAccelerationStructureKHRReplayFeature)6334 TEST_F(VkLayerTest, ValidateCreateAccelerationStructureKHRReplayFeature) {
6335     TEST_DESCRIPTION("Validate acceleration structure creation replay feature.");
6336     if (!InitFrameworkForRayTracingTest(this, true, m_instance_extension_names, m_device_extension_names, m_errorMonitor, false,
6337                                         false, true)) {
6338         return;
6339     }
6340 
6341     PFN_vkGetPhysicalDeviceFeatures2KHR vkGetPhysicalDeviceFeatures2KHR =
6342         (PFN_vkGetPhysicalDeviceFeatures2KHR)vk::GetInstanceProcAddr(instance(), "vkGetPhysicalDeviceFeatures2KHR");
6343     auto acc_struct_features = LvlInitStruct<VkPhysicalDeviceAccelerationStructureFeaturesKHR>();
6344     VkPhysicalDeviceFeatures2KHR features2 = LvlInitStruct<VkPhysicalDeviceFeatures2KHR>(&acc_struct_features);
6345     vkGetPhysicalDeviceFeatures2KHR(gpu(), &features2);
6346     acc_struct_features.accelerationStructureCaptureReplay = VK_FALSE;
6347     ASSERT_NO_FATAL_FAILURE(InitState(nullptr, &acc_struct_features));
6348     PFN_vkCreateAccelerationStructureKHR vkCreateAccelerationStructureKHR = reinterpret_cast<PFN_vkCreateAccelerationStructureKHR>(
6349         vk::GetDeviceProcAddr(m_device->handle(), "vkCreateAccelerationStructureKHR"));
6350     assert(vkCreateAccelerationStructureKHR != nullptr);
6351     PFN_vkGetBufferDeviceAddressKHR vkGetBufferDeviceAddressKHR =
6352         (PFN_vkGetBufferDeviceAddressKHR)vk::GetDeviceProcAddr(device(), "vkGetBufferDeviceAddressKHR");
6353     assert(vkGetBufferDeviceAddressKHR != nullptr);
6354 
6355     VkBufferObj buffer;
6356     buffer.init(*m_device, 4096, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, VK_BUFFER_USAGE_ACCELERATION_STRUCTURE_STORAGE_BIT_KHR);
6357 
6358     VkBufferDeviceAddressInfo device_address_info = LvlInitStruct<VkBufferDeviceAddressInfo>();
6359     device_address_info.buffer = buffer.handle();
6360     VkDeviceAddress device_address = vkGetBufferDeviceAddressKHR(m_device->handle(), &device_address_info);
6361 
6362     VkAccelerationStructureCreateInfoKHR as_create_info = LvlInitStruct<VkAccelerationStructureCreateInfoKHR>();
6363     as_create_info.buffer = buffer.handle();
6364     as_create_info.createFlags = VK_ACCELERATION_STRUCTURE_CREATE_DEVICE_ADDRESS_CAPTURE_REPLAY_BIT_KHR;
6365     as_create_info.offset = 0;
6366     as_create_info.size = 0;
6367     as_create_info.type = VK_ACCELERATION_STRUCTURE_TYPE_BOTTOM_LEVEL_KHR;
6368     as_create_info.deviceAddress = device_address;
6369 
6370     VkAccelerationStructureKHR as;
6371     m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkAccelerationStructureCreateInfoKHR-createFlags-03613");
6372     m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCreateAccelerationStructureKHR-deviceAddress-03488");
6373     vkCreateAccelerationStructureKHR(m_device->handle(), &as_create_info, nullptr, &as);
6374     m_errorMonitor->VerifyFound();
6375 }
6376 
TEST_F(VkLayerTest,ValidateBindAccelerationStructureNV)6377 TEST_F(VkLayerTest, ValidateBindAccelerationStructureNV) {
6378     TEST_DESCRIPTION("Validate acceleration structure binding.");
6379     if (!InitFrameworkForRayTracingTest(this, false, m_instance_extension_names, m_device_extension_names, m_errorMonitor)) {
6380         return;
6381     }
6382 
6383     PFN_vkBindAccelerationStructureMemoryNV vkBindAccelerationStructureMemoryNV =
6384         reinterpret_cast<PFN_vkBindAccelerationStructureMemoryNV>(
6385             vk::GetDeviceProcAddr(m_device->handle(), "vkBindAccelerationStructureMemoryNV"));
6386     assert(vkBindAccelerationStructureMemoryNV != nullptr);
6387 
6388     VkBufferObj vbo;
6389     VkBufferObj ibo;
6390     VkGeometryNV geometry;
6391     GetSimpleGeometryForAccelerationStructureTests(*m_device, &vbo, &ibo, &geometry);
6392 
6393     VkAccelerationStructureCreateInfoNV as_create_info = {};
6394     as_create_info.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_CREATE_INFO_NV;
6395     as_create_info.info.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_INFO_NV;
6396     as_create_info.info.type = VK_ACCELERATION_STRUCTURE_TYPE_BOTTOM_LEVEL_NV;
6397     as_create_info.info.geometryCount = 1;
6398     as_create_info.info.pGeometries = &geometry;
6399     as_create_info.info.instanceCount = 0;
6400 
6401     VkAccelerationStructureObj as(*m_device, as_create_info, false);
6402     m_errorMonitor->VerifyNotFound();
6403 
6404     VkMemoryRequirements as_memory_requirements = as.memory_requirements().memoryRequirements;
6405 
6406     VkBindAccelerationStructureMemoryInfoNV as_bind_info = {};
6407     as_bind_info.sType = VK_STRUCTURE_TYPE_BIND_ACCELERATION_STRUCTURE_MEMORY_INFO_NV;
6408     as_bind_info.accelerationStructure = as.handle();
6409 
6410     VkMemoryAllocateInfo as_memory_alloc = {};
6411     as_memory_alloc.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
6412     as_memory_alloc.allocationSize = as_memory_requirements.size;
6413     ASSERT_TRUE(m_device->phy().set_memory_type(as_memory_requirements.memoryTypeBits, &as_memory_alloc, 0));
6414 
6415     // Can not bind already freed memory
6416     {
6417         VkDeviceMemory as_memory_freed = VK_NULL_HANDLE;
6418         ASSERT_VK_SUCCESS(vk::AllocateMemory(device(), &as_memory_alloc, NULL, &as_memory_freed));
6419         vk::FreeMemory(device(), as_memory_freed, NULL);
6420 
6421         VkBindAccelerationStructureMemoryInfoNV as_bind_info_freed = as_bind_info;
6422         as_bind_info_freed.memory = as_memory_freed;
6423         as_bind_info_freed.memoryOffset = 0;
6424         m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkBindAccelerationStructureMemoryInfoNV-memory-parameter");
6425         (void)vkBindAccelerationStructureMemoryNV(device(), 1, &as_bind_info_freed);
6426         m_errorMonitor->VerifyFound();
6427     }
6428 
6429     // Can not bind with bad alignment
6430     if (as_memory_requirements.alignment > 1) {
6431         VkMemoryAllocateInfo as_memory_alloc_bad_alignment = as_memory_alloc;
6432         as_memory_alloc_bad_alignment.allocationSize += 1;
6433 
6434         VkDeviceMemory as_memory_bad_alignment = VK_NULL_HANDLE;
6435         ASSERT_VK_SUCCESS(vk::AllocateMemory(device(), &as_memory_alloc_bad_alignment, NULL, &as_memory_bad_alignment));
6436 
6437         VkBindAccelerationStructureMemoryInfoNV as_bind_info_bad_alignment = as_bind_info;
6438         as_bind_info_bad_alignment.memory = as_memory_bad_alignment;
6439         as_bind_info_bad_alignment.memoryOffset = 1;
6440 
6441         m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkBindAccelerationStructureMemoryInfoNV-memoryOffset-03623");
6442         (void)vkBindAccelerationStructureMemoryNV(device(), 1, &as_bind_info_bad_alignment);
6443         m_errorMonitor->VerifyFound();
6444 
6445         vk::FreeMemory(device(), as_memory_bad_alignment, NULL);
6446     }
6447 
6448     // Can not bind with offset outside the allocation
6449     {
6450         VkDeviceMemory as_memory_bad_offset = VK_NULL_HANDLE;
6451         ASSERT_VK_SUCCESS(vk::AllocateMemory(device(), &as_memory_alloc, NULL, &as_memory_bad_offset));
6452 
6453         VkBindAccelerationStructureMemoryInfoNV as_bind_info_bad_offset = as_bind_info;
6454         as_bind_info_bad_offset.memory = as_memory_bad_offset;
6455         as_bind_info_bad_offset.memoryOffset =
6456             (as_memory_alloc.allocationSize + as_memory_requirements.alignment) & ~(as_memory_requirements.alignment - 1);
6457 
6458         m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkBindAccelerationStructureMemoryInfoNV-memoryOffset-03621");
6459         (void)vkBindAccelerationStructureMemoryNV(device(), 1, &as_bind_info_bad_offset);
6460         m_errorMonitor->VerifyFound();
6461 
6462         vk::FreeMemory(device(), as_memory_bad_offset, NULL);
6463     }
6464 
6465     // Can not bind with offset that doesn't leave enough size
6466     {
6467         VkDeviceSize offset = (as_memory_requirements.size - 1) & ~(as_memory_requirements.alignment - 1);
6468         if (offset > 0 && (as_memory_requirements.size < (as_memory_alloc.allocationSize - as_memory_requirements.alignment))) {
6469             VkDeviceMemory as_memory_bad_offset = VK_NULL_HANDLE;
6470             ASSERT_VK_SUCCESS(vk::AllocateMemory(device(), &as_memory_alloc, NULL, &as_memory_bad_offset));
6471 
6472             VkBindAccelerationStructureMemoryInfoNV as_bind_info_bad_offset = as_bind_info;
6473             as_bind_info_bad_offset.memory = as_memory_bad_offset;
6474             as_bind_info_bad_offset.memoryOffset = offset;
6475 
6476             m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkBindAccelerationStructureMemoryInfoNV-size-03624");
6477             (void)vkBindAccelerationStructureMemoryNV(device(), 1, &as_bind_info_bad_offset);
6478             m_errorMonitor->VerifyFound();
6479 
6480             vk::FreeMemory(device(), as_memory_bad_offset, NULL);
6481         }
6482     }
6483 
6484     // Can not bind with memory that has unsupported memory type
6485     {
6486         VkPhysicalDeviceMemoryProperties memory_properties = {};
6487         vk::GetPhysicalDeviceMemoryProperties(m_device->phy().handle(), &memory_properties);
6488 
6489         uint32_t supported_memory_type_bits = as_memory_requirements.memoryTypeBits;
6490         uint32_t unsupported_mem_type_bits = ((1 << memory_properties.memoryTypeCount) - 1) & ~supported_memory_type_bits;
6491         if (unsupported_mem_type_bits != 0) {
6492             VkMemoryAllocateInfo as_memory_alloc_bad_type = as_memory_alloc;
6493             ASSERT_TRUE(m_device->phy().set_memory_type(unsupported_mem_type_bits, &as_memory_alloc_bad_type, 0));
6494 
6495             VkDeviceMemory as_memory_bad_type = VK_NULL_HANDLE;
6496             ASSERT_VK_SUCCESS(vk::AllocateMemory(device(), &as_memory_alloc_bad_type, NULL, &as_memory_bad_type));
6497 
6498             VkBindAccelerationStructureMemoryInfoNV as_bind_info_bad_type = as_bind_info;
6499             as_bind_info_bad_type.memory = as_memory_bad_type;
6500 
6501             m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkBindAccelerationStructureMemoryInfoNV-memory-03622");
6502             (void)vkBindAccelerationStructureMemoryNV(device(), 1, &as_bind_info_bad_type);
6503             m_errorMonitor->VerifyFound();
6504 
6505             vk::FreeMemory(device(), as_memory_bad_type, NULL);
6506         }
6507     }
6508 
6509     // Can not bind memory twice
6510     {
6511         VkAccelerationStructureObj as_twice(*m_device, as_create_info, false);
6512 
6513         VkDeviceMemory as_memory_twice_1 = VK_NULL_HANDLE;
6514         VkDeviceMemory as_memory_twice_2 = VK_NULL_HANDLE;
6515         ASSERT_VK_SUCCESS(vk::AllocateMemory(device(), &as_memory_alloc, NULL, &as_memory_twice_1));
6516         ASSERT_VK_SUCCESS(vk::AllocateMemory(device(), &as_memory_alloc, NULL, &as_memory_twice_2));
6517         VkBindAccelerationStructureMemoryInfoNV as_bind_info_twice_1 = as_bind_info;
6518         VkBindAccelerationStructureMemoryInfoNV as_bind_info_twice_2 = as_bind_info;
6519         as_bind_info_twice_1.accelerationStructure = as_twice.handle();
6520         as_bind_info_twice_2.accelerationStructure = as_twice.handle();
6521         as_bind_info_twice_1.memory = as_memory_twice_1;
6522         as_bind_info_twice_2.memory = as_memory_twice_2;
6523 
6524         ASSERT_VK_SUCCESS(vkBindAccelerationStructureMemoryNV(device(), 1, &as_bind_info_twice_1));
6525         m_errorMonitor->VerifyNotFound();
6526         m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkBindAccelerationStructureMemoryInfoNV-accelerationStructure-03620");
6527         (void)vkBindAccelerationStructureMemoryNV(device(), 1, &as_bind_info_twice_2);
6528         m_errorMonitor->VerifyFound();
6529 
6530         vk::FreeMemory(device(), as_memory_twice_1, NULL);
6531         vk::FreeMemory(device(), as_memory_twice_2, NULL);
6532     }
6533 }
6534 
TEST_F(VkLayerTest,ValidateWriteDescriptorSetAccelerationStructureNV)6535 TEST_F(VkLayerTest, ValidateWriteDescriptorSetAccelerationStructureNV) {
6536     TEST_DESCRIPTION("Validate acceleration structure descriptor writing.");
6537     if (!InitFrameworkForRayTracingTest(this, false, m_instance_extension_names, m_device_extension_names, m_errorMonitor)) {
6538         return;
6539     }
6540 
6541     OneOffDescriptorSet ds(m_device,
6542                            {
6543                                {0, VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_NV, 1, VK_SHADER_STAGE_RAYGEN_BIT_NV, nullptr},
6544                            });
6545 
6546     VkWriteDescriptorSet descriptor_write = {};
6547     descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
6548     descriptor_write.dstSet = ds.set_;
6549     descriptor_write.dstBinding = 0;
6550     descriptor_write.descriptorCount = 1;
6551     descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_NV;
6552 
6553     VkWriteDescriptorSetAccelerationStructureNV acc = {};
6554     acc.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET_ACCELERATION_STRUCTURE_NV;
6555     acc.accelerationStructureCount = 1;
6556     VkAccelerationStructureCreateInfoNV top_level_as_create_info = {};
6557     top_level_as_create_info.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_CREATE_INFO_NV;
6558     top_level_as_create_info.info.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_INFO_NV;
6559     top_level_as_create_info.info.type = VK_ACCELERATION_STRUCTURE_TYPE_TOP_LEVEL_NV;
6560     top_level_as_create_info.info.instanceCount = 1;
6561     top_level_as_create_info.info.geometryCount = 0;
6562 
6563     VkAccelerationStructureObj top_level_as(*m_device, top_level_as_create_info);
6564 
6565     acc.pAccelerationStructures = &top_level_as.handle();
6566     descriptor_write.pNext = &acc;
6567     m_errorMonitor->ExpectSuccess();
6568     vk::UpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
6569     m_errorMonitor->VerifyNotFound();
6570 }
6571 
TEST_F(VkLayerTest,ValidateCmdBuildAccelerationStructureNV)6572 TEST_F(VkLayerTest, ValidateCmdBuildAccelerationStructureNV) {
6573     TEST_DESCRIPTION("Validate acceleration structure building.");
6574     if (!InitFrameworkForRayTracingTest(this, false, m_instance_extension_names, m_device_extension_names, m_errorMonitor)) {
6575         return;
6576     }
6577 
6578     PFN_vkCmdBuildAccelerationStructureNV vkCmdBuildAccelerationStructureNV =
6579         reinterpret_cast<PFN_vkCmdBuildAccelerationStructureNV>(
6580             vk::GetDeviceProcAddr(m_device->handle(), "vkCmdBuildAccelerationStructureNV"));
6581     assert(vkCmdBuildAccelerationStructureNV != nullptr);
6582 
6583     VkBufferObj vbo;
6584     VkBufferObj ibo;
6585     VkGeometryNV geometry;
6586     GetSimpleGeometryForAccelerationStructureTests(*m_device, &vbo, &ibo, &geometry);
6587 
6588     VkAccelerationStructureCreateInfoNV bot_level_as_create_info = {};
6589     bot_level_as_create_info.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_CREATE_INFO_NV;
6590     bot_level_as_create_info.info.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_INFO_NV;
6591     bot_level_as_create_info.info.type = VK_ACCELERATION_STRUCTURE_TYPE_BOTTOM_LEVEL_NV;
6592     bot_level_as_create_info.info.instanceCount = 0;
6593     bot_level_as_create_info.info.geometryCount = 1;
6594     bot_level_as_create_info.info.pGeometries = &geometry;
6595 
6596     VkAccelerationStructureObj bot_level_as(*m_device, bot_level_as_create_info);
6597     m_errorMonitor->VerifyNotFound();
6598 
6599     VkBufferObj bot_level_as_scratch;
6600     bot_level_as.create_scratch_buffer(*m_device, &bot_level_as_scratch);
6601 
6602     // Command buffer must be in recording state
6603     m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdBuildAccelerationStructureNV-commandBuffer-recording");
6604     vkCmdBuildAccelerationStructureNV(m_commandBuffer->handle(), &bot_level_as_create_info.info, VK_NULL_HANDLE, 0, VK_FALSE,
6605                                       bot_level_as.handle(), VK_NULL_HANDLE, bot_level_as_scratch.handle(), 0);
6606     m_errorMonitor->VerifyFound();
6607 
6608     m_commandBuffer->begin();
6609 
6610     // Incompatible type
6611     VkAccelerationStructureInfoNV as_build_info_with_incompatible_type = bot_level_as_create_info.info;
6612     as_build_info_with_incompatible_type.type = VK_ACCELERATION_STRUCTURE_TYPE_TOP_LEVEL_NV;
6613     as_build_info_with_incompatible_type.instanceCount = 1;
6614     as_build_info_with_incompatible_type.geometryCount = 0;
6615 
6616     // This is duplicated since it triggers one error for different types and one error for lower instance count - the
6617     // build info is incompatible but still needs to be valid to get past the stateless checks.
6618     m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdBuildAccelerationStructureNV-dst-02488");
6619     m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdBuildAccelerationStructureNV-dst-02488");
6620     vkCmdBuildAccelerationStructureNV(m_commandBuffer->handle(), &as_build_info_with_incompatible_type, VK_NULL_HANDLE, 0, VK_FALSE,
6621                                       bot_level_as.handle(), VK_NULL_HANDLE, bot_level_as_scratch.handle(), 0);
6622     m_errorMonitor->VerifyFound();
6623 
6624     // Incompatible flags
6625     VkAccelerationStructureInfoNV as_build_info_with_incompatible_flags = bot_level_as_create_info.info;
6626     as_build_info_with_incompatible_flags.flags = VK_BUILD_ACCELERATION_STRUCTURE_LOW_MEMORY_BIT_NV;
6627     m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdBuildAccelerationStructureNV-dst-02488");
6628     vkCmdBuildAccelerationStructureNV(m_commandBuffer->handle(), &as_build_info_with_incompatible_flags, VK_NULL_HANDLE, 0,
6629                                       VK_FALSE, bot_level_as.handle(), VK_NULL_HANDLE, bot_level_as_scratch.handle(), 0);
6630     m_errorMonitor->VerifyFound();
6631 
6632     // Incompatible build size
6633     VkGeometryNV geometry_with_more_vertices = geometry;
6634     geometry_with_more_vertices.geometry.triangles.vertexCount += 1;
6635 
6636     VkAccelerationStructureInfoNV as_build_info_with_incompatible_geometry = bot_level_as_create_info.info;
6637     as_build_info_with_incompatible_geometry.pGeometries = &geometry_with_more_vertices;
6638     m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdBuildAccelerationStructureNV-dst-02488");
6639     vkCmdBuildAccelerationStructureNV(m_commandBuffer->handle(), &as_build_info_with_incompatible_geometry, VK_NULL_HANDLE, 0,
6640                                       VK_FALSE, bot_level_as.handle(), VK_NULL_HANDLE, bot_level_as_scratch.handle(), 0);
6641     m_errorMonitor->VerifyFound();
6642 
6643     // Scratch buffer too small
6644     VkBufferCreateInfo too_small_scratch_buffer_info = {};
6645     too_small_scratch_buffer_info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
6646     too_small_scratch_buffer_info.usage = VK_BUFFER_USAGE_RAY_TRACING_BIT_NV;
6647     too_small_scratch_buffer_info.size = 1;
6648     VkBufferObj too_small_scratch_buffer(*m_device, too_small_scratch_buffer_info);
6649     m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdBuildAccelerationStructureNV-update-02491");
6650     vkCmdBuildAccelerationStructureNV(m_commandBuffer->handle(), &bot_level_as_create_info.info, VK_NULL_HANDLE, 0, VK_FALSE,
6651                                       bot_level_as.handle(), VK_NULL_HANDLE, too_small_scratch_buffer.handle(), 0);
6652     m_errorMonitor->VerifyFound();
6653 
6654     // Scratch buffer with offset too small
6655     VkDeviceSize scratch_buffer_offset = 5;
6656     m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdBuildAccelerationStructureNV-update-02491");
6657     vkCmdBuildAccelerationStructureNV(m_commandBuffer->handle(), &bot_level_as_create_info.info, VK_NULL_HANDLE, 0, VK_FALSE,
6658                                       bot_level_as.handle(), VK_NULL_HANDLE, bot_level_as_scratch.handle(), scratch_buffer_offset);
6659     m_errorMonitor->VerifyFound();
6660 
6661     // Src must have been built before
6662     VkAccelerationStructureObj bot_level_as_updated(*m_device, bot_level_as_create_info);
6663     m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdBuildAccelerationStructureNV-update-02489");
6664     vkCmdBuildAccelerationStructureNV(m_commandBuffer->handle(), &bot_level_as_create_info.info, VK_NULL_HANDLE, 0, VK_TRUE,
6665                                       bot_level_as_updated.handle(), VK_NULL_HANDLE, bot_level_as_scratch.handle(), 0);
6666     m_errorMonitor->VerifyFound();
6667 
6668     // Src must have been built before with the VK_BUILD_ACCELERATION_STRUCTURE_ALLOW_UPDATE_BIT_NV flag
6669     vkCmdBuildAccelerationStructureNV(m_commandBuffer->handle(), &bot_level_as_create_info.info, VK_NULL_HANDLE, 0, VK_FALSE,
6670                                       bot_level_as.handle(), VK_NULL_HANDLE, bot_level_as_scratch.handle(), 0);
6671     m_errorMonitor->VerifyNotFound();
6672     m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdBuildAccelerationStructureNV-update-02490");
6673     vkCmdBuildAccelerationStructureNV(m_commandBuffer->handle(), &bot_level_as_create_info.info, VK_NULL_HANDLE, 0, VK_TRUE,
6674                                       bot_level_as_updated.handle(), bot_level_as.handle(), bot_level_as_scratch.handle(), 0);
6675     m_errorMonitor->VerifyFound();
6676 
6677     // invalid scratch buff
6678     VkBufferObj bot_level_as_invalid_scratch;
6679     VkBufferCreateInfo create_info = {};
6680     create_info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
6681     // invalid usage
6682     create_info.usage = VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT_KHR;
6683     bot_level_as.create_scratch_buffer(*m_device, &bot_level_as_invalid_scratch, &create_info);
6684     m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkAccelerationStructureInfoNV-scratch-02781");
6685     vkCmdBuildAccelerationStructureNV(m_commandBuffer->handle(), &bot_level_as_create_info.info, VK_NULL_HANDLE, 0, VK_FALSE,
6686                                       bot_level_as.handle(), VK_NULL_HANDLE, bot_level_as_invalid_scratch.handle(), 0);
6687     m_errorMonitor->VerifyFound();
6688 
6689     // invalid instance data.
6690     m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkAccelerationStructureInfoNV-instanceData-02782");
6691     vkCmdBuildAccelerationStructureNV(m_commandBuffer->handle(), &bot_level_as_create_info.info,
6692                                       bot_level_as_invalid_scratch.handle(), 0, VK_FALSE, bot_level_as.handle(), VK_NULL_HANDLE,
6693                                       bot_level_as_scratch.handle(), 0);
6694     m_errorMonitor->VerifyFound();
6695 
6696     // must be called outside renderpass
6697     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
6698     m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
6699     m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdBuildAccelerationStructureNV-renderpass");
6700     vkCmdBuildAccelerationStructureNV(m_commandBuffer->handle(), &bot_level_as_create_info.info, VK_NULL_HANDLE, 0, VK_FALSE,
6701                                       bot_level_as.handle(), VK_NULL_HANDLE, bot_level_as_scratch.handle(), 0);
6702     m_commandBuffer->EndRenderPass();
6703     m_errorMonitor->VerifyFound();
6704 }
6705 
TEST_F(VkLayerTest,ValidateGetAccelerationStructureHandleNV)6706 TEST_F(VkLayerTest, ValidateGetAccelerationStructureHandleNV) {
6707     TEST_DESCRIPTION("Validate acceleration structure handle querying.");
6708     if (!InitFrameworkForRayTracingTest(this, false, m_instance_extension_names, m_device_extension_names, m_errorMonitor)) {
6709         return;
6710     }
6711 
6712     PFN_vkGetAccelerationStructureHandleNV vkGetAccelerationStructureHandleNV =
6713         reinterpret_cast<PFN_vkGetAccelerationStructureHandleNV>(
6714             vk::GetDeviceProcAddr(m_device->handle(), "vkGetAccelerationStructureHandleNV"));
6715     assert(vkGetAccelerationStructureHandleNV != nullptr);
6716 
6717     VkBufferObj vbo;
6718     VkBufferObj ibo;
6719     VkGeometryNV geometry;
6720     GetSimpleGeometryForAccelerationStructureTests(*m_device, &vbo, &ibo, &geometry);
6721 
6722     VkAccelerationStructureCreateInfoNV bot_level_as_create_info = {};
6723     bot_level_as_create_info.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_CREATE_INFO_NV;
6724     bot_level_as_create_info.info.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_INFO_NV;
6725     bot_level_as_create_info.info.type = VK_ACCELERATION_STRUCTURE_TYPE_BOTTOM_LEVEL_NV;
6726     bot_level_as_create_info.info.instanceCount = 0;
6727     bot_level_as_create_info.info.geometryCount = 1;
6728     bot_level_as_create_info.info.pGeometries = &geometry;
6729 
6730     // Not enough space for the handle
6731     {
6732         VkAccelerationStructureObj bot_level_as(*m_device, bot_level_as_create_info);
6733         m_errorMonitor->VerifyNotFound();
6734 
6735         uint64_t handle = 0;
6736         m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkGetAccelerationStructureHandleNV-dataSize-02240");
6737         vkGetAccelerationStructureHandleNV(m_device->handle(), bot_level_as.handle(), sizeof(uint8_t), &handle);
6738         m_errorMonitor->VerifyFound();
6739     }
6740 
6741     // No memory bound to acceleration structure
6742     {
6743         VkAccelerationStructureObj bot_level_as(*m_device, bot_level_as_create_info, /*init_memory=*/false);
6744         m_errorMonitor->VerifyNotFound();
6745 
6746         uint64_t handle = 0;
6747         m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "UNASSIGNED-vkGetAccelerationStructureHandleNV-accelerationStructure-XXXX");
6748         vkGetAccelerationStructureHandleNV(m_device->handle(), bot_level_as.handle(), sizeof(uint64_t), &handle);
6749         m_errorMonitor->VerifyFound();
6750     }
6751 }
6752 
TEST_F(VkLayerTest,ValidateCmdCopyAccelerationStructureNV)6753 TEST_F(VkLayerTest, ValidateCmdCopyAccelerationStructureNV) {
6754     TEST_DESCRIPTION("Validate acceleration structure copying.");
6755     if (!InitFrameworkForRayTracingTest(this, false, m_instance_extension_names, m_device_extension_names, m_errorMonitor)) {
6756         return;
6757     }
6758 
6759     PFN_vkCmdCopyAccelerationStructureNV vkCmdCopyAccelerationStructureNV = reinterpret_cast<PFN_vkCmdCopyAccelerationStructureNV>(
6760         vk::GetDeviceProcAddr(m_device->handle(), "vkCmdCopyAccelerationStructureNV"));
6761     assert(vkCmdCopyAccelerationStructureNV != nullptr);
6762 
6763     VkBufferObj vbo;
6764     VkBufferObj ibo;
6765     VkGeometryNV geometry;
6766     GetSimpleGeometryForAccelerationStructureTests(*m_device, &vbo, &ibo, &geometry);
6767 
6768     VkAccelerationStructureCreateInfoNV as_create_info = {};
6769     as_create_info.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_CREATE_INFO_NV;
6770     as_create_info.info.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_INFO_NV;
6771     as_create_info.info.type = VK_ACCELERATION_STRUCTURE_TYPE_BOTTOM_LEVEL_NV;
6772     as_create_info.info.instanceCount = 0;
6773     as_create_info.info.geometryCount = 1;
6774     as_create_info.info.pGeometries = &geometry;
6775 
6776     VkAccelerationStructureObj src_as(*m_device, as_create_info);
6777     VkAccelerationStructureObj dst_as(*m_device, as_create_info);
6778     VkAccelerationStructureObj dst_as_without_mem(*m_device, as_create_info, false);
6779     m_errorMonitor->VerifyNotFound();
6780 
6781     // Command buffer must be in recording state
6782     m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdCopyAccelerationStructureNV-commandBuffer-recording");
6783     vkCmdCopyAccelerationStructureNV(m_commandBuffer->handle(), dst_as.handle(), src_as.handle(),
6784                                      VK_COPY_ACCELERATION_STRUCTURE_MODE_CLONE_NV);
6785     m_errorMonitor->VerifyFound();
6786 
6787     m_commandBuffer->begin();
6788 
6789     // Src must have been created with allow compaction flag
6790     m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdCopyAccelerationStructureNV-src-03411");
6791     vkCmdCopyAccelerationStructureNV(m_commandBuffer->handle(), dst_as.handle(), src_as.handle(),
6792                                      VK_COPY_ACCELERATION_STRUCTURE_MODE_COMPACT_NV);
6793     m_errorMonitor->VerifyFound();
6794 
6795     // Dst must have been bound with memory
6796     m_errorMonitor->SetDesiredFailureMsg(kErrorBit,
6797                                          "UNASSIGNED-CoreValidation-DrawState-InvalidCommandBuffer-VkAccelerationStructureNV");
6798     vkCmdCopyAccelerationStructureNV(m_commandBuffer->handle(), dst_as_without_mem.handle(), src_as.handle(),
6799                                      VK_COPY_ACCELERATION_STRUCTURE_MODE_CLONE_NV);
6800 
6801     m_errorMonitor->VerifyFound();
6802 
6803     // mode must be VK_COPY_ACCELERATION_STRUCTURE_MODE_COMPACT_KHR or VK_COPY_ACCELERATION_STRUCTURE_MODE_CLONE_KHR
6804     m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdCopyAccelerationStructureNV-mode-03410");
6805     vkCmdCopyAccelerationStructureNV(m_commandBuffer->handle(), dst_as.handle(), src_as.handle(),
6806                                      VK_COPY_ACCELERATION_STRUCTURE_MODE_DESERIALIZE_KHR);
6807     m_errorMonitor->VerifyFound();
6808 
6809     // mode must be a valid VkCopyAccelerationStructureModeKHR value
6810     m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdCopyAccelerationStructureNV-mode-parameter");
6811     vkCmdCopyAccelerationStructureNV(m_commandBuffer->handle(), dst_as.handle(), src_as.handle(),
6812                                      VK_COPY_ACCELERATION_STRUCTURE_MODE_MAX_ENUM_KHR);
6813     m_errorMonitor->VerifyFound();
6814 
6815     // This command must only be called outside of a render pass instance
6816     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
6817     m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
6818     m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdCopyAccelerationStructureNV-renderpass");
6819     vkCmdCopyAccelerationStructureNV(m_commandBuffer->handle(), dst_as.handle(), src_as.handle(),
6820                                      VK_COPY_ACCELERATION_STRUCTURE_MODE_CLONE_NV);
6821     m_commandBuffer->EndRenderPass();
6822     m_errorMonitor->VerifyFound();
6823 }
6824 
TEST_F(VkLayerTest,QueryPerformanceCreation)6825 TEST_F(VkLayerTest, QueryPerformanceCreation) {
6826     TEST_DESCRIPTION("Create performance query without support");
6827 
6828     if (InstanceExtensionSupported(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME)) {
6829         m_instance_extension_names.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
6830     } else {
6831         printf("%s Extension %s is not supported.\n", kSkipPrefix, VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
6832         return;
6833     }
6834     ASSERT_NO_FATAL_FAILURE(InitFramework(m_errorMonitor));
6835 
6836     if (DeviceExtensionSupported(gpu(), nullptr, VK_KHR_PERFORMANCE_QUERY_EXTENSION_NAME)) {
6837         m_device_extension_names.push_back(VK_KHR_PERFORMANCE_QUERY_EXTENSION_NAME);
6838     } else {
6839         printf("%s Extension %s is not supported.\n", kSkipPrefix, VK_KHR_PERFORMANCE_QUERY_EXTENSION_NAME);
6840         return;
6841     }
6842 
6843     PFN_vkGetPhysicalDeviceFeatures2KHR vkGetPhysicalDeviceFeatures2KHR =
6844         (PFN_vkGetPhysicalDeviceFeatures2KHR)vk::GetInstanceProcAddr(instance(), "vkGetPhysicalDeviceFeatures2KHR");
6845     ASSERT_TRUE(vkGetPhysicalDeviceFeatures2KHR != nullptr);
6846     VkPhysicalDeviceFeatures2KHR features2 = {};
6847     auto performance_features = LvlInitStruct<VkPhysicalDevicePerformanceQueryFeaturesKHR>();
6848     features2 = LvlInitStruct<VkPhysicalDeviceFeatures2KHR>(&performance_features);
6849     vkGetPhysicalDeviceFeatures2KHR(gpu(), &features2);
6850     if (!performance_features.performanceCounterQueryPools) {
6851         printf("%s Performance query pools are not supported.\n", kSkipPrefix);
6852         return;
6853     }
6854 
6855     ASSERT_NO_FATAL_FAILURE(InitState(nullptr, &performance_features));
6856     PFN_vkEnumeratePhysicalDeviceQueueFamilyPerformanceQueryCountersKHR
6857         vkEnumeratePhysicalDeviceQueueFamilyPerformanceQueryCountersKHR =
6858             (PFN_vkEnumeratePhysicalDeviceQueueFamilyPerformanceQueryCountersKHR)vk::GetInstanceProcAddr(
6859                 instance(), "vkEnumeratePhysicalDeviceQueueFamilyPerformanceQueryCountersKHR");
6860     ASSERT_TRUE(vkEnumeratePhysicalDeviceQueueFamilyPerformanceQueryCountersKHR != nullptr);
6861 
6862     auto queueFamilyProperties = m_device->phy().queue_properties();
6863     uint32_t queueFamilyIndex = queueFamilyProperties.size();
6864     std::vector<VkPerformanceCounterKHR> counters;
6865 
6866     for (uint32_t idx = 0; idx < queueFamilyProperties.size(); idx++) {
6867         uint32_t nCounters;
6868 
6869         vkEnumeratePhysicalDeviceQueueFamilyPerformanceQueryCountersKHR(gpu(), idx, &nCounters, nullptr, nullptr);
6870         if (nCounters == 0) continue;
6871 
6872         counters.resize(nCounters);
6873         for (auto &c : counters) {
6874             c.sType = VK_STRUCTURE_TYPE_PERFORMANCE_COUNTER_KHR;
6875             c.pNext = nullptr;
6876         }
6877         vkEnumeratePhysicalDeviceQueueFamilyPerformanceQueryCountersKHR(gpu(), idx, &nCounters, &counters[0], nullptr);
6878         queueFamilyIndex = idx;
6879         break;
6880     }
6881 
6882     if (counters.empty()) {
6883         printf("%s No queue reported any performance counter.\n", kSkipPrefix);
6884         return;
6885     }
6886 
6887     VkQueryPoolPerformanceCreateInfoKHR perf_query_pool_ci{};
6888     perf_query_pool_ci.sType = VK_STRUCTURE_TYPE_QUERY_POOL_PERFORMANCE_CREATE_INFO_KHR;
6889     perf_query_pool_ci.queueFamilyIndex = queueFamilyIndex;
6890     perf_query_pool_ci.counterIndexCount = counters.size();
6891     std::vector<uint32_t> counterIndices;
6892     for (uint32_t c = 0; c < counters.size(); c++) counterIndices.push_back(c);
6893     perf_query_pool_ci.pCounterIndices = &counterIndices[0];
6894     VkQueryPoolCreateInfo query_pool_ci{};
6895     query_pool_ci.sType = VK_STRUCTURE_TYPE_QUERY_POOL_CREATE_INFO;
6896     query_pool_ci.queryType = VK_QUERY_TYPE_PERFORMANCE_QUERY_KHR;
6897     query_pool_ci.queryCount = 1;
6898 
6899     // Missing pNext
6900     m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkQueryPoolCreateInfo-queryType-03222");
6901     VkQueryPool query_pool;
6902     vk::CreateQueryPool(m_device->device(), &query_pool_ci, nullptr, &query_pool);
6903     m_errorMonitor->VerifyFound();
6904 
6905     query_pool_ci.pNext = &perf_query_pool_ci;
6906 
6907     // Invalid counter indices
6908     counterIndices.push_back(counters.size());
6909     perf_query_pool_ci.counterIndexCount++;
6910     m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkQueryPoolPerformanceCreateInfoKHR-pCounterIndices-03321");
6911     vk::CreateQueryPool(m_device->device(), &query_pool_ci, nullptr, &query_pool);
6912     m_errorMonitor->VerifyFound();
6913     perf_query_pool_ci.counterIndexCount--;
6914     counterIndices.pop_back();
6915 
6916     // Success
6917     m_errorMonitor->ExpectSuccess(kErrorBit);
6918     vk::CreateQueryPool(m_device->device(), &query_pool_ci, nullptr, &query_pool);
6919     m_errorMonitor->VerifyNotFound();
6920 
6921     m_commandBuffer->begin();
6922 
6923     // Missing acquire lock
6924     {
6925         m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdBeginQuery-queryPool-03223");
6926         vk::CmdBeginQuery(m_commandBuffer->handle(), query_pool, 0, 0);
6927         m_errorMonitor->VerifyFound();
6928     }
6929 
6930     m_commandBuffer->end();
6931 
6932     vk::DestroyQueryPool(m_device->device(), query_pool, NULL);
6933 }
6934 
TEST_F(VkLayerTest,QueryPerformanceCounterCommandbufferScope)6935 TEST_F(VkLayerTest, QueryPerformanceCounterCommandbufferScope) {
6936     TEST_DESCRIPTION("Insert a performance query begin/end with respect to the command buffer counter scope");
6937 
6938     if (InstanceExtensionSupported(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME)) {
6939         m_instance_extension_names.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
6940     } else {
6941         printf("%s Extension %s is not supported.\n", kSkipPrefix, VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
6942         return;
6943     }
6944     ASSERT_NO_FATAL_FAILURE(InitFramework(m_errorMonitor));
6945 
6946     if (DeviceExtensionSupported(gpu(), nullptr, VK_KHR_PERFORMANCE_QUERY_EXTENSION_NAME)) {
6947         m_device_extension_names.push_back(VK_KHR_PERFORMANCE_QUERY_EXTENSION_NAME);
6948     } else {
6949         printf("%s Extension %s is not supported.\n", kSkipPrefix, VK_KHR_PERFORMANCE_QUERY_EXTENSION_NAME);
6950         return;
6951     }
6952 
6953     PFN_vkGetPhysicalDeviceFeatures2KHR vkGetPhysicalDeviceFeatures2KHR =
6954         (PFN_vkGetPhysicalDeviceFeatures2KHR)vk::GetInstanceProcAddr(instance(), "vkGetPhysicalDeviceFeatures2KHR");
6955     ASSERT_TRUE(vkGetPhysicalDeviceFeatures2KHR != nullptr);
6956     VkPhysicalDeviceFeatures2KHR features2 = {};
6957     auto performanceFeatures = LvlInitStruct<VkPhysicalDevicePerformanceQueryFeaturesKHR>();
6958     features2 = LvlInitStruct<VkPhysicalDeviceFeatures2KHR>(&performanceFeatures);
6959     vkGetPhysicalDeviceFeatures2KHR(gpu(), &features2);
6960     if (!performanceFeatures.performanceCounterQueryPools) {
6961         printf("%s Performance query pools are not supported.\n", kSkipPrefix);
6962         return;
6963     }
6964 
6965     VkCommandPoolCreateFlags pool_flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT;
6966     ASSERT_NO_FATAL_FAILURE(InitState(nullptr, &performanceFeatures, pool_flags));
6967     PFN_vkEnumeratePhysicalDeviceQueueFamilyPerformanceQueryCountersKHR
6968         vkEnumeratePhysicalDeviceQueueFamilyPerformanceQueryCountersKHR =
6969             (PFN_vkEnumeratePhysicalDeviceQueueFamilyPerformanceQueryCountersKHR)vk::GetInstanceProcAddr(
6970                 instance(), "vkEnumeratePhysicalDeviceQueueFamilyPerformanceQueryCountersKHR");
6971     ASSERT_TRUE(vkEnumeratePhysicalDeviceQueueFamilyPerformanceQueryCountersKHR != nullptr);
6972 
6973     auto queueFamilyProperties = m_device->phy().queue_properties();
6974     uint32_t queueFamilyIndex = queueFamilyProperties.size();
6975     std::vector<VkPerformanceCounterKHR> counters;
6976     std::vector<uint32_t> counterIndices;
6977 
6978     // Find a single counter with VK_QUERY_SCOPE_COMMAND_BUFFER_KHR scope.
6979     for (uint32_t idx = 0; idx < queueFamilyProperties.size(); idx++) {
6980         uint32_t nCounters;
6981 
6982         vkEnumeratePhysicalDeviceQueueFamilyPerformanceQueryCountersKHR(gpu(), idx, &nCounters, nullptr, nullptr);
6983         if (nCounters == 0) continue;
6984 
6985         counters.resize(nCounters);
6986         for (auto &c : counters) {
6987             c.sType = VK_STRUCTURE_TYPE_PERFORMANCE_COUNTER_KHR;
6988             c.pNext = nullptr;
6989         }
6990         vkEnumeratePhysicalDeviceQueueFamilyPerformanceQueryCountersKHR(gpu(), idx, &nCounters, &counters[0], nullptr);
6991         queueFamilyIndex = idx;
6992 
6993         for (uint32_t counterIdx = 0; counterIdx < counters.size(); counterIdx++) {
6994             if (counters[counterIdx].scope == VK_QUERY_SCOPE_COMMAND_BUFFER_KHR) {
6995                 counterIndices.push_back(counterIdx);
6996                 break;
6997             }
6998         }
6999 
7000         if (counterIndices.empty()) {
7001             counters.clear();
7002             continue;
7003         }
7004         break;
7005     }
7006 
7007     if (counterIndices.empty()) {
7008         printf("%s No queue reported any performance counter with command buffer scope.\n", kSkipPrefix);
7009         return;
7010     }
7011 
7012     VkQueryPoolPerformanceCreateInfoKHR perf_query_pool_ci{};
7013     perf_query_pool_ci.sType = VK_STRUCTURE_TYPE_QUERY_POOL_PERFORMANCE_CREATE_INFO_KHR;
7014     perf_query_pool_ci.queueFamilyIndex = queueFamilyIndex;
7015     perf_query_pool_ci.counterIndexCount = counterIndices.size();
7016     perf_query_pool_ci.pCounterIndices = &counterIndices[0];
7017     VkQueryPoolCreateInfo query_pool_ci{};
7018     query_pool_ci.sType = VK_STRUCTURE_TYPE_QUERY_POOL_CREATE_INFO;
7019     query_pool_ci.pNext = &perf_query_pool_ci;
7020     query_pool_ci.queryType = VK_QUERY_TYPE_PERFORMANCE_QUERY_KHR;
7021     query_pool_ci.queryCount = 1;
7022 
7023     VkQueryPool query_pool;
7024     vk::CreateQueryPool(device(), &query_pool_ci, nullptr, &query_pool);
7025 
7026     VkQueue queue = VK_NULL_HANDLE;
7027     vk::GetDeviceQueue(device(), queueFamilyIndex, 0, &queue);
7028 
7029     PFN_vkAcquireProfilingLockKHR vkAcquireProfilingLockKHR =
7030         (PFN_vkAcquireProfilingLockKHR)vk::GetInstanceProcAddr(instance(), "vkAcquireProfilingLockKHR");
7031     ASSERT_TRUE(vkAcquireProfilingLockKHR != nullptr);
7032     PFN_vkReleaseProfilingLockKHR vkReleaseProfilingLockKHR =
7033         (PFN_vkReleaseProfilingLockKHR)vk::GetInstanceProcAddr(instance(), "vkReleaseProfilingLockKHR");
7034     ASSERT_TRUE(vkReleaseProfilingLockKHR != nullptr);
7035 
7036     {
7037         VkAcquireProfilingLockInfoKHR lock_info{};
7038         lock_info.sType = VK_STRUCTURE_TYPE_ACQUIRE_PROFILING_LOCK_INFO_KHR;
7039         VkResult result = vkAcquireProfilingLockKHR(device(), &lock_info);
7040         ASSERT_TRUE(result == VK_SUCCESS);
7041     }
7042 
7043     // Not the first command.
7044     {
7045         VkBufferCreateInfo buf_info = {};
7046         buf_info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
7047         buf_info.usage = VK_BUFFER_USAGE_TRANSFER_DST_BIT;
7048         buf_info.size = 4096;
7049         buf_info.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
7050         VkBuffer buffer;
7051         VkResult err = vk::CreateBuffer(device(), &buf_info, NULL, &buffer);
7052         ASSERT_VK_SUCCESS(err);
7053 
7054         VkMemoryRequirements mem_reqs;
7055         vk::GetBufferMemoryRequirements(device(), buffer, &mem_reqs);
7056 
7057         VkMemoryAllocateInfo alloc_info = {};
7058         alloc_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
7059         alloc_info.allocationSize = 4096;
7060         VkDeviceMemory mem;
7061         err = vk::AllocateMemory(device(), &alloc_info, NULL, &mem);
7062         ASSERT_VK_SUCCESS(err);
7063         vk::BindBufferMemory(device(), buffer, mem, 0);
7064 
7065         m_commandBuffer->begin();
7066         vk::CmdFillBuffer(m_commandBuffer->handle(), buffer, 0, 4096, 0);
7067 
7068         m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdBeginQuery-queryPool-03224");
7069         vk::CmdBeginQuery(m_commandBuffer->handle(), query_pool, 0, 0);
7070         m_errorMonitor->VerifyFound();
7071 
7072         m_commandBuffer->end();
7073 
7074         VkSubmitInfo submit_info;
7075         submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
7076         submit_info.pNext = NULL;
7077         submit_info.waitSemaphoreCount = 0;
7078         submit_info.pWaitSemaphores = NULL;
7079         submit_info.pWaitDstStageMask = NULL;
7080         submit_info.commandBufferCount = 1;
7081         submit_info.pCommandBuffers = &m_commandBuffer->handle();
7082         submit_info.signalSemaphoreCount = 0;
7083         submit_info.pSignalSemaphores = NULL;
7084         vk::QueueSubmit(queue, 1, &submit_info, VK_NULL_HANDLE);
7085         vk::QueueWaitIdle(queue);
7086 
7087         vk::DestroyBuffer(device(), buffer, nullptr);
7088         vk::FreeMemory(device(), mem, NULL);
7089     }
7090 
7091     // First command: success.
7092     {
7093         VkBufferCreateInfo buf_info = {};
7094         buf_info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
7095         buf_info.usage = VK_BUFFER_USAGE_TRANSFER_DST_BIT;
7096         buf_info.size = 4096;
7097         buf_info.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
7098         VkBuffer buffer;
7099         VkResult err = vk::CreateBuffer(device(), &buf_info, NULL, &buffer);
7100         ASSERT_VK_SUCCESS(err);
7101 
7102         VkMemoryRequirements mem_reqs;
7103         vk::GetBufferMemoryRequirements(device(), buffer, &mem_reqs);
7104 
7105         VkMemoryAllocateInfo alloc_info = {};
7106         alloc_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
7107         alloc_info.allocationSize = 4096;
7108         VkDeviceMemory mem;
7109         err = vk::AllocateMemory(device(), &alloc_info, NULL, &mem);
7110         ASSERT_VK_SUCCESS(err);
7111         vk::BindBufferMemory(device(), buffer, mem, 0);
7112 
7113         m_commandBuffer->begin();
7114 
7115         m_errorMonitor->ExpectSuccess(kErrorBit);
7116         vk::CmdBeginQuery(m_commandBuffer->handle(), query_pool, 0, 0);
7117         m_errorMonitor->VerifyNotFound();
7118 
7119         vk::CmdFillBuffer(m_commandBuffer->handle(), buffer, 0, 4096, 0);
7120 
7121         vk::CmdEndQuery(m_commandBuffer->handle(), query_pool, 0);
7122 
7123         m_commandBuffer->end();
7124 
7125         VkSubmitInfo submit_info;
7126         submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
7127         submit_info.pNext = NULL;
7128         submit_info.waitSemaphoreCount = 0;
7129         submit_info.pWaitSemaphores = NULL;
7130         submit_info.pWaitDstStageMask = NULL;
7131         submit_info.commandBufferCount = 1;
7132         submit_info.pCommandBuffers = &m_commandBuffer->handle();
7133         submit_info.signalSemaphoreCount = 0;
7134         submit_info.pSignalSemaphores = NULL;
7135         vk::QueueSubmit(queue, 1, &submit_info, VK_NULL_HANDLE);
7136         vk::QueueWaitIdle(queue);
7137 
7138         vk::DestroyBuffer(device(), buffer, nullptr);
7139         vk::FreeMemory(device(), mem, NULL);
7140     }
7141 
7142     vk::DestroyQueryPool(m_device->device(), query_pool, NULL);
7143 
7144     vkReleaseProfilingLockKHR(device());
7145 }
7146 
TEST_F(VkLayerTest,QueryPerformanceCounterRenderPassScope)7147 TEST_F(VkLayerTest, QueryPerformanceCounterRenderPassScope) {
7148     TEST_DESCRIPTION("Insert a performance query begin/end with respect to the render pass counter scope");
7149 
7150     if (InstanceExtensionSupported(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME)) {
7151         m_instance_extension_names.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
7152     } else {
7153         printf("%s Extension %s is not supported.\n", kSkipPrefix, VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
7154         return;
7155     }
7156     ASSERT_NO_FATAL_FAILURE(InitFramework(m_errorMonitor));
7157 
7158     if (DeviceExtensionSupported(gpu(), nullptr, VK_KHR_PERFORMANCE_QUERY_EXTENSION_NAME)) {
7159         m_device_extension_names.push_back(VK_KHR_PERFORMANCE_QUERY_EXTENSION_NAME);
7160     } else {
7161         printf("%s Extension %s is not supported.\n", kSkipPrefix, VK_KHR_PERFORMANCE_QUERY_EXTENSION_NAME);
7162         return;
7163     }
7164 
7165     PFN_vkGetPhysicalDeviceFeatures2KHR vkGetPhysicalDeviceFeatures2KHR =
7166         (PFN_vkGetPhysicalDeviceFeatures2KHR)vk::GetInstanceProcAddr(instance(), "vkGetPhysicalDeviceFeatures2KHR");
7167     ASSERT_TRUE(vkGetPhysicalDeviceFeatures2KHR != nullptr);
7168     VkPhysicalDeviceFeatures2KHR features2 = {};
7169     auto performanceFeatures = LvlInitStruct<VkPhysicalDevicePerformanceQueryFeaturesKHR>();
7170     features2 = LvlInitStruct<VkPhysicalDeviceFeatures2KHR>(&performanceFeatures);
7171     vkGetPhysicalDeviceFeatures2KHR(gpu(), &features2);
7172     if (!performanceFeatures.performanceCounterQueryPools) {
7173         printf("%s Performance query pools are not supported.\n", kSkipPrefix);
7174         return;
7175     }
7176 
7177     VkCommandPoolCreateFlags pool_flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT;
7178     ASSERT_NO_FATAL_FAILURE(InitState(nullptr, nullptr, pool_flags));
7179     PFN_vkEnumeratePhysicalDeviceQueueFamilyPerformanceQueryCountersKHR
7180         vkEnumeratePhysicalDeviceQueueFamilyPerformanceQueryCountersKHR =
7181             (PFN_vkEnumeratePhysicalDeviceQueueFamilyPerformanceQueryCountersKHR)vk::GetInstanceProcAddr(
7182                 instance(), "vkEnumeratePhysicalDeviceQueueFamilyPerformanceQueryCountersKHR");
7183     ASSERT_TRUE(vkEnumeratePhysicalDeviceQueueFamilyPerformanceQueryCountersKHR != nullptr);
7184 
7185     auto queueFamilyProperties = m_device->phy().queue_properties();
7186     uint32_t queueFamilyIndex = queueFamilyProperties.size();
7187     std::vector<VkPerformanceCounterKHR> counters;
7188     std::vector<uint32_t> counterIndices;
7189 
7190     // Find a single counter with VK_QUERY_SCOPE_RENDER_PASS_KHR scope.
7191     for (uint32_t idx = 0; idx < queueFamilyProperties.size(); idx++) {
7192         uint32_t nCounters;
7193 
7194         vkEnumeratePhysicalDeviceQueueFamilyPerformanceQueryCountersKHR(gpu(), idx, &nCounters, nullptr, nullptr);
7195         if (nCounters == 0) continue;
7196 
7197         counters.resize(nCounters);
7198         for (auto &c : counters) {
7199             c.sType = VK_STRUCTURE_TYPE_PERFORMANCE_COUNTER_KHR;
7200             c.pNext = nullptr;
7201         }
7202         vkEnumeratePhysicalDeviceQueueFamilyPerformanceQueryCountersKHR(gpu(), idx, &nCounters, &counters[0], nullptr);
7203         queueFamilyIndex = idx;
7204 
7205         for (uint32_t counterIdx = 0; counterIdx < counters.size(); counterIdx++) {
7206             if (counters[counterIdx].scope == VK_QUERY_SCOPE_RENDER_PASS_KHR) {
7207                 counterIndices.push_back(counterIdx);
7208                 break;
7209             }
7210         }
7211 
7212         if (counterIndices.empty()) {
7213             counters.clear();
7214             continue;
7215         }
7216         break;
7217     }
7218 
7219     if (counterIndices.empty()) {
7220         printf("%s No queue reported any performance counter with render pass scope.\n", kSkipPrefix);
7221         return;
7222     }
7223 
7224     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
7225 
7226     VkQueryPoolPerformanceCreateInfoKHR perf_query_pool_ci{};
7227     perf_query_pool_ci.sType = VK_STRUCTURE_TYPE_QUERY_POOL_PERFORMANCE_CREATE_INFO_KHR;
7228     perf_query_pool_ci.queueFamilyIndex = queueFamilyIndex;
7229     perf_query_pool_ci.counterIndexCount = counterIndices.size();
7230     perf_query_pool_ci.pCounterIndices = &counterIndices[0];
7231     VkQueryPoolCreateInfo query_pool_ci{};
7232     query_pool_ci.sType = VK_STRUCTURE_TYPE_QUERY_POOL_CREATE_INFO;
7233     query_pool_ci.pNext = &perf_query_pool_ci;
7234     query_pool_ci.queryType = VK_QUERY_TYPE_PERFORMANCE_QUERY_KHR;
7235     query_pool_ci.queryCount = 1;
7236 
7237     VkQueryPool query_pool;
7238     vk::CreateQueryPool(device(), &query_pool_ci, nullptr, &query_pool);
7239 
7240     VkQueue queue = VK_NULL_HANDLE;
7241     vk::GetDeviceQueue(device(), queueFamilyIndex, 0, &queue);
7242 
7243     PFN_vkAcquireProfilingLockKHR vkAcquireProfilingLockKHR =
7244         (PFN_vkAcquireProfilingLockKHR)vk::GetInstanceProcAddr(instance(), "vkAcquireProfilingLockKHR");
7245     ASSERT_TRUE(vkAcquireProfilingLockKHR != nullptr);
7246     PFN_vkReleaseProfilingLockKHR vkReleaseProfilingLockKHR =
7247         (PFN_vkReleaseProfilingLockKHR)vk::GetInstanceProcAddr(instance(), "vkReleaseProfilingLockKHR");
7248     ASSERT_TRUE(vkReleaseProfilingLockKHR != nullptr);
7249 
7250     {
7251         VkAcquireProfilingLockInfoKHR lock_info{};
7252         lock_info.sType = VK_STRUCTURE_TYPE_ACQUIRE_PROFILING_LOCK_INFO_KHR;
7253         VkResult result = vkAcquireProfilingLockKHR(device(), &lock_info);
7254         ASSERT_TRUE(result == VK_SUCCESS);
7255     }
7256 
7257     // Inside a render pass.
7258     {
7259         m_commandBuffer->begin();
7260         m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
7261 
7262         m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdBeginQuery-queryPool-03225");
7263         vk::CmdBeginQuery(m_commandBuffer->handle(), query_pool, 0, 0);
7264         m_errorMonitor->VerifyFound();
7265 
7266         m_commandBuffer->EndRenderPass();
7267         m_commandBuffer->end();
7268 
7269         VkSubmitInfo submit_info;
7270         submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
7271         submit_info.pNext = NULL;
7272         submit_info.waitSemaphoreCount = 0;
7273         submit_info.pWaitSemaphores = NULL;
7274         submit_info.pWaitDstStageMask = NULL;
7275         submit_info.commandBufferCount = 1;
7276         submit_info.pCommandBuffers = &m_commandBuffer->handle();
7277         submit_info.signalSemaphoreCount = 0;
7278         submit_info.pSignalSemaphores = NULL;
7279         vk::QueueSubmit(queue, 1, &submit_info, VK_NULL_HANDLE);
7280         vk::QueueWaitIdle(queue);
7281     }
7282 
7283     vkReleaseProfilingLockKHR(device());
7284 
7285     vk::DestroyQueryPool(m_device->device(), query_pool, NULL);
7286 }
7287 
TEST_F(VkLayerTest,QueryPerformanceReleaseProfileLockBeforeSubmit)7288 TEST_F(VkLayerTest, QueryPerformanceReleaseProfileLockBeforeSubmit) {
7289     TEST_DESCRIPTION("Verify that we get an error if we release the profiling lock during the recording of performance queries");
7290 
7291     if (InstanceExtensionSupported(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME)) {
7292         m_instance_extension_names.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
7293     } else {
7294         printf("%s Extension %s is not supported.\n", kSkipPrefix, VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
7295         return;
7296     }
7297     ASSERT_NO_FATAL_FAILURE(InitFramework(m_errorMonitor));
7298 
7299     if (DeviceExtensionSupported(gpu(), nullptr, VK_KHR_PERFORMANCE_QUERY_EXTENSION_NAME)) {
7300         m_device_extension_names.push_back(VK_KHR_PERFORMANCE_QUERY_EXTENSION_NAME);
7301     } else {
7302         printf("%s Extension %s is not supported.\n", kSkipPrefix, VK_KHR_PERFORMANCE_QUERY_EXTENSION_NAME);
7303         return;
7304     }
7305 
7306     PFN_vkGetPhysicalDeviceFeatures2KHR vkGetPhysicalDeviceFeatures2KHR =
7307         (PFN_vkGetPhysicalDeviceFeatures2KHR)vk::GetInstanceProcAddr(instance(), "vkGetPhysicalDeviceFeatures2KHR");
7308     ASSERT_TRUE(vkGetPhysicalDeviceFeatures2KHR != nullptr);
7309     VkPhysicalDeviceFeatures2KHR features2 = {};
7310     auto performanceFeatures = LvlInitStruct<VkPhysicalDevicePerformanceQueryFeaturesKHR>();
7311     features2 = LvlInitStruct<VkPhysicalDeviceFeatures2KHR>(&performanceFeatures);
7312     vkGetPhysicalDeviceFeatures2KHR(gpu(), &features2);
7313     if (!performanceFeatures.performanceCounterQueryPools) {
7314         printf("%s Performance query pools are not supported.\n", kSkipPrefix);
7315         return;
7316     }
7317 
7318     VkCommandPoolCreateFlags pool_flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT;
7319     ASSERT_NO_FATAL_FAILURE(InitState(nullptr, &performanceFeatures, pool_flags));
7320     PFN_vkEnumeratePhysicalDeviceQueueFamilyPerformanceQueryCountersKHR
7321         vkEnumeratePhysicalDeviceQueueFamilyPerformanceQueryCountersKHR =
7322             (PFN_vkEnumeratePhysicalDeviceQueueFamilyPerformanceQueryCountersKHR)vk::GetInstanceProcAddr(
7323                 instance(), "vkEnumeratePhysicalDeviceQueueFamilyPerformanceQueryCountersKHR");
7324     ASSERT_TRUE(vkEnumeratePhysicalDeviceQueueFamilyPerformanceQueryCountersKHR != nullptr);
7325 
7326     auto queueFamilyProperties = m_device->phy().queue_properties();
7327     uint32_t queueFamilyIndex = queueFamilyProperties.size();
7328     std::vector<VkPerformanceCounterKHR> counters;
7329     std::vector<uint32_t> counterIndices;
7330 
7331     // Find a single counter with VK_QUERY_SCOPE_COMMAND_KHR scope.
7332     for (uint32_t idx = 0; idx < queueFamilyProperties.size(); idx++) {
7333         uint32_t nCounters;
7334 
7335         vkEnumeratePhysicalDeviceQueueFamilyPerformanceQueryCountersKHR(gpu(), idx, &nCounters, nullptr, nullptr);
7336         if (nCounters == 0) continue;
7337 
7338         counters.resize(nCounters);
7339         for (auto &c : counters) {
7340             c.sType = VK_STRUCTURE_TYPE_PERFORMANCE_COUNTER_KHR;
7341             c.pNext = nullptr;
7342         }
7343         vkEnumeratePhysicalDeviceQueueFamilyPerformanceQueryCountersKHR(gpu(), idx, &nCounters, &counters[0], nullptr);
7344         queueFamilyIndex = idx;
7345 
7346         for (uint32_t counterIdx = 0; counterIdx < counters.size(); counterIdx++) {
7347             if (counters[counterIdx].scope == VK_QUERY_SCOPE_COMMAND_KHR) {
7348                 counterIndices.push_back(counterIdx);
7349                 break;
7350             }
7351         }
7352 
7353         if (counterIndices.empty()) {
7354             counters.clear();
7355             continue;
7356         }
7357         break;
7358     }
7359 
7360     if (counterIndices.empty()) {
7361         printf("%s No queue reported any performance counter with render pass scope.\n", kSkipPrefix);
7362         return;
7363     }
7364 
7365     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
7366 
7367     VkQueryPoolPerformanceCreateInfoKHR perf_query_pool_ci{};
7368     perf_query_pool_ci.sType = VK_STRUCTURE_TYPE_QUERY_POOL_PERFORMANCE_CREATE_INFO_KHR;
7369     perf_query_pool_ci.queueFamilyIndex = queueFamilyIndex;
7370     perf_query_pool_ci.counterIndexCount = counterIndices.size();
7371     perf_query_pool_ci.pCounterIndices = &counterIndices[0];
7372     VkQueryPoolCreateInfo query_pool_ci{};
7373     query_pool_ci.sType = VK_STRUCTURE_TYPE_QUERY_POOL_CREATE_INFO;
7374     query_pool_ci.pNext = &perf_query_pool_ci;
7375     query_pool_ci.queryType = VK_QUERY_TYPE_PERFORMANCE_QUERY_KHR;
7376     query_pool_ci.queryCount = 1;
7377 
7378     VkQueryPool query_pool;
7379     vk::CreateQueryPool(device(), &query_pool_ci, nullptr, &query_pool);
7380 
7381     VkQueue queue = VK_NULL_HANDLE;
7382     vk::GetDeviceQueue(device(), queueFamilyIndex, 0, &queue);
7383 
7384     PFN_vkAcquireProfilingLockKHR vkAcquireProfilingLockKHR =
7385         (PFN_vkAcquireProfilingLockKHR)vk::GetInstanceProcAddr(instance(), "vkAcquireProfilingLockKHR");
7386     ASSERT_TRUE(vkAcquireProfilingLockKHR != nullptr);
7387     PFN_vkReleaseProfilingLockKHR vkReleaseProfilingLockKHR =
7388         (PFN_vkReleaseProfilingLockKHR)vk::GetInstanceProcAddr(instance(), "vkReleaseProfilingLockKHR");
7389     ASSERT_TRUE(vkReleaseProfilingLockKHR != nullptr);
7390 
7391     {
7392         VkAcquireProfilingLockInfoKHR lock_info{};
7393         lock_info.sType = VK_STRUCTURE_TYPE_ACQUIRE_PROFILING_LOCK_INFO_KHR;
7394         VkResult result = vkAcquireProfilingLockKHR(device(), &lock_info);
7395         ASSERT_TRUE(result == VK_SUCCESS);
7396     }
7397 
7398     {
7399         m_commandBuffer->reset();
7400         m_commandBuffer->begin();
7401         vk::CmdResetQueryPool(m_commandBuffer->handle(), query_pool, 0, 1);
7402         m_commandBuffer->end();
7403 
7404         VkSubmitInfo submit_info;
7405         submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
7406         submit_info.pNext = NULL;
7407         submit_info.waitSemaphoreCount = 0;
7408         submit_info.pWaitSemaphores = NULL;
7409         submit_info.pWaitDstStageMask = NULL;
7410         submit_info.commandBufferCount = 1;
7411         submit_info.pCommandBuffers = &m_commandBuffer->handle();
7412         submit_info.signalSemaphoreCount = 0;
7413         submit_info.pSignalSemaphores = NULL;
7414 
7415         vk::QueueSubmit(queue, 1, &submit_info, VK_NULL_HANDLE);
7416         vk::QueueWaitIdle(queue);
7417     }
7418 
7419     {
7420         VkBufferCreateInfo buf_info = {};
7421         buf_info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
7422         buf_info.usage = VK_BUFFER_USAGE_TRANSFER_DST_BIT;
7423         buf_info.size = 4096;
7424         buf_info.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
7425         VkBuffer buffer;
7426         VkResult err = vk::CreateBuffer(device(), &buf_info, NULL, &buffer);
7427         ASSERT_VK_SUCCESS(err);
7428 
7429         VkMemoryRequirements mem_reqs;
7430         vk::GetBufferMemoryRequirements(device(), buffer, &mem_reqs);
7431 
7432         VkMemoryAllocateInfo alloc_info = {};
7433         alloc_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
7434         alloc_info.allocationSize = 4096;
7435         VkDeviceMemory mem;
7436         err = vk::AllocateMemory(device(), &alloc_info, NULL, &mem);
7437         ASSERT_VK_SUCCESS(err);
7438         vk::BindBufferMemory(device(), buffer, mem, 0);
7439 
7440         m_commandBuffer->reset();
7441         m_commandBuffer->begin();
7442 
7443         vk::CmdBeginQuery(m_commandBuffer->handle(), query_pool, 0, 0);
7444 
7445         // Release while recording.
7446         vkReleaseProfilingLockKHR(device());
7447         {
7448             VkAcquireProfilingLockInfoKHR lock_info{};
7449             lock_info.sType = VK_STRUCTURE_TYPE_ACQUIRE_PROFILING_LOCK_INFO_KHR;
7450             VkResult result = vkAcquireProfilingLockKHR(device(), &lock_info);
7451             ASSERT_TRUE(result == VK_SUCCESS);
7452         }
7453 
7454         vk::CmdEndQuery(m_commandBuffer->handle(), query_pool, 0);
7455 
7456         m_commandBuffer->end();
7457 
7458         VkSubmitInfo submit_info;
7459         submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
7460         submit_info.pNext = NULL;
7461         submit_info.waitSemaphoreCount = 0;
7462         submit_info.pWaitSemaphores = NULL;
7463         submit_info.pWaitDstStageMask = NULL;
7464         submit_info.commandBufferCount = 1;
7465         submit_info.pCommandBuffers = &m_commandBuffer->handle();
7466         submit_info.signalSemaphoreCount = 0;
7467         submit_info.pSignalSemaphores = NULL;
7468 
7469         m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkQueueSubmit-pCommandBuffers-03220");
7470         vk::QueueSubmit(queue, 1, &submit_info, VK_NULL_HANDLE);
7471         m_errorMonitor->VerifyFound();
7472 
7473         vk::QueueWaitIdle(queue);
7474 
7475         vk::DestroyBuffer(device(), buffer, nullptr);
7476         vk::FreeMemory(device(), mem, NULL);
7477     }
7478 
7479     vkReleaseProfilingLockKHR(device());
7480 
7481     vk::DestroyQueryPool(m_device->device(), query_pool, NULL);
7482 }
7483 
TEST_F(VkLayerTest,QueryPerformanceIncompletePasses)7484 TEST_F(VkLayerTest, QueryPerformanceIncompletePasses) {
7485     TEST_DESCRIPTION("Verify that we get an error if we don't submit a command buffer for each passes before getting the results.");
7486 
7487     if (InstanceExtensionSupported(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME)) {
7488         m_instance_extension_names.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
7489     } else {
7490         printf("%s Extension %s is not supported.\n", kSkipPrefix, VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
7491         return;
7492     }
7493     ASSERT_NO_FATAL_FAILURE(InitFramework(m_errorMonitor));
7494 
7495     if (DeviceExtensionSupported(gpu(), nullptr, VK_KHR_PERFORMANCE_QUERY_EXTENSION_NAME)) {
7496         m_device_extension_names.push_back(VK_KHR_PERFORMANCE_QUERY_EXTENSION_NAME);
7497     } else {
7498         printf("%s Extension %s is not supported.\n", kSkipPrefix, VK_KHR_PERFORMANCE_QUERY_EXTENSION_NAME);
7499         return;
7500     }
7501     if (DeviceExtensionSupported(gpu(), nullptr, VK_EXT_HOST_QUERY_RESET_EXTENSION_NAME)) {
7502         m_device_extension_names.push_back(VK_EXT_HOST_QUERY_RESET_EXTENSION_NAME);
7503     } else {
7504         printf("%s Extension %s is not supported.\n", kSkipPrefix, VK_EXT_HOST_QUERY_RESET_EXTENSION_NAME);
7505         return;
7506     }
7507 
7508     PFN_vkGetPhysicalDeviceFeatures2KHR vkGetPhysicalDeviceFeatures2KHR =
7509         (PFN_vkGetPhysicalDeviceFeatures2KHR)vk::GetInstanceProcAddr(instance(), "vkGetPhysicalDeviceFeatures2KHR");
7510     ASSERT_TRUE(vkGetPhysicalDeviceFeatures2KHR != nullptr);
7511     VkPhysicalDeviceFeatures2KHR features2 = {};
7512     auto hostQueryResetFeatures = LvlInitStruct<VkPhysicalDeviceHostQueryResetFeaturesEXT>();
7513     auto performanceFeatures = LvlInitStruct<VkPhysicalDevicePerformanceQueryFeaturesKHR>(&hostQueryResetFeatures);
7514     features2 = LvlInitStruct<VkPhysicalDeviceFeatures2KHR>(&performanceFeatures);
7515     vkGetPhysicalDeviceFeatures2KHR(gpu(), &features2);
7516     if (!performanceFeatures.performanceCounterQueryPools) {
7517         printf("%s Performance query pools are not supported.\n", kSkipPrefix);
7518         return;
7519     }
7520     if (!hostQueryResetFeatures.hostQueryReset) {
7521         printf("%s Missing host query reset.\n", kSkipPrefix);
7522         return;
7523     }
7524 
7525     VkCommandPoolCreateFlags pool_flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT;
7526     ASSERT_NO_FATAL_FAILURE(InitState(nullptr, &performanceFeatures, pool_flags));
7527     PFN_vkEnumeratePhysicalDeviceQueueFamilyPerformanceQueryCountersKHR
7528         vkEnumeratePhysicalDeviceQueueFamilyPerformanceQueryCountersKHR =
7529             (PFN_vkEnumeratePhysicalDeviceQueueFamilyPerformanceQueryCountersKHR)vk::GetInstanceProcAddr(
7530                 instance(), "vkEnumeratePhysicalDeviceQueueFamilyPerformanceQueryCountersKHR");
7531     ASSERT_TRUE(vkEnumeratePhysicalDeviceQueueFamilyPerformanceQueryCountersKHR != nullptr);
7532 
7533     PFN_vkGetPhysicalDeviceQueueFamilyPerformanceQueryPassesKHR vkGetPhysicalDeviceQueueFamilyPerformanceQueryPassesKHR =
7534         (PFN_vkGetPhysicalDeviceQueueFamilyPerformanceQueryPassesKHR)vk::GetInstanceProcAddr(
7535             instance(), "vkGetPhysicalDeviceQueueFamilyPerformanceQueryPassesKHR");
7536     ASSERT_TRUE(vkGetPhysicalDeviceQueueFamilyPerformanceQueryPassesKHR != nullptr);
7537 
7538     auto queueFamilyProperties = m_device->phy().queue_properties();
7539     uint32_t queueFamilyIndex = queueFamilyProperties.size();
7540     std::vector<VkPerformanceCounterKHR> counters;
7541     std::vector<uint32_t> counterIndices;
7542     uint32_t nPasses = 0;
7543 
7544     // Find all counters with VK_QUERY_SCOPE_COMMAND_KHR scope.
7545     for (uint32_t idx = 0; idx < queueFamilyProperties.size(); idx++) {
7546         uint32_t nCounters;
7547 
7548         vkEnumeratePhysicalDeviceQueueFamilyPerformanceQueryCountersKHR(gpu(), idx, &nCounters, nullptr, nullptr);
7549         if (nCounters == 0) continue;
7550 
7551         counters.resize(nCounters);
7552         for (auto &c : counters) {
7553             c.sType = VK_STRUCTURE_TYPE_PERFORMANCE_COUNTER_KHR;
7554             c.pNext = nullptr;
7555         }
7556         vkEnumeratePhysicalDeviceQueueFamilyPerformanceQueryCountersKHR(gpu(), idx, &nCounters, &counters[0], nullptr);
7557         queueFamilyIndex = idx;
7558 
7559         for (uint32_t counterIdx = 0; counterIdx < counters.size(); counterIdx++) {
7560             if (counters[counterIdx].scope == VK_QUERY_SCOPE_COMMAND_KHR) counterIndices.push_back(counterIdx);
7561         }
7562 
7563         VkQueryPoolPerformanceCreateInfoKHR create_info{};
7564         create_info.sType = VK_STRUCTURE_TYPE_QUERY_POOL_PERFORMANCE_CREATE_INFO_KHR;
7565         create_info.queueFamilyIndex = idx;
7566         create_info.counterIndexCount = counterIndices.size();
7567         create_info.pCounterIndices = &counterIndices[0];
7568 
7569         vkGetPhysicalDeviceQueueFamilyPerformanceQueryPassesKHR(gpu(), &create_info, &nPasses);
7570 
7571         if (nPasses < 2) {
7572             counters.clear();
7573             continue;
7574         }
7575         break;
7576     }
7577 
7578     if (counterIndices.empty()) {
7579         printf("%s No queue reported a set of counters that needs more than one pass.\n", kSkipPrefix);
7580         return;
7581     }
7582 
7583     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
7584 
7585     VkQueryPoolPerformanceCreateInfoKHR perf_query_pool_ci{};
7586     perf_query_pool_ci.sType = VK_STRUCTURE_TYPE_QUERY_POOL_PERFORMANCE_CREATE_INFO_KHR;
7587     perf_query_pool_ci.queueFamilyIndex = queueFamilyIndex;
7588     perf_query_pool_ci.counterIndexCount = counterIndices.size();
7589     perf_query_pool_ci.pCounterIndices = &counterIndices[0];
7590     VkQueryPoolCreateInfo query_pool_ci{};
7591     query_pool_ci.sType = VK_STRUCTURE_TYPE_QUERY_POOL_CREATE_INFO;
7592     query_pool_ci.pNext = &perf_query_pool_ci;
7593     query_pool_ci.queryType = VK_QUERY_TYPE_PERFORMANCE_QUERY_KHR;
7594     query_pool_ci.queryCount = 1;
7595 
7596     VkQueryPool query_pool;
7597     vk::CreateQueryPool(device(), &query_pool_ci, nullptr, &query_pool);
7598 
7599     VkQueue queue = VK_NULL_HANDLE;
7600     vk::GetDeviceQueue(device(), queueFamilyIndex, 0, &queue);
7601 
7602     PFN_vkAcquireProfilingLockKHR vkAcquireProfilingLockKHR =
7603         (PFN_vkAcquireProfilingLockKHR)vk::GetInstanceProcAddr(instance(), "vkAcquireProfilingLockKHR");
7604     ASSERT_TRUE(vkAcquireProfilingLockKHR != nullptr);
7605     PFN_vkReleaseProfilingLockKHR vkReleaseProfilingLockKHR =
7606         (PFN_vkReleaseProfilingLockKHR)vk::GetInstanceProcAddr(instance(), "vkReleaseProfilingLockKHR");
7607     ASSERT_TRUE(vkReleaseProfilingLockKHR != nullptr);
7608     PFN_vkResetQueryPoolEXT fpvkResetQueryPoolEXT =
7609         (PFN_vkResetQueryPoolEXT)vk::GetInstanceProcAddr(instance(), "vkResetQueryPoolEXT");
7610 
7611     {
7612         VkAcquireProfilingLockInfoKHR lock_info{};
7613         lock_info.sType = VK_STRUCTURE_TYPE_ACQUIRE_PROFILING_LOCK_INFO_KHR;
7614         VkResult result = vkAcquireProfilingLockKHR(device(), &lock_info);
7615         ASSERT_TRUE(result == VK_SUCCESS);
7616     }
7617 
7618     {
7619         VkBufferCreateInfo buf_info = {};
7620         buf_info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
7621         buf_info.usage = VK_BUFFER_USAGE_TRANSFER_DST_BIT;
7622         buf_info.size = 4096;
7623         buf_info.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
7624         VkBuffer buffer;
7625         VkResult err = vk::CreateBuffer(device(), &buf_info, NULL, &buffer);
7626         ASSERT_VK_SUCCESS(err);
7627 
7628         VkMemoryRequirements mem_reqs;
7629         vk::GetBufferMemoryRequirements(device(), buffer, &mem_reqs);
7630 
7631         VkMemoryAllocateInfo alloc_info = {};
7632         alloc_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
7633         alloc_info.allocationSize = 4096;
7634         VkDeviceMemory mem;
7635         err = vk::AllocateMemory(device(), &alloc_info, NULL, &mem);
7636         ASSERT_VK_SUCCESS(err);
7637         vk::BindBufferMemory(device(), buffer, mem, 0);
7638 
7639         VkCommandBufferBeginInfo command_buffer_begin_info{};
7640         command_buffer_begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
7641         command_buffer_begin_info.flags = VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT;
7642 
7643         fpvkResetQueryPoolEXT(m_device->device(), query_pool, 0, 1);
7644 
7645         m_commandBuffer->begin(&command_buffer_begin_info);
7646         vk::CmdBeginQuery(m_commandBuffer->handle(), query_pool, 0, 0);
7647         vk::CmdFillBuffer(m_commandBuffer->handle(), buffer, 0, 4096, 0);
7648         vk::CmdEndQuery(m_commandBuffer->handle(), query_pool, 0);
7649         m_commandBuffer->end();
7650 
7651         // Invalid pass index
7652         {
7653             VkPerformanceQuerySubmitInfoKHR perf_submit_info{};
7654             perf_submit_info.sType = VK_STRUCTURE_TYPE_PERFORMANCE_QUERY_SUBMIT_INFO_KHR;
7655             perf_submit_info.counterPassIndex = nPasses;
7656             VkSubmitInfo submit_info{};
7657             submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
7658             submit_info.pNext = &perf_submit_info;
7659             submit_info.waitSemaphoreCount = 0;
7660             submit_info.pWaitSemaphores = NULL;
7661             submit_info.pWaitDstStageMask = NULL;
7662             submit_info.commandBufferCount = 1;
7663             submit_info.pCommandBuffers = &m_commandBuffer->handle();
7664             submit_info.signalSemaphoreCount = 0;
7665             submit_info.pSignalSemaphores = NULL;
7666 
7667             m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkPerformanceQuerySubmitInfoKHR-counterPassIndex-03221");
7668             vk::QueueSubmit(queue, 1, &submit_info, VK_NULL_HANDLE);
7669             m_errorMonitor->VerifyFound();
7670         }
7671 
7672         // Leave the last pass out.
7673         for (uint32_t passIdx = 0; passIdx < (nPasses - 1); passIdx++) {
7674             VkPerformanceQuerySubmitInfoKHR perf_submit_info{};
7675             perf_submit_info.sType = VK_STRUCTURE_TYPE_PERFORMANCE_QUERY_SUBMIT_INFO_KHR;
7676             perf_submit_info.counterPassIndex = passIdx;
7677             VkSubmitInfo submit_info{};
7678             submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
7679             submit_info.pNext = &perf_submit_info;
7680             submit_info.waitSemaphoreCount = 0;
7681             submit_info.pWaitSemaphores = NULL;
7682             submit_info.pWaitDstStageMask = NULL;
7683             submit_info.commandBufferCount = 1;
7684             submit_info.pCommandBuffers = &m_commandBuffer->handle();
7685             submit_info.signalSemaphoreCount = 0;
7686             submit_info.pSignalSemaphores = NULL;
7687 
7688             vk::QueueSubmit(queue, 1, &submit_info, VK_NULL_HANDLE);
7689         }
7690 
7691         vk::QueueWaitIdle(queue);
7692 
7693         std::vector<VkPerformanceCounterResultKHR> results;
7694         results.resize(counterIndices.size());
7695 
7696         // The stride is too small to return the data
7697         if (counterIndices.size() > 2) {
7698             m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkGetQueryPoolResults-queryType-04519");
7699             vk::GetQueryPoolResults(m_device->device(), query_pool, 0, 1, sizeof(VkPerformanceCounterResultKHR) * results.size(),
7700                                     &results[0], sizeof(VkPerformanceCounterResultKHR) * (results.size() - 1), 0);
7701             m_errorMonitor->VerifyFound();
7702         } else {
7703             printf("%s Require counterIndexCount > two for the PerformanceCounterResult stride test, skipping.\n", kSkipPrefix);
7704         }
7705 
7706         m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkGetQueryPoolResults-queryType-03231");
7707         vk::GetQueryPoolResults(device(), query_pool, 0, 1, sizeof(VkPerformanceCounterResultKHR) * results.size(), &results[0],
7708                                 sizeof(VkPerformanceCounterResultKHR) * results.size(), VK_QUERY_RESULT_WAIT_BIT);
7709         m_errorMonitor->VerifyFound();
7710 
7711         {
7712             VkPerformanceQuerySubmitInfoKHR perf_submit_info{};
7713             perf_submit_info.sType = VK_STRUCTURE_TYPE_PERFORMANCE_QUERY_SUBMIT_INFO_KHR;
7714             perf_submit_info.counterPassIndex = nPasses - 1;
7715             VkSubmitInfo submit_info{};
7716             submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
7717             submit_info.pNext = &perf_submit_info;
7718             submit_info.waitSemaphoreCount = 0;
7719             submit_info.pWaitSemaphores = NULL;
7720             submit_info.pWaitDstStageMask = NULL;
7721             submit_info.commandBufferCount = 1;
7722             submit_info.pCommandBuffers = &m_commandBuffer->handle();
7723             submit_info.signalSemaphoreCount = 0;
7724             submit_info.pSignalSemaphores = NULL;
7725 
7726             vk::QueueSubmit(queue, 1, &submit_info, VK_NULL_HANDLE);
7727         }
7728 
7729         vk::QueueWaitIdle(queue);
7730 
7731         // Invalid stride
7732         {
7733             std::vector<VkPerformanceCounterResultKHR> results_invalid_stride;
7734             results_invalid_stride.resize(counterIndices.size() * 2);
7735             m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkGetQueryPoolResults-queryType-03229");
7736             vk::GetQueryPoolResults(
7737                 device(), query_pool, 0, 1, sizeof(VkPerformanceCounterResultKHR) * results_invalid_stride.size(),
7738                 &results_invalid_stride[0], sizeof(VkPerformanceCounterResultKHR) * results_invalid_stride.size() + 4,
7739                 VK_QUERY_RESULT_WAIT_BIT);
7740             m_errorMonitor->VerifyFound();
7741         }
7742 
7743         // Invalid flags
7744         m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkGetQueryPoolResults-queryType-03230");
7745         vk::GetQueryPoolResults(device(), query_pool, 0, 1, sizeof(VkPerformanceCounterResultKHR) * results.size(), &results[0],
7746                                 sizeof(VkPerformanceCounterResultKHR) * results.size(), VK_QUERY_RESULT_WITH_AVAILABILITY_BIT);
7747         m_errorMonitor->VerifyFound();
7748         m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkGetQueryPoolResults-queryType-03230");
7749         vk::GetQueryPoolResults(device(), query_pool, 0, 1, sizeof(VkPerformanceCounterResultKHR) * results.size(), &results[0],
7750                                 sizeof(VkPerformanceCounterResultKHR) * results.size(), VK_QUERY_RESULT_PARTIAL_BIT);
7751         m_errorMonitor->VerifyFound();
7752         m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkGetQueryPoolResults-queryType-03230");
7753         vk::GetQueryPoolResults(device(), query_pool, 0, 1, sizeof(VkPerformanceCounterResultKHR) * results.size(), &results[0],
7754                                 sizeof(VkPerformanceCounterResultKHR) * results.size(), VK_QUERY_RESULT_64_BIT);
7755         m_errorMonitor->VerifyFound();
7756 
7757         m_errorMonitor->ExpectSuccess(kErrorBit);
7758         vk::GetQueryPoolResults(device(), query_pool, 0, 1, sizeof(VkPerformanceCounterResultKHR) * results.size(), &results[0],
7759                                 sizeof(VkPerformanceCounterResultKHR) * results.size(), VK_QUERY_RESULT_WAIT_BIT);
7760         m_errorMonitor->VerifyNotFound();
7761 
7762         vk::DestroyBuffer(device(), buffer, nullptr);
7763         vk::FreeMemory(device(), mem, NULL);
7764     }
7765 
7766     vkReleaseProfilingLockKHR(device());
7767 
7768     vk::DestroyQueryPool(m_device->device(), query_pool, NULL);
7769 }
7770 
TEST_F(VkLayerTest,QueryPerformanceResetAndBegin)7771 TEST_F(VkLayerTest, QueryPerformanceResetAndBegin) {
7772     TEST_DESCRIPTION("Verify that we get an error if we reset & begin a performance query within the same primary command buffer.");
7773 
7774     if (InstanceExtensionSupported(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME)) {
7775         m_instance_extension_names.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
7776     } else {
7777         printf("%s Extension %s is not supported.\n", kSkipPrefix, VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
7778         return;
7779     }
7780     ASSERT_NO_FATAL_FAILURE(InitFramework(m_errorMonitor));
7781 
7782     if (DeviceExtensionSupported(gpu(), nullptr, VK_KHR_PERFORMANCE_QUERY_EXTENSION_NAME)) {
7783         m_device_extension_names.push_back(VK_KHR_PERFORMANCE_QUERY_EXTENSION_NAME);
7784     } else {
7785         printf("%s Extension %s is not supported.\n", kSkipPrefix, VK_KHR_PERFORMANCE_QUERY_EXTENSION_NAME);
7786         return;
7787     }
7788     if (DeviceExtensionSupported(gpu(), nullptr, VK_EXT_HOST_QUERY_RESET_EXTENSION_NAME)) {
7789         m_device_extension_names.push_back(VK_EXT_HOST_QUERY_RESET_EXTENSION_NAME);
7790     } else {
7791         printf("%s Extension %s is not supported.\n", kSkipPrefix, VK_EXT_HOST_QUERY_RESET_EXTENSION_NAME);
7792         return;
7793     }
7794 
7795     PFN_vkGetPhysicalDeviceFeatures2KHR vkGetPhysicalDeviceFeatures2KHR =
7796         (PFN_vkGetPhysicalDeviceFeatures2KHR)vk::GetInstanceProcAddr(instance(), "vkGetPhysicalDeviceFeatures2KHR");
7797     ASSERT_TRUE(vkGetPhysicalDeviceFeatures2KHR != nullptr);
7798     VkPhysicalDeviceFeatures2KHR features2 = {};
7799     auto hostQueryResetFeatures = LvlInitStruct<VkPhysicalDeviceHostQueryResetFeaturesEXT>();
7800     auto performanceFeatures = LvlInitStruct<VkPhysicalDevicePerformanceQueryFeaturesKHR>(&hostQueryResetFeatures);
7801     features2 = LvlInitStruct<VkPhysicalDeviceFeatures2KHR>(&performanceFeatures);
7802     vkGetPhysicalDeviceFeatures2KHR(gpu(), &features2);
7803     if (!performanceFeatures.performanceCounterQueryPools) {
7804         printf("%s Performance query pools are not supported.\n", kSkipPrefix);
7805         return;
7806     }
7807     if (!hostQueryResetFeatures.hostQueryReset) {
7808         printf("%s Missing host query reset.\n", kSkipPrefix);
7809         return;
7810     }
7811 
7812     VkCommandPoolCreateFlags pool_flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT;
7813     ASSERT_NO_FATAL_FAILURE(InitState(nullptr, &performanceFeatures, pool_flags));
7814     PFN_vkEnumeratePhysicalDeviceQueueFamilyPerformanceQueryCountersKHR
7815         vkEnumeratePhysicalDeviceQueueFamilyPerformanceQueryCountersKHR =
7816             (PFN_vkEnumeratePhysicalDeviceQueueFamilyPerformanceQueryCountersKHR)vk::GetInstanceProcAddr(
7817                 instance(), "vkEnumeratePhysicalDeviceQueueFamilyPerformanceQueryCountersKHR");
7818     ASSERT_TRUE(vkEnumeratePhysicalDeviceQueueFamilyPerformanceQueryCountersKHR != nullptr);
7819 
7820     PFN_vkGetPhysicalDeviceQueueFamilyPerformanceQueryPassesKHR vkGetPhysicalDeviceQueueFamilyPerformanceQueryPassesKHR =
7821         (PFN_vkGetPhysicalDeviceQueueFamilyPerformanceQueryPassesKHR)vk::GetInstanceProcAddr(
7822             instance(), "vkGetPhysicalDeviceQueueFamilyPerformanceQueryPassesKHR");
7823     ASSERT_TRUE(vkGetPhysicalDeviceQueueFamilyPerformanceQueryPassesKHR != nullptr);
7824 
7825     auto queueFamilyProperties = m_device->phy().queue_properties();
7826     uint32_t queueFamilyIndex = queueFamilyProperties.size();
7827     std::vector<VkPerformanceCounterKHR> counters;
7828     std::vector<uint32_t> counterIndices;
7829 
7830     // Find a single counter with VK_QUERY_SCOPE_COMMAND_KHR scope.
7831     for (uint32_t idx = 0; idx < queueFamilyProperties.size(); idx++) {
7832         uint32_t nCounters;
7833 
7834         vkEnumeratePhysicalDeviceQueueFamilyPerformanceQueryCountersKHR(gpu(), idx, &nCounters, nullptr, nullptr);
7835         if (nCounters == 0) continue;
7836 
7837         counters.resize(nCounters);
7838         for (auto &c : counters) {
7839             c.sType = VK_STRUCTURE_TYPE_PERFORMANCE_COUNTER_KHR;
7840             c.pNext = nullptr;
7841         }
7842         vkEnumeratePhysicalDeviceQueueFamilyPerformanceQueryCountersKHR(gpu(), idx, &nCounters, &counters[0], nullptr);
7843         queueFamilyIndex = idx;
7844 
7845         for (uint32_t counterIdx = 0; counterIdx < counters.size(); counterIdx++) {
7846             if (counters[counterIdx].scope == VK_QUERY_SCOPE_COMMAND_KHR) {
7847                 counterIndices.push_back(counterIdx);
7848                 break;
7849             }
7850         }
7851         break;
7852     }
7853 
7854     if (counterIndices.empty()) {
7855         printf("%s No queue reported a set of counters that needs more than one pass.\n", kSkipPrefix);
7856         return;
7857     }
7858 
7859     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
7860 
7861     VkQueryPoolPerformanceCreateInfoKHR perf_query_pool_ci{};
7862     perf_query_pool_ci.sType = VK_STRUCTURE_TYPE_QUERY_POOL_PERFORMANCE_CREATE_INFO_KHR;
7863     perf_query_pool_ci.queueFamilyIndex = queueFamilyIndex;
7864     perf_query_pool_ci.counterIndexCount = counterIndices.size();
7865     perf_query_pool_ci.pCounterIndices = &counterIndices[0];
7866     VkQueryPoolCreateInfo query_pool_ci{};
7867     query_pool_ci.sType = VK_STRUCTURE_TYPE_QUERY_POOL_CREATE_INFO;
7868     query_pool_ci.pNext = &perf_query_pool_ci;
7869     query_pool_ci.queryType = VK_QUERY_TYPE_PERFORMANCE_QUERY_KHR;
7870     query_pool_ci.queryCount = 1;
7871 
7872     VkQueryPool query_pool;
7873     vk::CreateQueryPool(device(), &query_pool_ci, nullptr, &query_pool);
7874 
7875     VkQueue queue = VK_NULL_HANDLE;
7876     vk::GetDeviceQueue(device(), queueFamilyIndex, 0, &queue);
7877 
7878     PFN_vkAcquireProfilingLockKHR vkAcquireProfilingLockKHR =
7879         (PFN_vkAcquireProfilingLockKHR)vk::GetInstanceProcAddr(instance(), "vkAcquireProfilingLockKHR");
7880     ASSERT_TRUE(vkAcquireProfilingLockKHR != nullptr);
7881     PFN_vkReleaseProfilingLockKHR vkReleaseProfilingLockKHR =
7882         (PFN_vkReleaseProfilingLockKHR)vk::GetInstanceProcAddr(instance(), "vkReleaseProfilingLockKHR");
7883     ASSERT_TRUE(vkReleaseProfilingLockKHR != nullptr);
7884 
7885     {
7886         VkAcquireProfilingLockInfoKHR lock_info{};
7887         lock_info.sType = VK_STRUCTURE_TYPE_ACQUIRE_PROFILING_LOCK_INFO_KHR;
7888         VkResult result = vkAcquireProfilingLockKHR(device(), &lock_info);
7889         ASSERT_TRUE(result == VK_SUCCESS);
7890     }
7891 
7892     {
7893         VkBufferCreateInfo buf_info = {};
7894         buf_info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
7895         buf_info.usage = VK_BUFFER_USAGE_TRANSFER_DST_BIT;
7896         buf_info.size = 4096;
7897         buf_info.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
7898         VkBuffer buffer;
7899         VkResult err = vk::CreateBuffer(device(), &buf_info, NULL, &buffer);
7900         ASSERT_VK_SUCCESS(err);
7901 
7902         VkMemoryRequirements mem_reqs;
7903         vk::GetBufferMemoryRequirements(device(), buffer, &mem_reqs);
7904 
7905         VkMemoryAllocateInfo alloc_info = {};
7906         alloc_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
7907         alloc_info.allocationSize = 4096;
7908         VkDeviceMemory mem;
7909         err = vk::AllocateMemory(device(), &alloc_info, NULL, &mem);
7910         ASSERT_VK_SUCCESS(err);
7911         vk::BindBufferMemory(device(), buffer, mem, 0);
7912 
7913         VkCommandBufferBeginInfo command_buffer_begin_info{};
7914         command_buffer_begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
7915         command_buffer_begin_info.flags = VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT;
7916 
7917         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdBeginQuery-None-02863");
7918 
7919         m_commandBuffer->reset();
7920         m_commandBuffer->begin(&command_buffer_begin_info);
7921         vk::CmdResetQueryPool(m_commandBuffer->handle(), query_pool, 0, 1);
7922         vk::CmdBeginQuery(m_commandBuffer->handle(), query_pool, 0, 0);
7923         vk::CmdEndQuery(m_commandBuffer->handle(), query_pool, 0);
7924         m_commandBuffer->end();
7925 
7926         {
7927             VkPerformanceQuerySubmitInfoKHR perf_submit_info{};
7928             perf_submit_info.sType = VK_STRUCTURE_TYPE_PERFORMANCE_QUERY_SUBMIT_INFO_KHR;
7929             perf_submit_info.counterPassIndex = 0;
7930             VkSubmitInfo submit_info{};
7931             submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
7932             submit_info.pNext = &perf_submit_info;
7933             submit_info.waitSemaphoreCount = 0;
7934             submit_info.pWaitSemaphores = NULL;
7935             submit_info.pWaitDstStageMask = NULL;
7936             submit_info.commandBufferCount = 1;
7937             submit_info.pCommandBuffers = &m_commandBuffer->handle();
7938             submit_info.signalSemaphoreCount = 0;
7939             submit_info.pSignalSemaphores = NULL;
7940 
7941             vk::QueueSubmit(queue, 1, &submit_info, VK_NULL_HANDLE);
7942         }
7943 
7944         vk::QueueWaitIdle(queue);
7945         m_errorMonitor->VerifyFound();
7946 
7947         vk::DestroyBuffer(device(), buffer, nullptr);
7948         vk::FreeMemory(device(), mem, NULL);
7949     }
7950 
7951     vkReleaseProfilingLockKHR(device());
7952 
7953     vk::DestroyQueryPool(m_device->device(), query_pool, NULL);
7954 }
7955 
TEST_F(VkLayerTest,QueueSubmitNoTimelineSemaphoreInfo)7956 TEST_F(VkLayerTest, QueueSubmitNoTimelineSemaphoreInfo) {
7957     TEST_DESCRIPTION("Submit a queue with a timeline semaphore but not a VkTimelineSemaphoreSubmitInfoKHR.");
7958 
7959     if (InstanceExtensionSupported(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME)) {
7960         m_instance_extension_names.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
7961     } else {
7962         printf("%s Extension %s is not supported.\n", kSkipPrefix, VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
7963         return;
7964     }
7965 
7966     ASSERT_NO_FATAL_FAILURE(InitFramework(m_errorMonitor));
7967 
7968     if (DeviceExtensionSupported(gpu(), nullptr, VK_KHR_TIMELINE_SEMAPHORE_EXTENSION_NAME)) {
7969         m_device_extension_names.push_back(VK_KHR_TIMELINE_SEMAPHORE_EXTENSION_NAME);
7970     } else {
7971         printf("%s Extension %s not supported by device; skipped.\n", kSkipPrefix, VK_KHR_TIMELINE_SEMAPHORE_EXTENSION_NAME);
7972         return;
7973     }
7974 
7975     if (!CheckTimelineSemaphoreSupportAndInitState(this)) {
7976         printf("%s Timeline semaphore not supported, skipping test\n", kSkipPrefix);
7977         return;
7978     }
7979 
7980     VkSemaphoreTypeCreateInfoKHR semaphore_type_create_info{};
7981     semaphore_type_create_info.sType = VK_STRUCTURE_TYPE_SEMAPHORE_TYPE_CREATE_INFO_KHR;
7982     semaphore_type_create_info.semaphoreType = VK_SEMAPHORE_TYPE_TIMELINE_KHR;
7983 
7984     VkSemaphoreCreateInfo semaphore_create_info{};
7985     semaphore_create_info.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO;
7986     semaphore_create_info.pNext = &semaphore_type_create_info;
7987 
7988     VkSemaphore semaphore;
7989     ASSERT_VK_SUCCESS(vk::CreateSemaphore(m_device->device(), &semaphore_create_info, nullptr, &semaphore));
7990 
7991     VkPipelineStageFlags stageFlags = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT;
7992     VkSubmitInfo submit_info[2] = {};
7993     submit_info[0].sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
7994     submit_info[0].commandBufferCount = 0;
7995     submit_info[0].pWaitDstStageMask = &stageFlags;
7996     submit_info[0].signalSemaphoreCount = 1;
7997     submit_info[0].pSignalSemaphores = &semaphore;
7998 
7999     m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkSubmitInfo-pWaitSemaphores-03239");
8000     vk::QueueSubmit(m_device->m_queue, 1, submit_info, VK_NULL_HANDLE);
8001     m_errorMonitor->VerifyFound();
8002 
8003     VkTimelineSemaphoreSubmitInfoKHR timeline_semaphore_submit_info{};
8004     uint64_t signalValue = 1;
8005     timeline_semaphore_submit_info.sType = VK_STRUCTURE_TYPE_TIMELINE_SEMAPHORE_SUBMIT_INFO_KHR;
8006     timeline_semaphore_submit_info.signalSemaphoreValueCount = 1;
8007     timeline_semaphore_submit_info.pSignalSemaphoreValues = &signalValue;
8008     submit_info[0].pNext = &timeline_semaphore_submit_info;
8009 
8010     submit_info[1].sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
8011     submit_info[1].commandBufferCount = 0;
8012     submit_info[1].pWaitDstStageMask = &stageFlags;
8013     submit_info[1].waitSemaphoreCount = 1;
8014     submit_info[1].pWaitSemaphores = &semaphore;
8015 
8016     m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkSubmitInfo-pWaitSemaphores-03239");
8017     vk::QueueSubmit(m_device->m_queue, 2, submit_info, VK_NULL_HANDLE);
8018     m_errorMonitor->VerifyFound();
8019 
8020     vk::DestroySemaphore(m_device->device(), semaphore, nullptr);
8021 }
8022 
TEST_F(VkLayerTest,QueueSubmitTimelineSemaphoreBadValue)8023 TEST_F(VkLayerTest, QueueSubmitTimelineSemaphoreBadValue) {
8024     TEST_DESCRIPTION("Submit a queue with a timeline semaphore using a wrong payload value.");
8025 
8026     if (InstanceExtensionSupported(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME)) {
8027         m_instance_extension_names.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
8028     } else {
8029         printf("%s Extension %s is not supported.\n", kSkipPrefix, VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
8030         return;
8031     }
8032 
8033     ASSERT_NO_FATAL_FAILURE(InitFramework(m_errorMonitor));
8034 
8035     if (DeviceExtensionSupported(gpu(), nullptr, VK_KHR_TIMELINE_SEMAPHORE_EXTENSION_NAME)) {
8036         m_device_extension_names.push_back(VK_KHR_TIMELINE_SEMAPHORE_EXTENSION_NAME);
8037     } else {
8038         printf("%s Extension %s not supported by device; skipped.\n", kSkipPrefix, VK_KHR_TIMELINE_SEMAPHORE_EXTENSION_NAME);
8039         return;
8040     }
8041 
8042     if (!CheckTimelineSemaphoreSupportAndInitState(this)) {
8043         printf("%s Timeline semaphore not supported, skipping test\n", kSkipPrefix);
8044         return;
8045     }
8046 
8047     PFN_vkGetPhysicalDeviceProperties2KHR vkGetPhysicalDeviceProperties2KHR =
8048         (PFN_vkGetPhysicalDeviceProperties2KHR)vk::GetInstanceProcAddr(instance(), "vkGetPhysicalDeviceProperties2KHR");
8049     ASSERT_TRUE(vkGetPhysicalDeviceProperties2KHR != nullptr);
8050     auto timelineproperties = LvlInitStruct<VkPhysicalDeviceTimelineSemaphorePropertiesKHR>();
8051     auto prop2 = LvlInitStruct<VkPhysicalDeviceProperties2KHR>(&timelineproperties);
8052     vkGetPhysicalDeviceProperties2KHR(gpu(), &prop2);
8053 
8054     VkSemaphoreTypeCreateInfoKHR semaphore_type_create_info{};
8055     semaphore_type_create_info.sType = VK_STRUCTURE_TYPE_SEMAPHORE_TYPE_CREATE_INFO_KHR;
8056     semaphore_type_create_info.semaphoreType = VK_SEMAPHORE_TYPE_TIMELINE_KHR;
8057 
8058     VkSemaphoreCreateInfo semaphore_create_info{};
8059     semaphore_create_info.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO;
8060     semaphore_create_info.pNext = &semaphore_type_create_info;
8061 
8062     VkSemaphore semaphore;
8063     ASSERT_VK_SUCCESS(vk::CreateSemaphore(m_device->device(), &semaphore_create_info, nullptr, &semaphore));
8064 
8065     VkTimelineSemaphoreSubmitInfoKHR timeline_semaphore_submit_info = {};
8066     uint64_t signalValue = 1;
8067     uint64_t waitValue = 3;
8068     timeline_semaphore_submit_info.sType = VK_STRUCTURE_TYPE_TIMELINE_SEMAPHORE_SUBMIT_INFO_KHR;
8069     timeline_semaphore_submit_info.signalSemaphoreValueCount = 1;
8070     timeline_semaphore_submit_info.pSignalSemaphoreValues = &signalValue;
8071     timeline_semaphore_submit_info.waitSemaphoreValueCount = 1;
8072     timeline_semaphore_submit_info.pWaitSemaphoreValues = &waitValue;
8073 
8074     VkPipelineStageFlags stageFlags = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT;
8075     VkSubmitInfo submit_info[2] = {};
8076     submit_info[0].sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
8077     submit_info[0].pNext = &timeline_semaphore_submit_info;
8078     submit_info[0].pWaitDstStageMask = &stageFlags;
8079     submit_info[0].signalSemaphoreCount = 1;
8080     submit_info[0].pSignalSemaphores = &semaphore;
8081 
8082     submit_info[1].sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
8083     submit_info[1].pNext = &timeline_semaphore_submit_info;
8084     submit_info[1].pWaitDstStageMask = &stageFlags;
8085     submit_info[1].waitSemaphoreCount = 1;
8086     submit_info[1].pWaitSemaphores = &semaphore;
8087 
8088     timeline_semaphore_submit_info.signalSemaphoreValueCount = 0;
8089     m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkSubmitInfo-pNext-03241");
8090     vk::QueueSubmit(m_device->m_queue, 1, submit_info, VK_NULL_HANDLE);
8091     m_errorMonitor->VerifyFound();
8092 
8093     timeline_semaphore_submit_info.signalSemaphoreValueCount = 1;
8094     timeline_semaphore_submit_info.waitSemaphoreValueCount = 0;
8095 
8096     m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkSubmitInfo-pNext-03240");
8097     vk::QueueSubmit(m_device->m_queue, 2, submit_info, VK_NULL_HANDLE);
8098     m_errorMonitor->VerifyFound();
8099 
8100     vk::DestroySemaphore(m_device->device(), semaphore, nullptr);
8101 
8102     timeline_semaphore_submit_info.waitSemaphoreValueCount = 1;
8103     semaphore_type_create_info.initialValue = 5;
8104     ASSERT_VK_SUCCESS(vk::CreateSemaphore(m_device->device(), &semaphore_create_info, nullptr, &semaphore));
8105 
8106     m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkSubmitInfo-pSignalSemaphores-03242");
8107     vk::QueueSubmit(m_device->m_queue, 1, submit_info, VK_NULL_HANDLE);
8108     m_errorMonitor->VerifyFound();
8109 
8110     vk::DestroySemaphore(m_device->device(), semaphore, nullptr);
8111 
8112     // Check if we can test violations of maxTimelineSemaphoreValueDifference
8113     if (timelineproperties.maxTimelineSemaphoreValueDifference < UINT64_MAX) {
8114         semaphore_type_create_info.initialValue = 0;
8115 
8116         ASSERT_VK_SUCCESS(vk::CreateSemaphore(m_device->device(), &semaphore_create_info, nullptr, &semaphore));
8117 
8118         signalValue = timelineproperties.maxTimelineSemaphoreValueDifference + 1;
8119         timeline_semaphore_submit_info.pSignalSemaphoreValues = &signalValue;
8120 
8121         m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkSubmitInfo-pSignalSemaphores-03244");
8122         vk::QueueSubmit(m_device->m_queue, 1, submit_info, VK_NULL_HANDLE);
8123         m_errorMonitor->VerifyFound();
8124 
8125         if (signalValue < UINT64_MAX) {
8126             waitValue = signalValue + 1;
8127             signalValue = 1;
8128 
8129             timeline_semaphore_submit_info.waitSemaphoreValueCount = 1;
8130             timeline_semaphore_submit_info.pWaitSemaphoreValues = &waitValue;
8131 
8132             m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkSubmitInfo-pWaitSemaphores-03243");
8133             vk::QueueSubmit(m_device->m_queue, 2, submit_info, VK_NULL_HANDLE);
8134             m_errorMonitor->VerifyFound();
8135         }
8136 
8137         vk::DestroySemaphore(m_device->device(), semaphore, nullptr);
8138     }
8139 }
8140 
TEST_F(VkLayerTest,QueueSubmitBinarySemaphoreNotSignaled)8141 TEST_F(VkLayerTest, QueueSubmitBinarySemaphoreNotSignaled) {
8142     TEST_DESCRIPTION("Submit a queue with a waiting binary semaphore not previously signaled.");
8143 
8144     bool timelineSemaphoresExtensionSupported = true;
8145 
8146     if (InstanceExtensionSupported(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME)) {
8147         m_instance_extension_names.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
8148     } else {
8149         timelineSemaphoresExtensionSupported = false;
8150     }
8151 
8152     ASSERT_NO_FATAL_FAILURE(InitFramework(m_errorMonitor));
8153 
8154     if (timelineSemaphoresExtensionSupported &&
8155         DeviceExtensionSupported(gpu(), nullptr, VK_KHR_TIMELINE_SEMAPHORE_EXTENSION_NAME)) {
8156         m_device_extension_names.push_back(VK_KHR_TIMELINE_SEMAPHORE_EXTENSION_NAME);
8157     } else {
8158         timelineSemaphoresExtensionSupported = false;
8159     }
8160 
8161     ASSERT_NO_FATAL_FAILURE(InitState());
8162 
8163     VkSemaphoreCreateInfo semaphore_create_info{};
8164     semaphore_create_info.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO;
8165 
8166     VkSemaphore semaphore[3];
8167     ASSERT_VK_SUCCESS(vk::CreateSemaphore(m_device->device(), &semaphore_create_info, nullptr, &semaphore[0]));
8168     ASSERT_VK_SUCCESS(vk::CreateSemaphore(m_device->device(), &semaphore_create_info, nullptr, &semaphore[1]));
8169     ASSERT_VK_SUCCESS(vk::CreateSemaphore(m_device->device(), &semaphore_create_info, nullptr, &semaphore[2]));
8170 
8171     VkPipelineStageFlags stageFlags = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT;
8172     VkSubmitInfo submit_info[3] = {};
8173     submit_info[0].sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
8174     submit_info[0].pWaitDstStageMask = &stageFlags;
8175     submit_info[0].waitSemaphoreCount = 1;
8176     submit_info[0].pWaitSemaphores = &(semaphore[0]);
8177     submit_info[0].signalSemaphoreCount = 1;
8178     submit_info[0].pSignalSemaphores = &(semaphore[1]);
8179 
8180     m_errorMonitor->SetDesiredFailureMsg(kErrorBit, timelineSemaphoresExtensionSupported
8181                                                         ? "VUID-vkQueueSubmit-pWaitSemaphores-03238"
8182                                                         : "VUID-vkQueueSubmit-pWaitSemaphores-00069");
8183     vk::QueueSubmit(m_device->m_queue, 1, submit_info, VK_NULL_HANDLE);
8184     m_errorMonitor->VerifyFound();
8185 
8186     submit_info[1].sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
8187     submit_info[1].pWaitDstStageMask = &stageFlags;
8188     submit_info[1].waitSemaphoreCount = 1;
8189     submit_info[1].pWaitSemaphores = &(semaphore[1]);
8190     submit_info[1].signalSemaphoreCount = 1;
8191     submit_info[1].pSignalSemaphores = &(semaphore[2]);
8192 
8193     m_errorMonitor->SetDesiredFailureMsg(kErrorBit, timelineSemaphoresExtensionSupported
8194                                                         ? "VUID-vkQueueSubmit-pWaitSemaphores-03238"
8195                                                         : "VUID-vkQueueSubmit-pWaitSemaphores-00069");
8196     vk::QueueSubmit(m_device->m_queue, 2, submit_info, VK_NULL_HANDLE);
8197     m_errorMonitor->VerifyFound();
8198 
8199     submit_info[2].sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
8200     submit_info[2].signalSemaphoreCount = 1;
8201     submit_info[2].pSignalSemaphores = &(semaphore[0]);
8202 
8203     ASSERT_VK_SUCCESS(vk::QueueSubmit(m_device->m_queue, 1, &(submit_info[2]), VK_NULL_HANDLE));
8204     ASSERT_VK_SUCCESS(vk::QueueSubmit(m_device->m_queue, 2, submit_info, VK_NULL_HANDLE));
8205 
8206     ASSERT_VK_SUCCESS(vk::QueueWaitIdle(m_device->m_queue));
8207     vk::DestroySemaphore(m_device->device(), semaphore[0], nullptr);
8208     vk::DestroySemaphore(m_device->device(), semaphore[1], nullptr);
8209     vk::DestroySemaphore(m_device->device(), semaphore[2], nullptr);
8210 }
8211 
TEST_F(VkLayerTest,QueueSubmitTimelineSemaphoreOutOfOrder)8212 TEST_F(VkLayerTest, QueueSubmitTimelineSemaphoreOutOfOrder) {
8213     TEST_DESCRIPTION("Submit out-of-order timeline semaphores.");
8214 
8215     if (InstanceExtensionSupported(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME)) {
8216         m_instance_extension_names.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
8217     } else {
8218         printf("%s Extension %s is not supported.\n", kSkipPrefix, VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
8219         return;
8220     }
8221 
8222     ASSERT_NO_FATAL_FAILURE(InitFramework(m_errorMonitor));
8223 
8224     if (DeviceExtensionSupported(gpu(), nullptr, VK_KHR_TIMELINE_SEMAPHORE_EXTENSION_NAME)) {
8225         m_device_extension_names.push_back(VK_KHR_TIMELINE_SEMAPHORE_EXTENSION_NAME);
8226     } else {
8227         printf("%s Extension %s not supported by device; skipped.\n", kSkipPrefix, VK_KHR_TIMELINE_SEMAPHORE_EXTENSION_NAME);
8228         return;
8229     }
8230 
8231     if (!CheckTimelineSemaphoreSupportAndInitState(this)) {
8232         printf("%s Timeline semaphore not supported, skipping test\n", kSkipPrefix);
8233         return;
8234     }
8235 
8236     // We need two queues for this
8237     uint32_t queue_count;
8238     vk::GetPhysicalDeviceQueueFamilyProperties(gpu(), &queue_count, NULL);
8239     std::vector<VkQueueFamilyProperties> queue_props(queue_count);
8240     vk::GetPhysicalDeviceQueueFamilyProperties(gpu(), &queue_count, queue_props.data());
8241 
8242     uint32_t family_index[2] = {0};
8243     uint32_t queue_index[2] = {0};
8244 
8245     if (queue_count > 1) {
8246         family_index[1]++;
8247     } else {
8248         // If there's only one family index, check if it supports more than 1 queue
8249         if (queue_props[0].queueCount > 1) {
8250             queue_index[1]++;
8251         } else {
8252             printf("%s Multiple queues are required to run this test. .\n", kSkipPrefix);
8253             return;
8254         }
8255     }
8256 
8257     float priorities[] = {1.0f, 1.0f};
8258     VkDeviceQueueCreateInfo queue_info[2] = {};
8259     queue_info[0].sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
8260     queue_info[0].queueFamilyIndex = family_index[0];
8261     queue_info[0].queueCount = queue_count > 1 ? 1 : 2;
8262     queue_info[0].pQueuePriorities = &(priorities[0]);
8263 
8264     queue_info[1].sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
8265     queue_info[1].queueFamilyIndex = family_index[1];
8266     queue_info[1].queueCount = queue_count > 1 ? 1 : 2;
8267     queue_info[1].pQueuePriorities = &(priorities[0]);
8268 
8269     VkDeviceCreateInfo dev_info{};
8270     dev_info.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
8271     dev_info.queueCreateInfoCount = queue_count > 1 ? 2 : 1;
8272     dev_info.pQueueCreateInfos = &(queue_info[0]);
8273     dev_info.enabledLayerCount = 0;
8274     dev_info.enabledExtensionCount = m_device_extension_names.size();
8275     dev_info.ppEnabledExtensionNames = m_device_extension_names.data();
8276 
8277     auto timeline_semaphore_features = LvlInitStruct<VkPhysicalDeviceTimelineSemaphoreFeatures>();
8278     timeline_semaphore_features.timelineSemaphore = true;
8279     auto features2 = LvlInitStruct<VkPhysicalDeviceFeatures2KHR>(&timeline_semaphore_features);
8280     dev_info.pNext = &features2;
8281 
8282     VkDevice dev;
8283     ASSERT_VK_SUCCESS(vk::CreateDevice(gpu(), &dev_info, nullptr, &dev));
8284 
8285     VkQueue queue[2];
8286     vk::GetDeviceQueue(dev, family_index[0], queue_index[0], &(queue[0]));
8287     vk::GetDeviceQueue(dev, family_index[1], queue_index[1], &(queue[1]));
8288 
8289     VkSemaphoreTypeCreateInfoKHR semaphore_type_create_info{};
8290     semaphore_type_create_info.sType = VK_STRUCTURE_TYPE_SEMAPHORE_TYPE_CREATE_INFO_KHR;
8291     semaphore_type_create_info.semaphoreType = VK_SEMAPHORE_TYPE_TIMELINE_KHR;
8292     semaphore_type_create_info.initialValue = 5;
8293 
8294     VkSemaphoreCreateInfo semaphore_create_info{};
8295     semaphore_create_info.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO;
8296     semaphore_create_info.pNext = &semaphore_type_create_info;
8297 
8298     VkSemaphore semaphore;
8299     ASSERT_VK_SUCCESS(vk::CreateSemaphore(dev, &semaphore_create_info, nullptr, &semaphore));
8300 
8301     uint64_t semaphoreValues[] = {10, 100, 0, 10};
8302     VkTimelineSemaphoreSubmitInfoKHR timeline_semaphore_submit_info{};
8303     timeline_semaphore_submit_info.sType = VK_STRUCTURE_TYPE_TIMELINE_SEMAPHORE_SUBMIT_INFO_KHR;
8304     timeline_semaphore_submit_info.waitSemaphoreValueCount = 1;
8305     timeline_semaphore_submit_info.pWaitSemaphoreValues = &(semaphoreValues[0]);
8306     timeline_semaphore_submit_info.signalSemaphoreValueCount = 1;
8307     timeline_semaphore_submit_info.pSignalSemaphoreValues = &(semaphoreValues[1]);
8308 
8309     VkPipelineStageFlags stageFlags = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT;
8310     VkSubmitInfo submit_info{};
8311     submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
8312     submit_info.pNext = &timeline_semaphore_submit_info;
8313     submit_info.pWaitDstStageMask = &stageFlags;
8314     submit_info.waitSemaphoreCount = 1;
8315     submit_info.pWaitSemaphores = &semaphore;
8316     submit_info.signalSemaphoreCount = 1;
8317     submit_info.pSignalSemaphores = &semaphore;
8318 
8319     ASSERT_VK_SUCCESS(vk::QueueSubmit(queue[0], 1, &submit_info, VK_NULL_HANDLE));
8320 
8321     timeline_semaphore_submit_info.pWaitSemaphoreValues = &(semaphoreValues[2]);
8322     timeline_semaphore_submit_info.pSignalSemaphoreValues = &(semaphoreValues[3]);
8323 
8324     ASSERT_VK_SUCCESS(vk::QueueSubmit(queue[1], 1, &submit_info, VK_NULL_HANDLE));
8325 
8326     vk::DeviceWaitIdle(dev);
8327     vk::DestroySemaphore(dev, semaphore, nullptr);
8328     vk::DestroyDevice(dev, nullptr);
8329 }
8330 
TEST_F(VkLayerTest,InvalidExternalSemaphore)8331 TEST_F(VkLayerTest, InvalidExternalSemaphore) {
8332     TEST_DESCRIPTION("Import and export invalid external semaphores, no queue sumbits involved.");
8333 #ifdef _WIN32
8334     printf("%s Test doesn't currently support Win32 semaphore, skipping test\n", kSkipPrefix);
8335     return;
8336 #else
8337     const auto extension_name = VK_KHR_EXTERNAL_SEMAPHORE_FD_EXTENSION_NAME;
8338 
8339     // Check for external semaphore instance extensions
8340     if (InstanceExtensionSupported(VK_KHR_EXTERNAL_SEMAPHORE_CAPABILITIES_EXTENSION_NAME)) {
8341         m_instance_extension_names.push_back(VK_KHR_EXTERNAL_SEMAPHORE_CAPABILITIES_EXTENSION_NAME);
8342         m_instance_extension_names.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
8343     } else {
8344         printf("%s External semaphore extension not supported, skipping test\n", kSkipPrefix);
8345         return;
8346     }
8347     ASSERT_NO_FATAL_FAILURE(InitFramework(m_errorMonitor));
8348 
8349     // Check for external semaphore device extensions
8350     if (DeviceExtensionSupported(gpu(), nullptr, extension_name)) {
8351         m_device_extension_names.push_back(extension_name);
8352         m_device_extension_names.push_back(VK_KHR_EXTERNAL_SEMAPHORE_EXTENSION_NAME);
8353     } else {
8354         printf("%s External semaphore extension not supported, skipping test\n", kSkipPrefix);
8355         return;
8356     }
8357     ASSERT_NO_FATAL_FAILURE(InitState());
8358 
8359     // Create a semaphore fpr importing
8360     VkSemaphoreCreateInfo semaphore_create_info = {VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO};
8361     semaphore_create_info.pNext = nullptr;
8362     semaphore_create_info.flags = 0;
8363     VkSemaphore import_semaphore;
8364     VkResult err = vk::CreateSemaphore(m_device->device(), &semaphore_create_info, nullptr, &import_semaphore);
8365     ASSERT_VK_SUCCESS(err);
8366 
8367     int fd = 0;
8368     VkImportSemaphoreFdInfoKHR import_semaphore_fd_info = {VK_STRUCTURE_TYPE_IMPORT_SEMAPHORE_FD_INFO_KHR};
8369     import_semaphore_fd_info.pNext = nullptr;
8370     import_semaphore_fd_info.semaphore = import_semaphore;
8371     import_semaphore_fd_info.flags = VK_SEMAPHORE_IMPORT_TEMPORARY_BIT_KHR;
8372     import_semaphore_fd_info.handleType = VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_D3D12_FENCE_BIT;
8373     import_semaphore_fd_info.fd = fd;
8374     auto vkImportSemaphoreFdKHR = (PFN_vkImportSemaphoreFdKHR)vk::GetDeviceProcAddr(m_device->device(), "vkImportSemaphoreFdKHR");
8375 
8376     m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkImportSemaphoreFdInfoKHR-handleType-01143");
8377     vkImportSemaphoreFdKHR(device(), &import_semaphore_fd_info);
8378     m_errorMonitor->VerifyFound();
8379 
8380     // Cleanup
8381     vk::DestroySemaphore(device(), import_semaphore, nullptr);
8382 #endif
8383 }
8384 
TEST_F(VkLayerTest,InvalidWaitSemaphoresType)8385 TEST_F(VkLayerTest, InvalidWaitSemaphoresType) {
8386     TEST_DESCRIPTION("Wait for a non Timeline Semaphore");
8387 
8388     if (InstanceExtensionSupported(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME)) {
8389         m_instance_extension_names.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
8390     } else {
8391         printf("%s Extension %s is not supported.\n", kSkipPrefix, VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
8392         return;
8393     }
8394 
8395     ASSERT_NO_FATAL_FAILURE(InitFramework(m_errorMonitor));
8396 
8397     if (DeviceExtensionSupported(gpu(), nullptr, VK_KHR_TIMELINE_SEMAPHORE_EXTENSION_NAME)) {
8398         m_device_extension_names.push_back(VK_KHR_TIMELINE_SEMAPHORE_EXTENSION_NAME);
8399     } else {
8400         printf("%s Extension %s not supported by device; skipped.\n", kSkipPrefix, VK_KHR_TIMELINE_SEMAPHORE_EXTENSION_NAME);
8401         return;
8402     }
8403 
8404     if (!CheckTimelineSemaphoreSupportAndInitState(this)) {
8405         printf("%s Timeline semaphore not supported, skipping test\n", kSkipPrefix);
8406         return;
8407     }
8408 
8409     VkSemaphoreTypeCreateInfoKHR semaphore_type_create_info{};
8410     semaphore_type_create_info.sType = VK_STRUCTURE_TYPE_SEMAPHORE_TYPE_CREATE_INFO_KHR;
8411     semaphore_type_create_info.semaphoreType = VK_SEMAPHORE_TYPE_TIMELINE_KHR;
8412 
8413     VkSemaphoreCreateInfo semaphore_create_info{};
8414     semaphore_create_info.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO;
8415     semaphore_create_info.pNext = &semaphore_type_create_info;
8416 
8417     VkSemaphore semaphore[2];
8418     ASSERT_VK_SUCCESS(vk::CreateSemaphore(m_device->device(), &semaphore_create_info, nullptr, &(semaphore[0])));
8419 
8420     semaphore_type_create_info.semaphoreType = VK_SEMAPHORE_TYPE_BINARY;
8421     ASSERT_VK_SUCCESS(vk::CreateSemaphore(m_device->device(), &semaphore_create_info, nullptr, &(semaphore[1])));
8422 
8423     VkSemaphoreWaitInfo semaphore_wait_info{};
8424     semaphore_wait_info.sType = VK_STRUCTURE_TYPE_SEMAPHORE_WAIT_INFO;
8425     semaphore_wait_info.semaphoreCount = 2;
8426     semaphore_wait_info.pSemaphores = &semaphore[0];
8427     const uint64_t wait_values[] = {10, 40};
8428     semaphore_wait_info.pValues = &wait_values[0];
8429     auto vkWaitSemaphoresKHR = (PFN_vkWaitSemaphoresKHR)vk::GetDeviceProcAddr(m_device->device(), "vkWaitSemaphoresKHR");
8430 
8431     m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkSemaphoreWaitInfo-pSemaphores-03256");
8432     vkWaitSemaphoresKHR(m_device->device(), &semaphore_wait_info, 10000);
8433     m_errorMonitor->VerifyFound();
8434 
8435     vk::DestroySemaphore(m_device->device(), semaphore[0], nullptr);
8436     vk::DestroySemaphore(m_device->device(), semaphore[1], nullptr);
8437 }
8438 
TEST_F(VkLayerTest,InvalidSignalSemaphoreType)8439 TEST_F(VkLayerTest, InvalidSignalSemaphoreType) {
8440     TEST_DESCRIPTION("Signal a non Timeline Semaphore");
8441 
8442     if (InstanceExtensionSupported(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME)) {
8443         m_instance_extension_names.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
8444     } else {
8445         printf("%s Extension %s is not supported.\n", kSkipPrefix, VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
8446         return;
8447     }
8448 
8449     ASSERT_NO_FATAL_FAILURE(InitFramework(m_errorMonitor));
8450 
8451     if (DeviceExtensionSupported(gpu(), nullptr, VK_KHR_TIMELINE_SEMAPHORE_EXTENSION_NAME)) {
8452         m_device_extension_names.push_back(VK_KHR_TIMELINE_SEMAPHORE_EXTENSION_NAME);
8453     } else {
8454         printf("%s Extension %s not supported by device; skipped.\n", kSkipPrefix, VK_KHR_TIMELINE_SEMAPHORE_EXTENSION_NAME);
8455         return;
8456     }
8457 
8458     PFN_vkGetPhysicalDeviceFeatures2KHR vkGetPhysicalDeviceFeatures2KHR =
8459         (PFN_vkGetPhysicalDeviceFeatures2KHR)vk::GetInstanceProcAddr(instance(), "vkGetPhysicalDeviceFeatures2KHR");
8460     ASSERT_TRUE(vkGetPhysicalDeviceFeatures2KHR != nullptr);
8461     auto timelinefeatures = LvlInitStruct<VkPhysicalDeviceTimelineSemaphoreFeaturesKHR>();
8462     auto features2 = LvlInitStruct<VkPhysicalDeviceFeatures2KHR>(&timelinefeatures);
8463     vkGetPhysicalDeviceFeatures2KHR(gpu(), &features2);
8464     if (!timelinefeatures.timelineSemaphore) {
8465         printf("%s Timeline semaphores are not supported.\n", kSkipPrefix);
8466         return;
8467     }
8468 
8469     ASSERT_NO_FATAL_FAILURE(InitState());
8470 
8471     VkSemaphoreCreateInfo semaphore_create_info{};
8472     semaphore_create_info.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO;
8473 
8474     VkSemaphore semaphore;
8475     ASSERT_VK_SUCCESS(vk::CreateSemaphore(m_device->device(), &semaphore_create_info, nullptr, &semaphore));
8476 
8477     VkSemaphoreSignalInfo semaphore_signal_info{};
8478     semaphore_signal_info.sType = VK_STRUCTURE_TYPE_SEMAPHORE_SIGNAL_INFO;
8479     semaphore_signal_info.semaphore = semaphore;
8480     semaphore_signal_info.value = 10;
8481     auto vkSignalSemaphoreKHR = (PFN_vkSignalSemaphoreKHR)vk::GetDeviceProcAddr(m_device->device(), "vkSignalSemaphoreKHR");
8482 
8483     m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkSemaphoreSignalInfo-semaphore-03257");
8484     vkSignalSemaphoreKHR(m_device->device(), &semaphore_signal_info);
8485     m_errorMonitor->VerifyFound();
8486 
8487     vk::DestroySemaphore(m_device->device(), semaphore, nullptr);
8488 }
8489 
TEST_F(VkLayerTest,InvalidSignalSemaphoreValue)8490 TEST_F(VkLayerTest, InvalidSignalSemaphoreValue) {
8491     TEST_DESCRIPTION("Signal a Timeline Semaphore with invalid values");
8492 
8493     if (InstanceExtensionSupported(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME)) {
8494         m_instance_extension_names.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
8495     } else {
8496         printf("%s Extension %s is not supported.\n", kSkipPrefix, VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
8497         return;
8498     }
8499 
8500     ASSERT_NO_FATAL_FAILURE(InitFramework(m_errorMonitor));
8501 
8502     if (DeviceExtensionSupported(gpu(), nullptr, VK_KHR_TIMELINE_SEMAPHORE_EXTENSION_NAME)) {
8503         m_device_extension_names.push_back(VK_KHR_TIMELINE_SEMAPHORE_EXTENSION_NAME);
8504     } else {
8505         printf("%s Extension %s not supported by device; skipped.\n", kSkipPrefix, VK_KHR_TIMELINE_SEMAPHORE_EXTENSION_NAME);
8506         return;
8507     }
8508 
8509     if (!CheckTimelineSemaphoreSupportAndInitState(this)) {
8510         printf("%s Timeline semaphore not supported, skipping test\n", kSkipPrefix);
8511         return;
8512     }
8513 
8514     PFN_vkGetPhysicalDeviceProperties2KHR vkGetPhysicalDeviceProperties2KHR =
8515         (PFN_vkGetPhysicalDeviceProperties2KHR)vk::GetInstanceProcAddr(instance(), "vkGetPhysicalDeviceProperties2KHR");
8516     ASSERT_TRUE(vkGetPhysicalDeviceProperties2KHR != nullptr);
8517     auto timelineproperties = LvlInitStruct<VkPhysicalDeviceTimelineSemaphorePropertiesKHR>();
8518     auto prop2 = LvlInitStruct<VkPhysicalDeviceProperties2KHR>(&timelineproperties);
8519     vkGetPhysicalDeviceProperties2KHR(gpu(), &prop2);
8520 
8521     VkSemaphoreTypeCreateInfoKHR semaphore_type_create_info{};
8522     semaphore_type_create_info.sType = VK_STRUCTURE_TYPE_SEMAPHORE_TYPE_CREATE_INFO_KHR;
8523     semaphore_type_create_info.semaphoreType = VK_SEMAPHORE_TYPE_TIMELINE_KHR;
8524     semaphore_type_create_info.initialValue = 5;
8525 
8526     VkSemaphoreCreateInfo semaphore_create_info{};
8527     semaphore_create_info.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO;
8528     semaphore_create_info.pNext = &semaphore_type_create_info;
8529 
8530     VkSemaphore semaphore[2];
8531     ASSERT_VK_SUCCESS(vk::CreateSemaphore(m_device->device(), &semaphore_create_info, nullptr, &semaphore[0]));
8532     ASSERT_VK_SUCCESS(vk::CreateSemaphore(m_device->device(), &semaphore_create_info, nullptr, &semaphore[1]));
8533 
8534     VkSemaphoreSignalInfo semaphore_signal_info{};
8535     semaphore_signal_info.sType = VK_STRUCTURE_TYPE_SEMAPHORE_SIGNAL_INFO;
8536     semaphore_signal_info.semaphore = semaphore[0];
8537     semaphore_signal_info.value = 3;
8538     auto vkSignalSemaphoreKHR = (PFN_vkSignalSemaphoreKHR)vk::GetDeviceProcAddr(m_device->device(), "vkSignalSemaphoreKHR");
8539 
8540     m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkSemaphoreSignalInfo-value-03258");
8541     vkSignalSemaphoreKHR(m_device->device(), &semaphore_signal_info);
8542     m_errorMonitor->VerifyFound();
8543 
8544     semaphore_signal_info.value = 10;
8545     ASSERT_VK_SUCCESS(vkSignalSemaphoreKHR(m_device->device(), &semaphore_signal_info));
8546 
8547     VkTimelineSemaphoreSubmitInfoKHR timeline_semaphore_submit_info{};
8548     uint64_t waitValue = 10;
8549     uint64_t signalValue = 20;
8550     timeline_semaphore_submit_info.sType = VK_STRUCTURE_TYPE_TIMELINE_SEMAPHORE_SUBMIT_INFO_KHR;
8551     timeline_semaphore_submit_info.waitSemaphoreValueCount = 1;
8552     timeline_semaphore_submit_info.pWaitSemaphoreValues = &waitValue;
8553     timeline_semaphore_submit_info.signalSemaphoreValueCount = 1;
8554     timeline_semaphore_submit_info.pSignalSemaphoreValues = &signalValue;
8555 
8556     VkPipelineStageFlags stageFlags = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT;
8557     VkSubmitInfo submit_info{};
8558     submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
8559     submit_info.pNext = &timeline_semaphore_submit_info;
8560     submit_info.pWaitDstStageMask = &stageFlags;
8561     submit_info.waitSemaphoreCount = 1;
8562     submit_info.pWaitSemaphores = &(semaphore[1]);
8563     submit_info.signalSemaphoreCount = 1;
8564     submit_info.pSignalSemaphores = &(semaphore[0]);
8565     ASSERT_VK_SUCCESS(vk::QueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE));
8566 
8567     semaphore_signal_info.value = 25;
8568 
8569     m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkSemaphoreSignalInfo-value-03259");
8570     vkSignalSemaphoreKHR(m_device->device(), &semaphore_signal_info);
8571     m_errorMonitor->VerifyFound();
8572 
8573     semaphore_signal_info.value = 15;
8574     ASSERT_VK_SUCCESS(vkSignalSemaphoreKHR(m_device->device(), &semaphore_signal_info));
8575     semaphore_signal_info.semaphore = semaphore[1];
8576     ASSERT_VK_SUCCESS(vkSignalSemaphoreKHR(m_device->device(), &semaphore_signal_info));
8577 
8578     // Check if we can test violations of maxTimelineSemaphoreValueDifference
8579     if (timelineproperties.maxTimelineSemaphoreValueDifference < UINT64_MAX) {
8580         VkSemaphore sem;
8581 
8582         semaphore_type_create_info.initialValue = 0;
8583         ASSERT_VK_SUCCESS(vk::CreateSemaphore(m_device->device(), &semaphore_create_info, nullptr, &sem));
8584 
8585         semaphore_signal_info.semaphore = sem;
8586         semaphore_signal_info.value = timelineproperties.maxTimelineSemaphoreValueDifference + 1;
8587 
8588         m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkSemaphoreSignalInfo-value-03260");
8589         vkSignalSemaphoreKHR(m_device->device(), &semaphore_signal_info);
8590         m_errorMonitor->VerifyFound();
8591 
8592         semaphore_signal_info.value--;
8593         ASSERT_VK_SUCCESS(vkSignalSemaphoreKHR(m_device->device(), &semaphore_signal_info));
8594 
8595         vk::DestroySemaphore(m_device->device(), sem, nullptr);
8596 
8597         // Regression test for value difference validations ran against binary semaphores
8598         {
8599             VkSemaphore timeline_sem;
8600             VkSemaphore binary_sem;
8601 
8602             semaphore_type_create_info.initialValue = 0;
8603             ASSERT_VK_SUCCESS(vk::CreateSemaphore(m_device->device(), &semaphore_create_info, nullptr, &timeline_sem));
8604 
8605             VkSemaphoreCreateInfo binary_semaphore_create_info{};
8606             binary_semaphore_create_info.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO;
8607 
8608             ASSERT_VK_SUCCESS(vk::CreateSemaphore(m_device->device(), &binary_semaphore_create_info, nullptr, &binary_sem));
8609 
8610             signalValue = 1;
8611             uint64_t offendingValue = timelineproperties.maxTimelineSemaphoreValueDifference + 1;
8612 
8613             submit_info.waitSemaphoreCount = 1;
8614             submit_info.pWaitSemaphores = &timeline_sem;
8615             submit_info.signalSemaphoreCount = 1;
8616             submit_info.pSignalSemaphores = &binary_sem;
8617 
8618             timeline_semaphore_submit_info.waitSemaphoreValueCount = 1;
8619             timeline_semaphore_submit_info.pWaitSemaphoreValues = &signalValue;
8620 
8621             // These two assignments are not required by the spec, but would segfault on older versions of validation layers
8622             timeline_semaphore_submit_info.signalSemaphoreValueCount = 1;
8623             timeline_semaphore_submit_info.pSignalSemaphoreValues = &offendingValue;
8624 
8625             m_errorMonitor->ExpectSuccess();
8626 
8627             vk::QueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
8628 
8629             semaphore_signal_info.semaphore = timeline_sem;
8630             semaphore_signal_info.value = 1;
8631             vkSignalSemaphoreKHR(m_device->device(), &semaphore_signal_info);
8632 
8633             m_errorMonitor->VerifyNotFound();
8634 
8635             vk::DestroySemaphore(m_device->device(), binary_sem, nullptr);
8636             vk::DestroySemaphore(m_device->device(), timeline_sem, nullptr);
8637         }
8638     }
8639 
8640     ASSERT_VK_SUCCESS(vk::QueueWaitIdle(m_device->m_queue));
8641     vk::DestroySemaphore(m_device->device(), semaphore[0], nullptr);
8642     vk::DestroySemaphore(m_device->device(), semaphore[1], nullptr);
8643 }
8644 
TEST_F(VkLayerTest,Sync2InvalidSignalSemaphoreValue)8645 TEST_F(VkLayerTest, Sync2InvalidSignalSemaphoreValue) {
8646     TEST_DESCRIPTION("Signal a Timeline Semaphore with invalid values");
8647     SetTargetApiVersion(VK_API_VERSION_1_2);
8648     ASSERT_NO_FATAL_FAILURE(InitFramework());
8649     if (DeviceExtensionSupported(gpu(), nullptr, VK_KHR_SYNCHRONIZATION_2_EXTENSION_NAME)) {
8650         m_device_extension_names.push_back(VK_KHR_SYNCHRONIZATION_2_EXTENSION_NAME);
8651     } else {
8652         printf("%s Synchronization2 not supported, skipping test\n", kSkipPrefix);
8653         return;
8654     }
8655 
8656     if (!CheckSynchronization2SupportAndInitState(this)) {
8657         printf("%s Synchronization2 not supported, skipping test\n", kSkipPrefix);
8658         return;
8659     }
8660     auto fpQueueSubmit2KHR = (PFN_vkQueueSubmit2KHR)vk::GetDeviceProcAddr(m_device->device(), "vkQueueSubmit2KHR");
8661 
8662     auto timelineproperties = LvlInitStruct<VkPhysicalDeviceTimelineSemaphorePropertiesKHR>();
8663     auto prop2 = LvlInitStruct<VkPhysicalDeviceProperties2KHR>(&timelineproperties);
8664     vk::GetPhysicalDeviceProperties2(gpu(), &prop2);
8665 
8666     VkSemaphoreTypeCreateInfoKHR semaphore_type_create_info{};
8667     semaphore_type_create_info.sType = VK_STRUCTURE_TYPE_SEMAPHORE_TYPE_CREATE_INFO_KHR;
8668     semaphore_type_create_info.semaphoreType = VK_SEMAPHORE_TYPE_TIMELINE_KHR;
8669     semaphore_type_create_info.initialValue = 5;
8670 
8671     VkSemaphoreCreateInfo semaphore_create_info{};
8672     semaphore_create_info.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO;
8673     semaphore_create_info.pNext = &semaphore_type_create_info;
8674 
8675     VkSemaphore semaphore[2];
8676     ASSERT_VK_SUCCESS(vk::CreateSemaphore(m_device->device(), &semaphore_create_info, nullptr, &semaphore[0]));
8677     ASSERT_VK_SUCCESS(vk::CreateSemaphore(m_device->device(), &semaphore_create_info, nullptr, &semaphore[1]));
8678 
8679     VkSemaphoreSignalInfo semaphore_signal_info{};
8680     semaphore_signal_info.sType = VK_STRUCTURE_TYPE_SEMAPHORE_SIGNAL_INFO;
8681     semaphore_signal_info.semaphore = semaphore[0];
8682     semaphore_signal_info.value = 10;
8683     ASSERT_VK_SUCCESS(vk::SignalSemaphore(m_device->device(), &semaphore_signal_info));
8684 
8685     auto signal_info = lvl_init_struct<VkSemaphoreSubmitInfoKHR>();
8686     signal_info.value = 20;
8687     signal_info.semaphore = semaphore[0];
8688 
8689     auto wait_info = lvl_init_struct<VkSemaphoreSubmitInfoKHR>();
8690     wait_info.value = 10;
8691     wait_info.semaphore = semaphore[1];
8692     wait_info.stageMask = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT;
8693 
8694     auto submit_info = lvl_init_struct<VkSubmitInfo2KHR>();
8695     submit_info.signalSemaphoreInfoCount = 1;
8696     submit_info.pSignalSemaphoreInfos = &signal_info;
8697     submit_info.waitSemaphoreInfoCount = 1;
8698     submit_info.pWaitSemaphoreInfos = &wait_info;
8699 
8700     ASSERT_VK_SUCCESS(fpQueueSubmit2KHR(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE));
8701 
8702     semaphore_signal_info.value = 25;
8703 
8704     m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkSemaphoreSignalInfo-value-03259");
8705     vk::SignalSemaphore(m_device->device(), &semaphore_signal_info);
8706     m_errorMonitor->VerifyFound();
8707 
8708     semaphore_signal_info.value = 15;
8709     ASSERT_VK_SUCCESS(vk::SignalSemaphore(m_device->device(), &semaphore_signal_info));
8710     semaphore_signal_info.semaphore = semaphore[1];
8711     ASSERT_VK_SUCCESS(vk::SignalSemaphore(m_device->device(), &semaphore_signal_info));
8712 
8713     // Check if we can test violations of maxTimelineSemaphoreValueDifference
8714     if (timelineproperties.maxTimelineSemaphoreValueDifference < UINT64_MAX) {
8715         // Regression test for value difference validations ran against binary semaphores
8716         {
8717             VkSemaphore timeline_sem;
8718             VkSemaphore binary_sem;
8719 
8720             semaphore_type_create_info.initialValue = 0;
8721             ASSERT_VK_SUCCESS(vk::CreateSemaphore(m_device->device(), &semaphore_create_info, nullptr, &timeline_sem));
8722 
8723             VkSemaphoreCreateInfo binary_semaphore_create_info{};
8724             binary_semaphore_create_info.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO;
8725 
8726             ASSERT_VK_SUCCESS(vk::CreateSemaphore(m_device->device(), &binary_semaphore_create_info, nullptr, &binary_sem));
8727 
8728             wait_info.semaphore = timeline_sem;
8729             wait_info.value = 1;
8730 
8731             signal_info.semaphore = binary_sem;
8732             signal_info.value = timelineproperties.maxTimelineSemaphoreValueDifference + 1;
8733 
8734             m_errorMonitor->ExpectSuccess();
8735 
8736             fpQueueSubmit2KHR(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
8737 
8738             semaphore_signal_info.semaphore = timeline_sem;
8739             semaphore_signal_info.value = 1;
8740             vk::SignalSemaphore(m_device->device(), &semaphore_signal_info);
8741 
8742             m_errorMonitor->VerifyNotFound();
8743 
8744             vk::DestroySemaphore(m_device->device(), binary_sem, nullptr);
8745             vk::DestroySemaphore(m_device->device(), timeline_sem, nullptr);
8746         }
8747     }
8748 
8749     ASSERT_VK_SUCCESS(vk::QueueWaitIdle(m_device->m_queue));
8750     vk::DestroySemaphore(m_device->device(), semaphore[0], nullptr);
8751     vk::DestroySemaphore(m_device->device(), semaphore[1], nullptr);
8752 }
8753 
TEST_F(VkLayerTest,InvalidSemaphoreCounterType)8754 TEST_F(VkLayerTest, InvalidSemaphoreCounterType) {
8755     TEST_DESCRIPTION("Get payload from a non Timeline Semaphore");
8756 
8757     if (InstanceExtensionSupported(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME)) {
8758         m_instance_extension_names.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
8759     } else {
8760         printf("%s Extension %s is not supported.\n", kSkipPrefix, VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
8761         return;
8762     }
8763 
8764     ASSERT_NO_FATAL_FAILURE(InitFramework(m_errorMonitor));
8765 
8766     if (DeviceExtensionSupported(gpu(), nullptr, VK_KHR_TIMELINE_SEMAPHORE_EXTENSION_NAME)) {
8767         m_device_extension_names.push_back(VK_KHR_TIMELINE_SEMAPHORE_EXTENSION_NAME);
8768     } else {
8769         printf("%s Extension %s not supported by device; skipped.\n", kSkipPrefix, VK_KHR_TIMELINE_SEMAPHORE_EXTENSION_NAME);
8770         return;
8771     }
8772 
8773     PFN_vkGetPhysicalDeviceFeatures2KHR vkGetPhysicalDeviceFeatures2KHR =
8774         (PFN_vkGetPhysicalDeviceFeatures2KHR)vk::GetInstanceProcAddr(instance(), "vkGetPhysicalDeviceFeatures2KHR");
8775     ASSERT_TRUE(vkGetPhysicalDeviceFeatures2KHR != nullptr);
8776     auto timelinefeatures = LvlInitStruct<VkPhysicalDeviceTimelineSemaphoreFeaturesKHR>();
8777     auto features2 = LvlInitStruct<VkPhysicalDeviceFeatures2KHR>(&timelinefeatures);
8778     vkGetPhysicalDeviceFeatures2KHR(gpu(), &features2);
8779     if (!timelinefeatures.timelineSemaphore) {
8780         printf("%s Timeline semaphores are not supported.\n", kSkipPrefix);
8781         return;
8782     }
8783 
8784     ASSERT_NO_FATAL_FAILURE(InitState());
8785 
8786     VkSemaphoreCreateInfo semaphore_create_info{};
8787     semaphore_create_info.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO;
8788 
8789     VkSemaphore semaphore;
8790     ASSERT_VK_SUCCESS(vk::CreateSemaphore(m_device->device(), &semaphore_create_info, nullptr, &semaphore));
8791 
8792     auto vkGetSemaphoreCounterValueKHR =
8793         (PFN_vkGetSemaphoreCounterValueKHR)vk::GetDeviceProcAddr(m_device->device(), "vkGetSemaphoreCounterValueKHR");
8794     uint64_t value = 0xdeadbeef;
8795 
8796     m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkGetSemaphoreCounterValue-semaphore-03255");
8797     vkGetSemaphoreCounterValueKHR(m_device->device(), semaphore, &value);
8798     m_errorMonitor->VerifyFound();
8799 
8800     vk::DestroySemaphore(m_device->device(), semaphore, nullptr);
8801 }
8802 
TEST_F(VkLayerTest,ImageDrmFormatModifer)8803 TEST_F(VkLayerTest, ImageDrmFormatModifer) {
8804     TEST_DESCRIPTION("General testing of VK_EXT_image_drm_format_modifier");
8805     if (InstanceExtensionSupported(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME)) {
8806         m_instance_extension_names.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
8807     } else {
8808         printf("%s Extension %s is not supported.\n", kSkipPrefix, VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
8809         return;
8810     }
8811 
8812     ASSERT_NO_FATAL_FAILURE(InitFramework(m_errorMonitor));
8813 
8814     if (IsPlatform(kMockICD)) {
8815         printf("%s Test not supported by MockICD, skipping tests\n", kSkipPrefix);
8816         return;
8817     }
8818     bool idfm_extensions = DeviceExtensionSupported(gpu(), nullptr, VK_EXT_IMAGE_DRM_FORMAT_MODIFIER_EXTENSION_NAME);
8819     idfm_extensions = idfm_extensions && DeviceExtensionSupported(gpu(), nullptr, VK_KHR_BIND_MEMORY_2_EXTENSION_NAME);
8820     idfm_extensions = idfm_extensions && DeviceExtensionSupported(gpu(), nullptr, VK_KHR_IMAGE_FORMAT_LIST_EXTENSION_NAME);
8821     idfm_extensions = idfm_extensions && DeviceExtensionSupported(gpu(), nullptr, VK_KHR_SAMPLER_YCBCR_CONVERSION_EXTENSION_NAME);
8822     idfm_extensions = idfm_extensions && DeviceExtensionSupported(gpu(), nullptr, VK_KHR_MAINTENANCE_1_EXTENSION_NAME);
8823     idfm_extensions = idfm_extensions && DeviceExtensionSupported(gpu(), nullptr, VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME);
8824 
8825     if (idfm_extensions) {
8826         m_device_extension_names.push_back(VK_EXT_IMAGE_DRM_FORMAT_MODIFIER_EXTENSION_NAME);
8827         m_device_extension_names.push_back(VK_KHR_BIND_MEMORY_2_EXTENSION_NAME);
8828         m_device_extension_names.push_back(VK_KHR_IMAGE_FORMAT_LIST_EXTENSION_NAME);
8829         m_device_extension_names.push_back(VK_KHR_SAMPLER_YCBCR_CONVERSION_EXTENSION_NAME);
8830         m_device_extension_names.push_back(VK_KHR_MAINTENANCE_1_EXTENSION_NAME);
8831         m_device_extension_names.push_back(VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME);
8832     } else {
8833         printf("%s Extension %s not supported by device; skipped.\n", kSkipPrefix, VK_EXT_IMAGE_DRM_FORMAT_MODIFIER_EXTENSION_NAME);
8834         return;
8835     }
8836 
8837     PFN_vkGetImageDrmFormatModifierPropertiesEXT vkGetImageDrmFormatModifierPropertiesEXT =
8838         (PFN_vkGetImageDrmFormatModifierPropertiesEXT)vk::GetInstanceProcAddr(instance(),
8839                                                                               "vkGetImageDrmFormatModifierPropertiesEXT");
8840     ASSERT_TRUE(vkGetImageDrmFormatModifierPropertiesEXT != nullptr);
8841 
8842     ASSERT_NO_FATAL_FAILURE(InitState());
8843 
8844     const uint64_t dummy_modifiers[2] = {0, 1};
8845 
8846     VkImageCreateInfo image_info = {};
8847     image_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
8848     image_info.pNext = nullptr;
8849     image_info.imageType = VK_IMAGE_TYPE_2D;
8850     image_info.arrayLayers = 1;
8851     image_info.extent = {64, 64, 1};
8852     image_info.format = VK_FORMAT_R8G8B8A8_UNORM;
8853     image_info.mipLevels = 1;
8854     image_info.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
8855     image_info.samples = VK_SAMPLE_COUNT_1_BIT;
8856     image_info.tiling = VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT;
8857     image_info.usage = VK_IMAGE_USAGE_SAMPLED_BIT;
8858 
8859     VkImageFormatProperties2 image_format_prop = {};
8860     image_format_prop.sType = VK_STRUCTURE_TYPE_IMAGE_FORMAT_PROPERTIES_2;
8861     VkPhysicalDeviceImageFormatInfo2 image_format_info = {};
8862     image_format_info.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_FORMAT_INFO_2;
8863     image_format_info.format = image_info.format;
8864     image_format_info.tiling = image_info.tiling;
8865     image_format_info.type = image_info.imageType;
8866     image_format_info.usage = image_info.usage;
8867     VkPhysicalDeviceImageDrmFormatModifierInfoEXT drm_format_mod_info = {};
8868     drm_format_mod_info.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_DRM_FORMAT_MODIFIER_INFO_EXT;
8869     drm_format_mod_info.pNext = nullptr;
8870     drm_format_mod_info.drmFormatModifier = dummy_modifiers[0];
8871     drm_format_mod_info.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
8872     drm_format_mod_info.queueFamilyIndexCount = 0;
8873     image_format_info.pNext = (void *)&drm_format_mod_info;
8874     vk::GetPhysicalDeviceImageFormatProperties2(m_device->phy().handle(), &image_format_info, &image_format_prop);
8875 
8876     {
8877         VkImageFormatProperties dummy_props;
8878         m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkGetPhysicalDeviceImageFormatProperties-tiling-02248");
8879         vk::GetPhysicalDeviceImageFormatProperties(m_device->phy().handle(), image_info.format, image_info.imageType,
8880                                                    image_info.tiling, image_info.usage, image_info.flags, &dummy_props);
8881         m_errorMonitor->VerifyFound();
8882     }
8883 
8884     VkSubresourceLayout dummyPlaneLayout = {0, 0, 0, 0, 0};
8885 
8886     VkImageDrmFormatModifierListCreateInfoEXT drm_format_mod_list = {};
8887     drm_format_mod_list.sType = VK_STRUCTURE_TYPE_IMAGE_DRM_FORMAT_MODIFIER_LIST_CREATE_INFO_EXT;
8888     drm_format_mod_list.pNext = nullptr;
8889     drm_format_mod_list.drmFormatModifierCount = 2;
8890     drm_format_mod_list.pDrmFormatModifiers = dummy_modifiers;
8891 
8892     VkImageDrmFormatModifierExplicitCreateInfoEXT drm_format_mod_explicit = {};
8893     drm_format_mod_explicit.sType = VK_STRUCTURE_TYPE_IMAGE_DRM_FORMAT_MODIFIER_EXPLICIT_CREATE_INFO_EXT;
8894     drm_format_mod_explicit.pNext = nullptr;
8895     drm_format_mod_explicit.drmFormatModifierPlaneCount = 1;
8896     drm_format_mod_explicit.pPlaneLayouts = &dummyPlaneLayout;
8897 
8898     VkImage image = VK_NULL_HANDLE;
8899 
8900     // No pNext
8901     m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkImageCreateInfo-tiling-02261");
8902     vk::CreateImage(device(), &image_info, nullptr, &image);
8903     m_errorMonitor->VerifyFound();
8904 
8905     auto drm_format_modifier = LvlInitStruct<VkPhysicalDeviceImageDrmFormatModifierInfoEXT>();
8906     drm_format_modifier.drmFormatModifier = dummy_modifiers[1];
8907     image_format_info.pNext = &drm_format_modifier;
8908     VkResult result = vk::GetPhysicalDeviceImageFormatProperties2(m_device->phy().handle(), &image_format_info, &image_format_prop);
8909     if (result == VK_ERROR_FORMAT_NOT_SUPPORTED) {
8910         printf("Format VK_FORMAT_R8G8B8A8_UNORM not supported with format modifiers, Skipping the remaining tests.\n");
8911         return;
8912     }
8913     // Postive check if only 1
8914     image_info.pNext = (void *)&drm_format_mod_list;
8915     m_errorMonitor->ExpectSuccess();
8916     vk::CreateImage(device(), &image_info, nullptr, &image);
8917     vk::DestroyImage(device(), image, nullptr);
8918     m_errorMonitor->VerifyNotFound();
8919 
8920     image_info.pNext = (void *)&drm_format_mod_explicit;
8921     m_errorMonitor->ExpectSuccess();
8922     vk::CreateImage(device(), &image_info, nullptr, &image);
8923     vk::DestroyImage(device(), image, nullptr);
8924     m_errorMonitor->VerifyNotFound();
8925 
8926     // Having both in pNext
8927     drm_format_mod_explicit.pNext = (void *)&drm_format_mod_list;
8928     m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkImageCreateInfo-tiling-02261");
8929     vk::CreateImage(device(), &image_info, nullptr, &image);
8930     m_errorMonitor->VerifyFound();
8931 
8932     // Only 1 pNext but wrong tiling
8933     image_info.pNext = (void *)&drm_format_mod_list;
8934     image_info.tiling = VK_IMAGE_TILING_LINEAR;
8935     m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkImageCreateInfo-pNext-02262");
8936     vk::CreateImage(device(), &image_info, nullptr, &image);
8937     m_errorMonitor->VerifyFound();
8938 }
8939 
TEST_F(VkLayerTest,ValidateNVDeviceDiagnosticCheckpoints)8940 TEST_F(VkLayerTest, ValidateNVDeviceDiagnosticCheckpoints) {
8941     TEST_DESCRIPTION("General testing of VK_NV_device_diagnostic_checkpoints");
8942     if (InstanceExtensionSupported(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME)) {
8943         m_instance_extension_names.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
8944     } else {
8945         printf("%s Extension %s is not supported.\n", kSkipPrefix, VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
8946         return;
8947     }
8948 
8949     ASSERT_NO_FATAL_FAILURE(InitFramework(m_errorMonitor));
8950 
8951     if (DeviceExtensionSupported(gpu(), nullptr, VK_NV_DEVICE_DIAGNOSTIC_CHECKPOINTS_EXTENSION_NAME)) {
8952         m_device_extension_names.push_back(VK_NV_DEVICE_DIAGNOSTIC_CHECKPOINTS_EXTENSION_NAME);
8953     } else {
8954         printf("%s Extension %s not supported by device; skipped.\n", kSkipPrefix,
8955                VK_NV_DEVICE_DIAGNOSTIC_CHECKPOINTS_EXTENSION_NAME);
8956         return;
8957     }
8958 
8959     ASSERT_NO_FATAL_FAILURE(InitState());
8960 
8961     auto vkGetQueueCheckpointDataNV =
8962         (PFN_vkGetQueueCheckpointDataNV)vk::GetDeviceProcAddr(m_device->device(), "vkGetQueueCheckpointDataNV");
8963 
8964     auto vkCmdSetCheckpointNV = (PFN_vkCmdSetCheckpointNV)vk::GetDeviceProcAddr(m_device->device(), "vkCmdSetCheckpointNV");
8965 
8966     ASSERT_TRUE(vkGetQueueCheckpointDataNV != nullptr);
8967     ASSERT_TRUE(vkCmdSetCheckpointNV != nullptr);
8968 
8969     uint32_t data = 100;
8970     m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdSetCheckpointNV-commandBuffer-recording");
8971     vkCmdSetCheckpointNV(m_commandBuffer->handle(), &data);
8972     m_errorMonitor->VerifyFound();
8973 }
8974 
TEST_F(VkLayerTest,InvalidGetDeviceQueue)8975 TEST_F(VkLayerTest, InvalidGetDeviceQueue) {
8976     TEST_DESCRIPTION("General testing of vkGetDeviceQueue and general Device creation cases");
8977     SetTargetApiVersion(VK_API_VERSION_1_1);
8978 
8979     if (InstanceExtensionSupported(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME)) {
8980         m_instance_extension_names.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
8981     } else {
8982         printf("%s Did not find VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME; skipped.\n", kSkipPrefix);
8983         return;
8984     }
8985 
8986     ASSERT_NO_FATAL_FAILURE(InitFramework(m_errorMonitor));
8987 
8988     // Needed for both protected memory and vkGetDeviceQueue2
8989     if (DeviceValidationVersion() < VK_API_VERSION_1_1) {
8990         printf("%s test requires Vulkan 1.1 extensions, not available.  Skipping.\n", kSkipPrefix);
8991         return;
8992     }
8993 
8994     PFN_vkGetPhysicalDeviceFeatures2KHR vkGetPhysicalDeviceFeatures2KHR =
8995         (PFN_vkGetPhysicalDeviceFeatures2KHR)vk::GetInstanceProcAddr(instance(), "vkGetPhysicalDeviceFeatures2KHR");
8996     ASSERT_TRUE(vkGetPhysicalDeviceFeatures2KHR != nullptr);
8997 
8998     VkDeviceQueueInfo2 queue_info_2 = LvlInitStruct<VkDeviceQueueInfo2>();
8999     VkDevice test_device = VK_NULL_HANDLE;
9000     VkQueue test_queue = VK_NULL_HANDLE;
9001     VkResult result;
9002 
9003     // Use the first Physical device and queue family
9004     // Makes test more portable as every driver has at least 1 queue with a queueCount of 1
9005     uint32_t queue_family_count = 1;
9006     uint32_t queue_family_index = 0;
9007     VkQueueFamilyProperties queue_properties;
9008     vk::GetPhysicalDeviceQueueFamilyProperties(gpu(), &queue_family_count, &queue_properties);
9009 
9010     float queue_priority = 1.0;
9011     VkDeviceQueueCreateInfo queue_create_info = LvlInitStruct<VkDeviceQueueCreateInfo>();
9012     queue_create_info.flags = VK_DEVICE_QUEUE_CREATE_PROTECTED_BIT;
9013     queue_create_info.queueFamilyIndex = queue_family_index;
9014     queue_create_info.queueCount = 1;
9015     queue_create_info.pQueuePriorities = &queue_priority;
9016 
9017     VkPhysicalDeviceProtectedMemoryFeatures protect_features = LvlInitStruct<VkPhysicalDeviceProtectedMemoryFeatures>();
9018     protect_features.protectedMemory = VK_FALSE;  // Starting with it off
9019 
9020     VkDeviceCreateInfo device_create_info = LvlInitStruct<VkDeviceCreateInfo>(&protect_features);
9021     device_create_info.flags = 0;
9022     device_create_info.pQueueCreateInfos = &queue_create_info;
9023     device_create_info.queueCreateInfoCount = 1;
9024     device_create_info.pEnabledFeatures = nullptr;
9025     device_create_info.enabledLayerCount = 0;
9026     device_create_info.enabledExtensionCount = 0;
9027 
9028     // Protect feature not set
9029     m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkDeviceQueueCreateInfo-flags-02861");
9030     vk::CreateDevice(gpu(), &device_create_info, nullptr, &test_device);
9031     m_errorMonitor->VerifyFound();
9032 
9033     VkPhysicalDeviceFeatures2 features2 = LvlInitStruct<VkPhysicalDeviceFeatures2>(&protect_features);
9034     vkGetPhysicalDeviceFeatures2KHR(gpu(), &features2);
9035 
9036     if (protect_features.protectedMemory == VK_TRUE) {
9037         result = vk::CreateDevice(gpu(), &device_create_info, nullptr, &test_device);
9038         if (result != VK_SUCCESS) {
9039             printf("%s CreateDevice returned back %s, skipping rest of tests\n", kSkipPrefix, string_VkResult(result));
9040             return;
9041         }
9042 
9043         // TODO: Re-enable test when Vulkan-Loader MR #581 is resolved and upstream into next SDK - tested ToT
9044         // Try using GetDeviceQueue with a queue that has as flag
9045         // m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkGetDeviceQueue-flags-01841");
9046         // vk::GetDeviceQueue(test_device, queue_family_index, 0, &test_queue);
9047         // m_errorMonitor->VerifyFound();
9048 
9049         PFN_vkGetDeviceQueue2 vkGetDeviceQueue2 = (PFN_vkGetDeviceQueue2)vk::GetDeviceProcAddr(test_device, "vkGetDeviceQueue2");
9050         ASSERT_TRUE(vkGetDeviceQueue2 != nullptr);
9051 
9052         // Test device created with flag and trying to query with no flag
9053         queue_info_2.flags = 0;
9054         queue_info_2.queueFamilyIndex = queue_family_index;
9055         queue_info_2.queueIndex = 0;
9056         m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkDeviceQueueInfo2-flags-06225");
9057         vkGetDeviceQueue2(test_device, &queue_info_2, &test_queue);
9058         m_errorMonitor->VerifyFound();
9059 
9060         vk::DestroyDevice(test_device, nullptr);
9061         test_device = VK_NULL_HANDLE;
9062     }
9063 
9064     // Create device without protected queue
9065     protect_features.protectedMemory = VK_FALSE;
9066     queue_create_info.flags = 0;
9067     result = vk::CreateDevice(gpu(), &device_create_info, nullptr, &test_device);
9068     if (result != VK_SUCCESS) {
9069         printf("%s CreateDevice returned back %s, skipping rest of tests\n", kSkipPrefix, string_VkResult(result));
9070         return;
9071     }
9072 
9073     // TODO: Re-enable test when Vulkan-Loader MR #581 is resolved and upstream into next SDK - tested ToT
9074     // if (queue_properties.queueCount > 1) {
9075     //     // Set queueIndex 1 over size of queueCount used to create device
9076     //     m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkGetDeviceQueue-queueIndex-00385");
9077     //     vk::GetDeviceQueue(test_device, queue_family_index, 1, &test_queue);
9078     //     m_errorMonitor->VerifyFound();
9079     // }
9080 
9081     // Use an unknown queue family index
9082     // m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkGetDeviceQueue-queueFamilyIndex-00384");
9083     // vk::GetDeviceQueue(test_device, queue_family_index + 1, 0, &test_queue);
9084     // m_errorMonitor->VerifyFound();
9085 
9086     PFN_vkGetDeviceQueue2 vkGetDeviceQueue2 = (PFN_vkGetDeviceQueue2)vk::GetDeviceProcAddr(test_device, "vkGetDeviceQueue2");
9087     ASSERT_TRUE(vkGetDeviceQueue2 != nullptr);
9088 
9089     queue_info_2.flags = 0;  // same as device creation
9090     queue_info_2.queueFamilyIndex = queue_family_index;
9091     queue_info_2.queueIndex = 0;
9092 
9093     if (queue_properties.queueCount > 1) {
9094         // Set queueIndex 1 over size of queueCount used to create device
9095         queue_info_2.queueIndex = 1;
9096         m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkDeviceQueueInfo2-queueIndex-01843");
9097         vkGetDeviceQueue2(test_device, &queue_info_2, &test_queue);
9098         m_errorMonitor->VerifyFound();
9099         queue_info_2.queueIndex = 0;  // reset
9100     }
9101 
9102     // Use an unknown queue family index
9103     queue_info_2.queueFamilyIndex = queue_family_index + 1;
9104     m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkDeviceQueueInfo2-queueFamilyIndex-01842");
9105     vkGetDeviceQueue2(test_device, &queue_info_2, &test_queue);
9106     m_errorMonitor->VerifyFound();
9107     queue_info_2.queueFamilyIndex = queue_family_index;  // reset
9108 
9109     // Test device created with no flags and trying to query with flag
9110     queue_info_2.flags = VK_DEVICE_QUEUE_CREATE_PROTECTED_BIT;
9111     m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkDeviceQueueInfo2-flags-06225");
9112     vkGetDeviceQueue2(test_device, &queue_info_2, &test_queue);
9113     m_errorMonitor->VerifyFound();
9114     queue_info_2.flags = 0;  // reset
9115 
9116     // Sanity check can still get the queue
9117     m_errorMonitor->ExpectSuccess();
9118     vk::GetDeviceQueue(test_device, queue_family_index, 0, &test_queue);
9119     m_errorMonitor->VerifyNotFound();
9120 
9121     vk::DestroyDevice(test_device, nullptr);
9122 }
9123 
TEST_F(VkLayerTest,UniqueQueueDeviceCreation)9124 TEST_F(VkLayerTest, UniqueQueueDeviceCreation) {
9125     TEST_DESCRIPTION("Vulkan 1.0 unique queue detection");
9126     SetTargetApiVersion(VK_API_VERSION_1_0);
9127 
9128     ASSERT_NO_FATAL_FAILURE(InitFramework(m_errorMonitor));
9129 
9130     // use first queue family with at least 2 queues in it
9131     bool found_queue = false;
9132     VkQueueFamilyProperties queue_properties;  // selected queue family used
9133     uint32_t queue_family_index = 0;
9134     uint32_t queue_family_count = 0;
9135     vk::GetPhysicalDeviceQueueFamilyProperties(gpu(), &queue_family_count, nullptr);
9136     std::vector<VkQueueFamilyProperties> queue_families(queue_family_count);
9137     vk::GetPhysicalDeviceQueueFamilyProperties(gpu(), &queue_family_count, queue_families.data());
9138 
9139     for (size_t i = 0; i < queue_families.size(); i++) {
9140         if (queue_families[i].queueCount > 1) {
9141             found_queue = true;
9142             queue_family_index = i;
9143             queue_properties = queue_families[i];
9144             break;
9145         }
9146     }
9147 
9148     if (found_queue == false) {
9149         printf("%s test requires queue family with 2 queues, not available.  Skipping.\n", kSkipPrefix);
9150         return;
9151     }
9152 
9153     float queue_priority = 1.0;
9154     VkDeviceQueueCreateInfo queue_create_info[2];
9155     queue_create_info[0] = LvlInitStruct<VkDeviceQueueCreateInfo>();
9156     queue_create_info[0].flags = 0;
9157     queue_create_info[0].queueFamilyIndex = queue_family_index;
9158     queue_create_info[0].queueCount = 1;
9159     queue_create_info[0].pQueuePriorities = &queue_priority;
9160 
9161     // queueFamilyIndex is the same
9162     queue_create_info[1] = queue_create_info[0];
9163 
9164     VkDevice test_device = VK_NULL_HANDLE;
9165     VkDeviceCreateInfo device_create_info = LvlInitStruct<VkDeviceCreateInfo>();
9166     device_create_info.flags = 0;
9167     device_create_info.pQueueCreateInfos = queue_create_info;
9168     device_create_info.queueCreateInfoCount = 2;
9169     device_create_info.pEnabledFeatures = nullptr;
9170     device_create_info.enabledLayerCount = 0;
9171     device_create_info.enabledExtensionCount = 0;
9172 
9173     const char *vuid = (DeviceValidationVersion() == VK_API_VERSION_1_0) ? "VUID-VkDeviceCreateInfo-queueFamilyIndex-00372"
9174                                                                          : "VUID-VkDeviceCreateInfo-queueFamilyIndex-02802";
9175     m_errorMonitor->SetDesiredFailureMsg(kErrorBit, vuid);
9176     vk::CreateDevice(gpu(), &device_create_info, nullptr, &test_device);
9177     m_errorMonitor->VerifyFound();
9178 }
9179 
TEST_F(VkLayerTest,UniqueQueueDeviceCreationBothProtected)9180 TEST_F(VkLayerTest, UniqueQueueDeviceCreationBothProtected) {
9181     TEST_DESCRIPTION("Vulkan 1.1 unique queue detection where both are protected and same queue family");
9182     SetTargetApiVersion(VK_API_VERSION_1_1);
9183 
9184     if (InstanceExtensionSupported(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME)) {
9185         m_instance_extension_names.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
9186     } else {
9187         printf("%s Did not find VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME; skipped.\n", kSkipPrefix);
9188         return;
9189     }
9190 
9191     ASSERT_NO_FATAL_FAILURE(InitFramework(m_errorMonitor));
9192 
9193     // Needed for both protected memory and vkGetDeviceQueue2
9194     if (DeviceValidationVersion() < VK_API_VERSION_1_1) {
9195         printf("%s test requires Vulkan 1.1 extensions, not available.  Skipping.\n", kSkipPrefix);
9196         return;
9197     }
9198 
9199     PFN_vkGetPhysicalDeviceFeatures2KHR vkGetPhysicalDeviceFeatures2KHR =
9200         (PFN_vkGetPhysicalDeviceFeatures2KHR)vk::GetInstanceProcAddr(instance(), "vkGetPhysicalDeviceFeatures2KHR");
9201     ASSERT_TRUE(vkGetPhysicalDeviceFeatures2KHR != nullptr);
9202 
9203     auto protected_features = LvlInitStruct<VkPhysicalDeviceProtectedMemoryFeatures>();
9204     auto features2 = LvlInitStruct<VkPhysicalDeviceFeatures2>(&protected_features);
9205     vkGetPhysicalDeviceFeatures2KHR(gpu(), &features2);
9206 
9207     if (protected_features.protectedMemory == VK_FALSE) {
9208         printf("%s test requires protectedMemory, not available.  Skipping.\n", kSkipPrefix);
9209         return;
9210     }
9211 
9212     // Try to find a protected queue family type
9213     bool protected_queue = false;
9214     VkQueueFamilyProperties queue_properties;  // selected queue family used
9215     uint32_t queue_family_index = 0;
9216     uint32_t queue_family_count = 0;
9217     vk::GetPhysicalDeviceQueueFamilyProperties(gpu(), &queue_family_count, nullptr);
9218     std::vector<VkQueueFamilyProperties> queue_families(queue_family_count);
9219     vk::GetPhysicalDeviceQueueFamilyProperties(gpu(), &queue_family_count, queue_families.data());
9220 
9221     for (size_t i = 0; i < queue_families.size(); i++) {
9222         // need to have at least 2 queues to use
9223         if (((queue_families[i].queueFlags & VK_QUEUE_PROTECTED_BIT) != 0) && (queue_families[i].queueCount > 1)) {
9224             protected_queue = true;
9225             queue_family_index = i;
9226             queue_properties = queue_families[i];
9227             break;
9228         }
9229     }
9230 
9231     if (protected_queue == false) {
9232         printf("%s test requires queue with VK_QUEUE_PROTECTED_BIT with 2 queues, not available.  Skipping.\n", kSkipPrefix);
9233         return;
9234     }
9235 
9236     float queue_priority = 1.0;
9237 
9238     VkDeviceQueueCreateInfo queue_create_info[2];
9239     queue_create_info[0] = LvlInitStruct<VkDeviceQueueCreateInfo>();
9240     queue_create_info[0].flags = 0;
9241     queue_create_info[0].queueFamilyIndex = queue_family_index;
9242     queue_create_info[0].queueCount = 1;
9243     queue_create_info[0].pQueuePriorities = &queue_priority;
9244 
9245     // queueFamilyIndex is the same and both are empty flags
9246     queue_create_info[1] = queue_create_info[0];
9247 
9248     VkDevice test_device = VK_NULL_HANDLE;
9249     VkDeviceCreateInfo device_create_info = LvlInitStruct<VkDeviceCreateInfo>(&protected_features);
9250     device_create_info.flags = 0;
9251     device_create_info.pQueueCreateInfos = queue_create_info;
9252     device_create_info.queueCreateInfoCount = 2;
9253     device_create_info.pEnabledFeatures = nullptr;
9254     device_create_info.enabledLayerCount = 0;
9255     device_create_info.enabledExtensionCount = 0;
9256 
9257     m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkDeviceCreateInfo-queueFamilyIndex-02802");
9258     vk::CreateDevice(gpu(), &device_create_info, nullptr, &test_device);
9259     m_errorMonitor->VerifyFound();
9260 
9261     // both protected
9262     queue_create_info[0].flags = VK_DEVICE_QUEUE_CREATE_PROTECTED_BIT;
9263     queue_create_info[1].flags = VK_DEVICE_QUEUE_CREATE_PROTECTED_BIT;
9264     m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkDeviceCreateInfo-queueFamilyIndex-02802");
9265     vk::CreateDevice(gpu(), &device_create_info, nullptr, &test_device);
9266     m_errorMonitor->VerifyFound();
9267 }
9268 
TEST_F(VkLayerTest,InvalidProtectedQueue)9269 TEST_F(VkLayerTest, InvalidProtectedQueue) {
9270     TEST_DESCRIPTION("Try creating queue without VK_QUEUE_PROTECTED_BIT capability");
9271     SetTargetApiVersion(VK_API_VERSION_1_1);
9272 
9273     if (InstanceExtensionSupported(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME)) {
9274         m_instance_extension_names.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
9275     } else {
9276         printf("%s Did not find VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME; skipped.\n", kSkipPrefix);
9277         return;
9278     }
9279 
9280     ASSERT_NO_FATAL_FAILURE(InitFramework(m_errorMonitor));
9281 
9282     if (DeviceValidationVersion() < VK_API_VERSION_1_1) {
9283         printf("%s test requires Vulkan 1.1 extensions, not available.  Skipping.\n", kSkipPrefix);
9284         return;
9285     }
9286 
9287     PFN_vkGetPhysicalDeviceFeatures2KHR vkGetPhysicalDeviceFeatures2KHR =
9288         (PFN_vkGetPhysicalDeviceFeatures2KHR)vk::GetInstanceProcAddr(instance(), "vkGetPhysicalDeviceFeatures2KHR");
9289     ASSERT_TRUE(vkGetPhysicalDeviceFeatures2KHR != nullptr);
9290 
9291     auto protected_features = LvlInitStruct<VkPhysicalDeviceProtectedMemoryFeatures>();
9292     auto features2 = LvlInitStruct<VkPhysicalDeviceFeatures2>(&protected_features);
9293     vkGetPhysicalDeviceFeatures2KHR(gpu(), &features2);
9294 
9295     if (protected_features.protectedMemory == VK_FALSE) {
9296         printf("%s test requires protectedMemory, not available. Skipping.\n", kSkipPrefix);
9297         return;
9298     }
9299 
9300     // Try to find a protected queue family type
9301     bool unprotected_queue = false;
9302     uint32_t queue_family_index = 0;
9303     uint32_t queue_family_count = 0;
9304     vk::GetPhysicalDeviceQueueFamilyProperties(gpu(), &queue_family_count, nullptr);
9305     std::vector<VkQueueFamilyProperties> queue_families(queue_family_count);
9306     vk::GetPhysicalDeviceQueueFamilyProperties(gpu(), &queue_family_count, queue_families.data());
9307 
9308     // need to find a queue without protected support
9309     for (size_t i = 0; i < queue_families.size(); i++) {
9310         if ((queue_families[i].queueFlags & VK_QUEUE_PROTECTED_BIT) == 0) {
9311             unprotected_queue = true;
9312             queue_family_index = i;
9313             break;
9314         }
9315     }
9316 
9317     if (unprotected_queue == false) {
9318         printf("%s test requires queue without VK_QUEUE_PROTECTED_BIT. Skipping.\n", kSkipPrefix);
9319         return;
9320     }
9321 
9322     float queue_priority = 1.0;
9323     VkDeviceQueueCreateInfo queue_create_info = LvlInitStruct<VkDeviceQueueCreateInfo>();
9324     queue_create_info.flags = VK_DEVICE_QUEUE_CREATE_PROTECTED_BIT;
9325     queue_create_info.queueFamilyIndex = queue_family_index;
9326     queue_create_info.queueCount = 1;
9327     queue_create_info.pQueuePriorities = &queue_priority;
9328 
9329     VkDevice test_device = VK_NULL_HANDLE;
9330     VkDeviceCreateInfo device_create_info = LvlInitStruct<VkDeviceCreateInfo>(&protected_features);
9331     device_create_info.flags = 0;
9332     device_create_info.pQueueCreateInfos = &queue_create_info;
9333     device_create_info.queueCreateInfoCount = 1;
9334     device_create_info.pEnabledFeatures = nullptr;
9335     device_create_info.enabledLayerCount = 0;
9336     device_create_info.enabledExtensionCount = 0;
9337 
9338     m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkDeviceQueueCreateInfo-flags-06449");
9339     vk::CreateDevice(gpu(), &device_create_info, nullptr, &test_device);
9340     m_errorMonitor->VerifyFound();
9341 }
9342 
TEST_F(VkLayerTest,InvalidProtectedSubmit)9343 TEST_F(VkLayerTest, InvalidProtectedSubmit) {
9344     TEST_DESCRIPTION("Setting protectedSubmit with a queue not created with VK_DEVICE_QUEUE_CREATE_PROTECTED_BIT");
9345 
9346     SetTargetApiVersion(VK_API_VERSION_1_1);
9347 
9348     if (InstanceExtensionSupported(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME)) {
9349         m_instance_extension_names.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
9350     } else {
9351         printf("%s Did not find required instance extension %s; skipped.\n", kSkipPrefix,
9352                VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
9353         return;
9354     }
9355     ASSERT_NO_FATAL_FAILURE(InitFramework(m_errorMonitor));
9356 
9357     if (DeviceValidationVersion() < VK_API_VERSION_1_1) {
9358         printf("%s test requires Vulkan 1.1 extensions, not available.  Skipping.\n", kSkipPrefix);
9359         return;
9360     }
9361 
9362     // creates a queue without VK_DEVICE_QUEUE_CREATE_PROTECTED_BIT
9363     ASSERT_NO_FATAL_FAILURE(InitState());
9364 
9365     VkCommandPool command_pool;
9366     VkCommandPoolCreateInfo pool_create_info = {};
9367     pool_create_info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
9368     pool_create_info.pNext = nullptr;
9369     pool_create_info.flags = VK_COMMAND_POOL_CREATE_PROTECTED_BIT;
9370     pool_create_info.queueFamilyIndex = m_device->graphics_queue_node_index_;
9371     m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkCommandPoolCreateInfo-flags-02860");
9372     vk::CreateCommandPool(device(), &pool_create_info, nullptr, &command_pool);
9373     m_errorMonitor->VerifyFound();
9374 
9375     VkBuffer buffer;
9376     VkBufferCreateInfo buffer_create_info = {};
9377     buffer_create_info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
9378     buffer_create_info.pNext = nullptr;
9379     buffer_create_info.flags = VK_BUFFER_CREATE_PROTECTED_BIT;
9380     buffer_create_info.size = 4096;
9381     buffer_create_info.usage = VK_BUFFER_USAGE_TRANSFER_DST_BIT;
9382     buffer_create_info.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
9383     m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkBufferCreateInfo-flags-01887");
9384     vk::CreateBuffer(device(), &buffer_create_info, nullptr, &buffer);
9385     m_errorMonitor->VerifyFound();
9386 
9387     VkImage image;
9388     VkImageCreateInfo image_create_info{};
9389     image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
9390     image_create_info.pNext = nullptr;
9391     image_create_info.flags = VK_IMAGE_CREATE_PROTECTED_BIT;
9392     image_create_info.extent = {64, 64, 1};
9393     image_create_info.format = VK_FORMAT_R8G8B8A8_UNORM;
9394     image_create_info.imageType = VK_IMAGE_TYPE_2D;
9395     image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL;
9396     image_create_info.usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
9397     image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
9398     image_create_info.arrayLayers = 1;
9399     image_create_info.mipLevels = 1;
9400     m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkImageCreateInfo-flags-01890");
9401     vk::CreateImage(device(), &image_create_info, nullptr, &image);
9402     m_errorMonitor->VerifyFound();
9403 
9404     // Try to find memory with protected bit in it at all
9405     VkDeviceMemory memory_protected = VK_NULL_HANDLE;
9406     VkMemoryAllocateInfo alloc_info = {};
9407     alloc_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
9408     alloc_info.pNext = nullptr;
9409     alloc_info.allocationSize = 4096;
9410 
9411     VkPhysicalDeviceMemoryProperties phys_mem_props;
9412     vk::GetPhysicalDeviceMemoryProperties(gpu(), &phys_mem_props);
9413     alloc_info.memoryTypeIndex = phys_mem_props.memoryTypeCount + 1;
9414     for (uint32_t i = 0; i < phys_mem_props.memoryTypeCount; i++) {
9415         // Check just protected bit is in type at all
9416         if ((phys_mem_props.memoryTypes[i].propertyFlags & VK_MEMORY_PROPERTY_PROTECTED_BIT) != 0) {
9417             alloc_info.memoryTypeIndex = i;
9418             break;
9419         }
9420     }
9421     if (alloc_info.memoryTypeIndex < phys_mem_props.memoryTypeCount) {
9422         m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkMemoryAllocateInfo-memoryTypeIndex-01872");
9423         vk::AllocateMemory(device(), &alloc_info, NULL, &memory_protected);
9424         m_errorMonitor->VerifyFound();
9425     }
9426 
9427     VkProtectedSubmitInfo protected_submit_info = {};
9428     protected_submit_info.sType = VK_STRUCTURE_TYPE_PROTECTED_SUBMIT_INFO;
9429     protected_submit_info.pNext = nullptr;
9430     protected_submit_info.protectedSubmit = VK_TRUE;
9431 
9432     VkSubmitInfo submit_info = {};
9433     submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
9434     submit_info.pNext = &protected_submit_info;
9435     submit_info.commandBufferCount = 1;
9436     submit_info.pCommandBuffers = &m_commandBuffer->handle();
9437 
9438     m_commandBuffer->begin();
9439     m_commandBuffer->end();
9440 
9441     m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkQueueSubmit-queue-06448");
9442     m_errorMonitor->SetUnexpectedError("VUID-VkSubmitInfo-pNext-04148");
9443     vk::QueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
9444     m_errorMonitor->VerifyFound();
9445 }
9446 
TEST_F(VkLayerTest,InvalidProtectedMemory)9447 TEST_F(VkLayerTest, InvalidProtectedMemory) {
9448     TEST_DESCRIPTION("Validate cases where protectedMemory feature is enabled and usages are invalid");
9449 
9450     SetTargetApiVersion(VK_API_VERSION_1_1);
9451 
9452     if (InstanceExtensionSupported(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME)) {
9453         m_instance_extension_names.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
9454     } else {
9455         printf("%s Did not find required instance extension %s; skipped.\n", kSkipPrefix,
9456                VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
9457         return;
9458     }
9459     ASSERT_NO_FATAL_FAILURE(InitFramework(m_errorMonitor));
9460 
9461     PFN_vkGetPhysicalDeviceFeatures2KHR vkGetPhysicalDeviceFeatures2KHR =
9462         (PFN_vkGetPhysicalDeviceFeatures2KHR)vk::GetInstanceProcAddr(instance(), "vkGetPhysicalDeviceFeatures2KHR");
9463     ASSERT_TRUE(vkGetPhysicalDeviceFeatures2KHR != nullptr);
9464 
9465     auto protected_memory_features = LvlInitStruct<VkPhysicalDeviceProtectedMemoryFeatures>();
9466     auto features2 = LvlInitStruct<VkPhysicalDeviceFeatures2KHR>(&protected_memory_features);
9467     vkGetPhysicalDeviceFeatures2KHR(gpu(), &features2);
9468 
9469     if (protected_memory_features.protectedMemory == VK_FALSE) {
9470         printf("%s protectedMemory feature not supported, skipped.\n", kSkipPrefix);
9471         return;
9472     };
9473 
9474     // Turns m_commandBuffer into a protected command buffer
9475     ASSERT_NO_FATAL_FAILURE(InitState(nullptr, &features2, VK_COMMAND_POOL_CREATE_PROTECTED_BIT));
9476 
9477     bool sparse_support = (m_device->phy().features().sparseBinding == VK_TRUE);
9478 
9479     if (DeviceValidationVersion() < VK_API_VERSION_1_1) {
9480         printf("%s Tests requires Vulkan 1.1+, skipping test\n", kSkipPrefix);
9481         return;
9482     }
9483 
9484     VkBuffer buffer_protected = VK_NULL_HANDLE;
9485     VkBuffer buffer_unprotected = VK_NULL_HANDLE;
9486     VkBufferCreateInfo buffer_create_info = {};
9487     buffer_create_info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
9488     buffer_create_info.pNext = nullptr;
9489     buffer_create_info.flags = VK_BUFFER_CREATE_PROTECTED_BIT | VK_BUFFER_CREATE_SPARSE_BINDING_BIT;
9490     buffer_create_info.size = 1 << 20;  // 1 MB
9491     buffer_create_info.usage = VK_BUFFER_USAGE_TRANSFER_DST_BIT;
9492     buffer_create_info.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
9493 
9494     if (sparse_support == true) {
9495         m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkBufferCreateInfo-None-01888");
9496         vk::CreateBuffer(device(), &buffer_create_info, nullptr, &buffer_protected);
9497         m_errorMonitor->VerifyFound();
9498     }
9499 
9500     // Create actual protected and unprotected buffers
9501     m_errorMonitor->ExpectSuccess();
9502     buffer_create_info.flags = VK_BUFFER_CREATE_PROTECTED_BIT;
9503     vk::CreateBuffer(device(), &buffer_create_info, nullptr, &buffer_protected);
9504     buffer_create_info.flags = 0;
9505     vk::CreateBuffer(device(), &buffer_create_info, nullptr, &buffer_unprotected);
9506     m_errorMonitor->VerifyNotFound();
9507 
9508     VkImage image_protected = VK_NULL_HANDLE;
9509     VkImage image_unprotected = VK_NULL_HANDLE;
9510     VkImageCreateInfo image_create_info{};
9511     image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
9512     image_create_info.pNext = nullptr;
9513     image_create_info.flags = VK_IMAGE_CREATE_PROTECTED_BIT | VK_IMAGE_CREATE_SPARSE_BINDING_BIT;
9514     image_create_info.extent = {8, 8, 1};
9515     image_create_info.format = VK_FORMAT_R8G8B8A8_UNORM;
9516     image_create_info.imageType = VK_IMAGE_TYPE_2D;
9517     image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL;
9518     image_create_info.usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
9519     image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
9520     image_create_info.arrayLayers = 1;
9521     image_create_info.mipLevels = 1;
9522 
9523     if (sparse_support == true) {
9524         m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkImageCreateInfo-None-01891");
9525         vk::CreateImage(device(), &image_create_info, nullptr, &image_protected);
9526         m_errorMonitor->VerifyFound();
9527     }
9528 
9529     // Create actual protected and unprotected images
9530     m_errorMonitor->ExpectSuccess();
9531     image_create_info.flags = VK_IMAGE_CREATE_PROTECTED_BIT;
9532     vk::CreateImage(device(), &image_create_info, nullptr, &image_protected);
9533     image_create_info.flags = 0;
9534     vk::CreateImage(device(), &image_create_info, nullptr, &image_unprotected);
9535     m_errorMonitor->VerifyNotFound();
9536 
9537     // Create protected and unproteced memory
9538     VkDeviceMemory memory_protected = VK_NULL_HANDLE;
9539     VkDeviceMemory memory_unprotected = VK_NULL_HANDLE;
9540 
9541     VkMemoryAllocateInfo alloc_info = {};
9542     alloc_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
9543     alloc_info.pNext = nullptr;
9544     alloc_info.allocationSize = 0;
9545 
9546     // set allocationSize to buffer as it will be larger than the image, but query image to avoid BP warning
9547     VkMemoryRequirements mem_reqs_protected;
9548     vk::GetImageMemoryRequirements(device(), image_protected, &mem_reqs_protected);
9549     vk::GetBufferMemoryRequirements(device(), buffer_protected, &mem_reqs_protected);
9550     VkMemoryRequirements mem_reqs_unprotected;
9551     vk::GetImageMemoryRequirements(device(), image_unprotected, &mem_reqs_unprotected);
9552     vk::GetBufferMemoryRequirements(device(), buffer_unprotected, &mem_reqs_unprotected);
9553 
9554     // Get memory index for a protected and unprotected memory
9555     VkPhysicalDeviceMemoryProperties phys_mem_props;
9556     vk::GetPhysicalDeviceMemoryProperties(gpu(), &phys_mem_props);
9557     uint32_t memory_type_protected = phys_mem_props.memoryTypeCount + 1;
9558     uint32_t memory_type_unprotected = phys_mem_props.memoryTypeCount + 1;
9559     for (uint32_t i = 0; i < phys_mem_props.memoryTypeCount; i++) {
9560         if ((mem_reqs_unprotected.memoryTypeBits & (1 << i)) &&
9561             ((phys_mem_props.memoryTypes[i].propertyFlags & VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT) ==
9562              VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT)) {
9563             memory_type_unprotected = i;
9564         }
9565         // Check just protected bit is in type at all
9566         if ((mem_reqs_protected.memoryTypeBits & (1 << i)) &&
9567             ((phys_mem_props.memoryTypes[i].propertyFlags & VK_MEMORY_PROPERTY_PROTECTED_BIT) != 0)) {
9568             memory_type_protected = i;
9569         }
9570     }
9571     if ((memory_type_protected >= phys_mem_props.memoryTypeCount) || (memory_type_unprotected >= phys_mem_props.memoryTypeCount)) {
9572         printf("%s No valid memory type index could be found; skipped.\n", kSkipPrefix);
9573         vk::DestroyImage(device(), image_protected, nullptr);
9574         vk::DestroyImage(device(), image_unprotected, nullptr);
9575         vk::DestroyBuffer(device(), buffer_protected, nullptr);
9576         vk::DestroyBuffer(device(), buffer_unprotected, nullptr);
9577         return;
9578     }
9579 
9580     alloc_info.memoryTypeIndex = memory_type_protected;
9581     alloc_info.allocationSize = mem_reqs_protected.size;
9582     vk::AllocateMemory(device(), &alloc_info, NULL, &memory_protected);
9583 
9584     alloc_info.allocationSize = mem_reqs_unprotected.size;
9585     alloc_info.memoryTypeIndex = memory_type_unprotected;
9586     vk::AllocateMemory(device(), &alloc_info, NULL, &memory_unprotected);
9587 
9588     // Bind protected buffer with unprotected memory
9589     m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkBindBufferMemory-None-01898");
9590     m_errorMonitor->SetUnexpectedError("VUID-vkBindBufferMemory-memory-01035");
9591     vk::BindBufferMemory(device(), buffer_protected, memory_unprotected, 0);
9592     m_errorMonitor->VerifyFound();
9593 
9594     // Bind unprotected buffer with protected memory
9595     m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkBindBufferMemory-None-01899");
9596     m_errorMonitor->SetUnexpectedError("VUID-vkBindBufferMemory-memory-01035");
9597     vk::BindBufferMemory(device(), buffer_unprotected, memory_protected, 0);
9598     m_errorMonitor->VerifyFound();
9599 
9600     // Bind protected image with unprotected memory
9601     m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkBindImageMemory-None-01901");
9602     m_errorMonitor->SetUnexpectedError("VUID-vkBindImageMemory-memory-01047");
9603     vk::BindImageMemory(device(), image_protected, memory_unprotected, 0);
9604     m_errorMonitor->VerifyFound();
9605 
9606     // Bind unprotected image with protected memory
9607     m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkBindImageMemory-None-01902");
9608     m_errorMonitor->SetUnexpectedError("VUID-vkBindImageMemory-memory-01047");
9609     vk::BindImageMemory(device(), image_unprotected, memory_protected, 0);
9610     m_errorMonitor->VerifyFound();
9611 
9612     vk::DestroyImage(device(), image_protected, nullptr);
9613     vk::DestroyImage(device(), image_unprotected, nullptr);
9614     vk::DestroyBuffer(device(), buffer_protected, nullptr);
9615     vk::DestroyBuffer(device(), buffer_unprotected, nullptr);
9616     vk::FreeMemory(device(), memory_protected, nullptr);
9617     vk::FreeMemory(device(), memory_unprotected, nullptr);
9618 }
9619 
TEST_F(VkLayerTest,ValidateCmdTraceRaysKHR)9620 TEST_F(VkLayerTest, ValidateCmdTraceRaysKHR) {
9621     TEST_DESCRIPTION("Validate vkCmdTraceRaysKHR.");
9622     if (!InitFrameworkForRayTracingTest(this, true, m_instance_extension_names, m_device_extension_names, m_errorMonitor)) {
9623         return;
9624     }
9625     VkBuffer buffer;
9626     VkBufferCreateInfo buf_info = {};
9627     buf_info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
9628     buf_info.usage = VK_BUFFER_USAGE_TRANSFER_DST_BIT;
9629     buf_info.size = 4096;
9630     buf_info.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
9631     VkResult err = vk::CreateBuffer(device(), &buf_info, NULL, &buffer);
9632     ASSERT_VK_SUCCESS(err);
9633 
9634     VkMemoryRequirements mem_reqs;
9635     vk::GetBufferMemoryRequirements(device(), buffer, &mem_reqs);
9636 
9637     VkMemoryAllocateInfo alloc_info = {};
9638     alloc_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
9639     alloc_info.allocationSize = 4096;
9640     VkDeviceMemory mem;
9641     err = vk::AllocateMemory(device(), &alloc_info, NULL, &mem);
9642     ASSERT_VK_SUCCESS(err);
9643     vk::BindBufferMemory(device(), buffer, mem, 0);
9644 
9645     PFN_vkGetPhysicalDeviceProperties2KHR vkGetPhysicalDeviceProperties2KHR =
9646         (PFN_vkGetPhysicalDeviceProperties2KHR)vk::GetInstanceProcAddr(instance(), "vkGetPhysicalDeviceProperties2KHR");
9647     ASSERT_TRUE(vkGetPhysicalDeviceProperties2KHR != nullptr);
9648 
9649     auto ray_tracing_properties = LvlInitStruct<VkPhysicalDeviceRayTracingPipelinePropertiesKHR>();
9650     auto properties2 = LvlInitStruct<VkPhysicalDeviceProperties2KHR>(&ray_tracing_properties);
9651     vkGetPhysicalDeviceProperties2KHR(gpu(), &properties2);
9652 
9653     PFN_vkCmdTraceRaysKHR vkCmdTraceRaysKHR = (PFN_vkCmdTraceRaysKHR)vk::GetInstanceProcAddr(instance(), "vkCmdTraceRaysKHR");
9654     ASSERT_TRUE(vkCmdTraceRaysKHR != nullptr);
9655     PFN_vkGetBufferDeviceAddressKHR vkGetBufferDeviceAddressKHR =
9656         (PFN_vkGetBufferDeviceAddressKHR)vk::GetDeviceProcAddr(device(), "vkGetBufferDeviceAddressKHR");
9657 
9658     VkBufferDeviceAddressInfo device_address_info = {VK_STRUCTURE_TYPE_BUFFER_DEVICE_ADDRESS_INFO, NULL, buffer};
9659     VkDeviceAddress device_address = vkGetBufferDeviceAddressKHR(m_device->handle(), &device_address_info);
9660 
9661     VkStridedDeviceAddressRegionKHR stridebufregion = {};
9662     stridebufregion.deviceAddress = device_address;
9663     stridebufregion.stride = ray_tracing_properties.shaderGroupHandleAlignment;
9664     stridebufregion.size = stridebufregion.stride;
9665 
9666     m_commandBuffer->begin();
9667     // Invalid stride multiplier
9668     {
9669         VkStridedDeviceAddressRegionKHR invalid_stride = stridebufregion;
9670         invalid_stride.stride = (stridebufregion.size + 1) % stridebufregion.size;
9671         if (invalid_stride.stride > 0) {
9672             m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdTraceRaysKHR-stride-03694");
9673             vkCmdTraceRaysKHR(m_commandBuffer->handle(), &stridebufregion, &stridebufregion, &stridebufregion, &invalid_stride, 100,
9674                               100, 1);
9675             m_errorMonitor->VerifyFound();
9676 
9677             m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdTraceRaysKHR-stride-03690");
9678             vkCmdTraceRaysKHR(m_commandBuffer->handle(), &stridebufregion, &stridebufregion, &invalid_stride, &stridebufregion, 100,
9679                               100, 1);
9680             m_errorMonitor->VerifyFound();
9681 
9682             m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdTraceRaysKHR-stride-03686");
9683             vkCmdTraceRaysKHR(m_commandBuffer->handle(), &stridebufregion, &invalid_stride, &stridebufregion, &stridebufregion, 100,
9684                               100, 1);
9685             m_errorMonitor->VerifyFound();
9686         }
9687     }
9688     // Invalid stride, greater than maxShaderGroupStride
9689     {
9690         VkStridedDeviceAddressRegionKHR invalid_stride = stridebufregion;
9691         uint32_t align = ray_tracing_properties.shaderGroupHandleSize;
9692         invalid_stride.stride =
9693             ray_tracing_properties.maxShaderGroupStride + (align - (ray_tracing_properties.maxShaderGroupStride % align));
9694         m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdTraceRaysKHR-stride-04041");
9695         vkCmdTraceRaysKHR(m_commandBuffer->handle(), &stridebufregion, &stridebufregion, &stridebufregion, &invalid_stride, 100,
9696                           100, 1);
9697         m_errorMonitor->VerifyFound();
9698 
9699         m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdTraceRaysKHR-stride-04035");
9700         vkCmdTraceRaysKHR(m_commandBuffer->handle(), &stridebufregion, &stridebufregion, &invalid_stride, &stridebufregion, 100,
9701                           100, 1);
9702         m_errorMonitor->VerifyFound();
9703 
9704         m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdTraceRaysKHR-stride-04029");
9705         vkCmdTraceRaysKHR(m_commandBuffer->handle(), &stridebufregion, &invalid_stride, &stridebufregion, &stridebufregion, 100,
9706                           100, 1);
9707         m_errorMonitor->VerifyFound();
9708     }
9709     m_commandBuffer->end();
9710 }
9711 
TEST_F(VkLayerTest,ValidateCmdTraceRaysIndirectKHR)9712 TEST_F(VkLayerTest, ValidateCmdTraceRaysIndirectKHR) {
9713     TEST_DESCRIPTION("Validate vkCmdTraceRaysIndirectKHR.");
9714     if (!InitFrameworkForRayTracingTest(this, true, m_instance_extension_names, m_device_extension_names, m_errorMonitor, false,
9715                                         false, true)) {
9716         return;
9717     }
9718     auto ray_tracing_features = LvlInitStruct<VkPhysicalDeviceRayTracingPipelineFeaturesKHR>();
9719     auto features2 = LvlInitStruct<VkPhysicalDeviceFeatures2KHR>(&ray_tracing_features);
9720     PFN_vkGetPhysicalDeviceFeatures2KHR vkGetPhysicalDeviceFeatures2KHR =
9721         (PFN_vkGetPhysicalDeviceFeatures2KHR)vk::GetInstanceProcAddr(instance(), "vkGetPhysicalDeviceFeatures2KHR");
9722     vkGetPhysicalDeviceFeatures2KHR(gpu(), &features2);
9723     if (ray_tracing_features.rayTracingPipelineTraceRaysIndirect == VK_FALSE) {
9724         printf("%s rayTracingIndirectTraceRays not supported, skipping tests\n", kSkipPrefix);
9725         return;
9726     }
9727     ASSERT_NO_FATAL_FAILURE(InitState(nullptr, &ray_tracing_features));
9728     VkBuffer buffer;
9729     VkBufferCreateInfo buf_info = {};
9730     buf_info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
9731     buf_info.usage = VK_BUFFER_USAGE_TRANSFER_DST_BIT;
9732     buf_info.size = 4096;
9733     buf_info.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
9734     VkResult err = vk::CreateBuffer(device(), &buf_info, NULL, &buffer);
9735     ASSERT_VK_SUCCESS(err);
9736 
9737     VkMemoryRequirements mem_reqs;
9738     vk::GetBufferMemoryRequirements(device(), buffer, &mem_reqs);
9739 
9740     VkMemoryAllocateInfo alloc_info = {};
9741     alloc_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
9742     alloc_info.allocationSize = 4096;
9743     VkDeviceMemory mem;
9744     err = vk::AllocateMemory(device(), &alloc_info, NULL, &mem);
9745     ASSERT_VK_SUCCESS(err);
9746     vk::BindBufferMemory(device(), buffer, mem, 0);
9747 
9748     PFN_vkGetPhysicalDeviceProperties2KHR vkGetPhysicalDeviceProperties2KHR =
9749         (PFN_vkGetPhysicalDeviceProperties2KHR)vk::GetInstanceProcAddr(instance(), "vkGetPhysicalDeviceProperties2KHR");
9750     ASSERT_TRUE(vkGetPhysicalDeviceProperties2KHR != nullptr);
9751 
9752     auto ray_tracing_properties = LvlInitStruct<VkPhysicalDeviceRayTracingPipelinePropertiesKHR>();
9753     auto properties2 = LvlInitStruct<VkPhysicalDeviceProperties2KHR>(&ray_tracing_properties);
9754     vkGetPhysicalDeviceProperties2KHR(gpu(), &properties2);
9755 
9756     PFN_vkCmdTraceRaysIndirectKHR vkCmdTraceRaysIndirectKHR =
9757         (PFN_vkCmdTraceRaysIndirectKHR)vk::GetInstanceProcAddr(instance(), "vkCmdTraceRaysIndirectKHR");
9758     ASSERT_TRUE(vkCmdTraceRaysIndirectKHR != nullptr);
9759 
9760     PFN_vkGetBufferDeviceAddressKHR vkGetBufferDeviceAddressKHR =
9761         (PFN_vkGetBufferDeviceAddressKHR)vk::GetDeviceProcAddr(device(), "vkGetBufferDeviceAddressKHR");
9762 
9763     VkBufferDeviceAddressInfo device_address_info = {VK_STRUCTURE_TYPE_BUFFER_DEVICE_ADDRESS_INFO, NULL, buffer};
9764     VkDeviceAddress device_address = vkGetBufferDeviceAddressKHR(m_device->handle(), &device_address_info);
9765 
9766     VkStridedDeviceAddressRegionKHR stridebufregion = {};
9767     stridebufregion.deviceAddress = device_address;
9768     stridebufregion.stride = ray_tracing_properties.shaderGroupHandleAlignment;
9769     stridebufregion.size = stridebufregion.stride;
9770 
9771     m_commandBuffer->begin();
9772     // Invalid stride multiplier
9773     {
9774         VkStridedDeviceAddressRegionKHR invalid_stride = stridebufregion;
9775         invalid_stride.stride = (stridebufregion.size + 1) % stridebufregion.size;
9776         if (invalid_stride.stride > 0) {
9777             m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdTraceRaysIndirectKHR-stride-03694");
9778             vkCmdTraceRaysIndirectKHR(m_commandBuffer->handle(), &stridebufregion, &stridebufregion, &stridebufregion,
9779                                       &invalid_stride, device_address);
9780             m_errorMonitor->VerifyFound();
9781 
9782             m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdTraceRaysIndirectKHR-stride-03690");
9783             vkCmdTraceRaysIndirectKHR(m_commandBuffer->handle(), &stridebufregion, &stridebufregion, &invalid_stride,
9784                                       &stridebufregion, device_address);
9785             m_errorMonitor->VerifyFound();
9786 
9787             m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdTraceRaysIndirectKHR-stride-03686");
9788             vkCmdTraceRaysIndirectKHR(m_commandBuffer->handle(), &stridebufregion, &invalid_stride, &stridebufregion,
9789                                       &stridebufregion, device_address);
9790             m_errorMonitor->VerifyFound();
9791         }
9792     }
9793     // Invalid stride, greater than maxShaderGroupStride
9794     {
9795         VkStridedDeviceAddressRegionKHR invalid_stride = stridebufregion;
9796         uint32_t align = ray_tracing_properties.shaderGroupHandleSize;
9797         invalid_stride.stride =
9798             ray_tracing_properties.maxShaderGroupStride + (align - (ray_tracing_properties.maxShaderGroupStride % align));
9799         m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdTraceRaysIndirectKHR-stride-04041");
9800         vkCmdTraceRaysIndirectKHR(m_commandBuffer->handle(), &stridebufregion, &stridebufregion, &stridebufregion, &invalid_stride,
9801                                   device_address);
9802         m_errorMonitor->VerifyFound();
9803 
9804         m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdTraceRaysIndirectKHR-stride-04035");
9805         vkCmdTraceRaysIndirectKHR(m_commandBuffer->handle(), &stridebufregion, &stridebufregion, &invalid_stride, &stridebufregion,
9806                                   device_address);
9807         m_errorMonitor->VerifyFound();
9808 
9809         m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdTraceRaysIndirectKHR-stride-04029");
9810         vkCmdTraceRaysIndirectKHR(m_commandBuffer->handle(), &stridebufregion, &invalid_stride, &stridebufregion, &stridebufregion,
9811                                   device_address);
9812         m_errorMonitor->VerifyFound();
9813     }
9814     m_commandBuffer->end();
9815 }
9816 
TEST_F(VkLayerTest,ValidateVkAccelerationStructureVersionInfoKHR)9817 TEST_F(VkLayerTest, ValidateVkAccelerationStructureVersionInfoKHR) {
9818     TEST_DESCRIPTION("Validate VkAccelerationStructureVersionInfoKHR.");
9819     if (!InitFrameworkForRayTracingTest(this, true, m_instance_extension_names, m_device_extension_names, m_errorMonitor, false,
9820                                         false, true)) {
9821         return;
9822     }
9823 
9824     auto ray_tracing_features = LvlInitStruct<VkPhysicalDeviceRayTracingPipelineFeaturesKHR>();
9825     auto features2 = LvlInitStruct<VkPhysicalDeviceFeatures2KHR>(&ray_tracing_features);
9826     PFN_vkGetPhysicalDeviceFeatures2KHR vkGetPhysicalDeviceFeatures2KHR =
9827         (PFN_vkGetPhysicalDeviceFeatures2KHR)vk::GetInstanceProcAddr(instance(), "vkGetPhysicalDeviceFeatures2KHR");
9828     vkGetPhysicalDeviceFeatures2KHR(gpu(), &features2);
9829     if (ray_tracing_features.rayTracingPipeline == VK_FALSE) {
9830         printf("%s rayTracing not supported, skipping tests\n", kSkipPrefix);
9831         return;
9832     }
9833     ASSERT_NO_FATAL_FAILURE(InitState(nullptr, &ray_tracing_features));
9834     PFN_vkGetDeviceAccelerationStructureCompatibilityKHR vkGetDeviceAccelerationStructureCompatibilityKHR =
9835         (PFN_vkGetDeviceAccelerationStructureCompatibilityKHR)vk::GetInstanceProcAddr(
9836             instance(), "vkGetDeviceAccelerationStructureCompatibilityKHR");
9837     ASSERT_TRUE(vkGetDeviceAccelerationStructureCompatibilityKHR != nullptr);
9838     VkAccelerationStructureVersionInfoKHR valid_version = {};
9839     VkAccelerationStructureCompatibilityKHR compatablity;
9840     uint8_t mode[] = {VK_COPY_ACCELERATION_STRUCTURE_MODE_COMPACT_KHR, VK_COPY_ACCELERATION_STRUCTURE_MODE_CLONE_KHR};
9841     valid_version.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_VERSION_INFO_KHR;
9842     valid_version.pVersionData = mode;
9843     {
9844         VkAccelerationStructureVersionInfoKHR invalid_version = valid_version;
9845         invalid_version.sType = VK_STRUCTURE_TYPE_MAX_ENUM;
9846         m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkAccelerationStructureVersionInfoKHR-sType-sType");
9847         vkGetDeviceAccelerationStructureCompatibilityKHR(m_device->handle(), &invalid_version, &compatablity);
9848         m_errorMonitor->VerifyFound();
9849     }
9850 
9851     {
9852         VkAccelerationStructureVersionInfoKHR invalid_version = valid_version;
9853         invalid_version.pVersionData = NULL;
9854         m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkAccelerationStructureVersionInfoKHR-pVersionData-parameter");
9855         vkGetDeviceAccelerationStructureCompatibilityKHR(m_device->handle(), &invalid_version, &compatablity);
9856         m_errorMonitor->VerifyFound();
9857     }
9858 }
9859 
TEST_F(VkLayerTest,ValidateCmdBuildAccelerationStructuresKHR)9860 TEST_F(VkLayerTest, ValidateCmdBuildAccelerationStructuresKHR) {
9861     TEST_DESCRIPTION("Validate acceleration structure building.");
9862 
9863     auto accel_features = LvlInitStruct<VkPhysicalDeviceAccelerationStructureFeaturesKHR>();
9864     accel_features.accelerationStructureIndirectBuild = VK_TRUE;
9865     accel_features.accelerationStructureHostCommands = VK_TRUE;
9866     auto features2 = LvlInitStruct<VkPhysicalDeviceFeatures2KHR>(&accel_features);
9867     if (!InitFrameworkForRayTracingTest(this, true, m_instance_extension_names, m_device_extension_names, m_errorMonitor, false,
9868                                         false, false, &features2)) {
9869         return;
9870     }
9871 
9872     PFN_vkCmdBuildAccelerationStructuresKHR vkCmdBuildAccelerationStructuresKHR =
9873         (PFN_vkCmdBuildAccelerationStructuresKHR)vk::GetDeviceProcAddr(device(), "vkCmdBuildAccelerationStructuresKHR");
9874     assert(vkCmdBuildAccelerationStructuresKHR != nullptr);
9875 
9876     PFN_vkGetBufferDeviceAddressKHR vkGetBufferDeviceAddressKHR =
9877         (PFN_vkGetBufferDeviceAddressKHR)vk::GetDeviceProcAddr(device(), "vkGetBufferDeviceAddressKHR");
9878 
9879     auto vkCmdBuildAccelerationStructuresIndirectKHR = reinterpret_cast<PFN_vkCmdBuildAccelerationStructuresIndirectKHR>(
9880         vk::GetDeviceProcAddr(device(), "vkCmdBuildAccelerationStructuresIndirectKHR"));
9881     assert(vkCmdBuildAccelerationStructuresKHR);
9882 
9883     auto vkBuildAccelerationStructuresKHR =
9884         reinterpret_cast<PFN_vkBuildAccelerationStructuresKHR>(vk::GetDeviceProcAddr(device(), "vkBuildAccelerationStructuresKHR"));
9885     assert(vkBuildAccelerationStructuresKHR);
9886 
9887     VkBufferObj vbo;
9888     VkBufferObj ibo;
9889     VkGeometryNV geometryNV;
9890     GetSimpleGeometryForAccelerationStructureTests(*m_device, &vbo, &ibo, &geometryNV);
9891 
9892     VkAccelerationStructureCreateInfoKHR as_create_info = {};
9893     VkBufferObj buffer;
9894     buffer.init(*m_device, 4096, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, VK_BUFFER_USAGE_ACCELERATION_STRUCTURE_STORAGE_BIT_KHR);
9895     as_create_info.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_CREATE_INFO_KHR;
9896     as_create_info.pNext = NULL;
9897     as_create_info.buffer = buffer.handle();
9898     as_create_info.createFlags = 0;
9899     as_create_info.offset = 0;
9900     as_create_info.size = 0;
9901     as_create_info.type = VK_ACCELERATION_STRUCTURE_TYPE_BOTTOM_LEVEL_KHR;
9902     as_create_info.deviceAddress = 0;
9903     VkAccelerationStructurekhrObj bot_level_as(*m_device, as_create_info);
9904 
9905     VkBufferDeviceAddressInfo vertexAddressInfo = {VK_STRUCTURE_TYPE_BUFFER_DEVICE_ADDRESS_INFO, NULL,
9906                                                    geometryNV.geometry.triangles.vertexData};
9907     VkDeviceAddress vertexAddress = vkGetBufferDeviceAddressKHR(m_device->handle(), &vertexAddressInfo);
9908 
9909     VkBufferDeviceAddressInfo indexAddressInfo = {VK_STRUCTURE_TYPE_BUFFER_DEVICE_ADDRESS_INFO, NULL,
9910                                                   geometryNV.geometry.triangles.indexData};
9911     VkDeviceAddress indexAddress = vkGetBufferDeviceAddressKHR(m_device->handle(), &indexAddressInfo);
9912     VkAccelerationStructureGeometryKHR valid_geometry_triangles = {VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_GEOMETRY_KHR};
9913     valid_geometry_triangles.geometryType = geometryNV.geometryType;
9914     valid_geometry_triangles.geometry.triangles.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_GEOMETRY_TRIANGLES_DATA_KHR;
9915     valid_geometry_triangles.geometry.triangles.pNext = NULL;
9916     valid_geometry_triangles.geometry.triangles.vertexFormat = geometryNV.geometry.triangles.vertexFormat;
9917     valid_geometry_triangles.geometry.triangles.vertexData.deviceAddress = vertexAddress;
9918     valid_geometry_triangles.geometry.triangles.vertexStride = 8;
9919     valid_geometry_triangles.geometry.triangles.indexType = VK_INDEX_TYPE_UINT32;
9920     valid_geometry_triangles.geometry.triangles.indexData.deviceAddress = indexAddress;
9921     valid_geometry_triangles.geometry.triangles.transformData.deviceAddress = 0;
9922     valid_geometry_triangles.geometry.triangles.maxVertex = 1;
9923     valid_geometry_triangles.flags = 0;
9924     VkAccelerationStructureGeometryKHR *pGeometry = new VkAccelerationStructureGeometryKHR[1];
9925     pGeometry[0] = valid_geometry_triangles;
9926 
9927     VkAccelerationStructureBuildGeometryInfoKHR build_info_khr;
9928     PFN_vkGetPhysicalDeviceProperties2KHR vkGetPhysicalDeviceProperties2KHR =
9929         (PFN_vkGetPhysicalDeviceProperties2KHR)vk::GetInstanceProcAddr(instance(), "vkGetPhysicalDeviceProperties2KHR");
9930     ASSERT_TRUE(vkGetPhysicalDeviceProperties2KHR != nullptr);
9931     auto acc_struct_properties = LvlInitStruct<VkPhysicalDeviceAccelerationStructurePropertiesKHR>();
9932     auto properties2 = LvlInitStruct<VkPhysicalDeviceProperties2KHR>(&acc_struct_properties);
9933     vkGetPhysicalDeviceProperties2KHR(gpu(), &properties2);
9934     VkBufferObj bot_level_as_scratch;
9935     VkBufferCreateInfo create_info = {};
9936     create_info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
9937     create_info.usage = VK_BUFFER_USAGE_SHADER_BINDING_TABLE_BIT_KHR | VK_BUFFER_USAGE_STORAGE_BUFFER_BIT;
9938     create_info.size = acc_struct_properties.minAccelerationStructureScratchOffsetAlignment;
9939     bot_level_as.create_scratch_buffer(*m_device, &bot_level_as_scratch, &create_info);
9940     VkBufferDeviceAddressInfo device_address_info = {VK_STRUCTURE_TYPE_BUFFER_DEVICE_ADDRESS_INFO, NULL,
9941                                                      bot_level_as_scratch.handle()};
9942     VkDeviceAddress device_address = vkGetBufferDeviceAddressKHR(m_device->handle(), &device_address_info);
9943     build_info_khr.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_BUILD_GEOMETRY_INFO_KHR;
9944     build_info_khr.pNext = NULL;
9945     build_info_khr.flags = 0;
9946     build_info_khr.type = VK_ACCELERATION_STRUCTURE_TYPE_BOTTOM_LEVEL_KHR;
9947     build_info_khr.mode = VK_BUILD_ACCELERATION_STRUCTURE_MODE_BUILD_KHR;
9948     build_info_khr.srcAccelerationStructure = VK_NULL_HANDLE;
9949     build_info_khr.dstAccelerationStructure = bot_level_as.handle();
9950     build_info_khr.geometryCount = 1;
9951     build_info_khr.pGeometries = pGeometry;
9952     build_info_khr.ppGeometries = NULL;
9953     build_info_khr.scratchData.deviceAddress = device_address;
9954 
9955     VkAccelerationStructureBuildGeometryInfoKHR build_info_ppGeometries_khr = build_info_khr;
9956     build_info_ppGeometries_khr.pGeometries = NULL;
9957     build_info_ppGeometries_khr.ppGeometries = &pGeometry;
9958 
9959     VkAccelerationStructureBuildRangeInfoKHR *pBuildRangeInfos = new VkAccelerationStructureBuildRangeInfoKHR[1];
9960     pBuildRangeInfos[0].firstVertex = 0;
9961     pBuildRangeInfos[0].primitiveCount = 1;
9962     pBuildRangeInfos[0].primitiveOffset = 3;
9963     pBuildRangeInfos[0].transformOffset = 0;
9964 
9965     m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdBuildAccelerationStructuresKHR-commandBuffer-recording");
9966     vkCmdBuildAccelerationStructuresKHR(m_commandBuffer->handle(), 1, &build_info_khr, &pBuildRangeInfos);
9967     m_errorMonitor->VerifyFound();
9968 
9969     {  // dstAccelerationStructure == VK_NULL_HANDLE
9970         auto build_info_null_dst_handle = build_info_khr;
9971         build_info_null_dst_handle.dstAccelerationStructure = VK_NULL_HANDLE;
9972 
9973         m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdBuildAccelerationStructuresKHR-dstAccelerationStructure-03800");
9974         vkCmdBuildAccelerationStructuresKHR(m_commandBuffer->handle(), 1, &build_info_null_dst_handle, &pBuildRangeInfos);
9975         m_errorMonitor->VerifyFound();
9976 
9977         if (accel_features.accelerationStructureIndirectBuild == VK_TRUE) {
9978             VkDeviceAddress range_ptrs{};
9979             uint32_t indirect_strides = sizeof(VkAccelerationStructureBuildRangeInfoKHR);
9980             uint32_t max_prim_counts[1] = {1};
9981             m_errorMonitor->SetDesiredFailureMsg(kErrorBit,
9982                                                  "VUID-vkCmdBuildAccelerationStructuresIndirectKHR-dstAccelerationStructure-03800");
9983             vkCmdBuildAccelerationStructuresIndirectKHR(m_commandBuffer->handle(), 1, &build_info_null_dst_handle, &range_ptrs,
9984                                                         &indirect_strides, reinterpret_cast<uint32_t **>(&max_prim_counts));
9985             m_errorMonitor->VerifyFound();
9986         }
9987 
9988         if (accel_features.accelerationStructureHostCommands == VK_TRUE) {
9989             m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkBuildAccelerationStructuresKHR-dstAccelerationStructure-03800");
9990             vkBuildAccelerationStructuresKHR(m_device->handle(), VK_NULL_HANDLE, 1, &build_info_null_dst_handle, &pBuildRangeInfos);
9991             m_errorMonitor->VerifyFound();
9992         }
9993     }
9994 
9995     m_commandBuffer->begin();
9996 
9997     m_errorMonitor->ExpectSuccess(kErrorBit);
9998     vkCmdBuildAccelerationStructuresKHR(m_commandBuffer->handle(), 1, &build_info_khr, &pBuildRangeInfos);
9999     m_errorMonitor->VerifyNotFound();
10000     m_errorMonitor->ExpectSuccess(kErrorBit);
10001     vkCmdBuildAccelerationStructuresKHR(m_commandBuffer->handle(), 1, &build_info_ppGeometries_khr, &pBuildRangeInfos);
10002     m_errorMonitor->VerifyNotFound();
10003     // Invalid info count
10004     {
10005         m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdBuildAccelerationStructuresKHR-infoCount-arraylength");
10006         m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdBuildAccelerationStructuresKHR-infoCount-arraylength");
10007         vkCmdBuildAccelerationStructuresKHR(m_commandBuffer->handle(), 0, &build_info_khr, &pBuildRangeInfos);
10008         m_errorMonitor->VerifyFound();
10009     }
10010 
10011     // Invalid pInfos
10012     {
10013         m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdBuildAccelerationStructuresKHR-pInfos-parameter");
10014         vkCmdBuildAccelerationStructuresKHR(m_commandBuffer->handle(), 1, NULL, &pBuildRangeInfos);
10015         m_errorMonitor->VerifyFound();
10016     }
10017 
10018     // Invalid ppBuildRangeInfos
10019     {
10020         m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdBuildAccelerationStructuresKHR-ppBuildRangeInfos-parameter");
10021         vkCmdBuildAccelerationStructuresKHR(m_commandBuffer->handle(), 1, &build_info_khr, NULL);
10022         m_errorMonitor->VerifyFound();
10023     }
10024 
10025     // must be called outside renderpass
10026     {
10027         ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
10028         m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
10029         m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdBuildAccelerationStructuresKHR-renderpass");
10030         vkCmdBuildAccelerationStructuresKHR(m_commandBuffer->handle(), 1, &build_info_khr, &pBuildRangeInfos);
10031         m_commandBuffer->EndRenderPass();
10032         m_errorMonitor->VerifyFound();
10033     }
10034     // Invalid flags
10035     {
10036         VkAccelerationStructureBuildGeometryInfoKHR invalid_build_info_khr = build_info_khr;
10037         invalid_build_info_khr.flags = VK_BUILD_ACCELERATION_STRUCTURE_FLAG_BITS_MAX_ENUM_KHR;
10038         m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkAccelerationStructureBuildGeometryInfoKHR-flags-parameter");
10039         vkCmdBuildAccelerationStructuresKHR(m_commandBuffer->handle(), 1, &invalid_build_info_khr, &pBuildRangeInfos);
10040         m_errorMonitor->VerifyFound();
10041     }
10042     // Invalid sType
10043     {
10044         VkAccelerationStructureBuildGeometryInfoKHR invalid_build_info_khr = build_info_khr;
10045         invalid_build_info_khr.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_GEOMETRY_KHR;
10046         m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkAccelerationStructureBuildGeometryInfoKHR-sType-sType");
10047         vkCmdBuildAccelerationStructuresKHR(m_commandBuffer->handle(), 1, &invalid_build_info_khr, &pBuildRangeInfos);
10048         m_errorMonitor->VerifyFound();
10049     }
10050     // Invalid Type
10051     {
10052         VkAccelerationStructureBuildGeometryInfoKHR invalid_build_info_khr = build_info_khr;
10053         invalid_build_info_khr.type = VK_ACCELERATION_STRUCTURE_TYPE_GENERIC_KHR;
10054         m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkAccelerationStructureBuildGeometryInfoKHR-type-03654");
10055         vkCmdBuildAccelerationStructuresKHR(m_commandBuffer->handle(), 1, &invalid_build_info_khr, &pBuildRangeInfos);
10056         m_errorMonitor->VerifyFound();
10057 
10058         invalid_build_info_khr.type = VK_ACCELERATION_STRUCTURE_TYPE_MAX_ENUM_KHR;
10059         m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkAccelerationStructureBuildGeometryInfoKHR-type-parameter");
10060         vkCmdBuildAccelerationStructuresKHR(m_commandBuffer->handle(), 1, &invalid_build_info_khr, &pBuildRangeInfos);
10061         m_errorMonitor->VerifyFound();
10062     }
10063 
10064     // Invalid VetexStride and Indexdata
10065     {
10066         VkAccelerationStructureGeometryKHR invalid_geometry_triangles = valid_geometry_triangles;
10067         invalid_geometry_triangles.geometry.triangles.vertexStride = UINT32_MAX + 1ull;
10068         VkAccelerationStructureBuildGeometryInfoKHR invalid_build_info_khr = build_info_khr;
10069         invalid_build_info_khr.pGeometries = &invalid_geometry_triangles;
10070         m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkAccelerationStructureGeometryTrianglesDataKHR-vertexStride-03819");
10071         vkCmdBuildAccelerationStructuresKHR(m_commandBuffer->handle(), 1, &invalid_build_info_khr, &pBuildRangeInfos);
10072         m_errorMonitor->VerifyFound();
10073 
10074         invalid_geometry_triangles = valid_geometry_triangles;
10075         invalid_geometry_triangles.geometry.triangles.indexType = VK_INDEX_TYPE_UINT8_EXT;
10076         invalid_build_info_khr.pGeometries = &invalid_geometry_triangles;
10077         m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkAccelerationStructureGeometryTrianglesDataKHR-indexType-03798");
10078         vkCmdBuildAccelerationStructuresKHR(m_commandBuffer->handle(), 1, &invalid_build_info_khr, &pBuildRangeInfos);
10079         m_errorMonitor->VerifyFound();
10080     }
10081 
10082     // ppGeometries and pGeometries both valid pointer
10083     {
10084         VkAccelerationStructureBuildGeometryInfoKHR invalid_build_info_khr = build_info_khr;
10085         invalid_build_info_khr.ppGeometries = &invalid_build_info_khr.pGeometries;
10086         m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkAccelerationStructureBuildGeometryInfoKHR-pGeometries-03788");
10087         vkCmdBuildAccelerationStructuresKHR(m_commandBuffer->handle(), 1, &invalid_build_info_khr, &pBuildRangeInfos);
10088         m_errorMonitor->VerifyFound();
10089     }
10090 
10091     // Buffer is missing VK_BUFFER_USAGE_ACCELERATION_STRUCTURE_BUILD_INPUT_READ_ONLY_BIT_KHR usage flag
10092     {
10093         VkBufferObj bad_usage_buffer;
10094         bad_usage_buffer.init(*m_device, 1024, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT,
10095                               VK_BUFFER_USAGE_RAY_TRACING_BIT_NV);
10096         VkBufferDeviceAddressInfo addr_info = {VK_STRUCTURE_TYPE_BUFFER_DEVICE_ADDRESS_INFO, nullptr, bad_usage_buffer.handle()};
10097         auto addr = vkGetBufferDeviceAddressKHR(m_device->handle(), &addr_info);
10098         pGeometry[0].geometry.triangles.vertexData.deviceAddress = addr;
10099         m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdBuildAccelerationStructuresKHR-geometry-03673");
10100         vkCmdBuildAccelerationStructuresKHR(m_commandBuffer->handle(), 1, &build_info_khr, &pBuildRangeInfos);
10101         m_errorMonitor->VerifyFound();
10102         pGeometry[0] = valid_geometry_triangles;  // reset to valid
10103     }
10104 
10105     // Scratch data buffer is missing VK_BUFFER_USAGE_STORAGE_BUFFER_BIT usage flag
10106     {
10107         VkBufferObj bad_scratch;
10108         VkBufferCreateInfo bad_create_info = LvlInitStruct<VkBufferCreateInfo>();
10109         bad_create_info.usage = VK_BUFFER_USAGE_SHADER_BINDING_TABLE_BIT_KHR;
10110         bad_create_info.size = acc_struct_properties.minAccelerationStructureScratchOffsetAlignment;
10111         bot_level_as.create_scratch_buffer(*m_device, &bad_scratch, &bad_create_info);
10112         VkBufferDeviceAddressInfo bad_device_address_info = LvlInitStruct<VkBufferDeviceAddressInfo>();
10113         bad_device_address_info.buffer = bad_scratch.handle();
10114         VkDeviceAddress bad_device_address = vkGetBufferDeviceAddressKHR(m_device->handle(), &bad_device_address_info);
10115 
10116         build_info_khr.scratchData.deviceAddress = bad_device_address;
10117         m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdBuildAccelerationStructuresKHR-pInfos-03674");
10118         vkCmdBuildAccelerationStructuresKHR(m_commandBuffer->handle(), 1, &build_info_khr, &pBuildRangeInfos);
10119         m_errorMonitor->VerifyFound();
10120     }
10121 
10122     delete[] pGeometry;
10123 }
10124 
TEST_F(VkLayerTest,ValidateImportMemoryHandleType)10125 TEST_F(VkLayerTest, ValidateImportMemoryHandleType) {
10126     TEST_DESCRIPTION("Validate import memory handleType for buffers and images");
10127 
10128 #ifdef _WIN32
10129     const auto ext_mem_extension_name = VK_KHR_EXTERNAL_MEMORY_WIN32_EXTENSION_NAME;
10130     const auto handle_type = VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_BIT_KHR;
10131 #else
10132     const auto ext_mem_extension_name = VK_KHR_EXTERNAL_MEMORY_FD_EXTENSION_NAME;
10133     const auto handle_type = VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT_KHR;
10134 #endif
10135     const auto wrong_handle_type = VK_EXTERNAL_MEMORY_HANDLE_TYPE_HOST_ALLOCATION_BIT_EXT;
10136 
10137     // Check for external memory instance extensions
10138     std::vector<const char *> reqd_instance_extensions = {
10139         {VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME, VK_KHR_EXTERNAL_MEMORY_CAPABILITIES_EXTENSION_NAME}};
10140     for (auto extension_name : reqd_instance_extensions) {
10141         if (InstanceExtensionSupported(extension_name)) {
10142             m_instance_extension_names.push_back(extension_name);
10143         } else {
10144             printf("%s Required instance extension %s not supported, skipping test\n", kSkipPrefix, extension_name);
10145             return;
10146         }
10147     }
10148 
10149     ASSERT_NO_FATAL_FAILURE(InitFramework(m_errorMonitor));
10150 
10151     auto vkGetPhysicalDeviceExternalBufferPropertiesKHR =
10152         (PFN_vkGetPhysicalDeviceExternalBufferPropertiesKHR)vk::GetInstanceProcAddr(
10153             instance(), "vkGetPhysicalDeviceExternalBufferPropertiesKHR");
10154 
10155     // Check for import/export capability
10156     // export used to feed memory to test import
10157     VkPhysicalDeviceExternalBufferInfoKHR ebi = {VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_BUFFER_INFO_KHR, nullptr, 0,
10158                                                  VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT, handle_type};
10159     VkExternalBufferPropertiesKHR ebp = {VK_STRUCTURE_TYPE_EXTERNAL_BUFFER_PROPERTIES_KHR, nullptr, {0, 0, 0}};
10160     ASSERT_TRUE(vkGetPhysicalDeviceExternalBufferPropertiesKHR != nullptr);
10161     vkGetPhysicalDeviceExternalBufferPropertiesKHR(gpu(), &ebi, &ebp);
10162     if (!(ebp.externalMemoryProperties.compatibleHandleTypes & handle_type) ||
10163         !(ebp.externalMemoryProperties.externalMemoryFeatures & VK_EXTERNAL_MEMORY_FEATURE_EXPORTABLE_BIT_KHR) ||
10164         !(ebp.externalMemoryProperties.externalMemoryFeatures & VK_EXTERNAL_MEMORY_FEATURE_IMPORTABLE_BIT_KHR)) {
10165         printf("%s External buffer does not support importing and exporting, skipping test\n", kSkipPrefix);
10166         return;
10167     }
10168 
10169     // Always use dedicated allocation
10170     if (DeviceExtensionSupported(gpu(), nullptr, VK_KHR_DEDICATED_ALLOCATION_EXTENSION_NAME)) {
10171         m_device_extension_names.push_back(VK_KHR_DEDICATED_ALLOCATION_EXTENSION_NAME);
10172         m_device_extension_names.push_back(VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME);
10173     } else {
10174         printf("%s Dedicated allocation extension not supported, skipping test\n", kSkipPrefix);
10175         return;
10176     }
10177 
10178     // Check for external memory device extensions
10179     if (DeviceExtensionSupported(gpu(), nullptr, ext_mem_extension_name)) {
10180         m_device_extension_names.push_back(ext_mem_extension_name);
10181         m_device_extension_names.push_back(VK_KHR_EXTERNAL_MEMORY_EXTENSION_NAME);
10182     } else {
10183         printf("%s External memory extension not supported, skipping test\n", kSkipPrefix);
10184         return;
10185     }
10186 
10187     // Check for bind memory 2
10188     if (DeviceExtensionSupported(gpu(), nullptr, VK_KHR_BIND_MEMORY_2_EXTENSION_NAME)) {
10189         m_device_extension_names.push_back(VK_KHR_BIND_MEMORY_2_EXTENSION_NAME);
10190     } else {
10191         printf("%s bind memory 2 extension not supported, skipping test\n", kSkipPrefix);
10192         return;
10193     }
10194     ASSERT_NO_FATAL_FAILURE(InitState());
10195 
10196     PFN_vkBindBufferMemory2KHR vkBindBufferMemory2Function =
10197         (PFN_vkBindBufferMemory2KHR)vk::GetDeviceProcAddr(m_device->handle(), "vkBindBufferMemory2KHR");
10198     PFN_vkBindImageMemory2KHR vkBindImageMemory2Function =
10199         (PFN_vkBindImageMemory2KHR)vk::GetDeviceProcAddr(m_device->handle(), "vkBindImageMemory2KHR");
10200 
10201     m_errorMonitor->ExpectSuccess(kErrorBit | kWarningBit);
10202 
10203     VkMemoryPropertyFlags mem_flags = 0;
10204     const VkDeviceSize buffer_size = 1024;
10205 
10206     // Create export and import buffers
10207     VkExternalMemoryBufferCreateInfoKHR external_buffer_info = {VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_BUFFER_CREATE_INFO_KHR, nullptr,
10208                                                                 handle_type};
10209     auto buffer_info = VkBufferObj::create_info(buffer_size, VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT);
10210     buffer_info.pNext = &external_buffer_info;
10211     VkBufferObj buffer_export;
10212     buffer_export.init_no_mem(*m_device, buffer_info);
10213     external_buffer_info.handleTypes = wrong_handle_type;
10214     VkBufferObj buffer_import;
10215     buffer_import.init_no_mem(*m_device, buffer_info);
10216 
10217     // Allocation info
10218     auto alloc_info = vk_testing::DeviceMemory::get_resource_alloc_info(*m_device, buffer_export.memory_requirements(), mem_flags);
10219 
10220     // Add export allocation info to pNext chain
10221     VkMemoryDedicatedAllocateInfoKHR dedicated_info = {VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO_KHR, nullptr,
10222                                                        VK_NULL_HANDLE, buffer_export.handle()};
10223     VkExportMemoryAllocateInfoKHR export_info = {VK_STRUCTURE_TYPE_EXPORT_MEMORY_ALLOCATE_INFO_KHR, &dedicated_info, handle_type};
10224     alloc_info.pNext = &export_info;
10225 
10226     // Allocate memory to be exported
10227     vk_testing::DeviceMemory memory_buffer_export;
10228     memory_buffer_export.init(*m_device, alloc_info);
10229 
10230     // Bind exported memory
10231     buffer_export.bind_memory(memory_buffer_export, 0);
10232 
10233     VkExternalMemoryImageCreateInfoKHR external_image_info = {VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_IMAGE_CREATE_INFO, nullptr,
10234                                                               handle_type};
10235     VkImageCreateInfo image_info{};
10236     image_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
10237     image_info.pNext = &external_image_info;
10238     image_info.extent = {64, 64, 1};
10239     image_info.format = VK_FORMAT_R8G8B8A8_UNORM;
10240     image_info.imageType = VK_IMAGE_TYPE_2D;
10241     image_info.tiling = VK_IMAGE_TILING_OPTIMAL;
10242     image_info.usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
10243     image_info.samples = VK_SAMPLE_COUNT_1_BIT;
10244     image_info.arrayLayers = 1;
10245     image_info.mipLevels = 1;
10246     VkImageObj image_export(m_device);
10247     image_export.init_no_mem(*m_device, image_info);
10248     external_image_info.handleTypes = wrong_handle_type;
10249     VkImageObj image_import(m_device);
10250     image_import.init_no_mem(*m_device, image_info);
10251 
10252     // Allocation info
10253     dedicated_info = {VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO_KHR, nullptr, image_export.handle(), VK_NULL_HANDLE};
10254     alloc_info = vk_testing::DeviceMemory::get_resource_alloc_info(*m_device, image_export.memory_requirements(), mem_flags);
10255     alloc_info.pNext = &export_info;
10256 
10257     // Allocate memory to be exported
10258     vk_testing::DeviceMemory memory_image_export;
10259     memory_image_export.init(*m_device, alloc_info);
10260 
10261     // Bind exported memory
10262     image_export.bind_memory(memory_image_export, 0);
10263 
10264 #ifdef _WIN32
10265     // Export memory to handle
10266     auto vkGetMemoryWin32HandleKHR =
10267         (PFN_vkGetMemoryWin32HandleKHR)vk::GetInstanceProcAddr(instance(), "vkGetMemoryWin32HandleKHR");
10268     ASSERT_TRUE(vkGetMemoryWin32HandleKHR != nullptr);
10269     VkMemoryGetWin32HandleInfoKHR mghi_buffer = {VK_STRUCTURE_TYPE_MEMORY_GET_WIN32_HANDLE_INFO_KHR, nullptr,
10270                                                  memory_buffer_export.handle(), handle_type};
10271     VkMemoryGetWin32HandleInfoKHR mghi_image = {VK_STRUCTURE_TYPE_MEMORY_GET_WIN32_HANDLE_INFO_KHR, nullptr,
10272                                                 memory_image_export.handle(), handle_type};
10273     HANDLE handle_buffer;
10274     HANDLE handle_image;
10275     ASSERT_VK_SUCCESS(vkGetMemoryWin32HandleKHR(m_device->device(), &mghi_buffer, &handle_buffer));
10276     ASSERT_VK_SUCCESS(vkGetMemoryWin32HandleKHR(m_device->device(), &mghi_image, &handle_image));
10277 
10278     VkImportMemoryWin32HandleInfoKHR import_info_buffer = {VK_STRUCTURE_TYPE_IMPORT_MEMORY_WIN32_HANDLE_INFO_KHR, nullptr,
10279                                                            handle_type, handle_buffer};
10280     VkImportMemoryWin32HandleInfoKHR import_info_image = {VK_STRUCTURE_TYPE_IMPORT_MEMORY_WIN32_HANDLE_INFO_KHR, nullptr,
10281                                                           handle_type, handle_image};
10282 #else
10283     // Export memory to fd
10284     auto vkGetMemoryFdKHR = (PFN_vkGetMemoryFdKHR)vk::GetInstanceProcAddr(instance(), "vkGetMemoryFdKHR");
10285     ASSERT_TRUE(vkGetMemoryFdKHR != nullptr);
10286     VkMemoryGetFdInfoKHR mgfi_buffer = {VK_STRUCTURE_TYPE_MEMORY_GET_FD_INFO_KHR, nullptr, memory_buffer_export.handle(),
10287                                         handle_type};
10288     VkMemoryGetFdInfoKHR mgfi_image = {VK_STRUCTURE_TYPE_MEMORY_GET_FD_INFO_KHR, nullptr, memory_image_export.handle(),
10289                                        handle_type};
10290     int fd_buffer;
10291     int fd_image;
10292     ASSERT_VK_SUCCESS(vkGetMemoryFdKHR(m_device->device(), &mgfi_buffer, &fd_buffer));
10293     ASSERT_VK_SUCCESS(vkGetMemoryFdKHR(m_device->device(), &mgfi_image, &fd_image));
10294 
10295     VkImportMemoryFdInfoKHR import_info_buffer = {VK_STRUCTURE_TYPE_IMPORT_MEMORY_FD_INFO_KHR, nullptr, handle_type, fd_buffer};
10296     VkImportMemoryFdInfoKHR import_info_image = {VK_STRUCTURE_TYPE_IMPORT_MEMORY_FD_INFO_KHR, nullptr, handle_type, fd_image};
10297 #endif
10298 
10299     // Import memory
10300     VkMemoryRequirements buffer_import_reqs = buffer_import.memory_requirements();
10301     if (buffer_import_reqs.memoryTypeBits == 0) {
10302         printf("%s no suitable memory found, skipping test\n", kSkipPrefix);
10303         return;
10304     }
10305     alloc_info = vk_testing::DeviceMemory::get_resource_alloc_info(*m_device, buffer_import_reqs, mem_flags);
10306     alloc_info.pNext = &import_info_buffer;
10307     vk_testing::DeviceMemory memory_buffer_import;
10308     memory_buffer_import.init(*m_device, alloc_info);
10309 
10310     VkMemoryRequirements image_import_reqs = image_import.memory_requirements();
10311     if (image_import_reqs.memoryTypeBits == 0) {
10312         printf("%s no suitable memory found, skipping test\n", kSkipPrefix);
10313         return;
10314     }
10315     alloc_info = vk_testing::DeviceMemory::get_resource_alloc_info(*m_device, image_import_reqs, mem_flags);
10316     alloc_info.pNext = &import_info_image;
10317     vk_testing::DeviceMemory memory_image_import;
10318     memory_image_import.init(*m_device, alloc_info);
10319     m_errorMonitor->VerifyNotFound();
10320 
10321     // Bind imported memory with different handleType
10322     m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkBindBufferMemory-memory-02727");
10323     vk::BindBufferMemory(device(), buffer_import.handle(), memory_buffer_import.handle(), 0);
10324     m_errorMonitor->VerifyFound();
10325 
10326     VkBindBufferMemoryInfo bind_buffer_info = LvlInitStruct<VkBindBufferMemoryInfo>();
10327     bind_buffer_info.buffer = buffer_import.handle();
10328     bind_buffer_info.memory = memory_buffer_import.handle();
10329     bind_buffer_info.memoryOffset = 0;
10330 
10331     m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkBindBufferMemoryInfo-memory-02727");
10332     vkBindBufferMemory2Function(device(), 1, &bind_buffer_info);
10333     m_errorMonitor->VerifyFound();
10334 
10335     m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkBindImageMemory-memory-02729");
10336     m_errorMonitor->SetUnexpectedError("VUID-VkBindImageMemoryInfo-memory-01614");
10337     m_errorMonitor->SetUnexpectedError("VUID-VkBindImageMemoryInfo-memory-01612");
10338     vk::BindImageMemory(device(), image_import.handle(), memory_image_import.handle(), 0);
10339     m_errorMonitor->VerifyFound();
10340 
10341     VkBindImageMemoryInfo bind_image_info = LvlInitStruct<VkBindImageMemoryInfo>();
10342     bind_image_info.image = image_import.handle();
10343     bind_image_info.memory = memory_image_import.handle();
10344     bind_image_info.memoryOffset = 0;
10345 
10346     m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkBindImageMemoryInfo-memory-02729");
10347     m_errorMonitor->SetUnexpectedError("VUID-VkBindImageMemoryInfo-memory-01614");
10348     m_errorMonitor->SetUnexpectedError("VUID-VkBindImageMemoryInfo-memory-01612");
10349     vkBindImageMemory2Function(device(), 1, &bind_image_info);
10350     m_errorMonitor->VerifyFound();
10351 }
10352 
TEST_F(VkLayerTest,ValidateExtendedDynamicStateDisabled)10353 TEST_F(VkLayerTest, ValidateExtendedDynamicStateDisabled) {
10354     TEST_DESCRIPTION("Validate VK_EXT_extended_dynamic_state VUs");
10355 
10356     uint32_t version = SetTargetApiVersion(VK_API_VERSION_1_1);
10357     if (version < VK_API_VERSION_1_1) {
10358         printf("%s At least Vulkan version 1.1 is required, skipping test.\n", kSkipPrefix);
10359         return;
10360     }
10361 
10362     ASSERT_NO_FATAL_FAILURE(InitFramework(m_errorMonitor));
10363     if (DeviceExtensionSupported(gpu(), nullptr, VK_EXT_EXTENDED_DYNAMIC_STATE_EXTENSION_NAME)) {
10364         m_device_extension_names.push_back(VK_EXT_EXTENDED_DYNAMIC_STATE_EXTENSION_NAME);
10365     } else {
10366         printf("%s Extension %s is not supported.\n", kSkipPrefix, VK_EXT_EXTENDED_DYNAMIC_STATE_EXTENSION_NAME);
10367         return;
10368     }
10369 
10370     auto extended_dynamic_state_features = LvlInitStruct<VkPhysicalDeviceExtendedDynamicStateFeaturesEXT>();
10371     auto features2 = LvlInitStruct<VkPhysicalDeviceFeatures2>(&extended_dynamic_state_features);
10372     vk::GetPhysicalDeviceFeatures2(gpu(), &features2);
10373     if (!extended_dynamic_state_features.extendedDynamicState) {
10374         printf("%s Test requires (unsupported) extendedDynamicState, skipping\n", kSkipPrefix);
10375         return;
10376     }
10377 
10378     // First test attempted uses of VK_EXT_extended_dynamic_state without it being enabled.
10379     extended_dynamic_state_features.extendedDynamicState = VK_FALSE;
10380     ASSERT_NO_FATAL_FAILURE(InitState(nullptr, &features2));
10381 
10382     auto vkCmdSetCullModeEXT = (PFN_vkCmdSetCullModeEXT)vk::GetDeviceProcAddr(m_device->device(), "vkCmdSetCullModeEXT");
10383     auto vkCmdSetFrontFaceEXT = (PFN_vkCmdSetFrontFaceEXT)vk::GetDeviceProcAddr(m_device->device(), "vkCmdSetFrontFaceEXT");
10384     auto vkCmdSetPrimitiveTopologyEXT =
10385         (PFN_vkCmdSetPrimitiveTopologyEXT)vk::GetDeviceProcAddr(m_device->device(), "vkCmdSetPrimitiveTopologyEXT");
10386     auto vkCmdSetViewportWithCountEXT =
10387         (PFN_vkCmdSetViewportWithCountEXT)vk::GetDeviceProcAddr(m_device->device(), "vkCmdSetViewportWithCountEXT");
10388     auto vkCmdSetScissorWithCountEXT =
10389         (PFN_vkCmdSetScissorWithCountEXT)vk::GetDeviceProcAddr(m_device->device(), "vkCmdSetScissorWithCountEXT");
10390     auto vkCmdSetDepthTestEnableEXT =
10391         (PFN_vkCmdSetDepthTestEnableEXT)vk::GetDeviceProcAddr(m_device->device(), "vkCmdSetDepthTestEnableEXT");
10392     auto vkCmdSetDepthWriteEnableEXT =
10393         (PFN_vkCmdSetDepthWriteEnableEXT)vk::GetDeviceProcAddr(m_device->device(), "vkCmdSetDepthWriteEnableEXT");
10394     auto vkCmdSetDepthCompareOpEXT =
10395         (PFN_vkCmdSetDepthCompareOpEXT)vk::GetDeviceProcAddr(m_device->device(), "vkCmdSetDepthCompareOpEXT");
10396     auto vkCmdSetDepthBoundsTestEnableEXT =
10397         (PFN_vkCmdSetDepthBoundsTestEnableEXT)vk::GetDeviceProcAddr(m_device->device(), "vkCmdSetDepthBoundsTestEnableEXT");
10398     auto vkCmdSetStencilTestEnableEXT =
10399         (PFN_vkCmdSetStencilTestEnableEXT)vk::GetDeviceProcAddr(m_device->device(), "vkCmdSetStencilTestEnableEXT");
10400     auto vkCmdSetStencilOpEXT = (PFN_vkCmdSetStencilOpEXT)vk::GetDeviceProcAddr(m_device->device(), "vkCmdSetStencilOpEXT");
10401 
10402     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
10403 
10404     CreatePipelineHelper pipe(*this);
10405     pipe.InitInfo();
10406     const VkDynamicState dyn_states[] = {
10407         VK_DYNAMIC_STATE_CULL_MODE_EXT,           VK_DYNAMIC_STATE_FRONT_FACE_EXT,
10408         VK_DYNAMIC_STATE_PRIMITIVE_TOPOLOGY_EXT,  VK_DYNAMIC_STATE_VIEWPORT_WITH_COUNT_EXT,
10409         VK_DYNAMIC_STATE_SCISSOR_WITH_COUNT_EXT,  VK_DYNAMIC_STATE_VERTEX_INPUT_BINDING_STRIDE_EXT,
10410         VK_DYNAMIC_STATE_DEPTH_TEST_ENABLE_EXT,   VK_DYNAMIC_STATE_DEPTH_WRITE_ENABLE_EXT,
10411         VK_DYNAMIC_STATE_DEPTH_COMPARE_OP_EXT,    VK_DYNAMIC_STATE_DEPTH_BOUNDS_TEST_ENABLE_EXT,
10412         VK_DYNAMIC_STATE_STENCIL_TEST_ENABLE_EXT, VK_DYNAMIC_STATE_STENCIL_OP_EXT,
10413     };
10414     VkPipelineDynamicStateCreateInfo dyn_state_ci = {};
10415     dyn_state_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO;
10416     dyn_state_ci.dynamicStateCount = size(dyn_states);
10417     dyn_state_ci.pDynamicStates = dyn_states;
10418     pipe.dyn_state_ci_ = dyn_state_ci;
10419     pipe.vp_state_ci_.viewportCount = 0;
10420     pipe.vp_state_ci_.scissorCount = 0;
10421     pipe.InitState();
10422     m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkGraphicsPipelineCreateInfo-pDynamicStates-03378");
10423     pipe.CreateGraphicsPipeline();
10424     m_errorMonitor->VerifyFound();
10425 
10426     VkCommandBufferObj commandBuffer(m_device, m_commandPool);
10427     commandBuffer.begin();
10428 
10429     m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdSetCullModeEXT-None-03384");
10430     vkCmdSetCullModeEXT(commandBuffer.handle(), VK_CULL_MODE_NONE);
10431     m_errorMonitor->VerifyFound();
10432 
10433     m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdSetDepthBoundsTestEnableEXT-None-03349");
10434     vkCmdSetDepthBoundsTestEnableEXT(commandBuffer.handle(), VK_FALSE);
10435     m_errorMonitor->VerifyFound();
10436 
10437     m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdSetDepthCompareOpEXT-None-03353");
10438     vkCmdSetDepthCompareOpEXT(commandBuffer.handle(), VK_COMPARE_OP_NEVER);
10439     m_errorMonitor->VerifyFound();
10440 
10441     m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdSetDepthTestEnableEXT-None-03352");
10442     vkCmdSetDepthTestEnableEXT(commandBuffer.handle(), VK_FALSE);
10443     m_errorMonitor->VerifyFound();
10444 
10445     m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdSetDepthWriteEnableEXT-None-03354");
10446     vkCmdSetDepthWriteEnableEXT(commandBuffer.handle(), VK_FALSE);
10447     m_errorMonitor->VerifyFound();
10448 
10449     m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdSetFrontFaceEXT-None-03383");
10450     vkCmdSetFrontFaceEXT(commandBuffer.handle(), VK_FRONT_FACE_CLOCKWISE);
10451     m_errorMonitor->VerifyFound();
10452 
10453     m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdSetPrimitiveTopologyEXT-None-03347");
10454     vkCmdSetPrimitiveTopologyEXT(commandBuffer.handle(), VK_PRIMITIVE_TOPOLOGY_POINT_LIST);
10455     m_errorMonitor->VerifyFound();
10456 
10457     m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdSetScissorWithCountEXT-None-03396");
10458     VkRect2D scissor = {{0, 0}, {1, 1}};
10459     vkCmdSetScissorWithCountEXT(commandBuffer.handle(), 1, &scissor);
10460     m_errorMonitor->VerifyFound();
10461 
10462     m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdSetStencilOpEXT-None-03351");
10463     vkCmdSetStencilOpEXT(commandBuffer.handle(), VK_STENCIL_FACE_BACK_BIT, VK_STENCIL_OP_ZERO, VK_STENCIL_OP_ZERO,
10464                          VK_STENCIL_OP_ZERO, VK_COMPARE_OP_NEVER);
10465     m_errorMonitor->VerifyFound();
10466 
10467     m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdSetStencilTestEnableEXT-None-03350");
10468     vkCmdSetStencilTestEnableEXT(commandBuffer.handle(), VK_FALSE);
10469     m_errorMonitor->VerifyFound();
10470 
10471     m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdSetViewportWithCountEXT-None-03393");
10472     VkViewport viewport = {0, 0, 1, 1, 0.0f, 0.0f};
10473     vkCmdSetViewportWithCountEXT(commandBuffer.handle(), 1, &viewport);
10474     m_errorMonitor->VerifyFound();
10475 
10476     commandBuffer.end();
10477 }
10478 
TEST_F(VkLayerTest,ValidateExtendedDynamicStateEnabled)10479 TEST_F(VkLayerTest, ValidateExtendedDynamicStateEnabled) {
10480     TEST_DESCRIPTION("Validate VK_EXT_extended_dynamic_state VUs");
10481 
10482     uint32_t version = SetTargetApiVersion(VK_API_VERSION_1_1);
10483     if (version < VK_API_VERSION_1_1) {
10484         printf("%s At least Vulkan version 1.1 is required, skipping test.\n", kSkipPrefix);
10485         return;
10486     }
10487 
10488     ASSERT_NO_FATAL_FAILURE(InitFramework(m_errorMonitor));
10489     if (DeviceExtensionSupported(gpu(), nullptr, VK_EXT_EXTENDED_DYNAMIC_STATE_EXTENSION_NAME)) {
10490         m_device_extension_names.push_back(VK_EXT_EXTENDED_DYNAMIC_STATE_EXTENSION_NAME);
10491     } else {
10492         printf("%s Extension %s is not supported.\n", kSkipPrefix, VK_EXT_EXTENDED_DYNAMIC_STATE_EXTENSION_NAME);
10493         return;
10494     }
10495 
10496     auto extended_dynamic_state_features = LvlInitStruct<VkPhysicalDeviceExtendedDynamicStateFeaturesEXT>();
10497     auto features2 = LvlInitStruct<VkPhysicalDeviceFeatures2>(&extended_dynamic_state_features);
10498     vk::GetPhysicalDeviceFeatures2(gpu(), &features2);
10499     if (!extended_dynamic_state_features.extendedDynamicState) {
10500         printf("%s Test requires (unsupported) extendedDynamicState, skipping\n", kSkipPrefix);
10501         return;
10502     }
10503 
10504     ASSERT_NO_FATAL_FAILURE(InitState(nullptr, &features2));
10505 
10506     auto vkCmdSetPrimitiveTopologyEXT =
10507         (PFN_vkCmdSetPrimitiveTopologyEXT)vk::GetDeviceProcAddr(m_device->device(), "vkCmdSetPrimitiveTopologyEXT");
10508     auto vkCmdSetViewportWithCountEXT =
10509         (PFN_vkCmdSetViewportWithCountEXT)vk::GetDeviceProcAddr(m_device->device(), "vkCmdSetViewportWithCountEXT");
10510     auto vkCmdSetScissorWithCountEXT =
10511         (PFN_vkCmdSetScissorWithCountEXT)vk::GetDeviceProcAddr(m_device->device(), "vkCmdSetScissorWithCountEXT");
10512     auto vkCmdBindVertexBuffers2EXT =
10513         (PFN_vkCmdBindVertexBuffers2EXT)vk::GetDeviceProcAddr(m_device->device(), "vkCmdBindVertexBuffers2EXT");
10514 
10515     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
10516 
10517     // Verify viewportCount and scissorCount are specified as zero.
10518     {
10519         CreatePipelineHelper pipe(*this);
10520         pipe.InitInfo();
10521         const VkDynamicState dyn_states[] = {
10522             VK_DYNAMIC_STATE_VIEWPORT_WITH_COUNT_EXT,
10523             VK_DYNAMIC_STATE_SCISSOR_WITH_COUNT_EXT,
10524         };
10525         VkPipelineDynamicStateCreateInfo dyn_state_ci = {};
10526         dyn_state_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO;
10527         dyn_state_ci.dynamicStateCount = size(dyn_states);
10528         dyn_state_ci.pDynamicStates = dyn_states;
10529         pipe.dyn_state_ci_ = dyn_state_ci;
10530         pipe.InitState();
10531         m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkGraphicsPipelineCreateInfo-pDynamicStates-03379");
10532         m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkGraphicsPipelineCreateInfo-pDynamicStates-03380");
10533         pipe.CreateGraphicsPipeline();
10534         m_errorMonitor->VerifyFound();
10535     }
10536 
10537     // Verify non-count and count dynamic states aren't used together
10538     {
10539         CreatePipelineHelper pipe(*this);
10540         pipe.InitInfo();
10541         const VkDynamicState dyn_states[] = {
10542             VK_DYNAMIC_STATE_VIEWPORT_WITH_COUNT_EXT, VK_DYNAMIC_STATE_VIEWPORT,  // viewports
10543             VK_DYNAMIC_STATE_SCISSOR_WITH_COUNT_EXT, VK_DYNAMIC_STATE_SCISSOR     // scissors
10544         };
10545         VkPipelineDynamicStateCreateInfo dyn_state_ci = {};
10546         dyn_state_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO;
10547         dyn_state_ci.dynamicStateCount = 2;
10548         pipe.dyn_state_ci_ = dyn_state_ci;
10549         pipe.InitState();
10550 
10551         pipe.dyn_state_ci_.pDynamicStates = &dyn_states[0];  // viewports
10552         pipe.vp_state_ci_.viewportCount = 0;
10553         pipe.vp_state_ci_.scissorCount = 1;
10554         m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkGraphicsPipelineCreateInfo-pDynamicStates-04132");
10555         pipe.CreateGraphicsPipeline();
10556         m_errorMonitor->VerifyFound();
10557 
10558         pipe.dyn_state_ci_.pDynamicStates = &dyn_states[2];  // scissors
10559         pipe.vp_state_ci_.viewportCount = 1;
10560         pipe.vp_state_ci_.scissorCount = 0;
10561         m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkGraphicsPipelineCreateInfo-pDynamicStates-04133");
10562         pipe.CreateGraphicsPipeline();
10563         m_errorMonitor->VerifyFound();
10564     }
10565 
10566     const VkDynamicState dyn_states[] = {
10567         VK_DYNAMIC_STATE_CULL_MODE_EXT,           VK_DYNAMIC_STATE_FRONT_FACE_EXT,
10568         VK_DYNAMIC_STATE_PRIMITIVE_TOPOLOGY_EXT,  VK_DYNAMIC_STATE_VIEWPORT_WITH_COUNT_EXT,
10569         VK_DYNAMIC_STATE_SCISSOR_WITH_COUNT_EXT,  VK_DYNAMIC_STATE_VERTEX_INPUT_BINDING_STRIDE_EXT,
10570         VK_DYNAMIC_STATE_DEPTH_TEST_ENABLE_EXT,   VK_DYNAMIC_STATE_DEPTH_WRITE_ENABLE_EXT,
10571         VK_DYNAMIC_STATE_DEPTH_COMPARE_OP_EXT,    VK_DYNAMIC_STATE_DEPTH_BOUNDS_TEST_ENABLE_EXT,
10572         VK_DYNAMIC_STATE_STENCIL_TEST_ENABLE_EXT, VK_DYNAMIC_STATE_STENCIL_OP_EXT,
10573     };
10574 
10575     // Verify dupes of every state.
10576     for (size_t i = 0; i < size(dyn_states); ++i) {
10577         CreatePipelineHelper pipe(*this);
10578         pipe.InitInfo();
10579         VkPipelineDynamicStateCreateInfo dyn_state_ci = {};
10580         dyn_state_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO;
10581         dyn_state_ci.dynamicStateCount = 2;
10582         VkDynamicState dyn_state_dupes[2] = {dyn_states[i], dyn_states[i]};
10583         dyn_state_ci.pDynamicStates = dyn_state_dupes;
10584         pipe.dyn_state_ci_ = dyn_state_ci;
10585         if (dyn_states[i] == VK_DYNAMIC_STATE_VIEWPORT_WITH_COUNT_EXT) {
10586             pipe.vp_state_ci_.viewportCount = 0;
10587         }
10588         if (dyn_states[i] == VK_DYNAMIC_STATE_SCISSOR_WITH_COUNT_EXT) {
10589             pipe.vp_state_ci_.scissorCount = 0;
10590         }
10591         pipe.InitState();
10592         m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkPipelineDynamicStateCreateInfo-pDynamicStates-01442");
10593         pipe.CreateGraphicsPipeline();
10594         m_errorMonitor->VerifyFound();
10595     }
10596 
10597     // Verify each vkCmdSet command
10598     CreatePipelineHelper pipe(*this);
10599     pipe.InitInfo();
10600     VkPipelineDynamicStateCreateInfo dyn_state_ci = {};
10601     dyn_state_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO;
10602     dyn_state_ci.dynamicStateCount = size(dyn_states);
10603     dyn_state_ci.pDynamicStates = dyn_states;
10604     pipe.dyn_state_ci_ = dyn_state_ci;
10605     pipe.vp_state_ci_.viewportCount = 0;
10606     pipe.vp_state_ci_.scissorCount = 0;
10607     pipe.vi_ci_.vertexBindingDescriptionCount = 1;
10608     VkVertexInputBindingDescription inputBinding = {0, sizeof(float), VK_VERTEX_INPUT_RATE_VERTEX};
10609     pipe.vi_ci_.pVertexBindingDescriptions = &inputBinding;
10610     pipe.vi_ci_.vertexAttributeDescriptionCount = 1;
10611     VkVertexInputAttributeDescription attribute = {0, 0, VK_FORMAT_R32_SFLOAT, 0};
10612     pipe.vi_ci_.pVertexAttributeDescriptions = &attribute;
10613     pipe.InitState();
10614     pipe.CreateGraphicsPipeline();
10615 
10616     VkBufferObj buffer;
10617     buffer.init(*m_device, 16, 0, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT);
10618     std::vector<VkBuffer> buffers(m_device->props.limits.maxVertexInputBindings + 1ull, buffer.handle());
10619     std::vector<VkDeviceSize> offsets(buffers.size(), 0);
10620 
10621     VkCommandBufferObj commandBuffer(m_device, m_commandPool);
10622     commandBuffer.begin();
10623 
10624     m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdBindVertexBuffers2EXT-firstBinding-03355");
10625     vkCmdBindVertexBuffers2EXT(commandBuffer.handle(), m_device->props.limits.maxVertexInputBindings, 1, buffers.data(),
10626                                offsets.data(), 0, 0);
10627     m_errorMonitor->VerifyFound();
10628 
10629     m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdBindVertexBuffers2EXT-firstBinding-03356");
10630     vkCmdBindVertexBuffers2EXT(commandBuffer.handle(), 0, m_device->props.limits.maxVertexInputBindings + 1, buffers.data(),
10631                                offsets.data(), 0, 0);
10632     m_errorMonitor->VerifyFound();
10633 
10634     {
10635         VkBufferObj bufferWrongUsage;
10636         bufferWrongUsage.init(*m_device, 16, 0, VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT);
10637         m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdBindVertexBuffers2EXT-pBuffers-03359");
10638         VkBuffer buffers2[1] = {bufferWrongUsage.handle()};
10639         VkDeviceSize offsets2[1] = {};
10640         vkCmdBindVertexBuffers2EXT(commandBuffer.handle(), 0, 1, buffers2, offsets2, 0, 0);
10641         m_errorMonitor->VerifyFound();
10642     }
10643 
10644     {
10645         m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdBindVertexBuffers2EXT-pBuffers-04111");
10646         m_errorMonitor->SetUnexpectedError("UNASSIGNED-GeneralParameterError-RequiredParameter");
10647         m_errorMonitor->SetUnexpectedError("VUID-vkCmdBindVertexBuffers2EXT-pBuffers-parameter");
10648         VkBuffer buffers2[1] = {VK_NULL_HANDLE};
10649         VkDeviceSize offsets2[1] = {16};
10650         VkDeviceSize strides[1] = {m_device->props.limits.maxVertexInputBindingStride + 1ull};
10651         vkCmdBindVertexBuffers2EXT(commandBuffer.handle(), 0, 1, buffers2, offsets2, 0, 0);
10652         m_errorMonitor->VerifyFound();
10653 
10654         buffers2[0] = buffers[0];
10655         VkDeviceSize sizes[1] = {16};
10656         m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdBindVertexBuffers2EXT-pOffsets-03357");
10657         m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdBindVertexBuffers2EXT-pSizes-03358");
10658         vkCmdBindVertexBuffers2EXT(commandBuffer.handle(), 0, 1, buffers2, offsets2, sizes, 0);
10659         m_errorMonitor->VerifyFound();
10660 
10661         m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdBindVertexBuffers2EXT-pStrides-03362");
10662         vkCmdBindVertexBuffers2EXT(commandBuffer.handle(), 0, 1, buffers2, offsets2, 0, strides);
10663         m_errorMonitor->VerifyFound();
10664     }
10665 
10666     commandBuffer.BeginRenderPass(m_renderPassBeginInfo);
10667 
10668     CreatePipelineHelper pipe2(*this);
10669     pipe2.InitInfo();
10670     VkPipelineDynamicStateCreateInfo dyn_state_ci2 = {};
10671     dyn_state_ci2.sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO;
10672     dyn_state_ci2.dynamicStateCount = 1;
10673     VkDynamicState dynamic_state2 = VK_DYNAMIC_STATE_VIEWPORT_WITH_COUNT_EXT;
10674     dyn_state_ci2.pDynamicStates = &dynamic_state2;
10675     pipe2.dyn_state_ci_ = dyn_state_ci2;
10676     pipe2.vp_state_ci_.viewportCount = 0;
10677     pipe2.InitState();
10678     pipe2.CreateGraphicsPipeline();
10679     vk::CmdBindPipeline(commandBuffer.handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe2.pipeline_);
10680 
10681     m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdDraw-viewportCount-03417");
10682     vk::CmdDraw(commandBuffer.handle(), 1, 1, 0, 0);
10683     m_errorMonitor->VerifyFound();
10684 
10685     CreatePipelineHelper pipe3(*this);
10686     pipe3.InitInfo();
10687     VkPipelineDynamicStateCreateInfo dyn_state_ci3 = {};
10688     dyn_state_ci3.sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO;
10689     dyn_state_ci3.dynamicStateCount = 1;
10690     VkDynamicState dynamic_state3 = VK_DYNAMIC_STATE_SCISSOR_WITH_COUNT_EXT;
10691     dyn_state_ci3.pDynamicStates = &dynamic_state3;
10692     pipe3.dyn_state_ci_ = dyn_state_ci3;
10693     pipe3.vp_state_ci_.scissorCount = 0;
10694     pipe3.InitState();
10695     pipe3.CreateGraphicsPipeline();
10696     vk::CmdBindPipeline(commandBuffer.handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe3.pipeline_);
10697 
10698     m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdDraw-scissorCount-03418");
10699     vk::CmdDraw(commandBuffer.handle(), 1, 1, 0, 0);
10700     m_errorMonitor->VerifyFound();
10701 
10702     vk::CmdBindPipeline(commandBuffer.handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.pipeline_);
10703 
10704     VkDeviceSize strides[1] = {0};
10705     vkCmdSetPrimitiveTopologyEXT(commandBuffer.handle(), VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP);
10706     vkCmdBindVertexBuffers2EXT(commandBuffer.handle(), 0, 1, buffers.data(), offsets.data(), 0, strides);
10707     VkRect2D scissor = {{0, 0}, {1, 1}};
10708     vkCmdSetScissorWithCountEXT(commandBuffer.handle(), 1, &scissor);
10709     m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdDraw-viewportCount-03419");
10710     vk::CmdDraw(commandBuffer.handle(), 1, 1, 0, 0);
10711     m_errorMonitor->VerifyFound();
10712 
10713     VkViewport viewport = {0, 0, 1, 1, 0.0f, 0.0f};
10714     vkCmdSetViewportWithCountEXT(commandBuffer.handle(), 1, &viewport);
10715     strides[0] = 1;
10716     vkCmdBindVertexBuffers2EXT(commandBuffer.handle(), 0, 1, buffers.data(), offsets.data(), 0, strides);
10717     m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdBindVertexBuffers2EXT-pStrides-06209");
10718     m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdDraw-None-02721");
10719     vk::CmdDraw(commandBuffer.handle(), 1, 1, 0, 0);
10720     m_errorMonitor->VerifyFound();
10721 
10722     strides[0] = 4;
10723     vkCmdBindVertexBuffers2EXT(commandBuffer.handle(), 0, 1, buffers.data(), offsets.data(), 0, strides);
10724 
10725     vkCmdSetPrimitiveTopologyEXT(commandBuffer.handle(), VK_PRIMITIVE_TOPOLOGY_LINE_LIST);
10726     m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdDraw-primitiveTopology-03420");
10727     vk::CmdDraw(commandBuffer.handle(), 1, 1, 0, 0);
10728     m_errorMonitor->VerifyFound();
10729 
10730     vk::CmdEndRenderPass(commandBuffer.handle());
10731 
10732     m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdSetViewportWithCountEXT-viewportCount-03394");
10733     m_errorMonitor->SetUnexpectedError("VUID-vkCmdSetViewportWithCountEXT-viewportCount-arraylength");
10734     VkViewport viewport2 = {
10735         0, 0, 1, 1, 0.0f, 0.0f,
10736     };
10737     vkCmdSetViewportWithCountEXT(commandBuffer.handle(), 0, &viewport2);
10738     m_errorMonitor->VerifyFound();
10739 
10740     {
10741         m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdSetScissorWithCountEXT-offset-03400");
10742         VkRect2D scissor2 = {{1, 0}, {INT32_MAX, 16}};
10743         vkCmdSetScissorWithCountEXT(commandBuffer.handle(), 1, &scissor2);
10744         m_errorMonitor->VerifyFound();
10745     }
10746 
10747     {
10748         m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdSetScissorWithCountEXT-offset-03401");
10749         VkRect2D scissor2 = {{0, 1}, {16, INT32_MAX}};
10750         vkCmdSetScissorWithCountEXT(commandBuffer.handle(), 1, &scissor2);
10751         m_errorMonitor->VerifyFound();
10752     }
10753 
10754     m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdSetScissorWithCountEXT-scissorCount-03397");
10755     m_errorMonitor->SetUnexpectedError("VUID-vkCmdSetScissorWithCountEXT-scissorCount-arraylength");
10756     vkCmdSetScissorWithCountEXT(commandBuffer.handle(), 0, 0);
10757     m_errorMonitor->VerifyFound();
10758 
10759     m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdSetScissorWithCountEXT-x-03399");
10760     m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdSetScissorWithCountEXT-x-03399");
10761     VkRect2D scissor3 = {{-1, -1}, {0, 0}};
10762     vkCmdSetScissorWithCountEXT(commandBuffer.handle(), 1, &scissor3);
10763     m_errorMonitor->VerifyFound();
10764 
10765     commandBuffer.end();
10766 }
10767 
TEST_F(VkLayerTest,ValidateExtendedDynamicStateEnabledNoMultiview)10768 TEST_F(VkLayerTest, ValidateExtendedDynamicStateEnabledNoMultiview) {
10769     TEST_DESCRIPTION("Validate VK_EXT_extended_dynamic_state VUs");
10770 
10771     uint32_t version = SetTargetApiVersion(VK_API_VERSION_1_1);
10772     if (version < VK_API_VERSION_1_1) {
10773         printf("%s At least Vulkan version 1.1 is required, skipping test.\n", kSkipPrefix);
10774         return;
10775     }
10776 
10777     ASSERT_NO_FATAL_FAILURE(InitFramework(m_errorMonitor));
10778     if (DeviceExtensionSupported(gpu(), nullptr, VK_EXT_EXTENDED_DYNAMIC_STATE_EXTENSION_NAME)) {
10779         m_device_extension_names.push_back(VK_EXT_EXTENDED_DYNAMIC_STATE_EXTENSION_NAME);
10780     } else {
10781         printf("%s Extension %s is not supported.\n", kSkipPrefix, VK_EXT_EXTENDED_DYNAMIC_STATE_EXTENSION_NAME);
10782         return;
10783     }
10784 
10785     auto extended_dynamic_state_features = LvlInitStruct<VkPhysicalDeviceExtendedDynamicStateFeaturesEXT>();
10786     auto features2 = LvlInitStruct<VkPhysicalDeviceFeatures2>(&extended_dynamic_state_features);
10787     vk::GetPhysicalDeviceFeatures2(gpu(), &features2);
10788     if (!extended_dynamic_state_features.extendedDynamicState) {
10789         printf("%s Test requires (unsupported) extendedDynamicState, skipping\n", kSkipPrefix);
10790         return;
10791     }
10792 
10793     features2.features.multiViewport = VK_FALSE;
10794     ASSERT_NO_FATAL_FAILURE(InitState(nullptr, &features2));
10795 
10796     auto vkCmdSetViewportWithCountEXT =
10797         (PFN_vkCmdSetViewportWithCountEXT)vk::GetDeviceProcAddr(m_device->device(), "vkCmdSetViewportWithCountEXT");
10798     auto vkCmdSetScissorWithCountEXT =
10799         (PFN_vkCmdSetScissorWithCountEXT)vk::GetDeviceProcAddr(m_device->device(), "vkCmdSetScissorWithCountEXT");
10800 
10801     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
10802 
10803     VkCommandBufferObj commandBuffer(m_device, m_commandPool);
10804     commandBuffer.begin();
10805 
10806     m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdSetViewportWithCountEXT-viewportCount-03395");
10807     VkViewport viewport = {0, 0, 1, 1, 0.0f, 0.0f};
10808     VkViewport viewports[] = {viewport, viewport};
10809     vkCmdSetViewportWithCountEXT(commandBuffer.handle(), size(viewports), viewports);
10810     m_errorMonitor->VerifyFound();
10811 
10812     m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdSetScissorWithCountEXT-scissorCount-03398");
10813     VkRect2D scissor = {{0, 0}, {1, 1}};
10814     VkRect2D scissors[] = {scissor, scissor};
10815     vkCmdSetScissorWithCountEXT(commandBuffer.handle(), size(scissors), scissors);
10816     m_errorMonitor->VerifyFound();
10817 
10818     commandBuffer.end();
10819 }
10820 
TEST_F(VkLayerTest,InvalidFragmentShadingRateDeviceFeatureCombinations)10821 TEST_F(VkLayerTest, InvalidFragmentShadingRateDeviceFeatureCombinations) {
10822     TEST_DESCRIPTION(
10823         "Specify invalid combinations of fragment shading rate, shading rate image, and fragment density map features");
10824 
10825     // Enable KHR_fragment_shading_rate and all of its required extensions
10826     bool fsr_extensions = InstanceExtensionSupported(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
10827     if (fsr_extensions) {
10828         m_instance_extension_names.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
10829     }
10830     ASSERT_NO_FATAL_FAILURE(InitFramework(m_errorMonitor));
10831 
10832     fsr_extensions = fsr_extensions && DeviceExtensionSupported(gpu(), nullptr, VK_KHR_MAINTENANCE_1_EXTENSION_NAME);
10833     fsr_extensions = fsr_extensions && DeviceExtensionSupported(gpu(), nullptr, VK_KHR_MAINTENANCE_2_EXTENSION_NAME);
10834     fsr_extensions = fsr_extensions && DeviceExtensionSupported(gpu(), nullptr, VK_KHR_MULTIVIEW_EXTENSION_NAME);
10835     fsr_extensions = fsr_extensions && DeviceExtensionSupported(gpu(), nullptr, VK_KHR_CREATE_RENDERPASS_2_EXTENSION_NAME);
10836     fsr_extensions = fsr_extensions && DeviceExtensionSupported(gpu(), nullptr, VK_KHR_FRAGMENT_SHADING_RATE_EXTENSION_NAME);
10837     if (fsr_extensions) {
10838         m_device_extension_names.push_back(VK_KHR_MAINTENANCE_1_EXTENSION_NAME);
10839         m_device_extension_names.push_back(VK_KHR_MAINTENANCE_2_EXTENSION_NAME);
10840         m_device_extension_names.push_back(VK_KHR_MULTIVIEW_EXTENSION_NAME);
10841         m_device_extension_names.push_back(VK_KHR_CREATE_RENDERPASS_2_EXTENSION_NAME);
10842         m_device_extension_names.push_back(VK_KHR_FRAGMENT_SHADING_RATE_EXTENSION_NAME);
10843     } else {
10844         printf("%s requires VK_KHR_fragment_shading_rate.\n", kSkipPrefix);
10845         return;
10846     }
10847 
10848     bool sri_extension = DeviceExtensionSupported(gpu(), nullptr, VK_NV_SHADING_RATE_IMAGE_EXTENSION_NAME);
10849     if (sri_extension) {
10850         m_device_extension_names.push_back(VK_NV_SHADING_RATE_IMAGE_EXTENSION_NAME);
10851     }
10852 
10853     bool fdm_extension = DeviceExtensionSupported(gpu(), nullptr, VK_EXT_FRAGMENT_DENSITY_MAP_EXTENSION_NAME);
10854     if (fdm_extension) {
10855         m_device_extension_names.push_back(VK_EXT_FRAGMENT_DENSITY_MAP_EXTENSION_NAME);
10856     }
10857 
10858     if (!fdm_extension && !sri_extension) {
10859         printf("%s requires VK_NV_shading_rate_image or VK_EXT_fragment_density_map.\n", kSkipPrefix);
10860         return;
10861     }
10862 
10863     PFN_vkGetPhysicalDeviceFeatures2KHR vkGetPhysicalDeviceFeatures2KHR =
10864         (PFN_vkGetPhysicalDeviceFeatures2KHR)vk::GetInstanceProcAddr(instance(), "vkGetPhysicalDeviceFeatures2KHR");
10865     ASSERT_TRUE(vkGetPhysicalDeviceFeatures2KHR != nullptr);
10866     VkPhysicalDeviceFragmentDensityMapFeaturesEXT fdm_query_features =
10867         LvlInitStruct<VkPhysicalDeviceFragmentDensityMapFeaturesEXT>();
10868     VkPhysicalDeviceShadingRateImageFeaturesNV sri_query_features = LvlInitStruct<VkPhysicalDeviceShadingRateImageFeaturesNV>();
10869     VkPhysicalDeviceFragmentShadingRateFeaturesKHR fsr_query_features =
10870         LvlInitStruct<VkPhysicalDeviceFragmentShadingRateFeaturesKHR>();
10871 
10872     if (fdm_extension) {
10873         fsr_query_features.pNext = &fdm_query_features;
10874     }
10875     if (sri_extension) {
10876         if (fdm_extension) {
10877             fdm_query_features.pNext = &sri_query_features;
10878         } else {
10879             fsr_query_features.pNext = &sri_query_features;
10880         }
10881     }
10882     VkPhysicalDeviceFeatures2KHR query_features2 = LvlInitStruct<VkPhysicalDeviceFeatures2KHR>(&fsr_query_features);
10883     vkGetPhysicalDeviceFeatures2KHR(gpu(), &query_features2);
10884 
10885     // Workaround for overzealous layers checking even the guaranteed 0th queue family
10886     const auto q_props = vk_testing::PhysicalDevice(gpu()).queue_properties();
10887     ASSERT_TRUE(q_props.size() > 0);
10888     ASSERT_TRUE(q_props[0].queueCount > 0);
10889 
10890     const float q_priority[] = {1.0f};
10891     VkDeviceQueueCreateInfo queue_ci = {};
10892     queue_ci.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
10893     queue_ci.queueFamilyIndex = 0;
10894     queue_ci.queueCount = 1;
10895     queue_ci.pQueuePriorities = q_priority;
10896 
10897     VkDeviceCreateInfo device_ci = {};
10898     device_ci.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
10899     device_ci.queueCreateInfoCount = 1;
10900     device_ci.pQueueCreateInfos = &queue_ci;
10901 
10902     VkPhysicalDeviceFragmentDensityMapFeaturesEXT fdm_features = LvlInitStruct<VkPhysicalDeviceFragmentDensityMapFeaturesEXT>();
10903     VkPhysicalDeviceShadingRateImageFeaturesNV sri_features = LvlInitStruct<VkPhysicalDeviceShadingRateImageFeaturesNV>();
10904     VkPhysicalDeviceFragmentShadingRateFeaturesKHR fsr_features = LvlInitStruct<VkPhysicalDeviceFragmentShadingRateFeaturesKHR>();
10905     VkPhysicalDeviceFeatures2KHR features2 = LvlInitStruct<VkPhysicalDeviceFeatures2KHR>(&fsr_features);
10906     device_ci.pNext = &features2;
10907 
10908     VkDevice testDevice;
10909 
10910     if (sri_query_features.shadingRateImage) {
10911         sri_features.shadingRateImage = true;
10912         fsr_features.pNext = &sri_features;
10913         if (fsr_query_features.pipelineFragmentShadingRate) {
10914             fsr_features.pipelineFragmentShadingRate = true;
10915             m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkDeviceCreateInfo-shadingRateImage-04478");
10916             vk::CreateDevice(gpu(), &device_ci, nullptr, &testDevice);
10917             m_errorMonitor->VerifyFound();
10918             fsr_features.pipelineFragmentShadingRate = false;
10919         }
10920         if (fsr_query_features.primitiveFragmentShadingRate) {
10921             fsr_features.primitiveFragmentShadingRate = true;
10922             m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkDeviceCreateInfo-shadingRateImage-04479");
10923             vk::CreateDevice(gpu(), &device_ci, nullptr, &testDevice);
10924             m_errorMonitor->VerifyFound();
10925             fsr_features.primitiveFragmentShadingRate = false;
10926         }
10927         if (fsr_query_features.attachmentFragmentShadingRate) {
10928             fsr_features.attachmentFragmentShadingRate = true;
10929             m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkDeviceCreateInfo-shadingRateImage-04480");
10930             vk::CreateDevice(gpu(), &device_ci, nullptr, &testDevice);
10931             m_errorMonitor->VerifyFound();
10932             fsr_features.attachmentFragmentShadingRate = false;
10933         }
10934         fsr_features.pNext = nullptr;
10935     }
10936 
10937     if (fdm_query_features.fragmentDensityMap) {
10938         fdm_features.fragmentDensityMap = true;
10939         fsr_features.pNext = &fdm_features;
10940         if (fsr_query_features.pipelineFragmentShadingRate) {
10941             fsr_features.pipelineFragmentShadingRate = true;
10942             m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkDeviceCreateInfo-fragmentDensityMap-04481");
10943             vk::CreateDevice(gpu(), &device_ci, nullptr, &testDevice);
10944             m_errorMonitor->VerifyFound();
10945             fsr_features.pipelineFragmentShadingRate = false;
10946         }
10947         if (fsr_query_features.primitiveFragmentShadingRate) {
10948             fsr_features.primitiveFragmentShadingRate = true;
10949             m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkDeviceCreateInfo-fragmentDensityMap-04482");
10950             vk::CreateDevice(gpu(), &device_ci, nullptr, &testDevice);
10951             m_errorMonitor->VerifyFound();
10952             fsr_features.primitiveFragmentShadingRate = false;
10953         }
10954         if (fsr_query_features.attachmentFragmentShadingRate) {
10955             fsr_features.attachmentFragmentShadingRate = true;
10956             m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkDeviceCreateInfo-fragmentDensityMap-04483");
10957             vk::CreateDevice(gpu(), &device_ci, nullptr, &testDevice);
10958             m_errorMonitor->VerifyFound();
10959             fsr_features.attachmentFragmentShadingRate = false;
10960         }
10961         fsr_features.pNext = nullptr;
10962     }
10963 }
10964 
TEST_F(VkLayerTest,ValidateArrayLength)10965 TEST_F(VkLayerTest, ValidateArrayLength) {
10966     TEST_DESCRIPTION("Validate arraylength VUs");
10967 
10968     ASSERT_NO_FATAL_FAILURE(Init());
10969     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
10970 
10971     // Used to have a valid pointed to set object too
10972     VkCommandBuffer unused_command_buffer;
10973     VkDescriptorSet unused_descriptor_set;
10974 
10975     VkDescriptorSetObj descriptor_set_obj(m_device);
10976     descriptor_set_obj.AppendDummy();
10977     descriptor_set_obj.CreateVKDescriptorSet(m_commandBuffer);
10978     VkDescriptorSet descriptor_set = descriptor_set_obj.GetDescriptorSetHandle();
10979 
10980     VkFence fence;
10981     VkFenceCreateInfo fence_create_info = {};
10982     fence_create_info.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
10983     fence_create_info.pNext = nullptr;
10984     vk::CreateFence(device(), &fence_create_info, nullptr, &fence);
10985 
10986     VkEvent event;
10987     VkEventCreateInfo event_create_info = {};
10988     event_create_info.sType = VK_STRUCTURE_TYPE_EVENT_CREATE_INFO;
10989     event_create_info.pNext = nullptr;
10990     vk::CreateEvent(device(), &event_create_info, nullptr, &event);
10991 
10992     m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkAllocateCommandBuffers-pAllocateInfo::commandBufferCount-arraylength");
10993     {
10994         VkCommandBufferAllocateInfo info = {};
10995         info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
10996         info.pNext = nullptr;
10997         info.commandPool = m_commandPool->handle();
10998         info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
10999         info.commandBufferCount = 0;  // invalid
11000         vk::AllocateCommandBuffers(device(), &info, &unused_command_buffer);
11001     }
11002     m_errorMonitor->VerifyFound();
11003 
11004     // One exception in spec where the size of a field is used in both the function call it and the struct
11005     m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkAllocateDescriptorSets-pAllocateInfo::descriptorSetCount-arraylength");
11006     // TODO - Figure out why  VUID-VkDescriptorSetAllocateInfo-descriptorSetCount-arraylength is not being generated, very low
11007     // priority since it is already caught with the above implicit VU. There was an internal MR and WG decided to keep both
11008     // len='descriptorSetCount' for anyone relying on it
11009     m_errorMonitor->SetUnexpectedError("VUID_Undefined");
11010     {
11011         VkDescriptorSetLayout set_layout = descriptor_set_obj.GetDescriptorSetLayout();
11012         VkDescriptorSetAllocateInfo info = {};
11013         info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
11014         info.pNext = nullptr;
11015         info.descriptorPool = descriptor_set_obj.handle();
11016         info.descriptorSetCount = 0;  // invalid
11017         info.pSetLayouts = &set_layout;
11018         vk::AllocateDescriptorSets(device(), &info, &unused_descriptor_set);
11019     }
11020     m_errorMonitor->VerifyFound();
11021 
11022     m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkFreeCommandBuffers-commandBufferCount-arraylength");
11023     vk::FreeCommandBuffers(device(), m_commandPool->handle(), 0, &unused_command_buffer);
11024     m_errorMonitor->VerifyFound();
11025 
11026     m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkFreeDescriptorSets-descriptorSetCount-arraylength");
11027     vk::FreeDescriptorSets(device(), descriptor_set_obj.handle(), 0, &descriptor_set);
11028     m_errorMonitor->VerifyFound();
11029 
11030     m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkResetFences-fenceCount-arraylength");
11031     vk::ResetFences(device(), 0, &fence);
11032     m_errorMonitor->VerifyFound();
11033 
11034     m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkWaitForFences-fenceCount-arraylength");
11035     vk::WaitForFences(device(), 0, &fence, true, 1);
11036     m_errorMonitor->VerifyFound();
11037 
11038     VkCommandBufferObj command_buffer(m_device, m_commandPool);
11039     command_buffer.begin();
11040 
11041     m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdBindDescriptorSets-descriptorSetCount-arraylength");
11042     vk::CmdBindDescriptorSets(command_buffer.handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, descriptor_set_obj.GetPipelineLayout(), 0,
11043                               0, &(descriptor_set), 0, nullptr);
11044     m_errorMonitor->VerifyFound();
11045 
11046     m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdExecuteCommands-commandBufferCount-arraylength");
11047     vk::CmdExecuteCommands(command_buffer.handle(), 0, &unused_command_buffer);
11048     m_errorMonitor->VerifyFound();
11049 
11050     m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdWaitEvents-eventCount-arraylength");
11051     vk::CmdWaitEvents(command_buffer.handle(), 0, &event, VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0,
11052                       nullptr, 0, nullptr, 0, nullptr);
11053     m_errorMonitor->VerifyFound();
11054 
11055     command_buffer.end();
11056 
11057     vk::DestroyFence(device(), fence, nullptr);
11058     vk::DestroyEvent(device(), event, nullptr);
11059 }
11060 
TEST_F(VkLayerTest,InvalidSpirvExtension)11061 TEST_F(VkLayerTest, InvalidSpirvExtension) {
11062     TEST_DESCRIPTION("Use an invalid SPIR-V extension in OpExtension.");
11063 
11064     SetTargetApiVersion(VK_API_VERSION_1_2);
11065 
11066     ASSERT_NO_FATAL_FAILURE(InitFramework(m_errorMonitor));
11067     if (DeviceValidationVersion() < VK_API_VERSION_1_2) {
11068         printf("%s Vulkan >= 1.2 required\n", kSkipPrefix);
11069         return;
11070     }
11071 
11072     ASSERT_NO_FATAL_FAILURE(InitState());
11073     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
11074 
11075     if (IsPlatform(kMockICD) || DeviceSimulation()) {
11076         printf("%s DevSim doesn't support Vulkan 1.1+, skipping tests\n", kSkipPrefix);
11077         return;
11078     }
11079 
11080     const std::string vertex_source = R"spirv(
11081                OpCapability Shader
11082           %1 = OpExtInstImport "GLSL.std.450"
11083                OpMemoryModel Logical GLSL450
11084                OpEntryPoint Vertex %4 "main"
11085                OpSource GLSL 450
11086                OpExtension "GL_EXT_scalar_block_layout"
11087                OpName %4 "main"
11088           %2 = OpTypeVoid
11089           %3 = OpTypeFunction %2
11090           %4 = OpFunction %2 None %3
11091           %5 = OpLabel
11092                OpReturn
11093                OpFunctionEnd
11094         )spirv";
11095     VkShaderObj vs(*m_device, VK_SHADER_STAGE_VERTEX_BIT);
11096     m_errorMonitor->SetUnexpectedError(kVUID_Core_Shader_InconsistentSpirv);
11097     if (!vs.InitFromASMTry(*this, vertex_source.c_str(), SPV_ENV_VULKAN_1_2)) {
11098         printf("%s Failed to compile shader\n", kSkipPrefix);
11099         return;
11100     }
11101     const VkShaderObj fs(m_device, bindStateFragShaderText, VK_SHADER_STAGE_FRAGMENT_BIT, this);
11102 
11103     m_errorMonitor->SetDesiredFailureMsg(kErrorBit, kVUID_Core_Shader_InvalidExtension);
11104     CreatePipelineHelper pipe(*this);
11105     pipe.InitInfo();
11106     pipe.shader_stages_ = {vs.GetStageCreateInfo(), fs.GetStageCreateInfo()};
11107     pipe.InitState();
11108     pipe.CreateGraphicsPipeline();
11109     m_errorMonitor->VerifyFound();
11110 }
11111 
TEST_F(VkLayerTest,CmdCopyAccelerationStructureToMemoryKHR)11112 TEST_F(VkLayerTest, CmdCopyAccelerationStructureToMemoryKHR) {
11113     TEST_DESCRIPTION("Validate CmdCopyAccelerationStructureToMemoryKHR.");
11114 
11115     SetTargetApiVersion(VK_API_VERSION_1_2);
11116     if (!InitFrameworkForRayTracingTest(this, true, m_instance_extension_names, m_device_extension_names, m_errorMonitor, false,
11117                                         false, true)) {
11118         return;
11119     }
11120 
11121     PFN_vkGetPhysicalDeviceFeatures2KHR vkGetPhysicalDeviceFeatures2KHR =
11122         (PFN_vkGetPhysicalDeviceFeatures2KHR)vk::GetInstanceProcAddr(instance(), "vkGetPhysicalDeviceFeatures2KHR");
11123     VkPhysicalDeviceFeatures2KHR features2 = {};
11124     auto ray_tracing_features = LvlInitStruct<VkPhysicalDeviceRayTracingPipelineFeaturesKHR>();
11125     auto ray_query_features = LvlInitStruct<VkPhysicalDeviceRayQueryFeaturesKHR>(&ray_tracing_features);
11126     auto acc_struct_features = LvlInitStruct<VkPhysicalDeviceAccelerationStructureFeaturesKHR>(&ray_query_features);
11127     features2 = LvlInitStruct<VkPhysicalDeviceFeatures2KHR>(&acc_struct_features);
11128     vkGetPhysicalDeviceFeatures2KHR(gpu(), &features2);
11129     if (ray_query_features.rayQuery == VK_FALSE && ray_tracing_features.rayTracingPipeline == VK_FALSE) {
11130         printf("%s Both of the required features rayQuery and rayTracing are not supported, skipping test\n", kSkipPrefix);
11131         return;
11132     }
11133     ASSERT_NO_FATAL_FAILURE(InitState(nullptr, &acc_struct_features));
11134 
11135     PFN_vkCreateAccelerationStructureKHR vkCreateAccelerationStructureKHR = reinterpret_cast<PFN_vkCreateAccelerationStructureKHR>(
11136         vk::GetDeviceProcAddr(m_device->handle(), "vkCreateAccelerationStructureKHR"));
11137     assert(vkCreateAccelerationStructureKHR != nullptr);
11138 
11139     PFN_vkDestroyAccelerationStructureKHR vkDestroyAccelerationStructureKHR =
11140         reinterpret_cast<PFN_vkDestroyAccelerationStructureKHR>(
11141             vk::GetDeviceProcAddr(m_device->handle(), "vkDestroyAccelerationStructureKHR"));
11142     assert(vkDestroyAccelerationStructureKHR != nullptr);
11143 
11144     constexpr VkDeviceSize buffer_size = 4096;
11145     auto buffer_ci = LvlInitStruct<VkBufferCreateInfo>();
11146     buffer_ci.size = buffer_size;
11147     buffer_ci.usage = VK_BUFFER_USAGE_ACCELERATION_STRUCTURE_STORAGE_BIT_KHR;
11148     buffer_ci.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
11149     VkBufferObj buffer;
11150     buffer.init_no_mem(*m_device, buffer_ci);
11151 
11152     auto as_create_info = LvlInitStruct<VkAccelerationStructureCreateInfoKHR>();
11153     as_create_info.pNext = NULL;
11154     as_create_info.buffer = buffer.handle();
11155     as_create_info.createFlags = 0;
11156     as_create_info.offset = 0;
11157     as_create_info.size = 0;
11158     as_create_info.type = VK_ACCELERATION_STRUCTURE_TYPE_BOTTOM_LEVEL_KHR;
11159     as_create_info.deviceAddress = 0;
11160 
11161     PFN_vkCmdCopyAccelerationStructureToMemoryKHR vkCmdCopyAccelerationStructureToMemoryKHR =
11162         reinterpret_cast<PFN_vkCmdCopyAccelerationStructureToMemoryKHR>(
11163             vk::GetDeviceProcAddr(device(), "vkCmdCopyAccelerationStructureToMemoryKHR"));
11164     assert(vkCmdCopyAccelerationStructureToMemoryKHR != nullptr);
11165 
11166     VkAccelerationStructureKHR as;
11167     vkCreateAccelerationStructureKHR(m_device->handle(), &as_create_info, nullptr, &as);
11168 
11169     constexpr intptr_t alignment_padding = 256 - 1;
11170     int8_t output[buffer_size + alignment_padding];
11171     VkDeviceOrHostAddressKHR output_data;
11172     output_data.hostAddress = reinterpret_cast<void *>(((intptr_t)output + alignment_padding) & ~alignment_padding);
11173     auto copy_info = LvlInitStruct<VkCopyAccelerationStructureToMemoryInfoKHR>();
11174     copy_info.src = as;
11175     copy_info.dst = output_data;
11176     copy_info.mode = VK_COPY_ACCELERATION_STRUCTURE_MODE_SERIALIZE_KHR;
11177     VkCommandBufferObj cb(m_device, m_commandPool);
11178     cb.begin();
11179 
11180     m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdCopyAccelerationStructureToMemoryKHR-None-03559");
11181     vkCmdCopyAccelerationStructureToMemoryKHR(cb.handle(), &copy_info);
11182     m_errorMonitor->VerifyFound();
11183 
11184     cb.end();
11185 
11186     vkDestroyAccelerationStructureKHR(m_device->handle(), as, nullptr);
11187 }
11188 
TEST_F(VkLayerTest,InvalidVkSemaphoreTypeCreateInfoCore)11189 TEST_F(VkLayerTest, InvalidVkSemaphoreTypeCreateInfoCore) {
11190     TEST_DESCRIPTION("Invalid usage of VkSemaphoreTypeCreateInfo with a 1.2 core version");
11191 
11192     SetTargetApiVersion(VK_API_VERSION_1_2);
11193     ASSERT_NO_FATAL_FAILURE(InitFramework(m_errorMonitor));
11194     if (DeviceValidationVersion() < VK_API_VERSION_1_2) {
11195         printf("%s Test requires Vulkan 1.2+, skipping test\n", kSkipPrefix);
11196         return;
11197     }
11198 
11199     // Core 1.2 supports timelineSemaphore feature bit but not enabled
11200     ASSERT_NO_FATAL_FAILURE(InitState());
11201 
11202     VkSemaphore semaphore;
11203 
11204     VkSemaphoreTypeCreateInfoKHR semaphore_type_create_info;
11205     semaphore_type_create_info.sType = VK_STRUCTURE_TYPE_SEMAPHORE_TYPE_CREATE_INFO_KHR;
11206     semaphore_type_create_info.pNext = nullptr;
11207     semaphore_type_create_info.semaphoreType = VK_SEMAPHORE_TYPE_TIMELINE;
11208     semaphore_type_create_info.initialValue = 1;
11209 
11210     VkSemaphoreCreateInfo semaphore_create_info;
11211     semaphore_create_info.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO;
11212     semaphore_create_info.pNext = &semaphore_type_create_info;
11213     semaphore_create_info.flags = 0;
11214 
11215     // timelineSemaphore feature bit not set
11216     m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkSemaphoreTypeCreateInfo-timelineSemaphore-03252");
11217     vk::CreateSemaphore(m_device->device(), &semaphore_create_info, nullptr, &semaphore);
11218     m_errorMonitor->VerifyFound();
11219 
11220     // Binary semaphore can't be initialValue 0
11221     semaphore_type_create_info.semaphoreType = VK_SEMAPHORE_TYPE_BINARY;
11222     m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkSemaphoreTypeCreateInfo-semaphoreType-03279");
11223     vk::CreateSemaphore(m_device->device(), &semaphore_create_info, nullptr, &semaphore);
11224     m_errorMonitor->VerifyFound();
11225 }
11226 
TEST_F(VkLayerTest,InvalidVkSemaphoreTypeCreateInfoExtension)11227 TEST_F(VkLayerTest, InvalidVkSemaphoreTypeCreateInfoExtension) {
11228     TEST_DESCRIPTION("Invalid usage of VkSemaphoreTypeCreateInfo with extension");
11229 
11230     SetTargetApiVersion(VK_API_VERSION_1_1);  // before timelineSemaphore was added to core
11231     if (InstanceExtensionSupported(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME)) {
11232         m_instance_extension_names.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
11233     } else {
11234         printf("%s Extension %s is not supported.\n", kSkipPrefix, VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
11235         return;
11236     }
11237 
11238     ASSERT_NO_FATAL_FAILURE(InitFramework(m_errorMonitor));
11239 
11240     if (DeviceExtensionSupported(gpu(), nullptr, VK_KHR_TIMELINE_SEMAPHORE_EXTENSION_NAME)) {
11241         m_device_extension_names.push_back(VK_KHR_TIMELINE_SEMAPHORE_EXTENSION_NAME);
11242     } else {
11243         printf("%s Extension %s not supported by device; skipped.\n", kSkipPrefix, VK_KHR_TIMELINE_SEMAPHORE_EXTENSION_NAME);
11244         return;
11245     }
11246 
11247     // Enabled extension but not the timelineSemaphore feature bit
11248     ASSERT_NO_FATAL_FAILURE(InitState());
11249 
11250     VkSemaphore semaphore;
11251 
11252     VkSemaphoreTypeCreateInfoKHR semaphore_type_create_info;
11253     semaphore_type_create_info.sType = VK_STRUCTURE_TYPE_SEMAPHORE_TYPE_CREATE_INFO_KHR;
11254     semaphore_type_create_info.pNext = nullptr;
11255     semaphore_type_create_info.semaphoreType = VK_SEMAPHORE_TYPE_TIMELINE;
11256     semaphore_type_create_info.initialValue = 1;
11257 
11258     VkSemaphoreCreateInfo semaphore_create_info;
11259     semaphore_create_info.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO;
11260     semaphore_create_info.pNext = &semaphore_type_create_info;
11261     semaphore_create_info.flags = 0;
11262 
11263     // timelineSemaphore feature bit not set
11264     m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkSemaphoreTypeCreateInfo-timelineSemaphore-03252");
11265     vk::CreateSemaphore(m_device->device(), &semaphore_create_info, nullptr, &semaphore);
11266     m_errorMonitor->VerifyFound();
11267 
11268     // Binary semaphore can't be initialValue 0
11269     semaphore_type_create_info.semaphoreType = VK_SEMAPHORE_TYPE_BINARY;
11270     m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkSemaphoreTypeCreateInfo-semaphoreType-03279");
11271     vk::CreateSemaphore(m_device->device(), &semaphore_create_info, nullptr, &semaphore);
11272     m_errorMonitor->VerifyFound();
11273 }
11274 
TEST_F(VkLayerTest,MixedTimelineAndBinarySemaphores)11275 TEST_F(VkLayerTest, MixedTimelineAndBinarySemaphores) {
11276     TEST_DESCRIPTION("Submit mixtures of timeline and binary semaphores");
11277 
11278     if (InstanceExtensionSupported(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME)) {
11279         m_instance_extension_names.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
11280     } else {
11281         printf("%s Extension %s is not supported.\n", kSkipPrefix, VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
11282         return;
11283     }
11284 
11285     ASSERT_NO_FATAL_FAILURE(InitFramework(m_errorMonitor));
11286 
11287     if (DeviceExtensionSupported(gpu(), nullptr, VK_KHR_TIMELINE_SEMAPHORE_EXTENSION_NAME)) {
11288         m_device_extension_names.push_back(VK_KHR_TIMELINE_SEMAPHORE_EXTENSION_NAME);
11289     } else {
11290         printf("%s Extension %s not supported by device; skipped.\n", kSkipPrefix, VK_KHR_TIMELINE_SEMAPHORE_EXTENSION_NAME);
11291         return;
11292     }
11293 
11294     if (!CheckTimelineSemaphoreSupportAndInitState(this)) {
11295         printf("%s Timeline semaphore not supported, skipping test\n", kSkipPrefix);
11296         return;
11297     }
11298 
11299     PFN_vkGetPhysicalDeviceProperties2KHR vkGetPhysicalDeviceProperties2KHR =
11300         (PFN_vkGetPhysicalDeviceProperties2KHR)vk::GetInstanceProcAddr(instance(), "vkGetPhysicalDeviceProperties2KHR");
11301     ASSERT_TRUE(vkGetPhysicalDeviceProperties2KHR != nullptr);
11302     auto timelineproperties = LvlInitStruct<VkPhysicalDeviceTimelineSemaphorePropertiesKHR>();
11303     auto prop2 = LvlInitStruct<VkPhysicalDeviceProperties2KHR>(&timelineproperties);
11304     vkGetPhysicalDeviceProperties2KHR(gpu(), &prop2);
11305 
11306     VkSemaphoreTypeCreateInfoKHR semaphore_type_create_info{};
11307     semaphore_type_create_info.sType = VK_STRUCTURE_TYPE_SEMAPHORE_TYPE_CREATE_INFO_KHR;
11308     semaphore_type_create_info.semaphoreType = VK_SEMAPHORE_TYPE_TIMELINE_KHR;
11309     semaphore_type_create_info.initialValue = 5;
11310 
11311     VkSemaphoreCreateInfo semaphore_create_info{};
11312     semaphore_create_info.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO;
11313     semaphore_create_info.pNext = &semaphore_type_create_info;
11314 
11315     VkSemaphore semaphore[2];
11316     ASSERT_VK_SUCCESS(vk::CreateSemaphore(m_device->device(), &semaphore_create_info, nullptr, &semaphore[0]));
11317     // index 1 should be a binary semaphore
11318     semaphore_create_info.pNext = nullptr;
11319     ASSERT_VK_SUCCESS(vk::CreateSemaphore(m_device->device(), &semaphore_create_info, nullptr, &semaphore[1]));
11320     VkSemaphore extra_binary;
11321     ASSERT_VK_SUCCESS(vk::CreateSemaphore(m_device->device(), &semaphore_create_info, nullptr, &extra_binary));
11322 
11323     VkSemaphoreSignalInfo semaphore_signal_info{};
11324     semaphore_signal_info.sType = VK_STRUCTURE_TYPE_SEMAPHORE_SIGNAL_INFO;
11325     semaphore_signal_info.semaphore = semaphore[0];
11326     semaphore_signal_info.value = 3;
11327     auto vkSignalSemaphoreKHR = (PFN_vkSignalSemaphoreKHR)vk::GetDeviceProcAddr(m_device->device(), "vkSignalSemaphoreKHR");
11328 
11329     semaphore_signal_info.value = 10;
11330     ASSERT_VK_SUCCESS(vkSignalSemaphoreKHR(m_device->device(), &semaphore_signal_info));
11331 
11332     VkTimelineSemaphoreSubmitInfoKHR timeline_semaphore_submit_info{};
11333     uint64_t signalValue = 20;
11334     timeline_semaphore_submit_info.sType = VK_STRUCTURE_TYPE_TIMELINE_SEMAPHORE_SUBMIT_INFO_KHR;
11335     timeline_semaphore_submit_info.waitSemaphoreValueCount = 0;
11336     timeline_semaphore_submit_info.pWaitSemaphoreValues = nullptr;
11337     // this array needs a length of 2, even though the binary semaphore won't look at the values array
11338     timeline_semaphore_submit_info.signalSemaphoreValueCount = 1;
11339     timeline_semaphore_submit_info.pSignalSemaphoreValues = &signalValue;
11340 
11341     VkPipelineStageFlags stageFlags = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT;
11342     VkSubmitInfo submit_info{};
11343     submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
11344     submit_info.pNext = &timeline_semaphore_submit_info;
11345     submit_info.pWaitDstStageMask = &stageFlags;
11346     submit_info.waitSemaphoreCount = 0;
11347     submit_info.pWaitSemaphores = nullptr;
11348     submit_info.signalSemaphoreCount = 2;
11349     submit_info.pSignalSemaphores = semaphore;
11350     m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkSubmitInfo-pNext-03241");
11351     vk::QueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
11352     m_errorMonitor->VerifyFound();
11353 
11354     uint64_t values[2] = {signalValue, 0 /*ignored*/};
11355     timeline_semaphore_submit_info.signalSemaphoreValueCount = 2;
11356     timeline_semaphore_submit_info.pSignalSemaphoreValues = values;
11357     m_errorMonitor->ExpectSuccess();
11358     vk::QueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
11359     m_errorMonitor->VerifyNotFound();
11360 
11361     // the indexes in pWaitSemaphores and pWaitSemaphoreValues should match
11362     VkSemaphore reversed[2] = {semaphore[1], semaphore[0]};
11363     uint64_t reversed_values[2] = {UINT64_MAX /* ignored */, 20};
11364     VkPipelineStageFlags wait_stages[2] = {VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT};
11365     submit_info.signalSemaphoreCount = 0;
11366     submit_info.pSignalSemaphores = nullptr;
11367     submit_info.waitSemaphoreCount = 2;
11368     submit_info.pWaitSemaphores = reversed;
11369     submit_info.pWaitDstStageMask = wait_stages;
11370     timeline_semaphore_submit_info.signalSemaphoreValueCount = 0;
11371     timeline_semaphore_submit_info.pSignalSemaphoreValues = nullptr;
11372     timeline_semaphore_submit_info.waitSemaphoreValueCount = 2;
11373     timeline_semaphore_submit_info.pWaitSemaphoreValues = reversed_values;
11374     m_errorMonitor->ExpectSuccess();
11375     vk::QueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
11376     m_errorMonitor->VerifyNotFound();
11377 
11378     // if we only signal a binary semaphore we don't need a 'values' array
11379     timeline_semaphore_submit_info.waitSemaphoreValueCount = 0;
11380     timeline_semaphore_submit_info.pWaitSemaphoreValues = nullptr;
11381     timeline_semaphore_submit_info.signalSemaphoreValueCount = 0;
11382     timeline_semaphore_submit_info.pSignalSemaphoreValues = nullptr;
11383     submit_info.waitSemaphoreCount = 0;
11384     submit_info.pWaitSemaphores = nullptr;
11385     submit_info.signalSemaphoreCount = 1;
11386     submit_info.pSignalSemaphores = &extra_binary;
11387     m_errorMonitor->ExpectSuccess();
11388     vk::QueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
11389     m_errorMonitor->VerifyNotFound();
11390 
11391     ASSERT_VK_SUCCESS(vk::QueueWaitIdle(m_device->m_queue));
11392     vk::DestroySemaphore(m_device->device(), semaphore[0], nullptr);
11393     vk::DestroySemaphore(m_device->device(), semaphore[1], nullptr);
11394     vk::DestroySemaphore(m_device->device(), extra_binary, nullptr);
11395 }
11396 
TEST_F(VkLayerTest,ValidateExtendedDynamicState2Disabled)11397 TEST_F(VkLayerTest, ValidateExtendedDynamicState2Disabled) {
11398     TEST_DESCRIPTION("Validate VK_EXT_extended_dynamic_state2 VUs");
11399 
11400     uint32_t version = SetTargetApiVersion(VK_API_VERSION_1_1);
11401     if (version < VK_API_VERSION_1_1) {
11402         printf("%s At least Vulkan version 1.1 is required, skipping test.\n", kSkipPrefix);
11403         return;
11404     }
11405 
11406     ASSERT_NO_FATAL_FAILURE(InitFramework(m_errorMonitor));
11407     if (DeviceValidationVersion() < VK_API_VERSION_1_1) {
11408         printf("%s Test requires Vulkan 1.1+, skipping test\n", kSkipPrefix);
11409         return;
11410     }
11411     if (DeviceExtensionSupported(gpu(), nullptr, VK_EXT_EXTENDED_DYNAMIC_STATE_2_EXTENSION_NAME)) {
11412         m_device_extension_names.push_back(VK_EXT_EXTENDED_DYNAMIC_STATE_2_EXTENSION_NAME);
11413     } else {
11414         printf("%s Extension %s is not supported.\n", kSkipPrefix, VK_EXT_EXTENDED_DYNAMIC_STATE_2_EXTENSION_NAME);
11415         return;
11416     }
11417 
11418     auto extended_dynamic_state2_features = LvlInitStruct<VkPhysicalDeviceExtendedDynamicState2FeaturesEXT>();
11419     auto features2 = LvlInitStruct<VkPhysicalDeviceFeatures2>(&extended_dynamic_state2_features);
11420     vk::GetPhysicalDeviceFeatures2(gpu(), &features2);
11421     if (!extended_dynamic_state2_features.extendedDynamicState2) {
11422         printf("%s Test requires (unsupported) extendedDynamicState2, skipping\n", kSkipPrefix);
11423         return;
11424     }
11425 
11426     // Attempt using VK_EXT_extended_dynamic_state2 without it being enabled.
11427     extended_dynamic_state2_features.extendedDynamicState2 = VK_FALSE;
11428     ASSERT_NO_FATAL_FAILURE(InitState(nullptr, &features2));
11429 
11430     auto vkCmdSetRasterizerDiscardEnableEXT =
11431         (PFN_vkCmdSetRasterizerDiscardEnableEXT)vk::GetDeviceProcAddr(m_device->device(), "vkCmdSetRasterizerDiscardEnableEXT");
11432     auto vkCmdSetDepthBiasEnableEXT =
11433         (PFN_vkCmdSetDepthBiasEnableEXT)vk::GetDeviceProcAddr(m_device->device(), "vkCmdSetDepthBiasEnableEXT");
11434     auto vkCmdSetPrimitiveRestartEnableEXT =
11435         (PFN_vkCmdSetPrimitiveRestartEnableEXT)vk::GetDeviceProcAddr(m_device->device(), "vkCmdSetPrimitiveRestartEnableEXT");
11436 
11437     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
11438 
11439     CreatePipelineHelper pipe(*this);
11440     pipe.InitInfo();
11441     const VkDynamicState dyn_states[] = {VK_DYNAMIC_STATE_RASTERIZER_DISCARD_ENABLE_EXT, VK_DYNAMIC_STATE_DEPTH_BIAS_ENABLE_EXT,
11442                                          VK_DYNAMIC_STATE_PRIMITIVE_RESTART_ENABLE_EXT};
11443     auto dyn_state_ci = LvlInitStruct<VkPipelineDynamicStateCreateInfo>();
11444     dyn_state_ci.dynamicStateCount = size(dyn_states);
11445     dyn_state_ci.pDynamicStates = dyn_states;
11446     pipe.dyn_state_ci_ = dyn_state_ci;
11447     pipe.InitState();
11448     m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkGraphicsPipelineCreateInfo-pDynamicStates-04868");
11449     pipe.CreateGraphicsPipeline();
11450     m_errorMonitor->VerifyFound();
11451 
11452     VkCommandBufferObj m_commandBuffer(m_device, m_commandPool);
11453     m_commandBuffer.begin();
11454 
11455     m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdSetRasterizerDiscardEnableEXT-None-04871");
11456     vkCmdSetRasterizerDiscardEnableEXT(m_commandBuffer.handle(), VK_TRUE);
11457     m_errorMonitor->VerifyFound();
11458 
11459     m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdSetDepthBiasEnableEXT-None-04872");
11460     vkCmdSetDepthBiasEnableEXT(m_commandBuffer.handle(), VK_TRUE);
11461     m_errorMonitor->VerifyFound();
11462 
11463     m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdSetPrimitiveRestartEnableEXT-None-04866");
11464     vkCmdSetPrimitiveRestartEnableEXT(m_commandBuffer.handle(), VK_TRUE);
11465     m_errorMonitor->VerifyFound();
11466 
11467     m_commandBuffer.end();
11468 }
11469 
TEST_F(VkLayerTest,ValidateExtendedDynamicState2PatchControlPointsDisabled)11470 TEST_F(VkLayerTest, ValidateExtendedDynamicState2PatchControlPointsDisabled) {
11471     TEST_DESCRIPTION("Validate VK_EXT_extended_dynamic_state2 PatchControlPoints VUs");
11472 
11473     uint32_t version = SetTargetApiVersion(VK_API_VERSION_1_1);
11474     if (version < VK_API_VERSION_1_1) {
11475         printf("%s At least Vulkan version 1.1 is required, skipping test.\n", kSkipPrefix);
11476         return;
11477     }
11478 
11479     ASSERT_NO_FATAL_FAILURE(InitFramework(m_errorMonitor));
11480     if (DeviceValidationVersion() < VK_API_VERSION_1_1) {
11481         printf("%s Test requires Vulkan 1.1+, skipping test\n", kSkipPrefix);
11482         return;
11483     }
11484     if (DeviceExtensionSupported(gpu(), nullptr, VK_EXT_EXTENDED_DYNAMIC_STATE_2_EXTENSION_NAME)) {
11485         m_device_extension_names.push_back(VK_EXT_EXTENDED_DYNAMIC_STATE_2_EXTENSION_NAME);
11486     } else {
11487         printf("%s Extension %s is not supported.\n", kSkipPrefix, VK_EXT_EXTENDED_DYNAMIC_STATE_2_EXTENSION_NAME);
11488         return;
11489     }
11490 
11491     auto extended_dynamic_state2_features = LvlInitStruct<VkPhysicalDeviceExtendedDynamicState2FeaturesEXT>();
11492     auto features2 = LvlInitStruct<VkPhysicalDeviceFeatures2>(&extended_dynamic_state2_features);
11493     vk::GetPhysicalDeviceFeatures2(gpu(), &features2);
11494     if (!extended_dynamic_state2_features.extendedDynamicState2PatchControlPoints) {
11495         printf("%s Test requires (unsupported) extendedDynamicState2LogicOp, skipping\n", kSkipPrefix);
11496         return;
11497     }
11498 
11499     // Attempt using VK_EXT_extended_dynamic_state2 without it being enabled.
11500     extended_dynamic_state2_features.extendedDynamicState2PatchControlPoints = VK_FALSE;
11501     ASSERT_NO_FATAL_FAILURE(InitState(nullptr, &features2));
11502 
11503     auto vkCmdSetPatchControlPointsEXT =
11504         (PFN_vkCmdSetPatchControlPointsEXT)vk::GetDeviceProcAddr(m_device->device(), "vkCmdSetPatchControlPointsEXT");
11505 
11506     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
11507 
11508     CreatePipelineHelper pipe(*this);
11509     pipe.InitInfo();
11510     const VkDynamicState dyn_states[] = {VK_DYNAMIC_STATE_PATCH_CONTROL_POINTS_EXT};
11511     auto dyn_state_ci = LvlInitStruct<VkPipelineDynamicStateCreateInfo>();
11512     dyn_state_ci.dynamicStateCount = size(dyn_states);
11513     dyn_state_ci.pDynamicStates = dyn_states;
11514     pipe.dyn_state_ci_ = dyn_state_ci;
11515     pipe.InitState();
11516     m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkGraphicsPipelineCreateInfo-pDynamicStates-04870");
11517     pipe.CreateGraphicsPipeline();
11518     m_errorMonitor->VerifyFound();
11519 
11520     VkCommandBufferObj m_commandBuffer(m_device, m_commandPool);
11521     m_commandBuffer.begin();
11522 
11523     m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdSetPatchControlPointsEXT-None-04873");
11524     vkCmdSetPatchControlPointsEXT(m_commandBuffer.handle(), 3);
11525     m_errorMonitor->VerifyFound();
11526 
11527     m_commandBuffer.end();
11528 }
11529 
TEST_F(VkLayerTest,ValidateExtendedDynamicState2LogicOpDisabled)11530 TEST_F(VkLayerTest, ValidateExtendedDynamicState2LogicOpDisabled) {
11531     TEST_DESCRIPTION("Validate VK_EXT_extended_dynamic_state2LogicOp VUs");
11532 
11533     uint32_t version = SetTargetApiVersion(VK_API_VERSION_1_1);
11534     if (version < VK_API_VERSION_1_1) {
11535         printf("%s At least Vulkan version 1.1 is required, skipping test.\n", kSkipPrefix);
11536         return;
11537     }
11538 
11539     ASSERT_NO_FATAL_FAILURE(InitFramework(m_errorMonitor));
11540     if (DeviceValidationVersion() < VK_API_VERSION_1_1) {
11541         printf("%s Test requires Vulkan 1.1+, skipping test\n", kSkipPrefix);
11542         return;
11543     }
11544     if (DeviceExtensionSupported(gpu(), nullptr, VK_EXT_EXTENDED_DYNAMIC_STATE_2_EXTENSION_NAME)) {
11545         m_device_extension_names.push_back(VK_EXT_EXTENDED_DYNAMIC_STATE_2_EXTENSION_NAME);
11546     } else {
11547         printf("%s Extension %s is not supported.\n", kSkipPrefix, VK_EXT_EXTENDED_DYNAMIC_STATE_2_EXTENSION_NAME);
11548         return;
11549     }
11550 
11551     auto extended_dynamic_state2_features = LvlInitStruct<VkPhysicalDeviceExtendedDynamicState2FeaturesEXT>();
11552     auto features2 = LvlInitStruct<VkPhysicalDeviceFeatures2>(&extended_dynamic_state2_features);
11553     vk::GetPhysicalDeviceFeatures2(gpu(), &features2);
11554     if (!extended_dynamic_state2_features.extendedDynamicState2LogicOp) {
11555         printf("%s Test requires (unsupported) extendedDynamicState2LogicOp, skipping\n", kSkipPrefix);
11556         return;
11557     }
11558 
11559     // Attempt using VK_EXT_extended_dynamic_state2 without it being enabled.
11560     extended_dynamic_state2_features.extendedDynamicState2LogicOp = VK_FALSE;
11561     ASSERT_NO_FATAL_FAILURE(InitState(nullptr, &features2));
11562 
11563     auto vkCmdSetLogicOpEXT = (PFN_vkCmdSetLogicOpEXT)vk::GetDeviceProcAddr(m_device->device(), "vkCmdSetLogicOpEXT");
11564 
11565     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
11566 
11567     CreatePipelineHelper pipe(*this);
11568     pipe.InitInfo();
11569     const VkDynamicState dyn_states[] = {VK_DYNAMIC_STATE_LOGIC_OP_EXT};
11570     auto dyn_state_ci = LvlInitStruct<VkPipelineDynamicStateCreateInfo>();
11571     dyn_state_ci.dynamicStateCount = size(dyn_states);
11572     dyn_state_ci.pDynamicStates = dyn_states;
11573     pipe.dyn_state_ci_ = dyn_state_ci;
11574     pipe.InitState();
11575     m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkGraphicsPipelineCreateInfo-pDynamicStates-04869");
11576     pipe.CreateGraphicsPipeline();
11577     m_errorMonitor->VerifyFound();
11578 
11579     VkCommandBufferObj m_commandBuffer(m_device, m_commandPool);
11580     m_commandBuffer.begin();
11581 
11582     m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdSetLogicOpEXT-None-04867");
11583     vkCmdSetLogicOpEXT(m_commandBuffer.handle(), VK_LOGIC_OP_AND);
11584     m_errorMonitor->VerifyFound();
11585 
11586     m_commandBuffer.end();
11587 }
11588 
TEST_F(VkLayerTest,ValidateExtendedDynamicState2Enabled)11589 TEST_F(VkLayerTest, ValidateExtendedDynamicState2Enabled) {
11590     TEST_DESCRIPTION("Validate VK_EXT_extended_dynamic_state2 LogicOp VUs");
11591 
11592     uint32_t version = SetTargetApiVersion(VK_API_VERSION_1_1);
11593     if (version < VK_API_VERSION_1_1) {
11594         printf("%s At least Vulkan version 1.1 is required, skipping test.\n", kSkipPrefix);
11595         return;
11596     }
11597 
11598     ASSERT_NO_FATAL_FAILURE(InitFramework(m_errorMonitor));
11599     if (DeviceValidationVersion() < VK_API_VERSION_1_1) {
11600         printf("%s Test requires Vulkan 1.1+, skipping test\n", kSkipPrefix);
11601         return;
11602     }
11603     if (DeviceExtensionSupported(gpu(), nullptr, VK_EXT_EXTENDED_DYNAMIC_STATE_2_EXTENSION_NAME)) {
11604         m_device_extension_names.push_back(VK_EXT_EXTENDED_DYNAMIC_STATE_2_EXTENSION_NAME);
11605     } else {
11606         printf("%s Extension %s is not supported.\n", kSkipPrefix, VK_EXT_EXTENDED_DYNAMIC_STATE_2_EXTENSION_NAME);
11607         return;
11608     }
11609 
11610     auto extended_dynamic_state2_features = LvlInitStruct<VkPhysicalDeviceExtendedDynamicState2FeaturesEXT>();
11611     auto features2 = LvlInitStruct<VkPhysicalDeviceFeatures2>(&extended_dynamic_state2_features);
11612     vk::GetPhysicalDeviceFeatures2(gpu(), &features2);
11613     if (!extended_dynamic_state2_features.extendedDynamicState2) {
11614         printf("%s Test requires (unsupported) extendedDynamicState2, skipping\n", kSkipPrefix);
11615         return;
11616     }
11617 
11618     ASSERT_NO_FATAL_FAILURE(InitState(nullptr, &features2));
11619     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
11620 
11621     const VkDynamicState dyn_states[] = {VK_DYNAMIC_STATE_RASTERIZER_DISCARD_ENABLE_EXT, VK_DYNAMIC_STATE_DEPTH_BIAS_ENABLE_EXT,
11622                                          VK_DYNAMIC_STATE_PRIMITIVE_RESTART_ENABLE_EXT};
11623 
11624     for (size_t i = 0; i < size(dyn_states); ++i) {
11625         // Verify duplicates of every dynamic state.
11626         {
11627             CreatePipelineHelper pipe(*this);
11628             pipe.InitInfo();
11629             auto dyn_state_ci = LvlInitStruct<VkPipelineDynamicStateCreateInfo>();
11630             dyn_state_ci.dynamicStateCount = 2;
11631             VkDynamicState dyn_state_dupes[2] = {dyn_states[i], dyn_states[i]};
11632             dyn_state_ci.pDynamicStates = dyn_state_dupes;
11633             pipe.dyn_state_ci_ = dyn_state_ci;
11634             pipe.InitState();
11635             m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkPipelineDynamicStateCreateInfo-pDynamicStates-01442");
11636             pipe.CreateGraphicsPipeline();
11637             m_errorMonitor->VerifyFound();
11638         }
11639 
11640         // Calling draw without setting the dynamic state is an error
11641         {
11642             CreatePipelineHelper pipe2(*this);
11643             pipe2.InitInfo();
11644             auto dyn_state_ci = LvlInitStruct<VkPipelineDynamicStateCreateInfo>();
11645             dyn_state_ci.dynamicStateCount = 1;
11646             dyn_state_ci.pDynamicStates = &dyn_states[i];
11647             pipe2.dyn_state_ci_ = dyn_state_ci;
11648             pipe2.InitState();
11649             pipe2.CreateGraphicsPipeline();
11650 
11651             VkCommandBufferObj m_commandBuffer(m_device, m_commandPool);
11652             m_commandBuffer.begin();
11653             m_commandBuffer.BeginRenderPass(m_renderPassBeginInfo);
11654 
11655             vk::CmdBindPipeline(m_commandBuffer.handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe2.pipeline_);
11656 
11657             if (dyn_states[i] == VK_DYNAMIC_STATE_RASTERIZER_DISCARD_ENABLE_EXT)
11658                 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdDraw-None-04876");
11659             if (dyn_states[i] == VK_DYNAMIC_STATE_DEPTH_BIAS_ENABLE_EXT)
11660                 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdDraw-None-04877");
11661             if (dyn_states[i] == VK_DYNAMIC_STATE_PRIMITIVE_RESTART_ENABLE_EXT)
11662                 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdDraw-None-04879");
11663             vk::CmdDraw(m_commandBuffer.handle(), 1, 1, 0, 0);
11664             m_errorMonitor->VerifyFound();
11665             vk::CmdEndRenderPass(m_commandBuffer.handle());
11666             m_commandBuffer.end();
11667         }
11668     }
11669 }
11670 
TEST_F(VkLayerTest,ValidateExtendedDynamicState2PatchControlPointsEnabled)11671 TEST_F(VkLayerTest, ValidateExtendedDynamicState2PatchControlPointsEnabled) {
11672     TEST_DESCRIPTION("Validate VK_EXT_extended_dynamic_state2 PatchControlPoints VUs");
11673 
11674     uint32_t version = SetTargetApiVersion(VK_API_VERSION_1_1);
11675     if (version < VK_API_VERSION_1_1) {
11676         printf("%s At least Vulkan version 1.1 is required, skipping test.\n", kSkipPrefix);
11677         return;
11678     }
11679 
11680     ASSERT_NO_FATAL_FAILURE(InitFramework(m_errorMonitor));
11681     if (DeviceValidationVersion() < VK_API_VERSION_1_1) {
11682         printf("%s Test requires Vulkan 1.1+, skipping test\n", kSkipPrefix);
11683         return;
11684     }
11685     if (DeviceExtensionSupported(gpu(), nullptr, VK_EXT_EXTENDED_DYNAMIC_STATE_2_EXTENSION_NAME)) {
11686         m_device_extension_names.push_back(VK_EXT_EXTENDED_DYNAMIC_STATE_2_EXTENSION_NAME);
11687     } else {
11688         printf("%s Extension %s is not supported.\n", kSkipPrefix, VK_EXT_EXTENDED_DYNAMIC_STATE_2_EXTENSION_NAME);
11689         return;
11690     }
11691 
11692     auto extended_dynamic_state2_features = LvlInitStruct<VkPhysicalDeviceExtendedDynamicState2FeaturesEXT>();
11693     auto features2 = LvlInitStruct<VkPhysicalDeviceFeatures2>(&extended_dynamic_state2_features);
11694     vk::GetPhysicalDeviceFeatures2(gpu(), &features2);
11695     if (!extended_dynamic_state2_features.extendedDynamicState2PatchControlPoints) {
11696         printf("%s Test requires (unsupported) extendedDynamicState2PatchControlPoints, skipping\n", kSkipPrefix);
11697         return;
11698     }
11699 
11700     ASSERT_NO_FATAL_FAILURE(InitState(nullptr, &features2));
11701     auto vkCmdSetPatchControlPointsEXT =
11702         (PFN_vkCmdSetPatchControlPointsEXT)vk::GetDeviceProcAddr(m_device->device(), "vkCmdSetPatchControlPointsEXT");
11703 
11704     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
11705 
11706     const VkDynamicState dyn_states[] = {VK_DYNAMIC_STATE_PATCH_CONTROL_POINTS_EXT};
11707 
11708     // Verify dupes of the dynamic state.
11709     for (size_t i = 0; i < size(dyn_states); ++i) {
11710         CreatePipelineHelper pipe(*this);
11711         pipe.InitInfo();
11712         auto dyn_state_ci = LvlInitStruct<VkPipelineDynamicStateCreateInfo>();
11713         dyn_state_ci.dynamicStateCount = 2;
11714         VkDynamicState dyn_state_dupes[2] = {dyn_states[i], dyn_states[i]};
11715         dyn_state_ci.pDynamicStates = dyn_state_dupes;
11716         pipe.dyn_state_ci_ = dyn_state_ci;
11717         pipe.InitState();
11718         m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkPipelineDynamicStateCreateInfo-pDynamicStates-01442");
11719         pipe.CreateGraphicsPipeline();
11720         m_errorMonitor->VerifyFound();
11721     }
11722 
11723     {
11724         CreatePipelineHelper pipe(*this);
11725         pipe.InitInfo();
11726         auto dyn_state_ci = LvlInitStruct<VkPipelineDynamicStateCreateInfo>();
11727         dyn_state_ci.dynamicStateCount = size(dyn_states);
11728         dyn_state_ci.pDynamicStates = dyn_states;
11729         pipe.dyn_state_ci_ = dyn_state_ci;
11730         pipe.InitState();
11731         pipe.CreateGraphicsPipeline();
11732 
11733         VkCommandBufferObj m_commandBuffer(m_device, m_commandPool);
11734         m_commandBuffer.begin();
11735         m_commandBuffer.BeginRenderPass(m_renderPassBeginInfo);
11736 
11737         vk::CmdBindPipeline(m_commandBuffer.handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.pipeline_);
11738 
11739         // Calling draw without setting the dynamic state is an error
11740         m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdDraw-None-04875");
11741         vk::CmdDraw(m_commandBuffer.handle(), 1, 1, 0, 0);
11742         m_errorMonitor->VerifyFound();
11743 
11744         // setting an invalid value for patchControlpoints is an error
11745         m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdSetPatchControlPointsEXT-patchControlPoints-04874");
11746         vkCmdSetPatchControlPointsEXT(m_commandBuffer.handle(), 0x1000);
11747         m_errorMonitor->VerifyFound();
11748         vk::CmdEndRenderPass(m_commandBuffer.handle());
11749         m_commandBuffer.end();
11750     }
11751 }
11752 
TEST_F(VkLayerTest,ValidateExtendedDynamicState2LogicOpEnabled)11753 TEST_F(VkLayerTest, ValidateExtendedDynamicState2LogicOpEnabled) {
11754     TEST_DESCRIPTION("Validate VK_EXT_extended_dynamic_state2 LogicOp VUs");
11755 
11756     uint32_t version = SetTargetApiVersion(VK_API_VERSION_1_1);
11757     if (version < VK_API_VERSION_1_1) {
11758         printf("%s At least Vulkan version 1.1 is required, skipping test.\n", kSkipPrefix);
11759         return;
11760     }
11761 
11762     ASSERT_NO_FATAL_FAILURE(InitFramework(m_errorMonitor));
11763     if (DeviceValidationVersion() < VK_API_VERSION_1_1) {
11764         printf("%s Test requires Vulkan 1.1+, skipping test\n", kSkipPrefix);
11765         return;
11766     }
11767     if (DeviceExtensionSupported(gpu(), nullptr, VK_EXT_EXTENDED_DYNAMIC_STATE_2_EXTENSION_NAME)) {
11768         m_device_extension_names.push_back(VK_EXT_EXTENDED_DYNAMIC_STATE_2_EXTENSION_NAME);
11769     } else {
11770         printf("%s Extension %s is not supported.\n", kSkipPrefix, VK_EXT_EXTENDED_DYNAMIC_STATE_2_EXTENSION_NAME);
11771         return;
11772     }
11773 
11774     auto extended_dynamic_state2_features = LvlInitStruct<VkPhysicalDeviceExtendedDynamicState2FeaturesEXT>();
11775     auto features2 = LvlInitStruct<VkPhysicalDeviceFeatures2>(&extended_dynamic_state2_features);
11776     vk::GetPhysicalDeviceFeatures2(gpu(), &features2);
11777     if (!extended_dynamic_state2_features.extendedDynamicState2LogicOp) {
11778         printf("%s Test requires (unsupported) extendedDynamicState2LogicOp, skipping\n", kSkipPrefix);
11779         return;
11780     }
11781 
11782     ASSERT_NO_FATAL_FAILURE(InitState(nullptr, &features2));
11783 
11784     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
11785 
11786     const VkDynamicState dyn_states[] = {VK_DYNAMIC_STATE_LOGIC_OP_EXT};
11787 
11788     // Verify dupes of the dynamic state.
11789     for (size_t i = 0; i < size(dyn_states); ++i) {
11790         CreatePipelineHelper pipe(*this);
11791         pipe.InitInfo();
11792         auto dyn_state_ci = LvlInitStruct<VkPipelineDynamicStateCreateInfo>();
11793         dyn_state_ci.dynamicStateCount = 2;
11794         VkDynamicState dyn_state_dupes[2] = {dyn_states[i], dyn_states[i]};
11795         dyn_state_ci.pDynamicStates = dyn_state_dupes;
11796         pipe.dyn_state_ci_ = dyn_state_ci;
11797         pipe.InitState();
11798         m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkPipelineDynamicStateCreateInfo-pDynamicStates-01442");
11799         pipe.CreateGraphicsPipeline();
11800         m_errorMonitor->VerifyFound();
11801     }
11802 
11803     {
11804         CreatePipelineHelper pipe(*this);
11805         pipe.InitInfo();
11806         auto dyn_state_ci = LvlInitStruct<VkPipelineDynamicStateCreateInfo>();
11807         dyn_state_ci.dynamicStateCount = size(dyn_states);
11808         dyn_state_ci.pDynamicStates = dyn_states;
11809         pipe.dyn_state_ci_ = dyn_state_ci;
11810         pipe.InitState();
11811         pipe.CreateGraphicsPipeline();
11812 
11813         VkCommandBufferObj m_commandBuffer(m_device, m_commandPool);
11814         m_commandBuffer.begin();
11815         m_commandBuffer.BeginRenderPass(m_renderPassBeginInfo);
11816 
11817         vk::CmdBindPipeline(m_commandBuffer.handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.pipeline_);
11818 
11819         // Calling draw without setting the dynamic state is an error
11820         m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdDraw-logicOp-04878");
11821         vk::CmdDraw(m_commandBuffer.handle(), 1, 1, 0, 0);
11822         m_errorMonitor->VerifyFound();
11823         vk::CmdEndRenderPass(m_commandBuffer.handle());
11824         m_commandBuffer.end();
11825     }
11826 }
11827 
TEST_F(VkLayerTest,ValidateVertexInputDynamicStateDisabled)11828 TEST_F(VkLayerTest, ValidateVertexInputDynamicStateDisabled) {
11829     TEST_DESCRIPTION("Validate VK_EXT_vertex_input_dynamic_state VUs when disabled");
11830 
11831     uint32_t version = SetTargetApiVersion(VK_API_VERSION_1_1);
11832     if (version < VK_API_VERSION_1_1) {
11833         printf("%s At least Vulkan version 1.1 is required, skipping test.\n", kSkipPrefix);
11834         return;
11835     }
11836 
11837     ASSERT_NO_FATAL_FAILURE(InitFramework(m_errorMonitor));
11838     if (DeviceValidationVersion() < VK_API_VERSION_1_1) {
11839         printf("%s Test requires Vulkan 1.1+, skipping test\n", kSkipPrefix);
11840         return;
11841     }
11842     if (DeviceExtensionSupported(gpu(), nullptr, VK_EXT_VERTEX_INPUT_DYNAMIC_STATE_EXTENSION_NAME)) {
11843         m_device_extension_names.push_back(VK_EXT_VERTEX_INPUT_DYNAMIC_STATE_EXTENSION_NAME);
11844     } else {
11845         printf("%s Extension %s is not supported.\n", kSkipPrefix, VK_EXT_VERTEX_INPUT_DYNAMIC_STATE_EXTENSION_NAME);
11846         return;
11847     }
11848 
11849     ASSERT_NO_FATAL_FAILURE(InitState());
11850 
11851     auto vkCmdSetVertexInputEXT = (PFN_vkCmdSetVertexInputEXT)vk::GetDeviceProcAddr(m_device->device(), "vkCmdSetVertexInputEXT");
11852 
11853     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
11854 
11855     // VUID-VkGraphicsPipelineCreateInfo-pDynamicStates-04807
11856     CreatePipelineHelper pipe(*this);
11857     pipe.InitInfo();
11858     const VkDynamicState dyn_states[] = {VK_DYNAMIC_STATE_VERTEX_INPUT_EXT};
11859     auto dyn_state_ci = LvlInitStruct<VkPipelineDynamicStateCreateInfo>();
11860     dyn_state_ci.dynamicStateCount = size(dyn_states);
11861     dyn_state_ci.pDynamicStates = dyn_states;
11862     pipe.dyn_state_ci_ = dyn_state_ci;
11863     pipe.InitState();
11864     m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkGraphicsPipelineCreateInfo-pDynamicStates-04807");
11865     pipe.CreateGraphicsPipeline();
11866     m_errorMonitor->VerifyFound();
11867 
11868     m_commandBuffer->begin();
11869 
11870     // VUID-vkCmdSetVertexInputEXT-None-04790
11871     m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdSetVertexInputEXT-None-04790");
11872     vkCmdSetVertexInputEXT(m_commandBuffer->handle(), 0, nullptr, 0, nullptr);
11873     m_errorMonitor->VerifyFound();
11874 
11875     m_commandBuffer->end();
11876 }
11877 
TEST_F(VkLayerTest,ValidateVertexInputDynamicStateEnabled)11878 TEST_F(VkLayerTest, ValidateVertexInputDynamicStateEnabled) {
11879     TEST_DESCRIPTION("Validate VK_EXT_vertex_input_dynamic_state VUs when enabled");
11880 
11881     uint32_t version = SetTargetApiVersion(VK_API_VERSION_1_1);
11882     if (version < VK_API_VERSION_1_1) {
11883         printf("%s At least Vulkan version 1.1 is required, skipping test.\n", kSkipPrefix);
11884         return;
11885     }
11886 
11887     ASSERT_NO_FATAL_FAILURE(InitFramework(m_errorMonitor));
11888     if (DeviceValidationVersion() < VK_API_VERSION_1_1) {
11889         printf("%s Test requires Vulkan 1.1+, skipping test\n", kSkipPrefix);
11890         return;
11891     }
11892     if (DeviceExtensionSupported(gpu(), nullptr, VK_EXT_VERTEX_INPUT_DYNAMIC_STATE_EXTENSION_NAME)) {
11893         m_device_extension_names.push_back(VK_EXT_VERTEX_INPUT_DYNAMIC_STATE_EXTENSION_NAME);
11894     } else {
11895         printf("%s Extension %s is not supported.\n", kSkipPrefix, VK_EXT_VERTEX_INPUT_DYNAMIC_STATE_EXTENSION_NAME);
11896         return;
11897     }
11898 
11899     auto vertex_input_dynamic_state_features = LvlInitStruct<VkPhysicalDeviceVertexInputDynamicStateFeaturesEXT>();
11900     auto features2 = LvlInitStruct<VkPhysicalDeviceFeatures2>(&vertex_input_dynamic_state_features);
11901     vk::GetPhysicalDeviceFeatures2(gpu(), &features2);
11902     if (!vertex_input_dynamic_state_features.vertexInputDynamicState) {
11903         printf("%s Test requires (unsupported) vertexInputDynamicState, skipping\n", kSkipPrefix);
11904         return;
11905     }
11906 
11907     ASSERT_NO_FATAL_FAILURE(InitState(nullptr, &features2));
11908 
11909     auto vkCmdSetVertexInputEXT = (PFN_vkCmdSetVertexInputEXT)vk::GetDeviceProcAddr(m_device->device(), "vkCmdSetVertexInputEXT");
11910 
11911     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
11912 
11913     // VUID-VkPipelineDynamicStateCreateInfo-pDynamicStates-01442
11914     CreatePipelineHelper pipe(*this);
11915     pipe.InitInfo();
11916     const VkDynamicState dyn_states[] = {VK_DYNAMIC_STATE_VERTEX_INPUT_EXT, VK_DYNAMIC_STATE_VERTEX_INPUT_EXT};
11917     auto dyn_state_ci = LvlInitStruct<VkPipelineDynamicStateCreateInfo>();
11918     dyn_state_ci.dynamicStateCount = size(dyn_states);
11919     dyn_state_ci.pDynamicStates = dyn_states;
11920     pipe.dyn_state_ci_ = dyn_state_ci;
11921     pipe.InitState();
11922     m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkPipelineDynamicStateCreateInfo-pDynamicStates-01442");
11923     pipe.CreateGraphicsPipeline();
11924     m_errorMonitor->VerifyFound();
11925 
11926     m_commandBuffer->begin();
11927 
11928     // VUID-vkCmdSetVertexInputEXT-vertexBindingDescriptionCount-04791
11929     {
11930         VkVertexInputBindingDescription2EXT binding = {
11931             VK_STRUCTURE_TYPE_VERTEX_INPUT_BINDING_DESCRIPTION_2_EXT, nullptr, 0, 0, VK_VERTEX_INPUT_RATE_VERTEX, 1};
11932         std::vector<VkVertexInputBindingDescription2EXT> bindings(m_device->props.limits.maxVertexInputBindings + 1u, binding);
11933         for (uint32_t i = 0; i < bindings.size(); ++i) bindings[i].binding = i;
11934         m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdSetVertexInputEXT-vertexBindingDescriptionCount-04791");
11935         vkCmdSetVertexInputEXT(m_commandBuffer->handle(), m_device->props.limits.maxVertexInputBindings + 1u, bindings.data(), 0,
11936                                nullptr);
11937         m_errorMonitor->VerifyFound();
11938     }
11939 
11940     // VUID-vkCmdSetVertexInputEXT-vertexAttributeDescriptionCount-04792
11941     {
11942         VkVertexInputBindingDescription2EXT binding = {
11943             VK_STRUCTURE_TYPE_VERTEX_INPUT_BINDING_DESCRIPTION_2_EXT, nullptr, 0, 0, VK_VERTEX_INPUT_RATE_VERTEX, 1};
11944         VkVertexInputAttributeDescription2EXT attribute = {
11945             VK_STRUCTURE_TYPE_VERTEX_INPUT_ATTRIBUTE_DESCRIPTION_2_EXT, nullptr, 0, 0, VK_FORMAT_R32G32B32A32_SFLOAT, 0};
11946         std::vector<VkVertexInputAttributeDescription2EXT> attributes(m_device->props.limits.maxVertexInputAttributes + 1u,
11947                                                                       attribute);
11948         for (uint32_t i = 0; i < attributes.size(); ++i) attributes[i].location = i;
11949         m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdSetVertexInputEXT-vertexAttributeDescriptionCount-04792");
11950         vkCmdSetVertexInputEXT(m_commandBuffer->handle(), 1, &binding, m_device->props.limits.maxVertexInputAttributes + 1u,
11951                                attributes.data());
11952         m_errorMonitor->VerifyFound();
11953     }
11954 
11955     // VUID-vkCmdSetVertexInputEXT-binding-04793
11956     {
11957         VkVertexInputBindingDescription2EXT binding = {
11958             VK_STRUCTURE_TYPE_VERTEX_INPUT_BINDING_DESCRIPTION_2_EXT, nullptr, 0, 0, VK_VERTEX_INPUT_RATE_VERTEX, 1};
11959         VkVertexInputAttributeDescription2EXT attribute = {
11960             VK_STRUCTURE_TYPE_VERTEX_INPUT_ATTRIBUTE_DESCRIPTION_2_EXT, nullptr, 0, 1, VK_FORMAT_R32G32B32A32_SFLOAT, 0};
11961         m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdSetVertexInputEXT-binding-04793");
11962         vkCmdSetVertexInputEXT(m_commandBuffer->handle(), 1, &binding, 1, &attribute);
11963         m_errorMonitor->VerifyFound();
11964     }
11965 
11966     // VUID-vkCmdSetVertexInputEXT-pVertexBindingDescriptions-04794
11967     {
11968         VkVertexInputBindingDescription2EXT bindings[2] = {
11969             {VK_STRUCTURE_TYPE_VERTEX_INPUT_BINDING_DESCRIPTION_2_EXT, nullptr, 0, 0, VK_VERTEX_INPUT_RATE_VERTEX, 1},
11970             {VK_STRUCTURE_TYPE_VERTEX_INPUT_BINDING_DESCRIPTION_2_EXT, nullptr, 0, 0, VK_VERTEX_INPUT_RATE_VERTEX, 1}};
11971         m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdSetVertexInputEXT-pVertexBindingDescriptions-04794");
11972         vkCmdSetVertexInputEXT(m_commandBuffer->handle(), 2, bindings, 0, nullptr);
11973         m_errorMonitor->VerifyFound();
11974     }
11975 
11976     // VUID-vkCmdSetVertexInputEXT-pVertexAttributeDescriptions-04795
11977     {
11978         VkVertexInputBindingDescription2EXT binding = {
11979             VK_STRUCTURE_TYPE_VERTEX_INPUT_BINDING_DESCRIPTION_2_EXT, nullptr, 0, 0, VK_VERTEX_INPUT_RATE_VERTEX, 1};
11980         VkVertexInputAttributeDescription2EXT attributes[2] = {
11981             {VK_STRUCTURE_TYPE_VERTEX_INPUT_ATTRIBUTE_DESCRIPTION_2_EXT, nullptr, 0, 0, VK_FORMAT_R32G32B32A32_SFLOAT, 0},
11982             {VK_STRUCTURE_TYPE_VERTEX_INPUT_ATTRIBUTE_DESCRIPTION_2_EXT, nullptr, 0, 0, VK_FORMAT_R32G32B32A32_SFLOAT, 0}};
11983         m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdSetVertexInputEXT-pVertexAttributeDescriptions-04795");
11984         vkCmdSetVertexInputEXT(m_commandBuffer->handle(), 1, &binding, 2, attributes);
11985         m_errorMonitor->VerifyFound();
11986     }
11987 
11988     // VUID-VkVertexInputBindingDescription2EXT-binding-04796
11989     {
11990         VkVertexInputBindingDescription2EXT binding = {VK_STRUCTURE_TYPE_VERTEX_INPUT_BINDING_DESCRIPTION_2_EXT,
11991                                                        nullptr,
11992                                                        m_device->props.limits.maxVertexInputBindings + 1u,
11993                                                        0,
11994                                                        VK_VERTEX_INPUT_RATE_VERTEX,
11995                                                        1};
11996         m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkVertexInputBindingDescription2EXT-binding-04796");
11997         vkCmdSetVertexInputEXT(m_commandBuffer->handle(), 1, &binding, 0, nullptr);
11998         m_errorMonitor->VerifyFound();
11999     }
12000 
12001     // VUID-VkVertexInputBindingDescription2EXT-stride-04797
12002     {
12003         VkVertexInputBindingDescription2EXT binding = {VK_STRUCTURE_TYPE_VERTEX_INPUT_BINDING_DESCRIPTION_2_EXT,
12004                                                        nullptr,
12005                                                        0,
12006                                                        m_device->props.limits.maxVertexInputBindingStride + 1u,
12007                                                        VK_VERTEX_INPUT_RATE_VERTEX,
12008                                                        1};
12009         m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkVertexInputBindingDescription2EXT-stride-04797");
12010         vkCmdSetVertexInputEXT(m_commandBuffer->handle(), 1, &binding, 0, nullptr);
12011         m_errorMonitor->VerifyFound();
12012     }
12013 
12014     // VUID-VkVertexInputBindingDescription2EXT-divisor-04798
12015     {
12016         VkVertexInputBindingDescription2EXT binding = {
12017             VK_STRUCTURE_TYPE_VERTEX_INPUT_BINDING_DESCRIPTION_2_EXT, nullptr, 0, 0, VK_VERTEX_INPUT_RATE_INSTANCE, 0};
12018         m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkVertexInputBindingDescription2EXT-divisor-04798");
12019         vkCmdSetVertexInputEXT(m_commandBuffer->handle(), 1, &binding, 0, nullptr);
12020         m_errorMonitor->VerifyFound();
12021     }
12022 
12023     // VUID-VkVertexInputBindingDescription2EXT-divisor-04799
12024     {
12025         VkVertexInputBindingDescription2EXT binding = {
12026             VK_STRUCTURE_TYPE_VERTEX_INPUT_BINDING_DESCRIPTION_2_EXT, nullptr, 0, 0, VK_VERTEX_INPUT_RATE_INSTANCE, 2};
12027         m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkVertexInputBindingDescription2EXT-divisor-04799");
12028         vkCmdSetVertexInputEXT(m_commandBuffer->handle(), 1, &binding, 0, nullptr);
12029         m_errorMonitor->VerifyFound();
12030     }
12031 
12032     // VUID-VkVertexInputAttributeDescription2EXT-location-06228
12033     {
12034         VkVertexInputBindingDescription2EXT binding = {
12035             VK_STRUCTURE_TYPE_VERTEX_INPUT_BINDING_DESCRIPTION_2_EXT, nullptr, 0, 0, VK_VERTEX_INPUT_RATE_VERTEX, 1};
12036         VkVertexInputAttributeDescription2EXT attribute = {VK_STRUCTURE_TYPE_VERTEX_INPUT_ATTRIBUTE_DESCRIPTION_2_EXT,
12037                                                            nullptr,
12038                                                            m_device->props.limits.maxVertexInputAttributes + 1u,
12039                                                            0,
12040                                                            VK_FORMAT_R32G32B32A32_SFLOAT,
12041                                                            0};
12042         m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkVertexInputAttributeDescription2EXT-location-06228");
12043         vkCmdSetVertexInputEXT(m_commandBuffer->handle(), 1, &binding, 1, &attribute);
12044         m_errorMonitor->VerifyFound();
12045     }
12046 
12047     // VUID-VkVertexInputAttributeDescription2EXT-binding-06229
12048     {
12049         VkVertexInputBindingDescription2EXT binding = {
12050             VK_STRUCTURE_TYPE_VERTEX_INPUT_BINDING_DESCRIPTION_2_EXT, nullptr, 0, 0, VK_VERTEX_INPUT_RATE_VERTEX, 1};
12051         VkVertexInputAttributeDescription2EXT attribute = {VK_STRUCTURE_TYPE_VERTEX_INPUT_ATTRIBUTE_DESCRIPTION_2_EXT,
12052                                                            nullptr,
12053                                                            0,
12054                                                            m_device->props.limits.maxVertexInputBindings + 1u,
12055                                                            VK_FORMAT_R32G32B32A32_SFLOAT,
12056                                                            0};
12057         m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkVertexInputAttributeDescription2EXT-binding-06229");
12058         m_errorMonitor->SetAllowedFailureMsg("VUID-vkCmdSetVertexInputEXT-binding-04793");
12059         vkCmdSetVertexInputEXT(m_commandBuffer->handle(), 1, &binding, 1, &attribute);
12060         m_errorMonitor->VerifyFound();
12061     }
12062 
12063     // VUID-VkVertexInputAttributeDescription2EXT-offset-06230
12064     {
12065         VkVertexInputBindingDescription2EXT binding = {
12066             VK_STRUCTURE_TYPE_VERTEX_INPUT_BINDING_DESCRIPTION_2_EXT, nullptr, 0, 0, VK_VERTEX_INPUT_RATE_VERTEX, 1};
12067         VkVertexInputAttributeDescription2EXT attribute = {
12068             VK_STRUCTURE_TYPE_VERTEX_INPUT_ATTRIBUTE_DESCRIPTION_2_EXT, nullptr, 0, 0, VK_FORMAT_R32G32B32A32_SFLOAT,
12069             m_device->props.limits.maxVertexInputAttributeOffset + 1u};
12070         m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkVertexInputAttributeDescription2EXT-offset-06230");
12071         vkCmdSetVertexInputEXT(m_commandBuffer->handle(), 1, &binding, 1, &attribute);
12072         m_errorMonitor->VerifyFound();
12073     }
12074 
12075     // VUID-VkVertexInputAttributeDescription2EXT-format-04805
12076     {
12077         VkVertexInputBindingDescription2EXT binding = {
12078             VK_STRUCTURE_TYPE_VERTEX_INPUT_BINDING_DESCRIPTION_2_EXT, nullptr, 0, 0, VK_VERTEX_INPUT_RATE_VERTEX, 1};
12079         VkVertexInputAttributeDescription2EXT attribute = {
12080             VK_STRUCTURE_TYPE_VERTEX_INPUT_ATTRIBUTE_DESCRIPTION_2_EXT, nullptr, 0, 0, VK_FORMAT_D16_UNORM, 0};
12081         m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkVertexInputAttributeDescription2EXT-format-04805");
12082         vkCmdSetVertexInputEXT(m_commandBuffer->handle(), 1, &binding, 1, &attribute);
12083         m_errorMonitor->VerifyFound();
12084     }
12085 
12086     m_commandBuffer->end();
12087 }
12088 
TEST_F(VkLayerTest,ValidateVertexInputDynamicStateDivisor)12089 TEST_F(VkLayerTest, ValidateVertexInputDynamicStateDivisor) {
12090     TEST_DESCRIPTION("Validate VK_EXT_vertex_input_dynamic_state VUs when VK_EXT_vertex_attribute_divisor is enabled");
12091 
12092     uint32_t version = SetTargetApiVersion(VK_API_VERSION_1_1);
12093     if (version < VK_API_VERSION_1_1) {
12094         printf("%s At least Vulkan version 1.1 is required, skipping test.\n", kSkipPrefix);
12095         return;
12096     }
12097 
12098     ASSERT_NO_FATAL_FAILURE(InitFramework(m_errorMonitor));
12099     if (DeviceValidationVersion() < VK_API_VERSION_1_1) {
12100         printf("%s Test requires Vulkan 1.1+, skipping test\n", kSkipPrefix);
12101         return;
12102     }
12103     if (DeviceExtensionSupported(gpu(), nullptr, VK_EXT_VERTEX_ATTRIBUTE_DIVISOR_EXTENSION_NAME)) {
12104         m_device_extension_names.push_back(VK_EXT_VERTEX_ATTRIBUTE_DIVISOR_EXTENSION_NAME);
12105     } else {
12106         printf("%s Extension %s is not supported.\n", kSkipPrefix, VK_EXT_VERTEX_ATTRIBUTE_DIVISOR_EXTENSION_NAME);
12107         return;
12108     }
12109     if (DeviceExtensionSupported(gpu(), nullptr, VK_EXT_VERTEX_INPUT_DYNAMIC_STATE_EXTENSION_NAME)) {
12110         m_device_extension_names.push_back(VK_EXT_VERTEX_INPUT_DYNAMIC_STATE_EXTENSION_NAME);
12111     } else {
12112         printf("%s Extension %s is not supported.\n", kSkipPrefix, VK_EXT_VERTEX_INPUT_DYNAMIC_STATE_EXTENSION_NAME);
12113         return;
12114     }
12115 
12116     auto vertex_attribute_divisor_features = LvlInitStruct<VkPhysicalDeviceVertexAttributeDivisorFeaturesEXT>();
12117     auto vertex_input_dynamic_state_features =
12118         LvlInitStruct<VkPhysicalDeviceVertexInputDynamicStateFeaturesEXT>(&vertex_attribute_divisor_features);
12119     auto features2 = LvlInitStruct<VkPhysicalDeviceFeatures2>(&vertex_input_dynamic_state_features);
12120     vk::GetPhysicalDeviceFeatures2(gpu(), &features2);
12121     if (!vertex_attribute_divisor_features.vertexAttributeInstanceRateDivisor) {
12122         printf("%s Test requires (unsupported) vertexAttributeInstanceRateDivisor, skipping\n", kSkipPrefix);
12123         return;
12124     }
12125     if (!vertex_input_dynamic_state_features.vertexInputDynamicState) {
12126         printf("%s Test requires (unsupported) vertexInputDynamicState, skipping\n", kSkipPrefix);
12127         return;
12128     }
12129 
12130     auto vertex_attribute_divisor_properties = LvlInitStruct<VkPhysicalDeviceVertexAttributeDivisorPropertiesEXT>();
12131     auto properties2 = LvlInitStruct<VkPhysicalDeviceProperties2>(&vertex_attribute_divisor_properties);
12132     vk::GetPhysicalDeviceProperties2(gpu(), &properties2);
12133 
12134     ASSERT_NO_FATAL_FAILURE(InitState(nullptr, &features2));
12135 
12136     auto vkCmdSetVertexInputEXT = (PFN_vkCmdSetVertexInputEXT)vk::GetDeviceProcAddr(m_device->device(), "vkCmdSetVertexInputEXT");
12137 
12138     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
12139 
12140     m_commandBuffer->begin();
12141 
12142     // VUID-VkVertexInputBindingDescription2EXT-divisor-06226
12143     if (vertex_attribute_divisor_properties.maxVertexAttribDivisor < 0xFFFFFFFFu) {
12144         VkVertexInputBindingDescription2EXT binding = {
12145             VK_STRUCTURE_TYPE_VERTEX_INPUT_BINDING_DESCRIPTION_2_EXT,       nullptr, 0, 0, VK_VERTEX_INPUT_RATE_INSTANCE,
12146             vertex_attribute_divisor_properties.maxVertexAttribDivisor + 1u};
12147         m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkVertexInputBindingDescription2EXT-divisor-06226");
12148         vkCmdSetVertexInputEXT(m_commandBuffer->handle(), 1, &binding, 0, nullptr);
12149         m_errorMonitor->VerifyFound();
12150     }
12151 
12152     // VUID-VkVertexInputBindingDescription2EXT-divisor-06227
12153     {
12154         VkVertexInputBindingDescription2EXT binding = {
12155             VK_STRUCTURE_TYPE_VERTEX_INPUT_BINDING_DESCRIPTION_2_EXT,  nullptr, 0, 0, VK_VERTEX_INPUT_RATE_VERTEX,
12156             vertex_attribute_divisor_properties.maxVertexAttribDivisor};
12157         m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkVertexInputBindingDescription2EXT-divisor-06227");
12158         vkCmdSetVertexInputEXT(m_commandBuffer->handle(), 1, &binding, 0, nullptr);
12159         m_errorMonitor->VerifyFound();
12160     }
12161 
12162     m_commandBuffer->end();
12163 }
12164 
TEST_F(VkLayerTest,ValidateViewportStateScissorOverflow)12165 TEST_F(VkLayerTest, ValidateViewportStateScissorOverflow) {
12166     TEST_DESCRIPTION("Validate sum of offset and width of viewport state scissor");
12167 
12168     ASSERT_NO_FATAL_FAILURE(Init());
12169     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
12170 
12171     VkViewport viewport = {0.0f, 0.0f, 64.0f, 64.0f, 0.0f, 1.0f};
12172     VkRect2D scissor_x = {{INT32_MAX / 2, 0}, {INT32_MAX / 2 + 64, 64}};
12173     VkRect2D scissor_y = {{0, INT32_MAX / 2}, {64, INT32_MAX / 2 + 64}};
12174 
12175     const auto break_vp_x = [&](CreatePipelineHelper &helper) {
12176         helper.vp_state_ci_.viewportCount = 1;
12177         helper.vp_state_ci_.pViewports = &viewport;
12178         helper.vp_state_ci_.scissorCount = 1;
12179         helper.vp_state_ci_.pScissors = &scissor_x;
12180     };
12181     CreatePipelineHelper::OneshotTest(*this, break_vp_x, kErrorBit,
12182                                       vector<std::string>({"VUID-VkPipelineViewportStateCreateInfo-offset-02822"}));
12183 
12184     const auto break_vp_y = [&](CreatePipelineHelper &helper) {
12185         helper.vp_state_ci_.viewportCount = 1;
12186         helper.vp_state_ci_.pViewports = &viewport;
12187         helper.vp_state_ci_.scissorCount = 1;
12188         helper.vp_state_ci_.pScissors = &scissor_y;
12189     };
12190     CreatePipelineHelper::OneshotTest(*this, break_vp_y, kErrorBit,
12191                                       vector<std::string>({"VUID-VkPipelineViewportStateCreateInfo-offset-02823"}));
12192 }
12193 
TEST_F(VkLayerTest,ValidateViewportStateScissorNegative)12194 TEST_F(VkLayerTest, ValidateViewportStateScissorNegative) {
12195     TEST_DESCRIPTION("Validate offset of viewport state scissor");
12196 
12197     ASSERT_NO_FATAL_FAILURE(Init());
12198     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
12199 
12200     VkViewport viewport = {0.0f, 0.0f, 64.0f, 64.0f, 0.0f, 1.0f};
12201     VkRect2D scissor_x = {{-64, 0}, {256, 256}};
12202     VkRect2D scissor_y = {{0, -64}, {256, 256}};
12203 
12204     const auto break_vp_x = [&](CreatePipelineHelper &helper) {
12205         helper.vp_state_ci_.viewportCount = 1;
12206         helper.vp_state_ci_.pViewports = &viewport;
12207         helper.vp_state_ci_.scissorCount = 1;
12208         helper.vp_state_ci_.pScissors = &scissor_x;
12209     };
12210     CreatePipelineHelper::OneshotTest(*this, break_vp_x, kErrorBit, "VUID-VkPipelineViewportStateCreateInfo-x-02821");
12211 
12212     const auto break_vp_y = [&](CreatePipelineHelper &helper) {
12213         helper.vp_state_ci_.viewportCount = 1;
12214         helper.vp_state_ci_.pViewports = &viewport;
12215         helper.vp_state_ci_.scissorCount = 1;
12216         helper.vp_state_ci_.pScissors = &scissor_y;
12217     };
12218     CreatePipelineHelper::OneshotTest(*this, break_vp_y, kErrorBit, "VUID-VkPipelineViewportStateCreateInfo-x-02821");
12219 }
12220 
TEST_F(VkLayerTest,WriteTimeStampInvalidQuery)12221 TEST_F(VkLayerTest, WriteTimeStampInvalidQuery) {
12222     TEST_DESCRIPTION("Test for invalid query slot in query pool.");
12223 
12224     if (InstanceExtensionSupported(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME)) {
12225         m_instance_extension_names.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
12226     } else {
12227         printf("%s Extension %s is not supported.\n", kSkipPrefix, VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
12228         return;
12229     }
12230 
12231     ASSERT_NO_FATAL_FAILURE(InitFramework());
12232     bool sync2 = false;
12233     VkPhysicalDeviceSynchronization2FeaturesKHR synchronization2 = LvlInitStruct<VkPhysicalDeviceSynchronization2FeaturesKHR>();
12234     synchronization2.synchronization2 = VK_TRUE;
12235     auto features2 = LvlInitStruct<VkPhysicalDeviceFeatures2KHR>();
12236     if (DeviceExtensionSupported(gpu(), nullptr, VK_KHR_SYNCHRONIZATION_2_EXTENSION_NAME)) {
12237         m_device_extension_names.push_back(VK_KHR_SYNCHRONIZATION_2_EXTENSION_NAME);
12238         features2.pNext = &synchronization2;
12239         sync2 = true;
12240     }
12241     InitState(nullptr, &features2);
12242     sync2 &= (synchronization2.synchronization2 == VK_TRUE);
12243     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
12244 
12245     uint32_t queue_count;
12246     vk::GetPhysicalDeviceQueueFamilyProperties(gpu(), &queue_count, NULL);
12247     std::vector<VkQueueFamilyProperties> queue_props(queue_count);
12248     vk::GetPhysicalDeviceQueueFamilyProperties(gpu(), &queue_count, queue_props.data());
12249     if (queue_props[m_device->graphics_queue_node_index_].timestampValidBits == 0) {
12250         printf("%s Device graphic queue has timestampValidBits of 0, skipping.\n", kSkipPrefix);
12251         return;
12252     }
12253 
12254     vk_testing::QueryPool query_pool;
12255     VkQueryPoolCreateInfo query_pool_ci = LvlInitStruct<VkQueryPoolCreateInfo>();
12256     query_pool_ci.queryType = VK_QUERY_TYPE_TIMESTAMP;
12257     query_pool_ci.queryCount = 1;
12258     query_pool.init(*m_device, query_pool_ci);
12259 
12260     m_commandBuffer->begin();
12261     m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdWriteTimestamp-query-04904");
12262     vk::CmdWriteTimestamp(m_commandBuffer->handle(), VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, query_pool.handle(), 1);
12263     m_errorMonitor->VerifyFound();
12264     if (sync2) {
12265         auto vkCmdWriteTimestamp2KHR =
12266             (PFN_vkCmdWriteTimestamp2KHR)vk::GetDeviceProcAddr(m_device->device(), "vkCmdWriteTimestamp2KHR");
12267 
12268         m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdWriteTimestamp2KHR-query-04903");
12269         vkCmdWriteTimestamp2KHR(m_commandBuffer->handle(), VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, query_pool.handle(), 1);
12270         m_errorMonitor->VerifyFound();
12271     }
12272     m_commandBuffer->end();
12273 }
12274 
TEST_F(VkLayerTest,DuplicatePhysicalDevices)12275 TEST_F(VkLayerTest, DuplicatePhysicalDevices) {
12276     TEST_DESCRIPTION("Duplicated physical devices in DeviceGroupDeviceCreateInfo.");
12277     SetTargetApiVersion(VK_API_VERSION_1_1);
12278     ASSERT_NO_FATAL_FAILURE(InitFramework(m_errorMonitor));
12279     uint32_t physical_device_group_count = 0;
12280     vk::EnumeratePhysicalDeviceGroups(instance(), &physical_device_group_count, nullptr);
12281 
12282     if (physical_device_group_count == 0) {
12283         printf("%s physical_device_group_count is 0, skipping test\n", kSkipPrefix);
12284         return;
12285     }
12286 
12287     std::vector<VkPhysicalDeviceGroupProperties> physical_device_group(physical_device_group_count,
12288                                                                        {VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_GROUP_PROPERTIES});
12289     vk::EnumeratePhysicalDeviceGroups(instance(), &physical_device_group_count, physical_device_group.data());
12290     VkPhysicalDevice physicalDevices[2] = {physical_device_group[0].physicalDevices[0],
12291                                            physical_device_group[0].physicalDevices[0]};
12292 
12293     VkDeviceGroupDeviceCreateInfo create_device_pnext = LvlInitStruct<VkDeviceGroupDeviceCreateInfo>();
12294     create_device_pnext.physicalDeviceCount = 2;
12295     create_device_pnext.pPhysicalDevices = physicalDevices;
12296 
12297     ASSERT_NO_FATAL_FAILURE(InitState());
12298 
12299     vk_testing::QueueCreateInfoArray queue_info(m_device->queue_props);
12300 
12301     VkDeviceCreateInfo create_info = LvlInitStruct<VkDeviceCreateInfo>();
12302     create_info.pNext = &create_device_pnext;
12303     create_info.queueCreateInfoCount = queue_info.size();
12304     create_info.pQueueCreateInfos = queue_info.data();
12305     create_info.enabledLayerCount = 0;
12306     create_info.ppEnabledLayerNames = nullptr;
12307     create_info.enabledExtensionCount = m_device_extension_names.size();
12308     create_info.ppEnabledExtensionNames = m_device_extension_names.data();
12309 
12310     VkDevice device;
12311     m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkDeviceGroupDeviceCreateInfo-pPhysicalDevices-00375");
12312     vk::CreateDevice(gpu(), &create_info, nullptr, &device);
12313     m_errorMonitor->VerifyFound();
12314 }
12315 
TEST_F(VkLayerTest,ValidateColorWriteDynamicStateDisabled)12316 TEST_F(VkLayerTest, ValidateColorWriteDynamicStateDisabled) {
12317     TEST_DESCRIPTION("Validate VK_EXT_color_write_enable VUs when disabled");
12318 
12319     if (InstanceExtensionSupported(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME)) {
12320         m_instance_extension_names.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
12321     } else {
12322         printf("%s Extension %s is not supported.\n", kSkipPrefix, VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
12323         return;
12324     }
12325 
12326     ASSERT_NO_FATAL_FAILURE(InitFramework(m_errorMonitor));
12327     if (DeviceExtensionSupported(gpu(), nullptr, VK_EXT_COLOR_WRITE_ENABLE_EXTENSION_NAME)) {
12328         m_device_extension_names.push_back(VK_EXT_COLOR_WRITE_ENABLE_EXTENSION_NAME);
12329     } else {
12330         printf("%s Extension %s is not supported.\n", kSkipPrefix, VK_EXT_COLOR_WRITE_ENABLE_EXTENSION_NAME);
12331         return;
12332     }
12333 
12334     ASSERT_NO_FATAL_FAILURE(InitState());
12335     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
12336 
12337     // VUID-VkGraphicsPipelineCreateInfo-pDynamicStates-04800
12338     CreatePipelineHelper pipe(*this);
12339     pipe.InitInfo();
12340     const VkDynamicState dyn_states[] = {VK_DYNAMIC_STATE_COLOR_WRITE_ENABLE_EXT};
12341     auto dyn_state_ci = LvlInitStruct<VkPipelineDynamicStateCreateInfo>();
12342     dyn_state_ci.dynamicStateCount = size(dyn_states);
12343     dyn_state_ci.pDynamicStates = dyn_states;
12344     pipe.dyn_state_ci_ = dyn_state_ci;
12345     pipe.InitState();
12346     m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkGraphicsPipelineCreateInfo-pDynamicStates-04800");
12347     pipe.CreateGraphicsPipeline();
12348     m_errorMonitor->VerifyFound();
12349 }
12350 
TEST_F(VkLayerTest,InvalidCombinationOfDeviceFeatures)12351 TEST_F(VkLayerTest, InvalidCombinationOfDeviceFeatures) {
12352     TEST_DESCRIPTION("Test invalid combinations of device features.");
12353 
12354     if (InstanceExtensionSupported(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME)) {
12355         m_instance_extension_names.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
12356     } else {
12357         printf("%s Did not find required instance extension %s; skipped.\n", kSkipPrefix,
12358                VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
12359         return;
12360     }
12361 
12362     VkPhysicalDeviceShaderImageAtomicInt64FeaturesEXT shader_image_atomic_int64_feature =
12363         LvlInitStruct<VkPhysicalDeviceShaderImageAtomicInt64FeaturesEXT>();
12364     shader_image_atomic_int64_feature.sparseImageInt64Atomics = VK_TRUE;
12365     shader_image_atomic_int64_feature.shaderImageInt64Atomics = VK_FALSE;
12366 
12367     VkPhysicalDeviceShaderAtomicFloatFeaturesEXT shader_atomic_float_feature =
12368         LvlInitStruct<VkPhysicalDeviceShaderAtomicFloatFeaturesEXT>();
12369     shader_atomic_float_feature.sparseImageFloat32Atomics = VK_TRUE;
12370     shader_atomic_float_feature.shaderImageFloat32Atomics = VK_FALSE;
12371     shader_atomic_float_feature.sparseImageFloat32AtomicAdd = VK_TRUE;
12372     shader_atomic_float_feature.shaderImageFloat32AtomicAdd = VK_FALSE;
12373 
12374     VkPhysicalDeviceShaderAtomicFloat2FeaturesEXT shader_atomic_float_feature2 =
12375         LvlInitStruct<VkPhysicalDeviceShaderAtomicFloat2FeaturesEXT>();
12376     shader_atomic_float_feature2.sparseImageFloat32AtomicMinMax = VK_TRUE;
12377     shader_atomic_float_feature2.shaderImageFloat32AtomicMinMax = VK_FALSE;
12378 
12379     VkPhysicalDeviceFeatures2 pd_features2 = LvlInitStruct<VkPhysicalDeviceFeatures2>(&shader_image_atomic_int64_feature);
12380 
12381     ASSERT_NO_FATAL_FAILURE(Init());
12382     vk_testing::QueueCreateInfoArray queue_info(m_device->queue_props);
12383     VkDeviceCreateInfo device_create_info = LvlInitStruct<VkDeviceCreateInfo>();
12384     device_create_info.pNext = &pd_features2;
12385     device_create_info.queueCreateInfoCount = queue_info.size();
12386     device_create_info.pQueueCreateInfos = queue_info.data();
12387 
12388     {
12389         VkDevice testDevice;
12390         m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkDeviceCreateInfo-None-04896");
12391         vk::CreateDevice(gpu(), &device_create_info, NULL, &testDevice);
12392         m_errorMonitor->VerifyFound();
12393     }
12394     {
12395         pd_features2.pNext = &shader_atomic_float_feature;
12396 
12397         VkDevice testDevice;
12398         m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkDeviceCreateInfo-None-04897");
12399         m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkDeviceCreateInfo-None-04898");
12400         vk::CreateDevice(gpu(), &device_create_info, NULL, &testDevice);
12401         m_errorMonitor->VerifyFound();
12402     }
12403     {
12404         pd_features2.pNext = &shader_atomic_float_feature2;
12405 
12406         VkDevice testDevice;
12407         m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkDeviceCreateInfo-sparseImageFloat32AtomicMinMax-04975");
12408         vk::CreateDevice(gpu(), &device_create_info, NULL, &testDevice);
12409         m_errorMonitor->VerifyFound();
12410     }
12411 }
12412 
TEST_F(VkLayerTest,ExternalMemoryAndExternalMemoryNV)12413 TEST_F(VkLayerTest, ExternalMemoryAndExternalMemoryNV) {
12414     TEST_DESCRIPTION("Test for both external memory and external memory NV in image create pNext chain.");
12415 
12416     ASSERT_NO_FATAL_FAILURE(InitFramework(m_errorMonitor));
12417 
12418     if ((DeviceExtensionSupported(gpu(), nullptr, VK_KHR_EXTERNAL_MEMORY_EXTENSION_NAME)) &&
12419         (DeviceExtensionSupported(gpu(), nullptr, VK_NV_EXTERNAL_MEMORY_EXTENSION_NAME))) {
12420         m_device_extension_names.push_back(VK_KHR_EXTERNAL_MEMORY_EXTENSION_NAME);
12421         m_device_extension_names.push_back(VK_NV_EXTERNAL_MEMORY_EXTENSION_NAME);
12422     } else {
12423         printf("%s %s extension not supported, skipping tests\n", kSkipPrefix, VK_KHR_EXTERNAL_MEMORY_EXTENSION_NAME);
12424         return;
12425     }
12426 
12427     ASSERT_NO_FATAL_FAILURE(InitState());
12428 
12429     VkExternalMemoryImageCreateInfoNV external_mem_nv = LvlInitStruct<VkExternalMemoryImageCreateInfoNV>();
12430     external_mem_nv.handleTypes = VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT;
12431 
12432     VkExternalMemoryImageCreateInfo external_mem = LvlInitStruct<VkExternalMemoryImageCreateInfo>(&external_mem_nv);
12433     external_mem.handleTypes = VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT;
12434 
12435     VkImageCreateInfo ici = LvlInitStruct<VkImageCreateInfo>(&external_mem);
12436     ici.imageType = VK_IMAGE_TYPE_2D;
12437     ici.arrayLayers = 1;
12438     ici.extent = {64, 64, 1};
12439     ici.format = VK_FORMAT_R8G8B8A8_UNORM;
12440     ici.mipLevels = 1;
12441     ici.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
12442     ici.samples = VK_SAMPLE_COUNT_1_BIT;
12443     ici.tiling = VK_IMAGE_TILING_OPTIMAL;
12444     ici.usage = VK_IMAGE_USAGE_SAMPLED_BIT;
12445 
12446     m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkImageCreateInfo-pNext-00988");
12447     VkImage test_image;
12448     vk::CreateImage(device(), &ici, nullptr, &test_image);
12449     m_errorMonitor->VerifyFound();
12450 }
12451 
TEST_F(VkLayerTest,InvalidImageCreateFlagWithPhysicalDeviceCount)12452 TEST_F(VkLayerTest, InvalidImageCreateFlagWithPhysicalDeviceCount) {
12453     TEST_DESCRIPTION("Test for invalid imageCreate flags bit with physicalDeviceCount.");
12454     SetTargetApiVersion(VK_API_VERSION_1_1);
12455 
12456     ASSERT_NO_FATAL_FAILURE(InitFramework(m_errorMonitor));
12457 
12458     if (DeviceValidationVersion() < VK_API_VERSION_1_1) {
12459         printf("%s Device Groups requires Vulkan 1.1+, skipping test\n", kSkipPrefix);
12460         return;
12461     }
12462     uint32_t physical_device_group_count = 0;
12463     vk::EnumeratePhysicalDeviceGroups(instance(), &physical_device_group_count, nullptr);
12464 
12465     if (physical_device_group_count == 0) {
12466         printf("%s physical_device_group_count is 0, skipping test\n", kSkipPrefix);
12467         return;
12468     }
12469 
12470     std::vector<VkPhysicalDeviceGroupProperties> physical_device_group(physical_device_group_count,
12471                                                                        {VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_GROUP_PROPERTIES});
12472     vk::EnumeratePhysicalDeviceGroups(instance(), &physical_device_group_count, physical_device_group.data());
12473     VkDeviceGroupDeviceCreateInfo create_device_pnext = LvlInitStruct<VkDeviceGroupDeviceCreateInfo>();
12474     create_device_pnext.physicalDeviceCount = 1;
12475     create_device_pnext.pPhysicalDevices = physical_device_group[0].physicalDevices;
12476     ASSERT_NO_FATAL_FAILURE(InitState(nullptr, &create_device_pnext, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT));
12477 
12478     VkImageCreateInfo ici = LvlInitStruct<VkImageCreateInfo>();
12479     ici.flags = VK_IMAGE_CREATE_SPLIT_INSTANCE_BIND_REGIONS_BIT;
12480     ici.imageType = VK_IMAGE_TYPE_2D;
12481     ici.arrayLayers = 1;
12482     ici.extent = {64, 64, 1};
12483     ici.format = VK_FORMAT_R8G8B8A8_UNORM;
12484     ici.mipLevels = 1;
12485     ici.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
12486     ici.samples = VK_SAMPLE_COUNT_1_BIT;
12487     ici.tiling = VK_IMAGE_TILING_OPTIMAL;
12488     ici.usage = VK_IMAGE_USAGE_SAMPLED_BIT;
12489 
12490     VkImageFormatProperties imageFormatProperties;
12491     VkResult result =
12492         vk::GetPhysicalDeviceImageFormatProperties(physical_device_group[0].physicalDevices[0], ici.format, ici.imageType,
12493                                                    ici.tiling, ici.usage, ici.flags, &imageFormatProperties);
12494     if (result == VK_ERROR_FORMAT_NOT_SUPPORTED) {
12495         printf("%s image format is not supported.\n", kSkipPrefix);
12496         return;
12497     }
12498 
12499     m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkImageCreateInfo-physicalDeviceCount-01421");
12500     VkImage test_image;
12501     vk::CreateImage(device(), &ici, nullptr, &test_image);
12502     m_errorMonitor->VerifyFound();
12503 }
12504 
TEST_F(VkLayerTest,ValidateGetPhysicalDeviceVideoFormatProperties)12505 TEST_F(VkLayerTest, ValidateGetPhysicalDeviceVideoFormatProperties) {
12506     TEST_DESCRIPTION("Validate getting physical device video format properties.");
12507 
12508     ASSERT_NO_FATAL_FAILURE(InitFramework(m_errorMonitor));
12509     if (!DeviceExtensionSupported(gpu(), nullptr, VK_KHR_VIDEO_QUEUE_EXTENSION_NAME)) {
12510         printf("%s Video queue Extension not supported, skipping tests\n", kSkipPrefix);
12511         return;
12512     }
12513     m_device_extension_names.push_back(VK_KHR_VIDEO_QUEUE_EXTENSION_NAME);
12514     ASSERT_NO_FATAL_FAILURE(InitState());
12515 
12516     VkVideoProfileKHR video_profile = LvlInitStruct<VkVideoProfileKHR>();
12517     video_profile.videoCodecOperation = VK_VIDEO_CODEC_OPERATION_DECODE_H264_BIT_EXT;
12518     video_profile.chromaSubsampling = VK_VIDEO_CHROMA_SUBSAMPLING_MONOCHROME_BIT_KHR;
12519     video_profile.lumaBitDepth = VK_VIDEO_COMPONENT_BIT_DEPTH_8_BIT_KHR;
12520     video_profile.chromaBitDepth = VK_VIDEO_COMPONENT_BIT_DEPTH_8_BIT_KHR;
12521 
12522     VkVideoProfilesKHR video_profiles = LvlInitStruct<VkVideoProfilesKHR>();
12523     video_profiles.profileCount = 1;
12524     video_profiles.pProfiles = &video_profile;
12525 
12526     VkPhysicalDeviceVideoFormatInfoKHR video_format_info = LvlInitStruct<VkPhysicalDeviceVideoFormatInfoKHR>();
12527     video_format_info.pVideoProfiles = &video_profiles;
12528 
12529     PFN_vkGetPhysicalDeviceVideoFormatPropertiesKHR vkGetPhysicalDeviceVideoFormatPropertiesKHR =
12530         (PFN_vkGetPhysicalDeviceVideoFormatPropertiesKHR)vk::GetInstanceProcAddr(instance(),
12531                                                                                  "vkGetPhysicalDeviceVideoFormatPropertiesKHR");
12532 
12533     uint32_t count;
12534     m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkGetPhysicalDeviceVideoFormatPropertiesKHR-imageUsage-04844");
12535     vkGetPhysicalDeviceVideoFormatPropertiesKHR(gpu(), &video_format_info, &count, nullptr);
12536     m_errorMonitor->VerifyFound();
12537 }
12538 
TEST_F(VkLayerTest,QueueSubmitWaitingSameSemaphore)12539 TEST_F(VkLayerTest, QueueSubmitWaitingSameSemaphore) {
12540     TEST_DESCRIPTION("Submit to queue with waitSemaphore that another queue is already waiting on.");
12541 
12542     ASSERT_NO_FATAL_FAILURE(Init());
12543 
12544     if (m_device->graphics_queues().size() < 2) {
12545         printf("%s 2 graphics queues are needed.\n", kSkipPrefix);
12546         return;
12547     }
12548 
12549     VkSemaphoreCreateInfo sem_info = LvlInitStruct<VkSemaphoreCreateInfo>();
12550 
12551     vk_testing::Semaphore semaphore;
12552     semaphore.init(*m_device, sem_info);
12553 
12554     VkPipelineStageFlags stageFlags = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT;
12555 
12556     VkSubmitInfo signalSubmitInfo = LvlInitStruct<VkSubmitInfo>();
12557     signalSubmitInfo.signalSemaphoreCount = 1;
12558     signalSubmitInfo.pSignalSemaphores = &semaphore.handle();
12559 
12560     VkSubmitInfo waitSubmitInfo = LvlInitStruct<VkSubmitInfo>();
12561     waitSubmitInfo.waitSemaphoreCount = 1;
12562     waitSubmitInfo.pWaitSemaphores = &semaphore.handle();
12563     waitSubmitInfo.pWaitDstStageMask = &stageFlags;
12564 
12565     VkQueue other = m_device->graphics_queues()[1]->handle();
12566 
12567     vk::QueueSubmit(m_device->m_queue, 1, &signalSubmitInfo, VK_NULL_HANDLE);
12568     vk::QueueSubmit(m_device->m_queue, 1, &waitSubmitInfo, VK_NULL_HANDLE);
12569     m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkQueueSubmit-pWaitSemaphores-00068");
12570     vk::QueueSubmit(other, 1, &waitSubmitInfo, VK_NULL_HANDLE);
12571     m_errorMonitor->VerifyFound();
12572 }
12573 
TEST_F(VkLayerTest,QueueSubmit2KHRUsedButSynchronizaion2Disabled)12574 TEST_F(VkLayerTest, QueueSubmit2KHRUsedButSynchronizaion2Disabled) {
12575     TEST_DESCRIPTION("Using QueueSubmit2KHR when synchronization2 is not enabled");
12576     SetTargetApiVersion(VK_API_VERSION_1_2);
12577     ASSERT_NO_FATAL_FAILURE(InitFramework());
12578     if (!DeviceExtensionSupported(gpu(), nullptr, VK_KHR_SYNCHRONIZATION_2_EXTENSION_NAME)) {
12579         printf("%s Synchronization2 not supported, skipping test\n", kSkipPrefix);
12580         return;
12581     }
12582     m_device_extension_names.push_back(VK_KHR_SYNCHRONIZATION_2_EXTENSION_NAME);
12583     InitState();
12584 
12585     auto fpQueueSubmit2KHR = (PFN_vkQueueSubmit2KHR)vk::GetDeviceProcAddr(m_device->device(), "vkQueueSubmit2KHR");
12586 
12587     auto submit_info = LvlInitStruct<VkSubmitInfo2KHR>();
12588     m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkQueueSubmit2KHR-synchronization2-03866");
12589     fpQueueSubmit2KHR(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
12590     m_errorMonitor->VerifyFound();
12591 }
12592 
TEST_F(VkLayerTest,WaitEventsDifferentQueues)12593 TEST_F(VkLayerTest, WaitEventsDifferentQueues) {
12594     TEST_DESCRIPTION("Using CmdWaitEvents with invalid barrier queues");
12595     ASSERT_NO_FATAL_FAILURE(Init());
12596     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
12597 
12598     uint32_t no_gfx = m_device->QueueFamilyWithoutCapabilities(VK_QUEUE_GRAPHICS_BIT);
12599     if (no_gfx == UINT32_MAX) {
12600         printf("%s Required queue families not present (non-graphics capable required).\n", kSkipPrefix);
12601         return;
12602     }
12603 
12604     VkEvent event;
12605     VkEventCreateInfo event_create_info = {};
12606     event_create_info.sType = VK_STRUCTURE_TYPE_EVENT_CREATE_INFO;
12607     vk::CreateEvent(m_device->device(), &event_create_info, nullptr, &event);
12608 
12609     VkBufferObj buffer;
12610     VkMemoryPropertyFlags mem_prop = VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT;
12611     buffer.init_as_src_and_dst(*m_device, 256, mem_prop);
12612 
12613     VkBufferMemoryBarrier buffer_memory_barrier = LvlInitStruct<VkBufferMemoryBarrier>();
12614     buffer_memory_barrier.srcAccessMask = 0;
12615     buffer_memory_barrier.dstAccessMask = 0;
12616     buffer_memory_barrier.buffer = buffer.handle();
12617     buffer_memory_barrier.offset = 0;
12618     buffer_memory_barrier.size = 256;
12619     buffer_memory_barrier.srcQueueFamilyIndex = m_device->graphics_queue_node_index_;
12620     buffer_memory_barrier.dstQueueFamilyIndex = no_gfx;
12621 
12622     VkImageObj image(m_device);
12623     image.Init(32, 32, 1, VK_FORMAT_B8G8R8A8_UNORM, VK_IMAGE_USAGE_SAMPLED_BIT, VK_IMAGE_TILING_OPTIMAL, 0);
12624 
12625     VkImageMemoryBarrier image_memory_barrier = LvlInitStruct<VkImageMemoryBarrier>();
12626     image_memory_barrier.srcAccessMask = 0;
12627     image_memory_barrier.dstAccessMask = 0;
12628     image_memory_barrier.oldLayout = VK_IMAGE_LAYOUT_GENERAL;
12629     image_memory_barrier.newLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
12630     image_memory_barrier.image = image.handle();
12631     image_memory_barrier.srcQueueFamilyIndex = m_device->graphics_queue_node_index_;
12632     image_memory_barrier.dstQueueFamilyIndex = no_gfx;
12633     image_memory_barrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
12634     image_memory_barrier.subresourceRange.baseArrayLayer = 0;
12635     image_memory_barrier.subresourceRange.baseMipLevel = 0;
12636     image_memory_barrier.subresourceRange.layerCount = 1;
12637     image_memory_barrier.subresourceRange.levelCount = 1;
12638 
12639     m_commandBuffer->begin();
12640     vk::CmdSetEvent(m_commandBuffer->handle(), event, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT);
12641     m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdWaitEvents-srcQueueFamilyIndex-02803");
12642     vk::CmdWaitEvents(m_commandBuffer->handle(), 1, &event, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, 0,
12643                       nullptr, 1, &buffer_memory_barrier, 0, nullptr);
12644     m_errorMonitor->VerifyFound();
12645     m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdWaitEvents-srcQueueFamilyIndex-02803");
12646     vk::CmdWaitEvents(m_commandBuffer->handle(), 1, &event, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, 0,
12647                       nullptr, 0, nullptr, 1, &image_memory_barrier);
12648     m_errorMonitor->VerifyFound();
12649     m_commandBuffer->end();
12650 }
12651 
TEST_F(VkLayerTest,InvalidColorWriteEnableAttachmentCount)12652 TEST_F(VkLayerTest, InvalidColorWriteEnableAttachmentCount) {
12653     TEST_DESCRIPTION("Invalid usage of vkCmdSetColorWriteEnableEXT with attachment count 0");
12654 
12655     if (!InstanceExtensionSupported(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME)) {
12656         printf("%s %s Extension not supported, skipping tests\n", kSkipPrefix,
12657                VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
12658         return;
12659     }
12660     m_instance_extension_names.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
12661 
12662     ASSERT_NO_FATAL_FAILURE(InitFramework());
12663 
12664     if (!DeviceExtensionSupported(gpu(), nullptr, VK_EXT_COLOR_WRITE_ENABLE_EXTENSION_NAME)) {
12665         printf("%s Extension %s is not supported.\n", kSkipPrefix, VK_EXT_COLOR_WRITE_ENABLE_EXTENSION_NAME);
12666         return;
12667     }
12668     m_device_extension_names.push_back(VK_EXT_COLOR_WRITE_ENABLE_EXTENSION_NAME);
12669 
12670     ASSERT_NO_FATAL_FAILURE(InitState());
12671     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
12672 
12673     VkBool32 colorWriteEnable[2] = {VK_TRUE, VK_FALSE};
12674 
12675     PFN_vkCmdSetColorWriteEnableEXT fpCmdSetColorWriteEnableEXT =
12676         (PFN_vkCmdSetColorWriteEnableEXT)vk::GetDeviceProcAddr(m_device->handle(), "vkCmdSetColorWriteEnableEXT");
12677 
12678     CreatePipelineHelper helper(*this);
12679     helper.InitInfo();
12680     helper.InitState();
12681     helper.CreateGraphicsPipeline();
12682 
12683     m_commandBuffer->begin();
12684     vk::CmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, helper.pipeline_);
12685     m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdSetColorWriteEnableEXT-None-04803");
12686     m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdSetColorWriteEnableEXT-attachmentCount-04804");
12687     fpCmdSetColorWriteEnableEXT(m_commandBuffer->handle(), 2, colorWriteEnable);
12688     m_errorMonitor->VerifyFound();
12689     m_commandBuffer->end();
12690 }
12691 
TEST_F(VkLayerTest,InvalidCmdSetDiscardRectangleEXTRectangleCount)12692 TEST_F(VkLayerTest, InvalidCmdSetDiscardRectangleEXTRectangleCount) {
12693     TEST_DESCRIPTION("Test CmdSetDiscardRectangleEXT with invalid offsets in pDiscardRectangles");
12694 
12695     if (!InstanceExtensionSupported(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME)) {
12696         printf("%s Did not find required instance extension %s; skipped.\n", kSkipPrefix,
12697                VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
12698         return;
12699     }
12700     m_instance_extension_names.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
12701 
12702     ASSERT_NO_FATAL_FAILURE(InitFramework());
12703     if (!DeviceExtensionSupported(gpu(), nullptr, VK_EXT_DISCARD_RECTANGLES_EXTENSION_NAME)) {
12704         printf("%s %s not supported, skipping test\n", kSkipPrefix, VK_EXT_DISCARD_RECTANGLES_EXTENSION_NAME);
12705         return;
12706     }
12707     m_device_extension_names.push_back(VK_EXT_DISCARD_RECTANGLES_EXTENSION_NAME);
12708     InitState();
12709 
12710     VkPhysicalDeviceDiscardRectanglePropertiesEXT discard_rectangle_properties =
12711         LvlInitStruct<VkPhysicalDeviceDiscardRectanglePropertiesEXT>();
12712 
12713     auto phys_dev_props_2 = LvlInitStruct<VkPhysicalDeviceProperties2>();
12714     phys_dev_props_2.pNext = &discard_rectangle_properties;
12715     vk::GetPhysicalDeviceProperties2(gpu(), &phys_dev_props_2);
12716 
12717     auto fpCmdSetDiscardRectangleEXT =
12718         (PFN_vkCmdSetDiscardRectangleEXT)vk::GetDeviceProcAddr(m_device->device(), "vkCmdSetDiscardRectangleEXT");
12719 
12720     VkRect2D discard_rectangles = {};
12721     discard_rectangles.offset.x = 0;
12722     discard_rectangles.offset.y = 0;
12723     discard_rectangles.extent.width = 64;
12724     discard_rectangles.extent.height = 64;
12725 
12726     m_commandBuffer->begin();
12727     m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdSetDiscardRectangleEXT-firstDiscardRectangle-00585");
12728     fpCmdSetDiscardRectangleEXT(m_commandBuffer->handle(), discard_rectangle_properties.maxDiscardRectangles, 1,
12729                                 &discard_rectangles);
12730     m_errorMonitor->VerifyFound();
12731 }
12732 
TEST_F(VkLayerTest,InvalidCmdEndQueryIndexedEXTIndex)12733 TEST_F(VkLayerTest, InvalidCmdEndQueryIndexedEXTIndex) {
12734     TEST_DESCRIPTION("Test InvalidCmdEndQueryIndexedEXT with invalid index");
12735 
12736     if (!InstanceExtensionSupported(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME)) {
12737         printf("%s Did not find required instance extension %s; skipped.\n", kSkipPrefix,
12738                VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
12739         return;
12740     }
12741     m_instance_extension_names.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
12742 
12743     ASSERT_NO_FATAL_FAILURE(InitFramework());
12744     if (!DeviceExtensionSupported(gpu(), nullptr, VK_EXT_TRANSFORM_FEEDBACK_EXTENSION_NAME)) {
12745         printf("%s %s not supported, skipping test\n", kSkipPrefix, VK_EXT_TRANSFORM_FEEDBACK_EXTENSION_NAME);
12746         return;
12747     }
12748     m_device_extension_names.push_back(VK_EXT_TRANSFORM_FEEDBACK_EXTENSION_NAME);
12749     InitState();
12750 
12751     VkPhysicalDeviceTransformFeedbackPropertiesEXT transform_feedback_properties =
12752         LvlInitStruct<VkPhysicalDeviceTransformFeedbackPropertiesEXT>();
12753 
12754     auto phys_dev_props_2 = LvlInitStruct<VkPhysicalDeviceProperties2>(&transform_feedback_properties);
12755     vk::GetPhysicalDeviceProperties2(gpu(), &phys_dev_props_2);
12756 
12757     auto fpCmdBeginQueryIndexedEXT =
12758         (PFN_vkCmdBeginQueryIndexedEXT)vk::GetDeviceProcAddr(m_device->device(), "vkCmdBeginQueryIndexedEXT");
12759     auto fpCmdEndQueryIndexedEXT =
12760         (PFN_vkCmdEndQueryIndexedEXT)vk::GetDeviceProcAddr(m_device->device(), "vkCmdEndQueryIndexedEXT");
12761 
12762     VkQueryPoolCreateInfo qpci = LvlInitStruct<VkQueryPoolCreateInfo>();
12763     qpci.queryType = VK_QUERY_TYPE_TRANSFORM_FEEDBACK_STREAM_EXT;
12764     qpci.queryCount = 1;
12765 
12766     VkQueryPool tf_query_pool;
12767     vk::CreateQueryPool(m_device->device(), &qpci, nullptr, &tf_query_pool);
12768 
12769     VkQueryPool query_pool;
12770     qpci.queryType = VK_QUERY_TYPE_OCCLUSION;
12771     vk::CreateQueryPool(m_device->device(), &qpci, nullptr, &query_pool);
12772 
12773     m_commandBuffer->begin();
12774     fpCmdBeginQueryIndexedEXT(m_commandBuffer->handle(), tf_query_pool, 0, 0, 0);
12775     m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdEndQueryIndexedEXT-queryType-02346");
12776     fpCmdEndQueryIndexedEXT(m_commandBuffer->handle(), tf_query_pool, 0, transform_feedback_properties.maxTransformFeedbackStreams);
12777 
12778     fpCmdBeginQueryIndexedEXT(m_commandBuffer->handle(), query_pool, 0, 0, 0);
12779     m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdEndQueryIndexedEXT-queryType-02347");
12780     fpCmdEndQueryIndexedEXT(m_commandBuffer->handle(), query_pool, 0, 1);
12781     m_errorMonitor->VerifyFound();
12782 
12783     m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdEndQueryIndexedEXT-None-02342");
12784     m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdEndQueryIndexedEXT-query-02343");
12785     fpCmdEndQueryIndexedEXT(m_commandBuffer->handle(), query_pool, 1, 0);
12786     m_errorMonitor->VerifyFound();
12787 
12788     fpCmdEndQueryIndexedEXT(m_commandBuffer->handle(), query_pool, 0, 0);
12789     m_commandBuffer->end();
12790 }
12791 
TEST_F(VkLayerTest,Features12AndppEnabledExtensionNames)12792 TEST_F(VkLayerTest, Features12AndppEnabledExtensionNames) {
12793     TEST_DESCRIPTION("Test VkPhysicalDeviceVulkan12Features and illegal extension in ppEnabledExtensionNames");
12794 
12795     SetTargetApiVersion(VK_API_VERSION_1_2);
12796     if (!InstanceExtensionSupported(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME)) {
12797         printf("%s %s Extension not supported, skipping tests\n", kSkipPrefix,
12798                VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
12799         return;
12800     }
12801     m_instance_extension_names.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
12802     ASSERT_NO_FATAL_FAILURE(InitFramework(m_errorMonitor));
12803     if (DeviceValidationVersion() < VK_API_VERSION_1_2) {
12804         printf("%s Vulkan12Struct requires Vulkan 1.2+, skipping test\n", kSkipPrefix);
12805         return;
12806     }
12807     if (!DeviceExtensionSupported(gpu(), nullptr, VK_EXT_BUFFER_DEVICE_ADDRESS_EXTENSION_NAME)) {
12808         printf("%s %s not supported, skipping tests\n", kSkipPrefix, VK_EXT_BUFFER_DEVICE_ADDRESS_EXTENSION_NAME);
12809         return;
12810     }
12811     m_device_extension_names.push_back(VK_EXT_BUFFER_DEVICE_ADDRESS_EXTENSION_NAME);
12812 
12813     VkPhysicalDeviceVulkan12Features features12 = LvlInitStruct<VkPhysicalDeviceVulkan12Features>();
12814     features12.bufferDeviceAddress = VK_TRUE;
12815 
12816     float priority = 1.0f;
12817     VkDeviceQueueCreateInfo queue_info = LvlInitStruct<VkDeviceQueueCreateInfo>();
12818     queue_info.queueFamilyIndex = 0;
12819     queue_info.queueCount = 1;
12820     queue_info.pQueuePriorities = &priority;
12821 
12822     const char *enabled_ext = VK_EXT_BUFFER_DEVICE_ADDRESS_EXTENSION_NAME;
12823 
12824     VkDeviceCreateInfo device_create_info = LvlInitStruct<VkDeviceCreateInfo>(&features12);
12825     device_create_info.queueCreateInfoCount = 1;
12826     device_create_info.pQueueCreateInfos = &queue_info;
12827     device_create_info.enabledExtensionCount = 1;
12828     device_create_info.ppEnabledExtensionNames = &enabled_ext;
12829 
12830     VkDevice testDevice;
12831     m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkDeviceCreateInfo-pNext-04748");
12832     vk::CreateDevice(gpu(), &device_create_info, NULL, &testDevice);
12833     m_errorMonitor->VerifyFound();
12834 }
12835 
TEST_F(VkLayerTest,InvalidCmdSetDiscardRectangleEXTOffsets)12836 TEST_F(VkLayerTest, InvalidCmdSetDiscardRectangleEXTOffsets) {
12837     TEST_DESCRIPTION("Test CmdSetDiscardRectangleEXT with invalid offsets in pDiscardRectangles");
12838 
12839     if (!InstanceExtensionSupported(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME)) {
12840         printf("%s Did not find required instance extension %s; skipped.\n", kSkipPrefix,
12841                VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
12842         return;
12843     }
12844     m_instance_extension_names.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
12845     ASSERT_NO_FATAL_FAILURE(InitFramework());
12846     if (!DeviceExtensionSupported(gpu(), nullptr, VK_EXT_DISCARD_RECTANGLES_EXTENSION_NAME)) {
12847         printf("%s %s not supported, skipping test\n", kSkipPrefix, VK_EXT_DISCARD_RECTANGLES_EXTENSION_NAME);
12848         return;
12849     }
12850     m_device_extension_names.push_back(VK_EXT_DISCARD_RECTANGLES_EXTENSION_NAME);
12851     InitState();
12852 
12853     VkPhysicalDeviceDiscardRectanglePropertiesEXT discard_rectangle_properties =
12854         LvlInitStruct<VkPhysicalDeviceDiscardRectanglePropertiesEXT>();
12855 
12856     auto phys_dev_props_2 = LvlInitStruct<VkPhysicalDeviceProperties2>();
12857     phys_dev_props_2.pNext = &discard_rectangle_properties;
12858     vk::GetPhysicalDeviceProperties2(gpu(), &phys_dev_props_2);
12859 
12860     auto fpCmdSetDiscardRectangleEXT =
12861         (PFN_vkCmdSetDiscardRectangleEXT)vk::GetDeviceProcAddr(m_device->device(), "vkCmdSetDiscardRectangleEXT");
12862 
12863     if (discard_rectangle_properties.maxDiscardRectangles == 0) {
12864         printf("%s Discard rectangles are not supported, skipping test\n", kSkipPrefix);
12865         return;
12866     }
12867 
12868     VkRect2D discard_rectangles = {};
12869     discard_rectangles.offset.x = -1;
12870     discard_rectangles.offset.y = 0;
12871     discard_rectangles.extent.width = 64;
12872     discard_rectangles.extent.height = 64;
12873 
12874     m_commandBuffer->begin();
12875     m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdSetDiscardRectangleEXT-x-00587");
12876     fpCmdSetDiscardRectangleEXT(m_commandBuffer->handle(), 0, 1, &discard_rectangles);
12877     m_errorMonitor->VerifyFound();
12878 
12879     discard_rectangles.offset.x = 0;
12880     discard_rectangles.offset.y = -32;
12881     m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdSetDiscardRectangleEXT-x-00587");
12882     fpCmdSetDiscardRectangleEXT(m_commandBuffer->handle(), 0, 1, &discard_rectangles);
12883     m_errorMonitor->VerifyFound();
12884     m_commandBuffer->end();
12885 }
12886 
TEST_F(VkLayerTest,BeginQueryTypeTransformFeedbackStream)12887 TEST_F(VkLayerTest, BeginQueryTypeTransformFeedbackStream) {
12888     TEST_DESCRIPTION(
12889         "Call CmdBeginQuery with query type transform feedback stream when transformFeedbackQueries is not supported.");
12890 
12891     if (!InstanceExtensionSupported(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME)) {
12892         printf("%s Did not find required instance extension %s; skipped.\n", kSkipPrefix,
12893                VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
12894         return;
12895     }
12896     m_instance_extension_names.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
12897     ASSERT_NO_FATAL_FAILURE(InitFramework());
12898     if (!DeviceExtensionSupported(gpu(), nullptr, VK_EXT_TRANSFORM_FEEDBACK_EXTENSION_NAME)) {
12899         printf("%s %s not supported, skipping test\n", kSkipPrefix, VK_EXT_TRANSFORM_FEEDBACK_EXTENSION_NAME);
12900         return;
12901     }
12902     m_device_extension_names.push_back(VK_EXT_TRANSFORM_FEEDBACK_EXTENSION_NAME);
12903     InitState();
12904 
12905     VkPhysicalDeviceTransformFeedbackPropertiesEXT transform_feedback_props =
12906         LvlInitStruct<VkPhysicalDeviceTransformFeedbackPropertiesEXT>();
12907     VkPhysicalDeviceProperties2 phys_dev_props_2 = LvlInitStruct<VkPhysicalDeviceProperties2>(&transform_feedback_props);
12908 
12909     vk::GetPhysicalDeviceProperties2(gpu(), &phys_dev_props_2);
12910     if (transform_feedback_props.transformFeedbackQueries) {
12911         printf("%s Transform feedback queries are supported, skipping test\n", kSkipPrefix);
12912         return;
12913     }
12914 
12915     VkQueryPool query_pool;
12916     VkQueryPoolCreateInfo query_pool_create_info = LvlInitStruct<VkQueryPoolCreateInfo>();
12917     query_pool_create_info.queryType = VK_QUERY_TYPE_TRANSFORM_FEEDBACK_STREAM_EXT;
12918     query_pool_create_info.queryCount = 1;
12919     vk::CreateQueryPool(m_device->device(), &query_pool_create_info, nullptr, &query_pool);
12920 
12921     m_commandBuffer->begin();
12922     vk::CmdResetQueryPool(m_commandBuffer->handle(), query_pool, 0, 1);
12923     m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdBeginQuery-queryType-02328");
12924     vk::CmdBeginQuery(m_commandBuffer->handle(), query_pool, 0, 0);
12925     m_errorMonitor->VerifyFound();
12926     m_commandBuffer->end();
12927 
12928     vk::DestroyQueryPool(m_device->device(), query_pool, nullptr);
12929 }
12930 
TEST_F(VkLayerTest,CmdSetDiscardRectangleEXTRectangleCountOverflow)12931 TEST_F(VkLayerTest, CmdSetDiscardRectangleEXTRectangleCountOverflow) {
12932     TEST_DESCRIPTION("Test CmdSetDiscardRectangleEXT with invalid offsets in pDiscardRectangles");
12933 
12934     if (!InstanceExtensionSupported(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME)) {
12935         printf("%s Did not find required instance extension %s; skipped.\n", kSkipPrefix,
12936                VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
12937         return;
12938     }
12939     m_instance_extension_names.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
12940 
12941     ASSERT_NO_FATAL_FAILURE(InitFramework());
12942     if (!DeviceExtensionSupported(gpu(), nullptr, VK_EXT_DISCARD_RECTANGLES_EXTENSION_NAME)) {
12943         printf("%s %s not supported, skipping test\n", kSkipPrefix, VK_EXT_DISCARD_RECTANGLES_EXTENSION_NAME);
12944         return;
12945     }
12946     m_device_extension_names.push_back(VK_EXT_DISCARD_RECTANGLES_EXTENSION_NAME);
12947     InitState();
12948 
12949     auto vkCmdSetDiscardRectangleEXT =
12950         (PFN_vkCmdSetDiscardRectangleEXT)vk::GetDeviceProcAddr(m_device->device(), "vkCmdSetDiscardRectangleEXT");
12951 
12952     VkRect2D discard_rectangles = {};
12953     discard_rectangles.offset.x = 1;
12954     discard_rectangles.offset.y = 0;
12955     discard_rectangles.extent.width = static_cast<uint32_t>(std::numeric_limits<int32_t>::max());
12956     discard_rectangles.extent.height = 64;
12957 
12958     m_commandBuffer->begin();
12959     m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdSetDiscardRectangleEXT-offset-00588");
12960     vkCmdSetDiscardRectangleEXT(m_commandBuffer->handle(), 0, 1, &discard_rectangles);
12961     m_errorMonitor->VerifyFound();
12962 
12963     discard_rectangles.offset.x = 0;
12964     discard_rectangles.offset.y = std::numeric_limits<int32_t>::max();
12965     discard_rectangles.extent.width = 64;
12966     discard_rectangles.extent.height = 1;
12967     m_commandBuffer->begin();
12968     m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdSetDiscardRectangleEXT-offset-00589");
12969     vkCmdSetDiscardRectangleEXT(m_commandBuffer->handle(), 0, 1, &discard_rectangles);
12970     m_errorMonitor->VerifyFound();
12971 }
12972 
TEST_F(VkLayerTest,ValidateBeginQueryQueryPoolType)12973 TEST_F(VkLayerTest, ValidateBeginQueryQueryPoolType) {
12974     TEST_DESCRIPTION("Test CmdBeginQuery with invalid queryPool queryType");
12975 
12976     if (!InstanceExtensionSupported(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME)) {
12977         printf("%s Did not find required instance extension %s; skipped.\n", kSkipPrefix,
12978                VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
12979         return;
12980     }
12981     m_instance_extension_names.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
12982 
12983     ASSERT_NO_FATAL_FAILURE(InitFramework(m_errorMonitor));
12984     bool khr_acceleration_structure = false;
12985     bool nv_ray_tracing = false;
12986     bool ext_transform_feedback = false;
12987     if (DeviceExtensionSupported(VK_KHR_MAINTENANCE_3_EXTENSION_NAME) &&
12988         DeviceExtensionSupported(VK_EXT_DESCRIPTOR_INDEXING_EXTENSION_NAME) &&
12989         DeviceExtensionSupported(VK_KHR_BUFFER_DEVICE_ADDRESS_EXTENSION_NAME) &&
12990         DeviceExtensionSupported(VK_KHR_DEFERRED_HOST_OPERATIONS_EXTENSION_NAME) &&
12991         DeviceExtensionSupported(VK_KHR_ACCELERATION_STRUCTURE_EXTENSION_NAME)) {
12992         m_device_extension_names.push_back(VK_KHR_MAINTENANCE_3_EXTENSION_NAME);
12993         m_device_extension_names.push_back(VK_EXT_DESCRIPTOR_INDEXING_EXTENSION_NAME);
12994         m_device_extension_names.push_back(VK_KHR_BUFFER_DEVICE_ADDRESS_EXTENSION_NAME);
12995         m_device_extension_names.push_back(VK_KHR_DEFERRED_HOST_OPERATIONS_EXTENSION_NAME);
12996         m_device_extension_names.push_back(VK_KHR_ACCELERATION_STRUCTURE_EXTENSION_NAME);
12997         khr_acceleration_structure = true;
12998     }
12999 
13000     if (DeviceExtensionSupported(VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME) &&
13001         DeviceExtensionSupported(VK_NV_RAY_TRACING_EXTENSION_NAME)) {
13002         m_device_extension_names.push_back(VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME);
13003         m_device_extension_names.push_back(VK_NV_RAY_TRACING_EXTENSION_NAME);
13004         nv_ray_tracing = true;
13005     }
13006     if (!khr_acceleration_structure && !nv_ray_tracing) {
13007         printf("%s Extensions %s and %s are not supported.\n", kSkipPrefix, VK_KHR_ACCELERATION_STRUCTURE_EXTENSION_NAME,
13008                VK_NV_RAY_TRACING_EXTENSION_NAME);
13009         return;
13010     }
13011     if (DeviceExtensionSupported(gpu(), nullptr, VK_EXT_TRANSFORM_FEEDBACK_EXTENSION_NAME)) {
13012         m_device_extension_names.push_back(VK_EXT_TRANSFORM_FEEDBACK_EXTENSION_NAME);
13013         ext_transform_feedback = true;
13014     }
13015     ASSERT_NO_FATAL_FAILURE(InitState());
13016 
13017     PFN_vkCmdBeginQueryIndexedEXT vkCmdBeginQueryIndexedEXT =
13018         (PFN_vkCmdBeginQueryIndexedEXT)vk::GetDeviceProcAddr(m_device->device(), "vkCmdBeginQueryIndexedEXT");
13019 
13020     VkQueryPoolCreateInfo query_pool_ci = LvlInitStruct<VkQueryPoolCreateInfo>();
13021     query_pool_ci.queryCount = 1;
13022 
13023     if (khr_acceleration_structure) {
13024         {
13025             query_pool_ci.queryType = VK_QUERY_TYPE_ACCELERATION_STRUCTURE_COMPACTED_SIZE_KHR;
13026             VkQueryPool query_pool;
13027             vk::CreateQueryPool(device(), &query_pool_ci, nullptr, &query_pool);
13028 
13029             m_commandBuffer->begin();
13030             m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdBeginQuery-queryType-04728");
13031             vk::CmdBeginQuery(m_commandBuffer->handle(), query_pool, 0, 0);
13032             m_errorMonitor->VerifyFound();
13033 
13034             if (ext_transform_feedback) {
13035                 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdBeginQueryIndexedEXT-queryType-04728");
13036                 vkCmdBeginQueryIndexedEXT(m_commandBuffer->handle(), query_pool, 0, 0, 0);
13037                 m_errorMonitor->VerifyFound();
13038             }
13039             m_commandBuffer->end();
13040         }
13041 
13042         {
13043             query_pool_ci.queryType = VK_QUERY_TYPE_ACCELERATION_STRUCTURE_SERIALIZATION_SIZE_KHR;
13044             VkQueryPool query_pool;
13045             vk::CreateQueryPool(device(), &query_pool_ci, nullptr, &query_pool);
13046 
13047             m_commandBuffer->begin();
13048             m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdBeginQuery-queryType-04728");
13049             vk::CmdBeginQuery(m_commandBuffer->handle(), query_pool, 0, 0);
13050             m_errorMonitor->VerifyFound();
13051 
13052             if (ext_transform_feedback) {
13053                 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdBeginQueryIndexedEXT-queryType-04728");
13054                 vkCmdBeginQueryIndexedEXT(m_commandBuffer->handle(), query_pool, 0, 0, 0);
13055                 m_errorMonitor->VerifyFound();
13056             }
13057             m_commandBuffer->end();
13058         }
13059     }
13060     if (nv_ray_tracing) {
13061         query_pool_ci.queryType = VK_QUERY_TYPE_ACCELERATION_STRUCTURE_COMPACTED_SIZE_NV;
13062         VkQueryPool query_pool;
13063         vk::CreateQueryPool(device(), &query_pool_ci, nullptr, &query_pool);
13064 
13065         m_commandBuffer->begin();
13066         m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdBeginQuery-queryType-04729");
13067         vk::CmdBeginQuery(m_commandBuffer->handle(), query_pool, 0, 0);
13068         m_errorMonitor->VerifyFound();
13069 
13070         if (ext_transform_feedback) {
13071             m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdBeginQueryIndexedEXT-queryType-04729");
13072             vkCmdBeginQueryIndexedEXT(m_commandBuffer->handle(), query_pool, 0, 0, 0);
13073             m_errorMonitor->VerifyFound();
13074         }
13075         m_commandBuffer->end();
13076     }
13077 }
13078 
TEST_F(VkLayerTest,GetQueryPoolResultsFlags)13079 TEST_F(VkLayerTest, GetQueryPoolResultsFlags) {
13080     TEST_DESCRIPTION("Test GetQueryPoolResults with invalid pData and stride");
13081     SetTargetApiVersion(VK_API_VERSION_1_1);
13082 
13083     ASSERT_NO_FATAL_FAILURE(InitFramework(m_errorMonitor));
13084 
13085     if (DeviceValidationVersion() < VK_API_VERSION_1_1) {
13086         printf("%s Test does not run on Vulkan 1.0, skipping test\n", kSkipPrefix);
13087         return;
13088     }
13089     if (DeviceExtensionSupported(gpu(), nullptr, VK_KHR_VIDEO_QUEUE_EXTENSION_NAME)) {
13090         m_device_extension_names.push_back(VK_KHR_VIDEO_QUEUE_EXTENSION_NAME);
13091     } else {
13092         printf("%s Extension %s is not supported.\n", kSkipPrefix, VK_KHR_VIDEO_QUEUE_EXTENSION_NAME);
13093         return;
13094     }
13095     ASSERT_NO_FATAL_FAILURE(InitState());
13096 
13097     vk_testing::QueryPool query_pool;
13098     VkQueryPoolCreateInfo qpci = LvlInitStruct<VkQueryPoolCreateInfo>();
13099     qpci.queryType = VK_QUERY_TYPE_OCCLUSION;
13100     qpci.queryCount = 1;
13101     query_pool.init(*m_device, qpci);
13102 
13103     const size_t out_data_size = 16;
13104     uint8_t data[out_data_size];
13105 
13106     VkQueryResultFlags flags = VK_QUERY_RESULT_WITH_STATUS_BIT_KHR | VK_QUERY_RESULT_WITH_AVAILABILITY_BIT;
13107 
13108     m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkGetQueryPoolResults-flags-04811");
13109     vk::GetQueryPoolResults(m_device->device(), query_pool.handle(), 0, 1, out_data_size, data + 1, 4, flags);
13110     m_errorMonitor->VerifyFound();
13111 }
13112 
TEST_F(VkLayerTest,QueryPoolResultStatusOnly)13113 TEST_F(VkLayerTest, QueryPoolResultStatusOnly) {
13114     TEST_DESCRIPTION("Request result status only query result.");
13115 
13116     SetTargetApiVersion(VK_API_VERSION_1_1);
13117     ASSERT_NO_FATAL_FAILURE(InitFramework(m_errorMonitor));
13118 
13119     if (DeviceValidationVersion() < VK_API_VERSION_1_1) {
13120         printf("%s Test does not run on Vulkan 1.0, skipping test\n", kSkipPrefix);
13121         return;
13122     }
13123     if (!DeviceExtensionSupported(gpu(), nullptr, VK_KHR_VIDEO_QUEUE_EXTENSION_NAME)) {
13124         printf("%s Video queue Extension not supported, skipping tests\n", kSkipPrefix);
13125         return;
13126     }
13127     m_device_extension_names.push_back(VK_KHR_VIDEO_QUEUE_EXTENSION_NAME);
13128     ASSERT_NO_FATAL_FAILURE(InitState());
13129 
13130     VkQueryPool query_pool;
13131     VkQueryPoolCreateInfo query_pool_ci = LvlInitStruct<VkQueryPoolCreateInfo>();
13132     query_pool_ci.queryType = VK_QUERY_TYPE_RESULT_STATUS_ONLY_KHR;
13133     query_pool_ci.queryCount = 1;
13134     VkResult err = vk::CreateQueryPool(m_device->device(), &query_pool_ci, nullptr, &query_pool);
13135     if (err != VK_SUCCESS) {
13136         printf("%s Required query not supported, skipping tests\n", kSkipPrefix);
13137         return;
13138     }
13139 
13140     const size_t out_data_size = 16;
13141     uint8_t data[out_data_size];
13142     m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkGetQueryPoolResults-queryType-04810");
13143     vk::GetQueryPoolResults(m_device->device(), query_pool, 0, 1, out_data_size, &data, sizeof(uint32_t), 0);
13144     m_errorMonitor->VerifyFound();
13145 
13146     vk::DestroyQueryPool(m_device->handle(), query_pool, NULL);
13147 }
13148 
TEST_F(VkLayerTest,InvalidCopyQueryResults)13149 TEST_F(VkLayerTest, InvalidCopyQueryResults) {
13150     TEST_DESCRIPTION("Test CmdCopyQueryPoolResults with unsupported query type");
13151     SetTargetApiVersion(VK_API_VERSION_1_1);
13152 
13153     ASSERT_NO_FATAL_FAILURE(InitFramework(m_errorMonitor));
13154 
13155     if (DeviceValidationVersion() < VK_API_VERSION_1_1) {
13156         printf("%s Test does not run on Vulkan 1.0, skipping test\n", kSkipPrefix);
13157         return;
13158     }
13159     if (DeviceExtensionSupported(gpu(), nullptr, VK_KHR_VIDEO_QUEUE_EXTENSION_NAME)) {
13160         m_device_extension_names.push_back(VK_KHR_VIDEO_QUEUE_EXTENSION_NAME);
13161     } else {
13162         printf("%s Extension %s is not supported.\n", kSkipPrefix, VK_KHR_VIDEO_QUEUE_EXTENSION_NAME);
13163         return;
13164     }
13165     ASSERT_NO_FATAL_FAILURE(InitState());
13166 
13167     VkQueryPool query_pool_encode;
13168     VkQueryPool query_pool_result;
13169     VkQueryPoolCreateInfo qpci = LvlInitStruct<VkQueryPoolCreateInfo>();
13170     qpci.queryType = VK_QUERY_TYPE_VIDEO_ENCODE_BITSTREAM_BUFFER_RANGE_KHR;
13171     qpci.queryCount = 1;
13172 
13173     VkResult err;
13174     err = vk::CreateQueryPool(m_device->device(), &qpci, nullptr, &query_pool_encode);
13175     if (err != VK_SUCCESS) {
13176         printf("%s Required query not supported, skipping tests\n", kSkipPrefix);
13177         return;
13178     }
13179     qpci.queryType = VK_QUERY_TYPE_RESULT_STATUS_ONLY_KHR;
13180     err = vk::CreateQueryPool(m_device->device(), &qpci, nullptr, &query_pool_result);
13181     if (err != VK_SUCCESS) {
13182         printf("%s Required query not supported, skipping tests\n", kSkipPrefix);
13183         return;
13184     }
13185 
13186     VkBufferObj buffer;
13187     buffer.init(*m_device, 128, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, VK_BUFFER_USAGE_TRANSFER_DST_BIT);
13188     m_commandBuffer->begin();
13189 
13190     m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdCopyQueryPoolResults-queryType-04812");
13191     vk::CmdCopyQueryPoolResults(m_commandBuffer->handle(), query_pool_encode, 0, 1, buffer.handle(), 0, 0, 0);
13192     m_errorMonitor->VerifyFound();
13193 
13194     m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdCopyQueryPoolResults-queryType-04812");
13195     vk::CmdCopyQueryPoolResults(m_commandBuffer->handle(), query_pool_result, 0, 1, buffer.handle(), 0, 0, 0);
13196     m_errorMonitor->VerifyFound();
13197 
13198     m_commandBuffer->end();
13199 
13200     vk::DestroyQueryPool(device(), query_pool_encode, nullptr);
13201     vk::DestroyQueryPool(device(), query_pool_result, nullptr);
13202 }
13203 
TEST_F(VkLayerTest,CopyUnboundAccelerationStructure)13204 TEST_F(VkLayerTest, CopyUnboundAccelerationStructure) {
13205     TEST_DESCRIPTION("Test CmdCopyQueryPoolResults with unsupported query type");
13206 
13207     AddRequiredExtensions(VK_KHR_ACCELERATION_STRUCTURE_EXTENSION_NAME);
13208     ASSERT_NO_FATAL_FAILURE(InitFramework(m_errorMonitor));
13209     if (!AreRequestedExtensionsEnabled()) {
13210         printf("%s Extension %s is not supported, skipping test.\n", kSkipPrefix, VK_KHR_ACCELERATION_STRUCTURE_EXTENSION_NAME);
13211         return;
13212     }
13213     ASSERT_NO_FATAL_FAILURE(InitState());
13214 
13215     auto vkCmdCopyAccelerationStructureKHR = reinterpret_cast<PFN_vkCmdCopyAccelerationStructureKHR>(
13216         vk::GetDeviceProcAddr(device(), "vkCmdCopyAccelerationStructureKHR"));
13217     assert(vkCmdCopyAccelerationStructureKHR != nullptr);
13218 
13219     auto vkGetBufferDeviceAddressKHR =
13220         (PFN_vkGetBufferDeviceAddressKHR)vk::GetDeviceProcAddr(device(), "vkGetBufferDeviceAddressKHR");
13221     assert(vkGetBufferDeviceAddressKHR != nullptr);
13222 
13223     auto buffer_ci = LvlInitStruct<VkBufferCreateInfo>();
13224     buffer_ci.size = 4096;
13225     buffer_ci.usage = VK_BUFFER_USAGE_ACCELERATION_STRUCTURE_STORAGE_BIT_KHR;
13226     VkBufferObj buffer_no_mem;
13227     buffer_no_mem.init_no_mem(*m_device, buffer_ci);
13228 
13229     VkBufferObj buffer;
13230     buffer.init(*m_device, buffer_ci);
13231 
13232     VkBufferDeviceAddressInfo device_address_info = LvlInitStruct<VkBufferDeviceAddressInfo>();
13233     device_address_info.buffer = buffer_no_mem.handle();
13234     VkDeviceAddress device_address = vkGetBufferDeviceAddressKHR(m_device->handle(), &device_address_info);
13235     if (device_address == 0) {
13236         printf("%s Failed to get device address, skipping test.\n", kSkipPrefix);
13237         return;
13238     }
13239 
13240     auto as_create_info = LvlInitStruct<VkAccelerationStructureCreateInfoKHR>();
13241     as_create_info.buffer = buffer_no_mem.handle();
13242     as_create_info.type = VK_ACCELERATION_STRUCTURE_TYPE_BOTTOM_LEVEL_KHR;
13243     as_create_info.deviceAddress = device_address;
13244 
13245     vk_testing::AccelerationStructureKHR invalid_as(*m_device, as_create_info);
13246 
13247     device_address_info.buffer = buffer.handle();
13248     as_create_info.buffer = buffer.handle();
13249     vk_testing::AccelerationStructureKHR valid_as(*m_device, as_create_info);
13250 
13251     auto copy_info = LvlInitStruct<VkCopyAccelerationStructureInfoKHR>();
13252     copy_info.src = invalid_as.handle();
13253     copy_info.dst = valid_as.handle();
13254     copy_info.mode = VK_COPY_ACCELERATION_STRUCTURE_MODE_CLONE_KHR;
13255 
13256     m_commandBuffer->begin();
13257 
13258     m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkCopyAccelerationStructureInfoKHR-buffer-03718");
13259     vkCmdCopyAccelerationStructureKHR(m_commandBuffer->handle(), &copy_info);
13260     m_errorMonitor->VerifyFound();
13261 
13262     copy_info.src = valid_as.handle();
13263     copy_info.dst = invalid_as.handle();
13264     m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkCopyAccelerationStructureInfoKHR-buffer-03719");
13265     vkCmdCopyAccelerationStructureKHR(m_commandBuffer->handle(), &copy_info);
13266     m_errorMonitor->VerifyFound();
13267 
13268     m_commandBuffer->end();
13269 }
13270 
TEST_F(VkLayerTest,DestroyActiveQueryPool)13271 TEST_F(VkLayerTest, DestroyActiveQueryPool) {
13272     TEST_DESCRIPTION("Destroy query pool after GetQueryPoolResults() without VK_QUERY_RESULT_PARTIAL_BIT returns VK_SUCCESS");
13273 
13274     ASSERT_NO_FATAL_FAILURE(Init());
13275 
13276     VkQueryPoolCreateInfo query_pool_create_info = LvlInitStruct<VkQueryPoolCreateInfo>();
13277     query_pool_create_info.queryType = VK_QUERY_TYPE_TIMESTAMP;
13278     query_pool_create_info.queryCount = 1;
13279 
13280     VkQueryPool query_pool;
13281     vk::CreateQueryPool(device(), &query_pool_create_info, nullptr, &query_pool);
13282 
13283     m_commandBuffer->begin();
13284     vk::CmdResetQueryPool(m_commandBuffer->handle(), query_pool, 0, 1);
13285     vk::CmdWriteTimestamp(m_commandBuffer->handle(), VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT, query_pool, 0);
13286     m_commandBuffer->end();
13287 
13288     VkSubmitInfo submit_info = LvlInitStruct<VkSubmitInfo>();
13289     submit_info.commandBufferCount = 1;
13290     submit_info.pCommandBuffers = &m_commandBuffer->handle();
13291     vk::QueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
13292 
13293     const size_t out_data_size = 16;
13294     uint8_t data[out_data_size];
13295     VkResult res;
13296     do {
13297         res = vk::GetQueryPoolResults(m_device->device(), query_pool, 0, 1, out_data_size, &data, 4, 0);
13298     } while (res != VK_SUCCESS);
13299 
13300     // Submit the command buffer again, making query pool in use and invalid to destroy
13301     vk::QueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
13302 
13303     m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkDestroyQueryPool-queryPool-00793");
13304     vk::DestroyQueryPool(m_device->handle(), query_pool, nullptr);
13305     m_errorMonitor->VerifyFound();
13306 }
13307 
TEST_F(VkLayerTest,ValidateExternalMemoryImageLayout)13308 TEST_F(VkLayerTest, ValidateExternalMemoryImageLayout) {
13309     TEST_DESCRIPTION("Validate layout of image with external memory");
13310 
13311 #ifdef _WIN32
13312     const auto handle_type = VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_BIT_KHR;
13313 #else
13314     const auto handle_type = VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT_KHR;
13315 #endif
13316 
13317     SetTargetApiVersion(VK_API_VERSION_1_1);
13318     ASSERT_NO_FATAL_FAILURE(Init());
13319     if (DeviceValidationVersion() < VK_API_VERSION_1_1) {
13320         printf("%s test requires Vulkan 1.1 extensions, not available, skipping test.\n", kSkipPrefix);
13321         return;
13322     }
13323 
13324     VkExternalMemoryImageCreateInfo external_mem = LvlInitStruct<VkExternalMemoryImageCreateInfo>();
13325     external_mem.handleTypes = handle_type;
13326 
13327     VkExternalMemoryImageCreateInfoNV external_mem_nv = LvlInitStruct<VkExternalMemoryImageCreateInfoNV>();
13328     external_mem_nv.handleTypes = handle_type;
13329 
13330     VkImageCreateInfo ici = LvlInitStruct<VkImageCreateInfo>(&external_mem);
13331     ici.imageType = VK_IMAGE_TYPE_2D;
13332     ici.arrayLayers = 1;
13333     ici.extent = {32, 32, 1};
13334     ici.format = VK_FORMAT_R8G8B8A8_UNORM;
13335     ici.mipLevels = 1;
13336     ici.initialLayout = VK_IMAGE_LAYOUT_PREINITIALIZED;
13337     ici.samples = VK_SAMPLE_COUNT_1_BIT;
13338     ici.tiling = VK_IMAGE_TILING_OPTIMAL;
13339     ici.usage = VK_IMAGE_USAGE_SAMPLED_BIT;
13340 
13341     VkImage test_image;
13342     m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkImageCreateInfo-pNext-01443");
13343     vk::CreateImage(device(), &ici, nullptr, &test_image);
13344     m_errorMonitor->VerifyFound();
13345 
13346     ici.pNext = &external_mem_nv;
13347     m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkImageCreateInfo-pNext-01443");
13348     vk::CreateImage(device(), &ici, nullptr, &test_image);
13349     m_errorMonitor->VerifyFound();
13350 }
13351 
TEST_F(VkLayerTest,ValidateCreateSamplerWithBorderColorSwizzle)13352 TEST_F(VkLayerTest, ValidateCreateSamplerWithBorderColorSwizzle) {
13353     TEST_DESCRIPTION("Validate vkCreateSampler with VkSamplerBorderColorComponentMappingCreateInfoEXT");
13354 
13355     ASSERT_NO_FATAL_FAILURE(InitFramework());
13356     ASSERT_NO_FATAL_FAILURE(InitState());
13357 
13358     VkSamplerBorderColorComponentMappingCreateInfoEXT border_color_component_mapping = {};
13359     border_color_component_mapping.sType = VK_STRUCTURE_TYPE_SAMPLER_BORDER_COLOR_COMPONENT_MAPPING_CREATE_INFO_EXT;
13360     border_color_component_mapping.components = {VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY,
13361                                                  VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY};
13362 
13363     VkSamplerCreateInfo sampler_create_info = SafeSaneSamplerCreateInfo();
13364     sampler_create_info.pNext = &border_color_component_mapping;
13365 
13366     VkSampler sampler = VK_NULL_HANDLE;
13367 
13368     m_errorMonitor->SetDesiredFailureMsg(kErrorBit,
13369                                          "VUID-VkSamplerBorderColorComponentMappingCreateInfoEXT-borderColorSwizzle-06437");
13370     vk::CreateSampler(device(), &sampler_create_info, nullptr, &sampler);
13371     m_errorMonitor->VerifyFound();
13372 
13373     vk::DestroySampler(device(), sampler, nullptr);
13374 }
13375 
TEST_F(VkLayerTest,ValidateBeginRenderingDisabled)13376 TEST_F(VkLayerTest, ValidateBeginRenderingDisabled) {
13377     TEST_DESCRIPTION("Validate VK_KHR_dynamic_rendering VUs when disabled");
13378 
13379     SetTargetApiVersion(VK_API_VERSION_1_1);
13380 
13381     ASSERT_NO_FATAL_FAILURE(InitFramework());
13382 
13383     if (!AddRequiredDeviceExtensions(VK_KHR_DYNAMIC_RENDERING_EXTENSION_NAME)) {
13384         printf("%s %s Extension not supported, skipping tests\n", kSkipPrefix, VK_AMD_DEVICE_COHERENT_MEMORY_EXTENSION_NAME);
13385         return;
13386     }
13387 
13388     ASSERT_NO_FATAL_FAILURE(InitState());
13389 
13390     auto begin_rendering_info = LvlInitStruct<VkRenderingInfoKHR>();
13391 
13392     m_commandBuffer->begin();
13393 
13394     m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdBeginRenderingKHR-dynamicRendering-06446");
13395     m_commandBuffer->BeginRendering(begin_rendering_info);
13396     m_errorMonitor->VerifyFound();
13397 
13398     m_commandBuffer->end();
13399 }
13400