blob: 56dab038ecd6e2f7d9009ada06e4c34eb49d6be0 [file] [log] [blame]
Camden Stockerf55721f2019-09-09 11:04:49 -06001/*
sfricke-samsungae54c1e2022-01-21 05:35:21 -08002 * Copyright (c) 2015-2022 The Khronos Group Inc.
3 * Copyright (c) 2015-2022 Valve Corporation
4 * Copyright (c) 2015-2022 LunarG, Inc.
5 * Copyright (c) 2015-2022 Google, Inc.
Nadav Gevafe502952021-05-21 13:51:56 -04006 * Modifications Copyright (C) 2020 Advanced Micro Devices, Inc. All rights reserved.
Camden Stockerf55721f2019-09-09 11:04:49 -06007 *
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: Camden Stocker <camden@lunarg.com>
Nadav Gevafe502952021-05-21 13:51:56 -040015 * Author: Nadav Geva <nadav.geva@amd.com>
Camden Stockerf55721f2019-09-09 11:04:49 -060016 */
17
18#include "cast_utils.h"
19#include "layer_validation_tests.h"
Nathaniel Cesario4ce98382021-05-28 11:33:20 -060020#include "best_practices_error_enums.h"
paul-lunarg821b85f2022-07-18 15:57:57 -060021#include "core_validation_error_enums.h"
Camden Stockerf55721f2019-09-09 11:04:49 -060022
Camden Stocker9ac2d8e2019-11-15 12:40:40 -080023void VkBestPracticesLayerTest::InitBestPracticesFramework() {
sfricke-samsungae54c1e2022-01-21 05:35:21 -080024 // Enable all vendor-specific checks
25 InitBestPracticesFramework("");
Nadav Gevafe502952021-05-21 13:51:56 -040026}
27
28void VkBestPracticesLayerTest::InitBestPracticesFramework(const char* vendor_checks_to_enable) {
29 // Enable the vendor-specific checks spcified by vendor_checks_to_enable
Mark Lobodzinski8f8d6932020-06-08 14:25:36 -060030 VkLayerSettingValueDataEXT bp_setting_string_value{};
Nadav Gevafe502952021-05-21 13:51:56 -040031 bp_setting_string_value.arrayString.pCharArray = vendor_checks_to_enable;
Mark Lobodzinski8f8d6932020-06-08 14:25:36 -060032 bp_setting_string_value.arrayString.count = sizeof(bp_setting_string_value.arrayString.pCharArray);
33 VkLayerSettingValueEXT bp_vendor_all_setting_val = {"enables", VK_LAYER_SETTING_VALUE_TYPE_STRING_ARRAY_EXT,
34 bp_setting_string_value};
35 VkLayerSettingsEXT bp_settings{static_cast<VkStructureType>(VK_STRUCTURE_TYPE_INSTANCE_LAYER_SETTINGS_EXT), nullptr, 1,
36 &bp_vendor_all_setting_val};
37 features_.pNext = &bp_settings;
paul-lunargfc7ac122022-07-06 15:49:39 -060038
Petr Kraus3e6cd032020-04-14 20:41:16 +020039 InitFramework(m_errorMonitor, &features_);
Camden Stocker9ac2d8e2019-11-15 12:40:40 -080040}
41
Mark Lobodzinski48b5b782020-04-29 12:00:52 -060042TEST_F(VkBestPracticesLayerTest, ValidateReturnCodes) {
arno1689b372022-08-25 19:34:15 +020043 SetTargetApiVersion(VK_API_VERSION_1_2);
Mark Lobodzinski48b5b782020-04-29 12:00:52 -060044
sjfrickea83fbb92022-07-01 13:57:27 +090045 AddSurfaceExtension();
Mark Lobodzinski48b5b782020-04-29 12:00:52 -060046 ASSERT_NO_FATAL_FAILURE(InitBestPracticesFramework());
47
sjfrickea83fbb92022-07-01 13:57:27 +090048 if (!AreRequiredExtensionsEnabled()) {
49 GTEST_SKIP() << RequiredExtensionsNotSupported() << " not supported.";
Mark Lobodzinski48b5b782020-04-29 12:00:52 -060050 }
51
52 ASSERT_NO_FATAL_FAILURE(InitState());
arno1689b372022-08-25 19:34:15 +020053 if (DeviceValidationVersion() < VK_API_VERSION_1_2) {
arno-lunarg28838122022-08-26 17:09:02 +020054 GTEST_SKIP() << "At least Vulkan version 1.2 is required, skipping test.";
arno1689b372022-08-25 19:34:15 +020055 }
Mark Lobodzinski48b5b782020-04-29 12:00:52 -060056
57 if (!InitSwapchain()) {
arno-lunarg28838122022-08-26 17:09:02 +020058 GTEST_SKIP() << "Cannot create surface or swapchain, skipping CmdCopySwapchainImage test";
Mark Lobodzinski48b5b782020-04-29 12:00:52 -060059 }
60
61 // Attempt to force an invalid return code for an unsupported format
62 VkImageFormatProperties2 image_format_prop = {};
63 image_format_prop.sType = VK_STRUCTURE_TYPE_IMAGE_FORMAT_PROPERTIES_2;
64 VkPhysicalDeviceImageFormatInfo2 image_format_info = {};
65 image_format_info.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_FORMAT_INFO_2;
66 image_format_info.format = VK_FORMAT_R32G32B32_SFLOAT;
67 image_format_info.tiling = VK_IMAGE_TILING_LINEAR;
68 image_format_info.type = VK_IMAGE_TYPE_3D;
69 image_format_info.usage = VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT;
70
71 VkResult result = vk::GetPhysicalDeviceImageFormatProperties2(m_device->phy().handle(), &image_format_info, &image_format_prop);
72 // Only run this test if this super-wierd format is not supported
73 if (VK_SUCCESS != result) {
74 m_errorMonitor->SetDesiredFailureMsg(kWarningBit, "UNASSIGNED-BestPractices-Error-Result");
75 vk::GetPhysicalDeviceImageFormatProperties2(m_device->phy().handle(), &image_format_info, &image_format_prop);
76 m_errorMonitor->VerifyFound();
77 }
78
79 if (IsPlatform(kMockICD) || DeviceSimulation()) {
sjfricke11b24692022-06-21 20:49:53 +090080 GTEST_SKIP() << "Test not supported by MockICD";
Mark Lobodzinski48b5b782020-04-29 12:00:52 -060081 }
82
83 // Force a non-success success code by only asking for a subset of query results
84 uint32_t format_count;
85 std::vector<VkSurfaceFormatKHR> formats;
86 result = vk::GetPhysicalDeviceSurfaceFormatsKHR(gpu(), m_surface, &format_count, NULL);
87 if (result != VK_SUCCESS || format_count <= 1) {
88 printf("%s test requires 2 or more extensions available, skipping test.\n", kSkipPrefix);
89 return;
90 }
91 format_count -= 1;
92 formats.resize(format_count);
93
Mark Lobodzinskie7215152020-05-11 08:21:23 -060094 m_errorMonitor->SetDesiredFailureMsg(kInformationBit, "UNASSIGNED-BestPractices-NonSuccess-Result");
Mark Lobodzinski48b5b782020-04-29 12:00:52 -060095 result = vk::GetPhysicalDeviceSurfaceFormatsKHR(gpu(), m_surface, &format_count, formats.data());
96 m_errorMonitor->VerifyFound();
97}
98
Petr Kraus3e6cd032020-04-14 20:41:16 +020099TEST_F(VkBestPracticesLayerTest, UseDeprecatedInstanceExtensions) {
100 TEST_DESCRIPTION("Create an instance with a deprecated extension.");
Mark Lobodzinski6167e102020-02-24 17:03:55 -0700101
sjfricked8e01c52022-07-06 14:09:04 +0900102 SetTargetApiVersion(VK_API_VERSION_1_1);
103 AddRequiredExtensions(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
104
105 ASSERT_NO_FATAL_FAILURE(InitBestPracticesFramework());
106
107 if (DeviceValidationVersion() < VK_API_VERSION_1_1) {
108 GTEST_SKIP() << "At least Vulkan version 1.1 is required";
Mark Lobodzinski6167e102020-02-24 17:03:55 -0700109 }
Mark Lobodzinski997ee312020-02-19 11:28:07 -0700110
sjfricked8e01c52022-07-06 14:09:04 +0900111 if (!AreRequiredExtensionsEnabled()) {
112 GTEST_SKIP() << RequiredExtensionsNotSupported() << " not supported";
Mark Lobodzinski997ee312020-02-19 11:28:07 -0700113 }
114
Mark Lobodzinski7f2b55c2020-05-14 12:22:21 -0600115 // Create a 1.1 vulkan instance and request an extension promoted to core in 1.1
Mark Lobodzinski6167e102020-02-24 17:03:55 -0700116 m_errorMonitor->SetDesiredFailureMsg(kWarningBit, "UNASSIGNED-BestPractices-vkCreateInstance-deprecated-extension");
Hannes Harnisch607d1d92021-07-10 18:44:56 +0200117 m_errorMonitor->SetDesiredFailureMsg(kWarningBit, "UNASSIGNED-BestPractices-vkCreateInstance-specialuse-extension-debugging");
Petr Kraus3e6cd032020-04-14 20:41:16 +0200118 VkInstance dummy;
119 auto features = features_;
120 auto ici = GetInstanceCreateInfo();
121 features.pNext = ici.pNext;
122 ici.pNext = &features;
123 vk::CreateInstance(&ici, nullptr, &dummy);
Mark Lobodzinski997ee312020-02-19 11:28:07 -0700124 m_errorMonitor->VerifyFound();
Mark Lobodzinski7f2b55c2020-05-14 12:22:21 -0600125
126 // Create a 1.0 vulkan instance and request an extension promoted to core in 1.1
Mark Lobodzinskic33f5302020-05-21 13:55:32 -0600127 m_errorMonitor->SetUnexpectedError("UNASSIGNED-khronos-Validation-debug-build-warning-message");
Jeremy Gebben81c943e2022-01-20 13:47:01 -0700128 m_errorMonitor->SetUnexpectedError("UNASSIGNED-khronos-Validation-fine-grained-locking-warning-message");
Jeremy Gebben8315def2021-08-12 11:07:00 -0600129 VkApplicationInfo new_info{};
130 new_info.apiVersion = VK_API_VERSION_1_0;
131 new_info.pApplicationName = ici.pApplicationInfo->pApplicationName;
132 new_info.applicationVersion = ici.pApplicationInfo->applicationVersion;
133 new_info.pEngineName = ici.pApplicationInfo->pEngineName;
134 new_info.engineVersion = ici.pApplicationInfo->engineVersion;
135 ici.pApplicationInfo = &new_info;
Mark Lobodzinski7f2b55c2020-05-14 12:22:21 -0600136 vk::CreateInstance(&ici, nullptr, &dummy);
137 vk::DestroyInstance(dummy, nullptr);
Petr Kraus3e6cd032020-04-14 20:41:16 +0200138}
139
140TEST_F(VkBestPracticesLayerTest, UseDeprecatedDeviceExtensions) {
141 TEST_DESCRIPTION("Create a device with a deprecated extension.");
142
sjfricke50955f32022-06-05 10:12:52 +0900143 SetTargetApiVersion(VK_API_VERSION_1_2);
sjfricked8e01c52022-07-06 14:09:04 +0900144 AddRequiredExtensions(VK_KHR_BUFFER_DEVICE_ADDRESS_EXTENSION_NAME);
Petr Kraus3e6cd032020-04-14 20:41:16 +0200145
146 ASSERT_NO_FATAL_FAILURE(InitBestPracticesFramework());
Mark Lobodzinski997ee312020-02-19 11:28:07 -0700147
Mark Lobodzinski6167e102020-02-24 17:03:55 -0700148 if (DeviceValidationVersion() < VK_API_VERSION_1_2) {
sjfricke50955f32022-06-05 10:12:52 +0900149 GTEST_SKIP() << "At least Vulkan version 1.2 is required";
Mark Lobodzinski6167e102020-02-24 17:03:55 -0700150 }
151
sjfricked8e01c52022-07-06 14:09:04 +0900152 if (!AreRequiredExtensionsEnabled()) {
153 GTEST_SKIP() << RequiredExtensionsNotSupported() << " not supported";
Mark Lobodzinski997ee312020-02-19 11:28:07 -0700154 }
155
156 VkDevice local_device;
157 VkDeviceCreateInfo dev_info = {};
158 VkDeviceQueueCreateInfo queue_info = {};
159 queue_info.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
160 queue_info.pNext = NULL;
161 queue_info.queueFamilyIndex = 0;
162 queue_info.queueCount = 1;
paul-lunarg821b85f2022-07-18 15:57:57 -0600163 float qp = 1;
164 queue_info.pQueuePriorities = &qp;
Mark Lobodzinski997ee312020-02-19 11:28:07 -0700165 dev_info.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
166 dev_info.pNext = nullptr;
167 dev_info.queueCreateInfoCount = 1;
168 dev_info.pQueueCreateInfos = &queue_info;
169 dev_info.enabledLayerCount = 0;
170 dev_info.ppEnabledLayerNames = NULL;
171 dev_info.enabledExtensionCount = m_device_extension_names.size();
172 dev_info.ppEnabledExtensionNames = m_device_extension_names.data();
173
Mark Lobodzinskif22437ac2020-03-04 10:32:18 -0700174 m_errorMonitor->SetDesiredFailureMsg(kWarningBit, "UNASSIGNED-BestPractices-vkCreateDevice-deprecated-extension");
Mark Lobodzinski997ee312020-02-19 11:28:07 -0700175 vk::CreateDevice(this->gpu(), &dev_info, NULL, &local_device);
176 m_errorMonitor->VerifyFound();
177}
178
Mark Lobodzinski1019fbc2020-11-10 08:12:54 -0700179TEST_F(VkBestPracticesLayerTest, SpecialUseExtensions) {
180 TEST_DESCRIPTION("Create a device with a 'specialuse' extension.");
181
182 ASSERT_NO_FATAL_FAILURE(InitBestPracticesFramework());
183
184 if (DeviceExtensionSupported(gpu(), nullptr, VK_EXT_DEPTH_CLIP_ENABLE_EXTENSION_NAME)) {
185 m_device_extension_names.push_back(VK_EXT_DEPTH_CLIP_ENABLE_EXTENSION_NAME);
186 } else {
187 printf("%s %s Extension not supported, skipping test\n", kSkipPrefix, VK_EXT_DEPTH_CLIP_ENABLE_EXTENSION_NAME);
188 return;
189 }
190
191 VkDevice local_device;
192 VkDeviceCreateInfo dev_info = {};
193 VkDeviceQueueCreateInfo queue_info = {};
194 queue_info.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
195 queue_info.pNext = NULL;
196 queue_info.queueFamilyIndex = 0;
197 queue_info.queueCount = 1;
paul-lunarg821b85f2022-07-18 15:57:57 -0600198 float qp = 1;
199 queue_info.pQueuePriorities = &qp;
Mark Lobodzinski1019fbc2020-11-10 08:12:54 -0700200 dev_info.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
201 dev_info.pNext = nullptr;
202 dev_info.queueCreateInfoCount = 1;
203 dev_info.pQueueCreateInfos = &queue_info;
204 dev_info.enabledLayerCount = 0;
205 dev_info.ppEnabledLayerNames = NULL;
206 dev_info.enabledExtensionCount = m_device_extension_names.size();
207 dev_info.ppEnabledExtensionNames = m_device_extension_names.data();
208
Hannes Harnisch607d1d92021-07-10 18:44:56 +0200209 m_errorMonitor->SetDesiredFailureMsg(kWarningBit, "UNASSIGNED-BestPractices-vkCreateDevice-specialuse-extension-d3demulation");
Mark Lobodzinski1019fbc2020-11-10 08:12:54 -0700210 vk::CreateDevice(this->gpu(), &dev_info, NULL, &local_device);
211 m_errorMonitor->VerifyFound();
212}
213
Camden Stocker9ac2d8e2019-11-15 12:40:40 -0800214TEST_F(VkBestPracticesLayerTest, CmdClearAttachmentTest) {
215 TEST_DESCRIPTION("Test for validating usage of vkCmdClearAttachments");
216
217 InitBestPracticesFramework();
Camden Stockerf55721f2019-09-09 11:04:49 -0600218 InitState();
219 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
220
221 m_commandBuffer->begin();
Hans-Kristian Arntzen3cbe1972021-07-08 12:20:07 +0200222 m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
223
224 // Main thing we care about for this test is that the VkImage obj we're
225 // clearing matches Color Attachment of FB
226 // Also pass down other dummy params to keep driver and paramchecker happy
227 VkClearAttachment color_attachment;
228 color_attachment.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
229 color_attachment.clearValue.color.float32[0] = 1.0;
230 color_attachment.clearValue.color.float32[1] = 1.0;
231 color_attachment.clearValue.color.float32[2] = 1.0;
232 color_attachment.clearValue.color.float32[3] = 1.0;
233 color_attachment.colorAttachment = 0;
234 VkClearRect clear_rect = {{{0, 0}, {(uint32_t)m_width, (uint32_t)m_height}}, 0, 1};
235
236 // Call for full-sized FB Color attachment prior to issuing a Draw
237 m_errorMonitor->SetDesiredFailureMsg(kPerformanceWarningBit, "UNASSIGNED-BestPractices-DrawState-ClearCmdBeforeDraw");
238
239 vk::CmdClearAttachments(m_commandBuffer->handle(), 1, &color_attachment, 1, &clear_rect);
240 m_errorMonitor->VerifyFound();
241}
242
243TEST_F(VkBestPracticesLayerTest, CmdClearAttachmentTestSecondary) {
244 TEST_DESCRIPTION("Test for validating usage of vkCmdClearAttachments with secondary command buffers");
245
246 InitBestPracticesFramework();
247 InitState();
248
249 if (IsPlatform(PlatformType::kShieldTV) || IsPlatform(PlatformType::kShieldTVb)) {
250 printf("%s Test CmdClearAttachmentTestSecondary is unstable on ShieldTV, skipping test.\n", kSkipPrefix);
251 return;
252 }
253
254 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
255
256 m_commandBuffer->begin();
Hans-Kristian Arntzenbf8da8b2021-06-18 11:37:44 +0200257
Hans-Kristian Arntzen59e8ae32021-07-08 12:13:27 +0200258 VkCommandBufferObj secondary_full_clear(m_device, m_commandPool, VK_COMMAND_BUFFER_LEVEL_SECONDARY);
259 VkCommandBufferObj secondary_small_clear(m_device, m_commandPool, VK_COMMAND_BUFFER_LEVEL_SECONDARY);
Hans-Kristian Arntzenbf8da8b2021-06-18 11:37:44 +0200260 VkCommandBufferBeginInfo begin_info = { VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO };
261 begin_info.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT |
262 VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT;
263 VkCommandBufferInheritanceInfo inherit_info = { VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO };
264 begin_info.pInheritanceInfo = &inherit_info;
265 inherit_info.subpass = 0;
266 inherit_info.renderPass = m_renderPassBeginInfo.renderPass;
Camden Stockerf55721f2019-09-09 11:04:49 -0600267
268 // Main thing we care about for this test is that the VkImage obj we're
269 // clearing matches Color Attachment of FB
270 // Also pass down other dummy params to keep driver and paramchecker happy
271 VkClearAttachment color_attachment;
272 color_attachment.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
273 color_attachment.clearValue.color.float32[0] = 1.0;
274 color_attachment.clearValue.color.float32[1] = 1.0;
275 color_attachment.clearValue.color.float32[2] = 1.0;
276 color_attachment.clearValue.color.float32[3] = 1.0;
277 color_attachment.colorAttachment = 0;
Hans-Kristian Arntzen4aa5eb32021-06-18 11:10:16 +0200278 VkClearRect clear_rect_small = {{{0, 0}, {(uint32_t)m_width - 1u, (uint32_t)m_height - 1u}}, 0, 1};
Camden Stockerf55721f2019-09-09 11:04:49 -0600279 VkClearRect clear_rect = {{{0, 0}, {(uint32_t)m_width, (uint32_t)m_height}}, 0, 1};
280
Hans-Kristian Arntzenbf8da8b2021-06-18 11:37:44 +0200281 m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
282 {
283 // Small clears which don't cover the render area should not trigger the warning.
284 vk::CmdClearAttachments(m_commandBuffer->handle(), 1, &color_attachment, 1, &clear_rect_small);
Hans-Kristian Arntzenbf8da8b2021-06-18 11:37:44 +0200285 // Call for full-sized FB Color attachment prior to issuing a Draw
286 m_errorMonitor->SetDesiredFailureMsg(kPerformanceWarningBit, "UNASSIGNED-BestPractices-DrawState-ClearCmdBeforeDraw");
Nadav Gevafe502952021-05-21 13:51:56 -0400287 // This test may also trigger other warnings
288 m_errorMonitor->SetAllowedFailureMsg("UNASSIGNED-BestPractices-VkCommandBuffer-AvoidSecondaryCmdBuffers");
289 m_errorMonitor->SetAllowedFailureMsg("UNASSIGNED-BestPractices-VkCommandBuffer-AvoidSmallSecondaryCmdBuffers");
290
Hans-Kristian Arntzenbf8da8b2021-06-18 11:37:44 +0200291 vk::CmdClearAttachments(m_commandBuffer->handle(), 1, &color_attachment, 1, &clear_rect);
292 m_errorMonitor->VerifyFound();
293 }
294 m_commandBuffer->EndRenderPass();
295
Hans-Kristian Arntzen59e8ae32021-07-08 12:13:27 +0200296 secondary_small_clear.begin(&begin_info);
297 secondary_full_clear.begin(&begin_info);
298 vk::CmdClearAttachments(secondary_small_clear.handle(), 1, &color_attachment, 1, &clear_rect_small);
299 vk::CmdClearAttachments(secondary_full_clear.handle(), 1, &color_attachment, 1, &clear_rect);
300 secondary_small_clear.end();
301 secondary_full_clear.end();
Hans-Kristian Arntzenbf8da8b2021-06-18 11:37:44 +0200302
303 m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo, VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS);
304 {
305 // Small clears which don't cover the render area should not trigger the warning.
Hans-Kristian Arntzen59e8ae32021-07-08 12:13:27 +0200306 vk::CmdExecuteCommands(m_commandBuffer->handle(), 1, &secondary_small_clear.handle());
Hans-Kristian Arntzenbf8da8b2021-06-18 11:37:44 +0200307 // Call for full-sized FB Color attachment prior to issuing a Draw
308 m_errorMonitor->SetDesiredFailureMsg(kPerformanceWarningBit, "UNASSIGNED-BestPractices-DrawState-ClearCmdBeforeDraw");
Nadav Gevafe502952021-05-21 13:51:56 -0400309 // This test may also trigger other warnings
310 m_errorMonitor->SetAllowedFailureMsg("UNASSIGNED-BestPractices-VkCommandBuffer-AvoidSecondaryCmdBuffers");
311 m_errorMonitor->SetAllowedFailureMsg("UNASSIGNED-BestPractices-VkCommandBuffer-AvoidSmallSecondaryCmdBuffers");
312 m_errorMonitor->SetAllowedFailureMsg("UNASSIGNED-BestPractices-CmdPool-DisparateSizedCmdBuffers");
313
Hans-Kristian Arntzen59e8ae32021-07-08 12:13:27 +0200314 vk::CmdExecuteCommands(m_commandBuffer->handle(), 1, &secondary_full_clear.handle());
Hans-Kristian Arntzenbf8da8b2021-06-18 11:37:44 +0200315 m_errorMonitor->VerifyFound();
316 }
317 m_commandBuffer->EndRenderPass();
Camden Stockerf55721f2019-09-09 11:04:49 -0600318}
Mark Lobodzinski93a978f2019-12-20 11:20:07 -0700319
Hannes Harnischa95e7fb2021-07-15 13:00:51 +0200320TEST_F(VkBestPracticesLayerTest, CmdBeginRenderPassZeroSizeRenderArea) {
321 TEST_DESCRIPTION("Test for getting warned when render area is 0 in VkRenderPassBeginInfo during vkCmdBeginRenderPass");
322
323 InitBestPracticesFramework();
324 InitState();
325 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
326
327 m_errorMonitor->SetDesiredFailureMsg(kWarningBit, "UNASSIGNED-BestPractices-vkCmdBeginRenderPass-zero-size-render-area");
328
329 m_commandBuffer->begin();
330 m_renderPassBeginInfo.renderArea.extent.width = 0;
331 m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
332
333 m_errorMonitor->VerifyFound();
Hannes Harnischa95e7fb2021-07-15 13:00:51 +0200334}
335
Mark Lobodzinski93a978f2019-12-20 11:20:07 -0700336TEST_F(VkBestPracticesLayerTest, VtxBufferBadIndex) {
Attilio Provenzanoc7eca552020-02-27 12:02:39 +0000337 InitBestPracticesFramework();
338 InitState();
339
Mark Lobodzinski20310782020-02-28 14:25:17 -0700340 m_errorMonitor->SetDesiredFailureMsg(kPerformanceWarningBit, "UNASSIGNED-BestPractices-DrawState-VtxIndexOutOfBounds");
Mark Lobodzinski93a978f2019-12-20 11:20:07 -0700341
Attilio Provenzanoc7eca552020-02-27 12:02:39 +0000342 // This test may also trigger other warnings
343 m_errorMonitor->SetAllowedFailureMsg("UNASSIGNED-BestPractices-vkAllocateMemory-small-allocation");
344 m_errorMonitor->SetAllowedFailureMsg("UNASSIGNED-BestPractices-vkBindMemory-small-dedicated-allocation");
Nadav Gevafe502952021-05-21 13:51:56 -0400345 m_errorMonitor->SetAllowedFailureMsg("UNASSIGNED-BestPractices-VkCommandBuffer-AvoidTinyCmdBuffers");
Mark Lobodzinski93a978f2019-12-20 11:20:07 -0700346
347 ASSERT_NO_FATAL_FAILURE(InitViewport());
348 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
349
350 VkPipelineMultisampleStateCreateInfo pipe_ms_state_ci = {};
351 pipe_ms_state_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO;
352 pipe_ms_state_ci.pNext = NULL;
353 pipe_ms_state_ci.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT;
354 pipe_ms_state_ci.sampleShadingEnable = 0;
355 pipe_ms_state_ci.minSampleShading = 1.0;
356 pipe_ms_state_ci.pSampleMask = NULL;
357
358 CreatePipelineHelper pipe(*this);
359 pipe.InitInfo();
360 pipe.pipe_ms_state_ci_ = pipe_ms_state_ci;
361 pipe.InitState();
362 pipe.CreateGraphicsPipeline();
363
364 m_commandBuffer->begin();
365 m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
366 vk::CmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.pipeline_);
367 // Don't care about actual data, just need to get to draw to flag error
368 const float vbo_data[3] = {1.f, 0.f, 1.f};
Attilio Provenzanoc7eca552020-02-27 12:02:39 +0000369 VkConstantBufferObj vbo(m_device, sizeof(vbo_data), (const void*)&vbo_data, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT);
Mark Lobodzinski93a978f2019-12-20 11:20:07 -0700370 m_commandBuffer->BindVertexBuffer(&vbo, (VkDeviceSize)0, 1); // VBO idx 1, but no VBO in PSO
371 m_commandBuffer->Draw(1, 0, 0, 0);
372
373 m_errorMonitor->VerifyFound();
374
375 m_commandBuffer->EndRenderPass();
376 m_commandBuffer->end();
377}
Mark Lobodzinskie91181d2020-01-14 09:55:30 -0700378
379// This is a positive test. No failures are expected.
380TEST_F(VkBestPracticesLayerTest, TestDestroyFreeNullHandles) {
381 VkResult err;
382
383 TEST_DESCRIPTION("Call all applicable destroy and free routines with NULL handles, expecting no validation errors");
384
385 InitBestPracticesFramework();
386 InitState();
387
388 ASSERT_NO_FATAL_FAILURE(InitViewport());
389 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
390
Mark Lobodzinskie91181d2020-01-14 09:55:30 -0700391 vk::DestroyBuffer(m_device->device(), VK_NULL_HANDLE, NULL);
392 vk::DestroyBufferView(m_device->device(), VK_NULL_HANDLE, NULL);
393 vk::DestroyCommandPool(m_device->device(), VK_NULL_HANDLE, NULL);
394 vk::DestroyDescriptorPool(m_device->device(), VK_NULL_HANDLE, NULL);
395 vk::DestroyDescriptorSetLayout(m_device->device(), VK_NULL_HANDLE, NULL);
396 vk::DestroyDevice(VK_NULL_HANDLE, NULL);
397 vk::DestroyEvent(m_device->device(), VK_NULL_HANDLE, NULL);
398 vk::DestroyFence(m_device->device(), VK_NULL_HANDLE, NULL);
399 vk::DestroyFramebuffer(m_device->device(), VK_NULL_HANDLE, NULL);
400 vk::DestroyImage(m_device->device(), VK_NULL_HANDLE, NULL);
401 vk::DestroyImageView(m_device->device(), VK_NULL_HANDLE, NULL);
402 vk::DestroyInstance(VK_NULL_HANDLE, NULL);
403 vk::DestroyPipeline(m_device->device(), VK_NULL_HANDLE, NULL);
404 vk::DestroyPipelineCache(m_device->device(), VK_NULL_HANDLE, NULL);
405 vk::DestroyPipelineLayout(m_device->device(), VK_NULL_HANDLE, NULL);
406 vk::DestroyQueryPool(m_device->device(), VK_NULL_HANDLE, NULL);
407 vk::DestroyRenderPass(m_device->device(), VK_NULL_HANDLE, NULL);
408 vk::DestroySampler(m_device->device(), VK_NULL_HANDLE, NULL);
409 vk::DestroySemaphore(m_device->device(), VK_NULL_HANDLE, NULL);
410 vk::DestroyShaderModule(m_device->device(), VK_NULL_HANDLE, NULL);
411
412 VkCommandPool command_pool;
413 VkCommandPoolCreateInfo pool_create_info{};
414 pool_create_info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
415 pool_create_info.queueFamilyIndex = m_device->graphics_queue_node_index_;
416 pool_create_info.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT;
417 vk::CreateCommandPool(m_device->device(), &pool_create_info, nullptr, &command_pool);
418 VkCommandBuffer command_buffers[3] = {};
419 VkCommandBufferAllocateInfo command_buffer_allocate_info{};
420 command_buffer_allocate_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
421 command_buffer_allocate_info.commandPool = command_pool;
422 command_buffer_allocate_info.commandBufferCount = 1;
423 command_buffer_allocate_info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
424 vk::AllocateCommandBuffers(m_device->device(), &command_buffer_allocate_info, &command_buffers[1]);
425 vk::FreeCommandBuffers(m_device->device(), command_pool, 3, command_buffers);
426 vk::DestroyCommandPool(m_device->device(), command_pool, NULL);
427
428 VkDescriptorPoolSize ds_type_count = {};
429 ds_type_count.type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC;
430 ds_type_count.descriptorCount = 1;
431
432 VkDescriptorPoolCreateInfo ds_pool_ci = {};
433 ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
434 ds_pool_ci.pNext = NULL;
435 ds_pool_ci.maxSets = 1;
436 ds_pool_ci.poolSizeCount = 1;
437 ds_pool_ci.flags = VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT;
438 ds_pool_ci.pPoolSizes = &ds_type_count;
439
440 VkDescriptorPool ds_pool;
441 err = vk::CreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool);
442 ASSERT_VK_SUCCESS(err);
443
444 VkDescriptorSetLayoutBinding dsl_binding = {};
445 dsl_binding.binding = 2;
446 dsl_binding.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC;
447 dsl_binding.descriptorCount = 1;
448 dsl_binding.stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT;
449 dsl_binding.pImmutableSamplers = NULL;
450
451 const VkDescriptorSetLayoutObj ds_layout(m_device, {dsl_binding});
452
453 VkDescriptorSet descriptor_sets[3] = {};
454 VkDescriptorSetAllocateInfo alloc_info = {};
455 alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
456 alloc_info.descriptorSetCount = 1;
457 alloc_info.descriptorPool = ds_pool;
458 alloc_info.pSetLayouts = &ds_layout.handle();
459 err = vk::AllocateDescriptorSets(m_device->device(), &alloc_info, &descriptor_sets[1]);
460 ASSERT_VK_SUCCESS(err);
461 vk::FreeDescriptorSets(m_device->device(), ds_pool, 3, descriptor_sets);
462 vk::DestroyDescriptorPool(m_device->device(), ds_pool, NULL);
463
464 vk::FreeMemory(m_device->device(), VK_NULL_HANDLE, NULL);
Mark Lobodzinskie91181d2020-01-14 09:55:30 -0700465}
Attilio Provenzano2f51ed52020-02-27 11:24:35 +0000466
467TEST_F(VkBestPracticesLayerTest, CommandBufferReset) {
468 TEST_DESCRIPTION("Test for validating usage of vkCreateCommandPool with COMMAND_BUFFER_RESET_BIT");
469
470 InitBestPracticesFramework();
471 InitState();
472
Mark Lobodzinski20310782020-02-28 14:25:17 -0700473 m_errorMonitor->SetDesiredFailureMsg(kPerformanceWarningBit,
Attilio Provenzano2f51ed52020-02-27 11:24:35 +0000474 "UNASSIGNED-BestPractices-vkCreateCommandPool-command-buffer-reset");
475
476 VkCommandPool command_pool;
477 VkCommandPoolCreateInfo pool_create_info{};
478 pool_create_info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
479 pool_create_info.queueFamilyIndex = m_device->graphics_queue_node_index_;
480 pool_create_info.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT;
481 vk::CreateCommandPool(m_device->device(), &pool_create_info, nullptr, &command_pool);
482
483 m_errorMonitor->VerifyFound();
484}
485
486TEST_F(VkBestPracticesLayerTest, SimultaneousUse) {
487 TEST_DESCRIPTION("Test for validating usage of vkBeginCommandBuffer with SIMULTANEOUS_USE");
488
489 InitBestPracticesFramework();
490 InitState();
491
Mark Lobodzinski20310782020-02-28 14:25:17 -0700492 m_errorMonitor->SetDesiredFailureMsg(kPerformanceWarningBit, "UNASSIGNED-BestPractices-vkBeginCommandBuffer-simultaneous-use");
Attilio Provenzano2f51ed52020-02-27 11:24:35 +0000493
Attilio Provenzano99a161c2020-02-27 14:17:46 +0000494 m_errorMonitor->SetAllowedFailureMsg("UNASSIGNED-BestPractices-vkBeginCommandBuffer-one-time-submit");
Attilio Provenzano2f51ed52020-02-27 11:24:35 +0000495
496 VkCommandBufferBeginInfo cmd_begin_info{};
497 cmd_begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
498 cmd_begin_info.flags = VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT;
499 vk::BeginCommandBuffer(m_commandBuffer->handle(), &cmd_begin_info);
500
501 m_errorMonitor->VerifyFound();
502}
Attilio Provenzanoc7eca552020-02-27 12:02:39 +0000503
504TEST_F(VkBestPracticesLayerTest, SmallAllocation) {
505 TEST_DESCRIPTION("Test for small memory allocations");
506
507 InitBestPracticesFramework();
508 InitState();
509
Mark Lobodzinski20310782020-02-28 14:25:17 -0700510 m_errorMonitor->SetDesiredFailureMsg(kPerformanceWarningBit, "UNASSIGNED-BestPractices-vkAllocateMemory-small-allocation");
Attilio Provenzanoc7eca552020-02-27 12:02:39 +0000511
512 // Find appropriate memory type for given reqs
513 VkMemoryPropertyFlags mem_props = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT;
514 VkPhysicalDeviceMemoryProperties dev_mem_props = m_device->phy().memory_properties();
515
516 uint32_t mem_type_index = 0;
517 for (mem_type_index = 0; mem_type_index < dev_mem_props.memoryTypeCount; ++mem_type_index) {
518 if (mem_props == (mem_props & dev_mem_props.memoryTypes[mem_type_index].propertyFlags)) break;
519 }
520 EXPECT_LT(mem_type_index, dev_mem_props.memoryTypeCount) << "Could not find a suitable memory type.";
521
522 const uint32_t kSmallAllocationSize = 1024;
523
524 VkMemoryAllocateInfo alloc_info{};
525 alloc_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
526 alloc_info.allocationSize = kSmallAllocationSize;
527 alloc_info.memoryTypeIndex = mem_type_index;
528
529 VkDeviceMemory memory;
530 vk::AllocateMemory(m_device->device(), &alloc_info, nullptr, &memory);
531
532 m_errorMonitor->VerifyFound();
533}
534
535TEST_F(VkBestPracticesLayerTest, SmallDedicatedAllocation) {
536 TEST_DESCRIPTION("Test for small dedicated memory allocations");
537
538 InitBestPracticesFramework();
539 InitState();
540
Mark Lobodzinski20310782020-02-28 14:25:17 -0700541 m_errorMonitor->SetDesiredFailureMsg(kPerformanceWarningBit,
Attilio Provenzanoc7eca552020-02-27 12:02:39 +0000542 "UNASSIGNED-BestPractices-vkBindMemory-small-dedicated-allocation");
543
544 m_errorMonitor->SetAllowedFailureMsg("UNASSIGNED-BestPractices-vkAllocateMemory-small-allocation");
545
546 VkImageCreateInfo image_info{};
547 image_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
548 image_info.extent = {64, 64, 1};
549 image_info.format = VK_FORMAT_R8G8B8A8_UNORM;
550 image_info.imageType = VK_IMAGE_TYPE_2D;
551 image_info.tiling = VK_IMAGE_TILING_OPTIMAL;
552 image_info.usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
553 image_info.samples = VK_SAMPLE_COUNT_1_BIT;
554 image_info.arrayLayers = 1;
555 image_info.mipLevels = 1;
556
557 // Create a small image with a dedicated allocation
558 VkImageObj image(m_device);
559 image.init_no_mem(*m_device, image_info);
560
561 vk_testing::DeviceMemory mem;
562 mem.init(*m_device, vk_testing::DeviceMemory::get_resource_alloc_info(*m_device, image.memory_requirements(),
563 VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT));
564 vk::BindImageMemory(device(), image.handle(), mem.handle(), 0);
565
566 m_errorMonitor->VerifyFound();
567}
Attilio Provenzanocb689b02020-02-27 12:24:33 +0000568
569TEST_F(VkBestPracticesLayerTest, MSImageRequiresMemory) {
570 TEST_DESCRIPTION("Test for MS image that requires memory");
571
572 InitBestPracticesFramework();
573 InitState();
574
Mark Lobodzinski20310782020-02-28 14:25:17 -0700575 m_errorMonitor->SetDesiredFailureMsg(kPerformanceWarningBit,
Attilio Provenzanocb689b02020-02-27 12:24:33 +0000576 "UNASSIGNED-BestPractices-vkCreateRenderPass-image-requires-memory");
577
578 VkAttachmentDescription attachment{};
579 attachment.samples = VK_SAMPLE_COUNT_4_BIT;
580 attachment.loadOp = VK_ATTACHMENT_LOAD_OP_LOAD;
581 attachment.storeOp = VK_ATTACHMENT_STORE_OP_STORE;
paul-lunarg821b85f2022-07-18 15:57:57 -0600582 attachment.format = VK_FORMAT_B8G8R8A8_SRGB;
583 attachment.initialLayout = VK_IMAGE_LAYOUT_ATTACHMENT_OPTIMAL;
584 attachment.finalLayout = VK_IMAGE_LAYOUT_ATTACHMENT_OPTIMAL;
585
586 VkSubpassDescription sd{};
Attilio Provenzanocb689b02020-02-27 12:24:33 +0000587
588 VkRenderPassCreateInfo rp_info{};
589 rp_info.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO;
590 rp_info.attachmentCount = 1;
591 rp_info.pAttachments = &attachment;
paul-lunarg821b85f2022-07-18 15:57:57 -0600592 rp_info.subpassCount = 1;
593 rp_info.pSubpasses = &sd;
Attilio Provenzanocb689b02020-02-27 12:24:33 +0000594
595 VkRenderPass rp;
596 vk::CreateRenderPass(m_device->device(), &rp_info, nullptr, &rp);
597
598 m_errorMonitor->VerifyFound();
599}
600
601TEST_F(VkBestPracticesLayerTest, AttachmentShouldNotBeTransient) {
602 TEST_DESCRIPTION("Test for non-lazy multisampled images");
603
604 InitBestPracticesFramework();
605 InitState();
606
Tony-LunarGf4451f52020-07-14 15:21:24 -0600607 if (IsPlatform(kPixel2XL) || IsPlatform(kPixel3) || IsPlatform(kPixel3aXL) || IsPlatform(kShieldTV) || IsPlatform(kShieldTVb) ||
Mark Lobodzinskia9fb4112020-06-08 15:57:42 -0600608 IsPlatform(kNexusPlayer)) {
609 printf("%s This test seems super-picky on Android platforms\n", kSkipPrefix);
610 return;
611 }
612
Mark Lobodzinski20310782020-02-28 14:25:17 -0700613 m_errorMonitor->SetDesiredFailureMsg(kPerformanceWarningBit,
Attilio Provenzanocb689b02020-02-27 12:24:33 +0000614 "UNASSIGNED-BestPractices-vkCreateFramebuffer-attachment-should-not-be-transient");
615
616 m_errorMonitor->SetAllowedFailureMsg("UNASSIGNED-BestPractices-vkAllocateMemory-small-allocation");
617 m_errorMonitor->SetAllowedFailureMsg("UNASSIGNED-BestPractices-vkBindMemory-small-dedicated-allocation");
618 m_errorMonitor->SetAllowedFailureMsg("UNASSIGNED-BestPractices-vkBindImageMemory-non-lazy-transient-image");
Nadav Gevafe502952021-05-21 13:51:56 -0400619 m_errorMonitor->SetAllowedFailureMsg("UNASSIGNED-BestPractices-VkCommandBuffer-AvoidTinyCmdBuffers");
620 m_errorMonitor->SetAllowedFailureMsg("UNASSIGNED-BestPractices-vkImage-AvoidGeneral");
Attilio Provenzanocb689b02020-02-27 12:24:33 +0000621
622 VkAttachmentDescription attachment{};
623 attachment.samples = VK_SAMPLE_COUNT_1_BIT;
624 attachment.loadOp = VK_ATTACHMENT_LOAD_OP_LOAD;
625 attachment.storeOp = VK_ATTACHMENT_STORE_OP_STORE;
paul-lunarg821b85f2022-07-18 15:57:57 -0600626 attachment.format = VK_FORMAT_R8G8B8A8_UNORM;
627 attachment.initialLayout = VK_IMAGE_LAYOUT_ATTACHMENT_OPTIMAL;
628 attachment.finalLayout = VK_IMAGE_LAYOUT_ATTACHMENT_OPTIMAL;
629
630 VkSubpassDescription sd{};
Attilio Provenzanocb689b02020-02-27 12:24:33 +0000631
632 VkRenderPassCreateInfo rp_info{};
633 rp_info.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO;
634 rp_info.attachmentCount = 1;
635 rp_info.pAttachments = &attachment;
paul-lunarg821b85f2022-07-18 15:57:57 -0600636 rp_info.subpassCount = 1;
637 rp_info.pSubpasses = &sd;
Attilio Provenzanocb689b02020-02-27 12:24:33 +0000638
639 VkRenderPass rp = VK_NULL_HANDLE;
640 vk::CreateRenderPass(m_device->device(), &rp_info, nullptr, &rp);
641
642 VkImageCreateInfo image_info{};
643 image_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
644 image_info.extent = {1920, 1080, 1};
645 image_info.format = VK_FORMAT_R8G8B8A8_UNORM;
646 image_info.imageType = VK_IMAGE_TYPE_2D;
647 image_info.tiling = VK_IMAGE_TILING_OPTIMAL;
648 image_info.usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT;
649 image_info.samples = VK_SAMPLE_COUNT_1_BIT;
650 image_info.arrayLayers = 1;
651 image_info.mipLevels = 1;
652
653 VkImageObj image(m_device);
654 image.init(&image_info);
655
656 VkImageViewCreateInfo iv_info{};
657 iv_info.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
658 iv_info.format = VK_FORMAT_R8G8B8A8_UNORM;
659 iv_info.image = image.handle();
660 iv_info.viewType = VK_IMAGE_VIEW_TYPE_2D;
661 iv_info.subresourceRange = {VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1};
662 iv_info.components = {VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_A};
663
664 VkImageView image_view = VK_NULL_HANDLE;
665 vk::CreateImageView(m_device->device(), &iv_info, nullptr, &image_view);
666
667 VkFramebufferCreateInfo fb_info{};
668 fb_info.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO;
669 fb_info.renderPass = rp;
670 fb_info.layers = 1;
671 fb_info.width = 1920;
672 fb_info.height = 1080;
673 fb_info.attachmentCount = 1;
674 fb_info.pAttachments = &image_view;
675
676 VkFramebuffer fb = VK_NULL_HANDLE;
677 vk::CreateFramebuffer(m_device->device(), &fb_info, nullptr, &fb);
678
679 m_errorMonitor->VerifyFound();
Jeremy Gebben8315def2021-08-12 11:07:00 -0600680 vk::DestroyImageView(m_device->device(), image_view, nullptr);
681 vk::DestroyFramebuffer(m_device->device(), fb, nullptr);
682 vk::DestroyRenderPass(m_device->device(), rp, nullptr);
Attilio Provenzanocb689b02020-02-27 12:24:33 +0000683}
684
685TEST_F(VkBestPracticesLayerTest, TooManyInstancedVertexBuffers) {
686 TEST_DESCRIPTION("Test for too many instanced vertex buffers");
687
688 InitBestPracticesFramework();
689 InitState();
690
Mark Lobodzinski20310782020-02-28 14:25:17 -0700691 m_errorMonitor->SetDesiredFailureMsg(kPerformanceWarningBit,
Attilio Provenzanocb689b02020-02-27 12:24:33 +0000692 "UNASSIGNED-BestPractices-vkCreateGraphicsPipelines-too-many-instanced-vertex-buffers");
693
694 // This test may also trigger the small allocation warnings
695 m_errorMonitor->SetAllowedFailureMsg("UNASSIGNED-BestPractices-vkAllocateMemory-small-allocation");
696 m_errorMonitor->SetAllowedFailureMsg("UNASSIGNED-BestPractices-vkBindMemory-small-dedicated-allocation");
Nadav Gevafe502952021-05-21 13:51:56 -0400697 m_errorMonitor->SetAllowedFailureMsg("UNASSIGNED-BestPractices-VkCommandBuffer-AvoidTinyCmdBuffers");
Attilio Provenzanocb689b02020-02-27 12:24:33 +0000698
paul-lunarg821b85f2022-07-18 15:57:57 -0600699 // This test does not need for the shader to consume the vertex input
700 m_errorMonitor->SetAllowedFailureMsg(kVUID_Core_Shader_OutputNotConsumed);
701
Attilio Provenzanocb689b02020-02-27 12:24:33 +0000702 ASSERT_NO_FATAL_FAILURE(InitViewport());
703 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
704
705 std::vector<VkVertexInputBindingDescription> bindings(2, VkVertexInputBindingDescription{});
706 std::vector<VkVertexInputAttributeDescription> attributes(2, VkVertexInputAttributeDescription{});
707
708 bindings[0].binding = 0;
709 bindings[0].stride = 4;
710 bindings[0].inputRate = VK_VERTEX_INPUT_RATE_INSTANCE;
711
712 attributes[0].binding = 0;
paul-lunarg821b85f2022-07-18 15:57:57 -0600713 attributes[0].location = 0;
714 attributes[0].format = VK_FORMAT_R32_SFLOAT;
Attilio Provenzanocb689b02020-02-27 12:24:33 +0000715
716 bindings[1].binding = 1;
717 bindings[1].stride = 8;
718 bindings[1].inputRate = VK_VERTEX_INPUT_RATE_INSTANCE;
719
720 attributes[1].binding = 1;
paul-lunarg821b85f2022-07-18 15:57:57 -0600721 attributes[1].location = 1;
722 attributes[1].format = VK_FORMAT_R32_SFLOAT;
Attilio Provenzanocb689b02020-02-27 12:24:33 +0000723
724 VkPipelineVertexInputStateCreateInfo vi_state_ci{};
725 vi_state_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO;
726 vi_state_ci.vertexBindingDescriptionCount = static_cast<uint32_t>(bindings.size());
727 vi_state_ci.pVertexBindingDescriptions = bindings.data();
728 vi_state_ci.vertexAttributeDescriptionCount = static_cast<uint32_t>(attributes.size());
729 vi_state_ci.pVertexAttributeDescriptions = attributes.data();
730
731 CreatePipelineHelper pipe(*this);
732 pipe.InitInfo();
733 pipe.vi_ci_ = vi_state_ci;
734 pipe.InitState();
735 pipe.CreateGraphicsPipeline();
736
737 m_errorMonitor->VerifyFound();
738}
739
740TEST_F(VkBestPracticesLayerTest, ClearAttachmentsAfterLoad) {
741 TEST_DESCRIPTION("Test for clearing attachments after load");
742
743 InitBestPracticesFramework();
744 InitState();
745
746 m_clear_via_load_op = false; // Force LOAD_OP_LOAD
747 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
748
Hans-Kristian Arntzen32de8032021-07-09 11:59:37 +0200749 m_errorMonitor->SetDesiredFailureMsg(kPerformanceWarningBit, "UNASSIGNED-BestPractices-vkCmdClearAttachments-clear-after-load");
750
751 // On tiled renderers, this can also trigger a warning about LOAD_OP_LOAD causing a readback
752 m_errorMonitor->SetAllowedFailureMsg("UNASSIGNED-BestPractices-vkCmdBeginRenderPass-attachment-needs-readback");
753 m_errorMonitor->SetAllowedFailureMsg("UNASSIGNED-BestPractices-DrawState-ClearCmdBeforeDraw");
754 m_errorMonitor->SetAllowedFailureMsg("UNASSIGNED-BestPractices-RenderPass-redundant-store");
755 m_errorMonitor->SetAllowedFailureMsg("UNASSIGNED-BestPractices-RenderPass-redundant-clear");
756 m_errorMonitor->SetAllowedFailureMsg("UNASSIGNED-BestPractices-RenderPass-inefficient-clear");
757
758 m_commandBuffer->begin();
759 m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
760
761 VkClearAttachment color_attachment;
762 color_attachment.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
763 color_attachment.clearValue.color.float32[0] = 1.0;
764 color_attachment.clearValue.color.float32[1] = 1.0;
765 color_attachment.clearValue.color.float32[2] = 1.0;
766 color_attachment.clearValue.color.float32[3] = 1.0;
767 color_attachment.colorAttachment = 0;
768 VkClearRect clear_rect = {{{0, 0}, {(uint32_t)m_width, (uint32_t)m_height}}, 0, 1};
769
770 vk::CmdClearAttachments(m_commandBuffer->handle(), 1, &color_attachment, 1, &clear_rect);
771
772 m_errorMonitor->VerifyFound();
773}
774
775TEST_F(VkBestPracticesLayerTest, ClearAttachmentsAfterLoadSecondary) {
776 TEST_DESCRIPTION("Test for clearing attachments after load with secondary command buffers");
777
778 InitBestPracticesFramework();
779 InitState();
780
781 if (IsPlatform(PlatformType::kShieldTV) || IsPlatform(PlatformType::kShieldTVb)) {
782 printf("%s Test CmdClearAttachmentAfterLoadSecondary is unstable on ShieldTV, skipping test.\n", kSkipPrefix);
783 return;
784 }
785
786 m_clear_via_load_op = false; // Force LOAD_OP_LOAD
787 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
788
Attilio Provenzanocb689b02020-02-27 12:24:33 +0000789 // On tiled renderers, this can also trigger a warning about LOAD_OP_LOAD causing a readback
Attilio Provenzano99a161c2020-02-27 14:17:46 +0000790 m_errorMonitor->SetAllowedFailureMsg("UNASSIGNED-BestPractices-vkCmdBeginRenderPass-attachment-needs-readback");
ZandroFargnoliacf12f02020-06-18 16:50:00 +0100791 m_errorMonitor->SetAllowedFailureMsg("UNASSIGNED-BestPractices-RenderPass-redundant-store");
792 m_errorMonitor->SetAllowedFailureMsg("UNASSIGNED-BestPractices-RenderPass-redundant-clear");
793 m_errorMonitor->SetAllowedFailureMsg("UNASSIGNED-BestPractices-RenderPass-inefficient-clear");
Attilio Provenzanocb689b02020-02-27 12:24:33 +0000794
Hans-Kristian Arntzen8d1041e2021-06-18 11:59:08 +0200795 CreatePipelineHelper pipe_masked(*this);
796 pipe_masked.InitInfo();
797 pipe_masked.InitState();
aitor-lunargf15acd52022-03-09 22:13:25 +0100798 pipe_masked.cb_attachments_[0].colorWriteMask = 0;
Hans-Kristian Arntzen8d1041e2021-06-18 11:59:08 +0200799 pipe_masked.CreateGraphicsPipeline();
800
801 CreatePipelineHelper pipe_writes(*this);
802 pipe_writes.InitInfo();
803 pipe_writes.InitState();
aitor-lunargf15acd52022-03-09 22:13:25 +0100804 pipe_writes.cb_attachments_[0].colorWriteMask = 0xf;
Hans-Kristian Arntzen8d1041e2021-06-18 11:59:08 +0200805 pipe_writes.CreateGraphicsPipeline();
806
Attilio Provenzanocb689b02020-02-27 12:24:33 +0000807 m_commandBuffer->begin();
Attilio Provenzanocb689b02020-02-27 12:24:33 +0000808
809 VkClearAttachment color_attachment;
810 color_attachment.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
811 color_attachment.clearValue.color.float32[0] = 1.0;
812 color_attachment.clearValue.color.float32[1] = 1.0;
813 color_attachment.clearValue.color.float32[2] = 1.0;
814 color_attachment.clearValue.color.float32[3] = 1.0;
815 color_attachment.colorAttachment = 0;
816 VkClearRect clear_rect = {{{0, 0}, {(uint32_t)m_width, (uint32_t)m_height}}, 0, 1};
817
Hans-Kristian Arntzen8d1041e2021-06-18 11:59:08 +0200818 // Plain clear after load.
819 m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
820 m_errorMonitor->SetDesiredFailureMsg(kPerformanceWarningBit, "UNASSIGNED-BestPractices-vkCmdClearAttachments-clear-after-load");
821 m_errorMonitor->SetDesiredFailureMsg(kPerformanceWarningBit, "UNASSIGNED-BestPractices-DrawState-ClearCmdBeforeDraw");
822 {
823 vk::CmdClearAttachments(m_commandBuffer->handle(), 1, &color_attachment, 1, &clear_rect);
824 m_errorMonitor->VerifyFound();
825 }
826 m_commandBuffer->EndRenderPass();
Attilio Provenzanocb689b02020-02-27 12:24:33 +0000827
Hans-Kristian Arntzen8d1041e2021-06-18 11:59:08 +0200828 // Test that a masked write is ignored before clear
829 m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
830 m_errorMonitor->SetDesiredFailureMsg(kPerformanceWarningBit, "UNASSIGNED-BestPractices-vkCmdClearAttachments-clear-after-load");
831 {
832 vk::CmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe_masked.pipeline_);
833 m_commandBuffer->Draw(1, 0, 0, 0);
834 vk::CmdClearAttachments(m_commandBuffer->handle(), 1, &color_attachment, 1, &clear_rect);
835 m_errorMonitor->VerifyFound();
836 }
837 m_commandBuffer->EndRenderPass();
838
839 // Test that an actual write will not trigger the clear warning
840 m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
841 {
842 vk::CmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe_writes.pipeline_);
843 m_commandBuffer->Draw(1, 0, 0, 0);
844 vk::CmdClearAttachments(m_commandBuffer->handle(), 1, &color_attachment, 1, &clear_rect);
Hans-Kristian Arntzen8d1041e2021-06-18 11:59:08 +0200845 }
846 m_commandBuffer->EndRenderPass();
847
848 // Try the same thing, but now with secondary command buffers.
849 VkCommandBufferBeginInfo begin_info = { VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO };
850 begin_info.flags = VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT |
851 VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT;
852 VkCommandBufferInheritanceInfo inherit_info = { VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO };
853 begin_info.pInheritanceInfo = &inherit_info;
854 inherit_info.subpass = 0;
855 inherit_info.renderPass = m_renderPassBeginInfo.renderPass;
856
Hans-Kristian Arntzen59e8ae32021-07-08 12:13:27 +0200857 VkCommandBufferObj secondary_clear(m_device, m_commandPool, VK_COMMAND_BUFFER_LEVEL_SECONDARY);
858 VkCommandBufferObj secondary_draw_masked(m_device, m_commandPool, VK_COMMAND_BUFFER_LEVEL_SECONDARY);
859 VkCommandBufferObj secondary_draw_write(m_device, m_commandPool, VK_COMMAND_BUFFER_LEVEL_SECONDARY);
Hans-Kristian Arntzen8d1041e2021-06-18 11:59:08 +0200860
Hans-Kristian Arntzen59e8ae32021-07-08 12:13:27 +0200861 secondary_clear.begin(&begin_info);
862 secondary_draw_masked.begin(&begin_info);
863 secondary_draw_write.begin(&begin_info);
Hans-Kristian Arntzen8d1041e2021-06-18 11:59:08 +0200864
Hans-Kristian Arntzen59e8ae32021-07-08 12:13:27 +0200865 vk::CmdClearAttachments(secondary_clear.handle(), 1, &color_attachment, 1, &clear_rect);
Hans-Kristian Arntzen8d1041e2021-06-18 11:59:08 +0200866
Hans-Kristian Arntzen59e8ae32021-07-08 12:13:27 +0200867 vk::CmdBindPipeline(secondary_draw_masked.handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe_masked.pipeline_);
868 secondary_draw_masked.Draw(1, 0, 0, 0);
Hans-Kristian Arntzen8d1041e2021-06-18 11:59:08 +0200869
Hans-Kristian Arntzen59e8ae32021-07-08 12:13:27 +0200870 vk::CmdBindPipeline(secondary_draw_write.handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe_writes.pipeline_);
871 secondary_draw_write.Draw(1, 0, 0, 0);
Hans-Kristian Arntzen8d1041e2021-06-18 11:59:08 +0200872
Hans-Kristian Arntzen59e8ae32021-07-08 12:13:27 +0200873 secondary_clear.end();
874 secondary_draw_masked.end();
875 secondary_draw_write.end();
Hans-Kristian Arntzen8d1041e2021-06-18 11:59:08 +0200876
877 // Plain clear after load.
878 m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo, VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS);
879 m_errorMonitor->SetDesiredFailureMsg(kPerformanceWarningBit, "UNASSIGNED-BestPractices-vkCmdClearAttachments-clear-after-load");
880 m_errorMonitor->SetDesiredFailureMsg(kPerformanceWarningBit, "UNASSIGNED-BestPractices-DrawState-ClearCmdBeforeDraw");
881 {
Hans-Kristian Arntzen59e8ae32021-07-08 12:13:27 +0200882 vk::CmdExecuteCommands(m_commandBuffer->handle(), 1, &secondary_clear.handle());
Hans-Kristian Arntzen8d1041e2021-06-18 11:59:08 +0200883 m_errorMonitor->VerifyFound();
884 }
885 m_commandBuffer->EndRenderPass();
886
887 // Test that a masked write is ignored before clear
888 m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo, VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS);
889 m_errorMonitor->SetDesiredFailureMsg(kPerformanceWarningBit, "UNASSIGNED-BestPractices-vkCmdClearAttachments-clear-after-load");
890 {
Hans-Kristian Arntzen59e8ae32021-07-08 12:13:27 +0200891 vk::CmdExecuteCommands(m_commandBuffer->handle(), 1, &secondary_draw_masked.handle());
892 vk::CmdExecuteCommands(m_commandBuffer->handle(), 1, &secondary_clear.handle());
Hans-Kristian Arntzen8d1041e2021-06-18 11:59:08 +0200893 m_errorMonitor->VerifyFound();
894 }
895 m_commandBuffer->EndRenderPass();
896
897 // Test that an actual write will not trigger the clear warning
898 m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo, VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS);
899 {
Hans-Kristian Arntzen59e8ae32021-07-08 12:13:27 +0200900 vk::CmdExecuteCommands(m_commandBuffer->handle(), 1, &secondary_draw_write.handle());
901 vk::CmdExecuteCommands(m_commandBuffer->handle(), 1, &secondary_clear.handle());
Hans-Kristian Arntzen8d1041e2021-06-18 11:59:08 +0200902 }
903 m_commandBuffer->EndRenderPass();
Attilio Provenzanocb689b02020-02-27 12:24:33 +0000904}
Attilio Provenzano99a161c2020-02-27 14:17:46 +0000905
Szilard Pappf7a43ed2020-06-10 14:43:00 +0100906TEST_F(VkBestPracticesLayerTest, TripleBufferingTest) {
907 TEST_DESCRIPTION("Test for usage of triple buffering");
908
sjfrickea83fbb92022-07-01 13:57:27 +0900909 AddSurfaceExtension();
Szilard Pappf7a43ed2020-06-10 14:43:00 +0100910 InitBestPracticesFramework();
sjfrickea83fbb92022-07-01 13:57:27 +0900911 if (!AreRequiredExtensionsEnabled()) {
912 GTEST_SKIP() << RequiredExtensionsNotSupported() << " not supported.";
913 }
Szilard Pappf7a43ed2020-06-10 14:43:00 +0100914 InitState();
915 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT,
916 "UNASSIGNED-BestPractices-vkCreateSwapchainKHR-suboptimal-swapchain-image-count");
sfricke-samsungb2c81e32021-02-06 07:19:30 -0800917 if (!InitSurface()) {
918 printf("%s Cannot create surface, skipping test\n", kSkipPrefix);
919 return;
920 }
921 InitSwapchainInfo();
sfricke-samsungd1de19f2021-02-20 23:52:25 -0800922
923 VkBool32 supported;
924 vk::GetPhysicalDeviceSurfaceSupportKHR(gpu(), m_device->graphics_queue_node_index_, m_surface, &supported);
925 if (!supported) {
926 printf("%s Graphics queue does not support present, skipping test\n", kSkipPrefix);
927 return;
928 }
929
ziga-lunarg8c3edb52022-03-30 16:25:14 +0200930 bool fifo_present = false;
931 for (const auto &present_mode : m_surface_present_modes) {
932 if (present_mode == VK_PRESENT_MODE_FIFO_KHR) {
933 fifo_present = true;
934 break;
935 }
936 }
937 if (!fifo_present) {
938 printf("%s fifo present mode not supported, skipping test.\n", kSkipPrefix);
939 return;
940 }
941
Szilard Pappf7a43ed2020-06-10 14:43:00 +0100942 VkImageUsageFlags imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
943 VkSurfaceTransformFlagBitsKHR preTransform = VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR;
Szilard Pappf7a43ed2020-06-10 14:43:00 +0100944
945 VkSwapchainCreateInfoKHR swapchain_create_info = {};
946 swapchain_create_info.sType = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR;
947 swapchain_create_info.pNext = 0;
948 swapchain_create_info.surface = m_surface;
949 swapchain_create_info.minImageCount = 2;
sfricke-samsungb2c81e32021-02-06 07:19:30 -0800950 swapchain_create_info.imageFormat = m_surface_formats[0].format;
951 swapchain_create_info.imageColorSpace = m_surface_formats[0].colorSpace;
952 swapchain_create_info.imageExtent = {m_surface_capabilities.minImageExtent.width, m_surface_capabilities.minImageExtent.height};
Szilard Pappf7a43ed2020-06-10 14:43:00 +0100953 swapchain_create_info.imageArrayLayers = 1;
954 swapchain_create_info.imageUsage = imageUsage;
955 swapchain_create_info.imageSharingMode = VK_SHARING_MODE_EXCLUSIVE;
956 swapchain_create_info.preTransform = preTransform;
sfricke-samsungb2c81e32021-02-06 07:19:30 -0800957 swapchain_create_info.compositeAlpha = m_surface_composite_alpha;
ziga-lunarg8c3edb52022-03-30 16:25:14 +0200958 swapchain_create_info.presentMode = VK_PRESENT_MODE_FIFO_KHR;
Szilard Pappf7a43ed2020-06-10 14:43:00 +0100959 swapchain_create_info.clipped = VK_FALSE;
960 swapchain_create_info.oldSwapchain = 0;
961
paul-lunarg444ec622022-08-09 02:22:41 +0200962 vk::CreateSwapchainKHR(device(), &swapchain_create_info, nullptr, &m_swapchain);
Szilard Pappf7a43ed2020-06-10 14:43:00 +0100963 m_errorMonitor->VerifyFound();
964
Szilard Pappf7a43ed2020-06-10 14:43:00 +0100965 swapchain_create_info.minImageCount = 3;
paul-lunarg444ec622022-08-09 02:22:41 +0200966 vk::CreateSwapchainKHR(device(), &swapchain_create_info, nullptr, &m_swapchain);
Nathaniel Cesariof121d122020-10-08 13:09:46 -0600967}
968
Shannon McPherson7931db52021-03-30 19:23:25 -0600969TEST_F(VkBestPracticesLayerTest, SwapchainCreationTest) {
970 TEST_DESCRIPTION("Test for correct swapchain creation");
971
sjfrickea83fbb92022-07-01 13:57:27 +0900972 AddSurfaceExtension();
Shannon McPherson7931db52021-03-30 19:23:25 -0600973 InitBestPracticesFramework();
sjfrickea83fbb92022-07-01 13:57:27 +0900974 if (!AreRequiredExtensionsEnabled()) {
975 GTEST_SKIP() << RequiredExtensionsNotSupported() << " not supported.";
976 }
Shannon McPherson7931db52021-03-30 19:23:25 -0600977 InitState();
978 if (!InitSurface()) {
979 printf("%s Cannot create surface, skipping test\n", kSkipPrefix);
980 return;
981 }
982
Shannon McPherson7931db52021-03-30 19:23:25 -0600983#ifdef VK_USE_PLATFORM_ANDROID_KHR
984 m_surface_composite_alpha = VK_COMPOSITE_ALPHA_INHERIT_BIT_KHR;
985#else
986 m_surface_composite_alpha = VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR;
987#endif
988
989 VkImageUsageFlags imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
990 VkSurfaceTransformFlagBitsKHR preTransform = VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR;
991
992 VkSwapchainCreateInfoKHR swapchain_create_info = {};
993 swapchain_create_info.sType = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR;
994 swapchain_create_info.pNext = 0;
995 swapchain_create_info.surface = m_surface;
996 swapchain_create_info.minImageCount = 3;
997 swapchain_create_info.imageArrayLayers = 1;
998 swapchain_create_info.imageUsage = imageUsage;
999 swapchain_create_info.imageSharingMode = VK_SHARING_MODE_EXCLUSIVE;
1000 swapchain_create_info.preTransform = preTransform;
1001 swapchain_create_info.compositeAlpha = m_surface_composite_alpha;
1002 swapchain_create_info.presentMode = VK_PRESENT_MODE_MAILBOX_KHR;
1003 swapchain_create_info.clipped = VK_FALSE;
1004 swapchain_create_info.oldSwapchain = 0;
1005
Shannon McPherson7931db52021-03-30 19:23:25 -06001006 // Test for successful swapchain creation when GetPhysicalDeviceSurfaceCapabilitiesKHR() and
1007 // GetPhysicalDeviceSurfaceFormatsKHR() are queried as expected and GetPhysicalDeviceSurfacePresentModesKHR() is not called but
1008 // the present mode is VK_PRESENT_MODE_FIFO_KHR
1009 vk::GetPhysicalDeviceSurfaceCapabilitiesKHR(gpu(), m_surface, &m_surface_capabilities);
1010
1011 uint32_t format_count;
1012 vk::GetPhysicalDeviceSurfaceFormatsKHR(gpu(), m_surface, &format_count, nullptr);
1013 if (format_count != 0) {
1014 m_surface_formats.resize(format_count);
1015 vk::GetPhysicalDeviceSurfaceFormatsKHR(gpu(), m_surface, &format_count, m_surface_formats.data());
1016 }
1017
1018 swapchain_create_info.imageFormat = m_surface_formats[0].format;
1019 swapchain_create_info.imageColorSpace = m_surface_formats[0].colorSpace;
1020 swapchain_create_info.imageExtent = {m_surface_capabilities.minImageExtent.width, m_surface_capabilities.minImageExtent.height};
paul-lunargf6d4ce02022-08-02 17:55:24 +02001021
1022 // GetPhysicalDeviceSurfacePresentModesKHR() not called before trying to create a swapchain
1023 m_errorMonitor->SetDesiredFailureMsg(kWarningBit, "UNASSIGNED-BestPractices-vkCreateSwapchainKHR-surface-not-retrieved");
1024
paul-lunarg17fa9752022-08-29 14:44:21 +02001025 // Warning is thrown any time the present mode is not VK_PRESENT_MODE_FIFO_KHR, but only with ARM BP
1026 m_errorMonitor->SetAllowedFailureMsg("UNASSIGNED-BestPractices-vkCreateSwapchainKHR-swapchain-presentmode-not-fifo");
paul-lunargf6d4ce02022-08-02 17:55:24 +02001027
paul-lunargba4c1272022-08-09 14:13:47 +02001028 vk::CreateSwapchainKHR(device(), &swapchain_create_info, nullptr, &m_swapchain);
paul-lunargf6d4ce02022-08-02 17:55:24 +02001029 m_errorMonitor->VerifyFound();
1030
Shannon McPherson7931db52021-03-30 19:23:25 -06001031 swapchain_create_info.presentMode = VK_PRESENT_MODE_FIFO_KHR;
1032
paul-lunargba4c1272022-08-09 14:13:47 +02001033 vk::CreateSwapchainKHR(device(), &swapchain_create_info, nullptr, &m_swapchain);
Shannon McPherson7931db52021-03-30 19:23:25 -06001034}
1035
Nathaniel Cesariof121d122020-10-08 13:09:46 -06001036TEST_F(VkBestPracticesLayerTest, ExpectedQueryDetails) {
1037 TEST_DESCRIPTION("Check that GetPhysicalDeviceQueueFamilyProperties is working as expected");
1038
Nathaniel Cesario56a96652020-12-30 13:23:42 -07001039 // Vulkan 1.1 required to test vkGetPhysicalDeviceQueueFamilyProperties2
1040 app_info_.apiVersion = VK_API_VERSION_1_1;
1041 // VK_KHR_get_physical_device_properties2 required to test vkGetPhysicalDeviceQueueFamilyProperties2KHR
1042 instance_extensions_.emplace_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
Nathaniel Cesariof121d122020-10-08 13:09:46 -06001043 ASSERT_NO_FATAL_FAILURE(InitBestPracticesFramework());
1044 const vk_testing::PhysicalDevice phys_device_obj(gpu_);
1045
1046 std::vector<VkQueueFamilyProperties> queue_family_props;
1047
Nathaniel Cesariof121d122020-10-08 13:09:46 -06001048 // Ensure we can find a graphics queue family.
1049 uint32_t queue_count = 0;
1050 vk::GetPhysicalDeviceQueueFamilyProperties(phys_device_obj.handle(), &queue_count, nullptr);
1051
1052 queue_family_props.resize(queue_count);
1053 vk::GetPhysicalDeviceQueueFamilyProperties(phys_device_obj.handle(), &queue_count, queue_family_props.data());
1054
Nathaniel Cesario56a96652020-12-30 13:23:42 -07001055 // Now for GetPhysicalDeviceQueueFamilyProperties2
1056 std::vector<VkQueueFamilyProperties2> queue_family_props2;
1057 vk::GetPhysicalDeviceQueueFamilyProperties2(phys_device_obj.handle(), &queue_count, nullptr);
1058
1059 queue_family_props2.resize(queue_count);
paul-lunargd79a1f72022-08-02 18:04:24 +02001060 for (uint32_t i = 0; i < queue_count; i++) {
1061 queue_family_props2[i].sType = VK_STRUCTURE_TYPE_QUEUE_FAMILY_PROPERTIES_2;
1062 }
Nathaniel Cesario56a96652020-12-30 13:23:42 -07001063 vk::GetPhysicalDeviceQueueFamilyProperties2(phys_device_obj.handle(), &queue_count, queue_family_props2.data());
1064
1065 // And for GetPhysicalDeviceQueueFamilyProperties2KHR
1066 PFN_vkGetPhysicalDeviceQueueFamilyProperties2KHR vkGetPhysicalDeviceQueueFamilyProperties2KHR =
1067 reinterpret_cast<PFN_vkGetPhysicalDeviceQueueFamilyProperties2KHR>(
1068 vk::GetInstanceProcAddr(instance(), "vkGetPhysicalDeviceQueueFamilyProperties2KHR"));
1069 if (vkGetPhysicalDeviceQueueFamilyProperties2KHR) {
1070 vkGetPhysicalDeviceQueueFamilyProperties2KHR(phys_device_obj.handle(), &queue_count, nullptr);
1071
1072 queue_family_props2.resize(queue_count);
1073 vkGetPhysicalDeviceQueueFamilyProperties2KHR(phys_device_obj.handle(), &queue_count, queue_family_props2.data());
1074 }
1075
Nathaniel Cesariof121d122020-10-08 13:09:46 -06001076 vk_testing::Device device(phys_device_obj.handle());
1077 device.init();
1078}
1079
1080TEST_F(VkBestPracticesLayerTest, MissingQueryDetails) {
1081 TEST_DESCRIPTION("Check that GetPhysicalDeviceQueueFamilyProperties generates appropriate query warning");
1082
1083 ASSERT_NO_FATAL_FAILURE(InitBestPracticesFramework());
1084 const vk_testing::PhysicalDevice phys_device_obj(gpu_);
1085
1086 std::vector<VkQueueFamilyProperties> queue_family_props(1);
1087 uint32_t queue_count = static_cast<uint32_t>(queue_family_props.size());
1088
1089 m_errorMonitor->SetDesiredFailureMsg(kWarningBit, "UNASSIGNED-CoreValidation-DevLimit-MissingQueryCount");
1090 vk::GetPhysicalDeviceQueueFamilyProperties(phys_device_obj.handle(), &queue_count, queue_family_props.data());
1091 m_errorMonitor->VerifyFound();
1092
1093 // Now get information correctly
Nathaniel Cesariof121d122020-10-08 13:09:46 -06001094 vk_testing::QueueCreateInfoArray queue_info(phys_device_obj.queue_properties());
1095 // Only request creation with queuefamilies that have at least one queue
1096 std::vector<VkDeviceQueueCreateInfo> create_queue_infos;
1097 auto qci = queue_info.data();
1098 for (uint32_t j = 0; j < queue_info.size(); ++j) {
1099 if (qci[j].queueCount) {
1100 create_queue_infos.push_back(qci[j]);
1101 }
1102 }
Nathaniel Cesariof121d122020-10-08 13:09:46 -06001103
paul-lunargd79a1f72022-08-02 18:04:24 +02001104 VkPhysicalDeviceFeatures all_features{};
Nathaniel Cesariof121d122020-10-08 13:09:46 -06001105 VkDeviceCreateInfo device_ci = {};
1106 device_ci.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
1107 device_ci.pNext = nullptr;
1108 device_ci.queueCreateInfoCount = create_queue_infos.size();
1109 device_ci.pQueueCreateInfos = create_queue_infos.data();
1110 device_ci.enabledLayerCount = 0;
1111 device_ci.ppEnabledLayerNames = NULL;
1112 device_ci.enabledExtensionCount = 0;
1113 device_ci.ppEnabledExtensionNames = nullptr;
1114 device_ci.pEnabledFeatures = &all_features;
1115
1116 // vkGetPhysicalDeviceFeatures has not been called, so this should produce a warning
1117 m_errorMonitor->SetDesiredFailureMsg(kWarningBit,
1118 "UNASSIGNED-BestPractices-vkCreateDevice-physical-device-features-not-retrieved");
1119 VkDevice device;
1120 vk::CreateDevice(phys_device_obj.handle(), &device_ci, nullptr, &device);
1121 m_errorMonitor->VerifyFound();
Mark Lobodzinski1019fbc2020-11-10 08:12:54 -07001122}
ZandroFargnoliacf12f02020-06-18 16:50:00 +01001123
Nathaniel Cesario4ce98382021-05-28 11:33:20 -06001124TEST_F(VkBestPracticesLayerTest, GetSwapchainImagesInvalidCount) {
1125 TEST_DESCRIPTION("Pass an 'incorrect' count to the second GetSwapchainImagesKHR call");
1126
sjfrickea83fbb92022-07-01 13:57:27 +09001127 AddSurfaceExtension();
Nathaniel Cesario4ce98382021-05-28 11:33:20 -06001128 ASSERT_NO_FATAL_FAILURE(InitBestPracticesFramework());
1129
sjfrickea83fbb92022-07-01 13:57:27 +09001130 if (!AreRequiredExtensionsEnabled()) {
1131 GTEST_SKIP() << RequiredExtensionsNotSupported() << " not supported.";
Nathaniel Cesario4ce98382021-05-28 11:33:20 -06001132 }
1133 ASSERT_NO_FATAL_FAILURE(InitState());
1134 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
1135 if (!InitSwapchain()) {
1136 printf("%s Cannot create surface or swapchain, skipping test\n", kSkipPrefix);
1137 return;
1138 }
1139
1140 uint32_t swapchain_images_count = 0;
1141 vk::GetSwapchainImagesKHR(device(), m_swapchain, &swapchain_images_count, nullptr);
Nathaniel Cesario4ce98382021-05-28 11:33:20 -06001142
1143 m_errorMonitor->SetDesiredFailureMsg(kWarningBit, kVUID_BestPractices_Swapchain_InvalidCount);
1144 ++swapchain_images_count; // Set the image count to something greater (i.e., "invalid") than what was returned
Nathaniel Cesario5919c922021-05-31 11:21:06 -06001145 std::vector<VkImage> swapchain_images(swapchain_images_count, VK_NULL_HANDLE);
Nathaniel Cesario4ce98382021-05-28 11:33:20 -06001146 vk::GetSwapchainImagesKHR(device(), m_swapchain, &swapchain_images_count, swapchain_images.data());
1147 m_errorMonitor->VerifyFound();
1148}
Nathaniel Cesario34ee4182021-06-03 14:15:02 -06001149
1150TEST_F(VkBestPracticesLayerTest, DepthBiasNoAttachment) {
1151 TEST_DESCRIPTION("Enable depthBias without a depth attachment");
1152
1153 InitBestPracticesFramework();
1154 InitState();
1155 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
1156
1157 CreatePipelineHelper pipe(*this);
1158 pipe.InitInfo();
1159 pipe.rs_state_ci_.depthBiasEnable = VK_TRUE;
1160 pipe.rs_state_ci_.depthBiasConstantFactor = 1.0f;
1161 pipe.InitState();
1162 pipe.CreateGraphicsPipeline();
1163
1164 m_commandBuffer->begin();
1165 m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
1166 vk::CmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.pipeline_);
1167
1168 m_errorMonitor->SetDesiredFailureMsg(kWarningBit, kVUID_BestPractices_DepthBiasNoAttachment);
1169 vk::CmdDraw(m_commandBuffer->handle(), 3, 1, 0, 0);
1170 m_errorMonitor->VerifyFound();
1171
paul-lunargd79a1f72022-08-02 18:04:24 +02001172 m_commandBuffer->EndRenderPass();
Nathaniel Cesario34ee4182021-06-03 14:15:02 -06001173 m_commandBuffer->end();
1174}
ziga-lunarg8346fe82021-08-22 17:30:50 +02001175
1176TEST_F(VkBestPracticesLayerTest, CreatePipelineVsFsTypeMismatchArraySize) {
1177 TEST_DESCRIPTION("Test that an error is produced for mismatched array sizes across the vertex->fragment shader interface");
1178
1179 ASSERT_NO_FATAL_FAILURE(Init());
1180 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
1181
1182 char const *vsSource = R"glsl(
1183 #version 450
1184 layout(location=0) out float x[2];
1185 void main(){
1186 x[0] = 0; x[1] = 0;
1187 gl_Position = vec4(1);
1188 }
1189 )glsl";
1190 char const *fsSource = R"glsl(
1191 #version 450
1192 layout(location=0) in float x[1];
1193 layout(location=0) out vec4 color;
1194 void main(){
1195 color = vec4(x[0]);
1196 }
1197 )glsl";
1198
sfricke-samsungae54c1e2022-01-21 05:35:21 -08001199 VkShaderObj vs(this, vsSource, VK_SHADER_STAGE_VERTEX_BIT);
1200 VkShaderObj fs(this, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT);
ziga-lunarg8346fe82021-08-22 17:30:50 +02001201
1202 const auto set_info = [&](CreatePipelineHelper &helper) {
1203 helper.shader_stages_ = {vs.GetStageCreateInfo(), fs.GetStageCreateInfo()};
1204 };
1205 CreatePipelineHelper::OneshotTest(*this, set_info, kPerformanceWarningBit | kErrorBit,
1206 "UNASSIGNED-CoreValidation-Shader-OutputNotConsumed");
1207}
sfricke-samsung41910c82022-02-11 14:44:01 -08001208
1209TEST_F(VkBestPracticesLayerTest, WorkgroupSizeDeprecated) {
1210 TEST_DESCRIPTION("SPIR-V 1.6 deprecated WorkgroupSize build-in.");
1211
1212 SetTargetApiVersion(VK_API_VERSION_1_3);
1213 AddRequiredExtensions(VK_KHR_MAINTENANCE_4_EXTENSION_NAME);
1214 ASSERT_NO_FATAL_FAILURE(InitBestPracticesFramework());
sjfricked700bc02022-05-30 16:35:06 +09001215 if (!AreRequiredExtensionsEnabled()) {
1216 GTEST_SKIP() << RequiredExtensionsNotSupported() << " not supported";
sfricke-samsung41910c82022-02-11 14:44:01 -08001217 }
sjfricked700bc02022-05-30 16:35:06 +09001218 ASSERT_NO_FATAL_FAILURE(InitState());
sfricke-samsung41910c82022-02-11 14:44:01 -08001219
sjfricke394227a2022-06-20 16:47:38 +09001220 const char *spv_source = R"(
sfricke-samsung41910c82022-02-11 14:44:01 -08001221 OpCapability Shader
1222 %1 = OpExtInstImport "GLSL.std.450"
1223 OpMemoryModel Logical GLSL450
1224 OpEntryPoint GLCompute %main "main"
1225 OpExecutionMode %main LocalSize 1 1 1
1226 OpSource GLSL 450
1227 OpName %main "main"
1228 OpDecorate %gl_WorkGroupSize BuiltIn WorkgroupSize
1229 %void = OpTypeVoid
1230 %3 = OpTypeFunction %void
1231 %uint = OpTypeInt 32 0
1232 %uint_1 = OpConstant %uint 1
1233 %v3uint = OpTypeVector %uint 3
1234%gl_WorkGroupSize = OpConstantComposite %v3uint %uint_1 %uint_1 %uint_1
1235 %main = OpFunction %void None %3
1236 %5 = OpLabel
1237 OpReturn
1238 OpFunctionEnd
1239 )";
1240
1241 const auto set_info = [&](CreateComputePipelineHelper &helper) {
1242 helper.cs_.reset(new VkShaderObj(this, spv_source, VK_SHADER_STAGE_COMPUTE_BIT, SPV_ENV_VULKAN_1_0, SPV_SOURCE_ASM));
1243 };
1244 CreateComputePipelineHelper::OneshotTest(*this, set_info, kWarningBit,
1245 "UNASSIGNED-BestPractices-SpirvDeprecated_WorkgroupSize");
1246}
ziga-lunarg298cf0f2022-03-08 17:34:01 +01001247
1248TEST_F(VkBestPracticesLayerTest, CreatePipelineWithoutRenderPass) {
1249 TEST_DESCRIPTION("Test creating a graphics pipeline with no render pass");
1250
1251 ASSERT_NO_FATAL_FAILURE(InitBestPracticesFramework());
1252 ASSERT_NO_FATAL_FAILURE(InitState());
1253
paul-lunargb32f5f72022-08-29 20:30:06 +02001254 // This test checks that no BP messages are incorrectly triggered, but triggers core errors
paul-lunargd79a1f72022-08-02 18:04:24 +02001255 m_errorMonitor->SetUnexpectedError("VUID-VkGraphicsPipelineCreateInfo-renderPass-06603");
1256 m_errorMonitor->SetUnexpectedError("VUID-VkGraphicsPipelineCreateInfo-renderPass-06574");
1257
ziga-lunarg298cf0f2022-03-08 17:34:01 +01001258 VkShaderObj vs(this, bindStateVertShaderText, VK_SHADER_STAGE_VERTEX_BIT);
1259 VkShaderObj fs(this, bindStateFragShaderText, VK_SHADER_STAGE_FRAGMENT_BIT);
1260
1261 CreatePipelineHelper pipe(*this);
1262 pipe.InitInfo();
1263 pipe.InitState();
1264 pipe.shader_stages_ = {vs.GetStageCreateInfo(), fs.GetStageCreateInfo()};
1265 pipe.CreateGraphicsPipeline();
ziga-lunarg298cf0f2022-03-08 17:34:01 +01001266}
ziga-lunarg73394762022-03-18 17:06:55 +01001267
1268TEST_F(VkBestPracticesLayerTest, ImageExtendedUsageWithoutMutableFormat) {
1269 TEST_DESCRIPTION("Create image with extended usage bit but not mutable format bit.");
1270
1271 ASSERT_NO_FATAL_FAILURE(InitBestPracticesFramework());
1272 ASSERT_NO_FATAL_FAILURE(InitState());
1273
1274 VkImageCreateInfo image_ci = LvlInitStruct<VkImageCreateInfo>();
1275 image_ci.flags = VK_IMAGE_CREATE_EXTENDED_USAGE_BIT;
1276 image_ci.imageType = VK_IMAGE_TYPE_2D;
1277 image_ci.format = VK_FORMAT_B8G8R8A8_UNORM;
1278 image_ci.extent.width = 256;
1279 image_ci.extent.height = 256;
1280 image_ci.extent.depth = 1;
1281 image_ci.mipLevels = 1;
1282 image_ci.arrayLayers = 1;
1283 image_ci.samples = VK_SAMPLE_COUNT_1_BIT;
1284 image_ci.tiling = VK_IMAGE_TILING_OPTIMAL;
1285 image_ci.usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
1286 image_ci.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
1287
1288 VkImage image;
1289 m_errorMonitor->SetDesiredFailureMsg(kWarningBit, kVUID_BestPractices_ImageCreateFlags);
1290 vk::CreateImage(device(), &image_ci, nullptr, &image);
1291 m_errorMonitor->VerifyFound();
1292}
Jeremy Gebben2f33b602022-03-17 09:48:09 -06001293
1294#if GTEST_IS_THREADSAFE
1295TEST_F(VkBestPracticesLayerTest, ThreadUpdateDescriptorUpdateAfterBindNoCollision) {
1296 TEST_DESCRIPTION("Two threads updating the same UAB descriptor set, expected not to generate a threading error");
Jeremy Gebben2f33b602022-03-17 09:48:09 -06001297
Jeremy Gebben2f33b602022-03-17 09:48:09 -06001298 AddRequiredExtensions(VK_EXT_DESCRIPTOR_INDEXING_EXTENSION_NAME);
1299 AddRequiredExtensions(VK_KHR_MAINTENANCE_3_EXTENSION_NAME);
1300
1301 ASSERT_NO_FATAL_FAILURE(InitFramework(m_errorMonitor));
sjfricked700bc02022-05-30 16:35:06 +09001302 if (!AreRequiredExtensionsEnabled()) {
1303 GTEST_SKIP() << RequiredExtensionsNotSupported() << " not supported";
Jeremy Gebben2f33b602022-03-17 09:48:09 -06001304 }
1305
Jeremy Gebben2f33b602022-03-17 09:48:09 -06001306 // Create a device that enables descriptorBindingStorageBufferUpdateAfterBind
1307 auto indexing_features = LvlInitStruct<VkPhysicalDeviceDescriptorIndexingFeaturesEXT>();
sjfricke11db0c72022-08-18 13:23:11 +09001308 auto features2 = GetPhysicalDeviceFeatures2(indexing_features);
Jeremy Gebben2f33b602022-03-17 09:48:09 -06001309
1310 if (VK_FALSE == indexing_features.descriptorBindingStorageBufferUpdateAfterBind) {
1311 printf("%s Test requires (unsupported) descriptorBindingStorageBufferUpdateAfterBind, skipping\n", kSkipPrefix);
1312 return;
1313 }
1314
1315 ASSERT_NO_FATAL_FAILURE(InitState(nullptr, &features2, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT));
1316 ASSERT_NO_FATAL_FAILURE(InitViewport());
1317 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
1318
1319 std::array<VkDescriptorBindingFlagsEXT, 2> flags = {
1320 {VK_DESCRIPTOR_BINDING_UPDATE_AFTER_BIND_BIT_EXT, VK_DESCRIPTOR_BINDING_UPDATE_AFTER_BIND_BIT_EXT}};
1321 auto flags_create_info = LvlInitStruct<VkDescriptorSetLayoutBindingFlagsCreateInfoEXT>();
1322 flags_create_info.bindingCount = (uint32_t)flags.size();
1323 flags_create_info.pBindingFlags = flags.data();
1324
1325 OneOffDescriptorSet normal_descriptor_set(m_device,
1326 {
1327 {0, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1, VK_SHADER_STAGE_COMPUTE_BIT, nullptr},
1328 {1, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1, VK_SHADER_STAGE_COMPUTE_BIT, nullptr},
1329 },
1330 VK_DESCRIPTOR_SET_LAYOUT_CREATE_UPDATE_AFTER_BIND_POOL_BIT_EXT, &flags_create_info,
1331 VK_DESCRIPTOR_POOL_CREATE_UPDATE_AFTER_BIND_BIT_EXT);
1332
1333 VkBufferObj buffer;
1334 buffer.init(*m_device, 256, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT);
1335
Jeremy Gebben33a96752022-07-08 15:04:03 -06001336 ThreadTestData data;
Jeremy Gebben2f33b602022-03-17 09:48:09 -06001337 data.device = device();
1338 data.descriptorSet = normal_descriptor_set.set_;
1339 data.binding = 0;
1340 data.buffer = buffer.handle();
Jeremy Gebbenc3a17642022-08-04 13:41:08 -06001341 std::atomic<bool> bailout{false};
Jeremy Gebben2f33b602022-03-17 09:48:09 -06001342 data.bailout = &bailout;
1343 m_errorMonitor->SetBailout(data.bailout);
1344
1345 // Update descriptors from another thread.
Jeremy Gebben33a96752022-07-08 15:04:03 -06001346 std::thread thread(UpdateDescriptor, &data);
Jeremy Gebben2f33b602022-03-17 09:48:09 -06001347 // Update descriptors from this thread at the same time.
1348
Jeremy Gebben33a96752022-07-08 15:04:03 -06001349 ThreadTestData data2;
Jeremy Gebben2f33b602022-03-17 09:48:09 -06001350 data2.device = device();
1351 data2.descriptorSet = normal_descriptor_set.set_;
1352 data2.binding = 1;
1353 data2.buffer = buffer.handle();
1354 data2.bailout = &bailout;
1355
1356 UpdateDescriptor(&data2);
1357
Jeremy Gebben018454b2022-07-08 14:48:50 -06001358 thread.join();
Jeremy Gebben2f33b602022-03-17 09:48:09 -06001359
1360 m_errorMonitor->SetBailout(NULL);
Jeremy Gebben2f33b602022-03-17 09:48:09 -06001361}
1362#endif // GTEST_IS_THREADSAFE
ziga-lunargaf4bf612022-03-19 18:45:23 +01001363
1364TEST_F(VkBestPracticesLayerTest, TransitionFromUndefinedToReadOnly) {
1365 TEST_DESCRIPTION("Transition image layout from undefined to read only");
1366
1367 ASSERT_NO_FATAL_FAILURE(InitBestPracticesFramework());
1368 ASSERT_NO_FATAL_FAILURE(InitState());
1369
1370 VkImageObj image(m_device);
paul-lunarg6f2c6d62022-08-02 21:20:29 +02001371 image.Init(128, 128, 1, VK_FORMAT_B8G8R8A8_UNORM, VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT, VK_IMAGE_TILING_OPTIMAL, 0);
ziga-lunargaf4bf612022-03-19 18:45:23 +01001372
1373 VkClearColorValue color_clear_value = {};
1374 color_clear_value.uint32[0] = 255;
1375 VkImageSubresourceRange clear_range;
1376 clear_range.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
1377 clear_range.baseMipLevel = 0;
1378 clear_range.baseArrayLayer = 0;
1379 clear_range.layerCount = 1;
1380 clear_range.levelCount = 1;
1381
1382 VkImageMemoryBarrier img_barrier = LvlInitStruct<VkImageMemoryBarrier>();
1383 img_barrier.srcAccessMask = 0;
1384 img_barrier.dstAccessMask = 0;
1385 img_barrier.oldLayout = VK_IMAGE_LAYOUT_UNDEFINED;
1386 img_barrier.newLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
1387 img_barrier.image = image.handle();
1388 img_barrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
1389 img_barrier.subresourceRange.baseArrayLayer = 0;
1390 img_barrier.subresourceRange.baseMipLevel = 0;
1391 img_barrier.subresourceRange.layerCount = 1;
1392 img_barrier.subresourceRange.levelCount = 1;
1393
1394 m_commandBuffer->begin();
1395
1396 m_commandBuffer->ClearColorImage(image.handle(), VK_IMAGE_LAYOUT_GENERAL, &color_clear_value, 1, &clear_range);
1397
1398 m_errorMonitor->SetDesiredFailureMsg(kWarningBit, "UNASSIGNED-BestPractices-TransitionUndefinedToReadOnly");
1399 vk::CmdPipelineBarrier(m_commandBuffer->handle(), VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, 0, 0,
1400 nullptr, 0, nullptr, 1, &img_barrier);
1401 m_errorMonitor->VerifyFound();
1402
1403 m_commandBuffer->end();
1404}
ziga-lunargee5e5262022-03-30 01:17:44 +02001405
1406TEST_F(VkBestPracticesLayerTest, CreateFifoRelaxedSwapchain) {
1407 TEST_DESCRIPTION("Test creating fifo relaxed swapchain");
1408
sjfrickea83fbb92022-07-01 13:57:27 +09001409 AddSurfaceExtension();
ziga-lunargee5e5262022-03-30 01:17:44 +02001410 InitBestPracticesFramework();
sjfrickea83fbb92022-07-01 13:57:27 +09001411 if (!AreRequiredExtensionsEnabled()) {
1412 GTEST_SKIP() << RequiredExtensionsNotSupported() << " not supported.";
1413 }
ziga-lunargee5e5262022-03-30 01:17:44 +02001414 InitState();
1415 if (!InitSurface()) {
1416 printf("%s Cannot create surface, skipping test\n", kSkipPrefix);
1417 return;
1418 }
1419 InitSwapchainInfo();
1420
1421 VkBool32 supported;
1422 vk::GetPhysicalDeviceSurfaceSupportKHR(gpu(), m_device->graphics_queue_node_index_, m_surface, &supported);
1423 if (!supported) {
1424 printf("%s Graphics queue does not support present, skipping test\n", kSkipPrefix);
1425 return;
1426 }
1427
1428 bool fifo_relaxed = false;
1429 for (const auto& present_mode : m_surface_present_modes) {
1430 if (present_mode == VK_PRESENT_MODE_FIFO_RELAXED_KHR) {
1431 fifo_relaxed = true;
1432 break;
1433 }
1434 }
1435 if (!fifo_relaxed) {
1436 printf("%s fifo relaxed present mode not supported, skipping test\n", kSkipPrefix);
1437 return;
1438 }
1439
1440 VkImageUsageFlags imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
1441 VkSurfaceTransformFlagBitsKHR preTransform = VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR;
1442
1443 VkSwapchainCreateInfoKHR swapchain_create_info = {};
1444 swapchain_create_info.sType = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR;
1445 swapchain_create_info.pNext = 0;
1446 swapchain_create_info.surface = m_surface;
1447 swapchain_create_info.minImageCount = 2;
1448 swapchain_create_info.imageFormat = m_surface_formats[0].format;
1449 swapchain_create_info.imageColorSpace = m_surface_formats[0].colorSpace;
1450 swapchain_create_info.imageExtent = {m_surface_capabilities.minImageExtent.width, m_surface_capabilities.minImageExtent.height};
1451 swapchain_create_info.imageArrayLayers = 1;
1452 swapchain_create_info.imageUsage = imageUsage;
1453 swapchain_create_info.imageSharingMode = VK_SHARING_MODE_EXCLUSIVE;
1454 swapchain_create_info.preTransform = preTransform;
1455 swapchain_create_info.compositeAlpha = m_surface_composite_alpha;
1456 swapchain_create_info.presentMode = VK_PRESENT_MODE_FIFO_RELAXED_KHR;
1457 swapchain_create_info.clipped = VK_FALSE;
1458 swapchain_create_info.oldSwapchain = 0;
1459
ziga-lunargee5e5262022-03-30 01:17:44 +02001460 vk::CreateSwapchainKHR(device(), &swapchain_create_info, nullptr, &m_swapchain);
ziga-lunargee5e5262022-03-30 01:17:44 +02001461}
ziga-lunargfe657b02022-04-17 18:04:28 +02001462
ziga-lunarg5e49e552022-04-18 00:15:43 +02001463TEST_F(VkBestPracticesLayerTest, SemaphoreSetWhenCountIsZero) {
1464 TEST_DESCRIPTION("Set semaphore in SubmitInfo but count is 0");
1465
1466 ASSERT_NO_FATAL_FAILURE(InitBestPracticesFramework());
1467 ASSERT_NO_FATAL_FAILURE(InitState());
1468
1469
1470 auto semaphore_ci = LvlInitStruct<VkSemaphoreCreateInfo>();
1471 vk_testing::Semaphore semaphore;
1472 semaphore.init(*m_device, semaphore_ci);
1473 VkSemaphore semaphore_handle = semaphore.handle();
1474
1475 VkSubmitInfo signal_submit_info = LvlInitStruct<VkSubmitInfo>();
1476 signal_submit_info.signalSemaphoreCount = 0;
1477 signal_submit_info.pSignalSemaphores = &semaphore_handle;
1478
1479 m_errorMonitor->SetDesiredFailureMsg(kWarningBit, "UNASSIGNED-BestPractices-SemaphoreCount");
1480 vk::QueueSubmit(m_device->m_queue, 1, &signal_submit_info, VK_NULL_HANDLE);
1481 m_errorMonitor->VerifyFound();
1482
ziga-lunarg5e49e552022-04-18 00:15:43 +02001483 signal_submit_info.signalSemaphoreCount = 1;
1484 vk::QueueSubmit(m_device->m_queue, 1, &signal_submit_info, VK_NULL_HANDLE);
ziga-lunarg5e49e552022-04-18 00:15:43 +02001485
1486 VkSubmitInfo wait_submit_info = LvlInitStruct<VkSubmitInfo>();
1487 wait_submit_info.waitSemaphoreCount = 0;
1488 wait_submit_info.pWaitSemaphores = &semaphore_handle;
1489
1490 m_errorMonitor->SetDesiredFailureMsg(kWarningBit, "UNASSIGNED-BestPractices-SemaphoreCount");
1491 vk::QueueSubmit(m_device->m_queue, 1, &wait_submit_info, VK_NULL_HANDLE);
1492 m_errorMonitor->VerifyFound();
paul-lunarg6f2c6d62022-08-02 21:20:29 +02001493
1494 vk::QueueWaitIdle(m_device->m_queue);
ziga-lunarg5e49e552022-04-18 00:15:43 +02001495}
1496
ziga-lunargfe657b02022-04-17 18:04:28 +02001497TEST_F(VkBestPracticesLayerTest, OverAllocateFromDescriptorPool) {
1498 TEST_DESCRIPTION("Attempt to allocate more sets and descriptors than descriptor pool has available.");
paul-lunarg444ec622022-08-09 02:22:41 +02001499
ziga-lunargfe657b02022-04-17 18:04:28 +02001500 SetTargetApiVersion(VK_API_VERSION_1_1);
1501
1502 ASSERT_NO_FATAL_FAILURE(InitBestPracticesFramework());
1503 ASSERT_NO_FATAL_FAILURE(InitState());
1504 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
1505
1506 if (DeviceValidationVersion() < VK_API_VERSION_1_1) {
sjfricke50955f32022-06-05 10:12:52 +09001507 GTEST_SKIP() << "At least Vulkan version 1.1 is required";
ziga-lunargfe657b02022-04-17 18:04:28 +02001508 }
1509
1510 // Create Pool w/ 1 Sampler descriptor, but try to alloc Uniform Buffer
1511 // descriptor from it
1512 VkDescriptorPoolSize ds_type_count = {};
1513 ds_type_count.type = VK_DESCRIPTOR_TYPE_SAMPLER;
1514 ds_type_count.descriptorCount = 2;
1515
1516 VkDescriptorPoolCreateInfo ds_pool_ci = LvlInitStruct<VkDescriptorPoolCreateInfo>();
1517 ds_pool_ci.flags = 0;
1518 ds_pool_ci.maxSets = 1;
1519 ds_pool_ci.poolSizeCount = 1;
1520 ds_pool_ci.pPoolSizes = &ds_type_count;
1521
paul-lunarg6f2c6d62022-08-02 21:20:29 +02001522 vk_testing::DescriptorPool ds_pool(*m_device, ds_pool_ci);
ziga-lunargfe657b02022-04-17 18:04:28 +02001523
1524 VkDescriptorSetLayoutBinding dsl_binding_samp = {};
1525 dsl_binding_samp.binding = 0;
1526 dsl_binding_samp.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER;
1527 dsl_binding_samp.descriptorCount = 1;
1528 dsl_binding_samp.stageFlags = VK_SHADER_STAGE_ALL;
1529 dsl_binding_samp.pImmutableSamplers = NULL;
1530
1531 const VkDescriptorSetLayoutObj ds_layout_samp(m_device, {dsl_binding_samp});
1532
1533 // Try to allocate 2 sets when pool only has 1 set
1534 VkDescriptorSet descriptor_sets[2];
1535 VkDescriptorSetLayout set_layouts[2] = {ds_layout_samp.handle(), ds_layout_samp.handle()};
1536 VkDescriptorSetAllocateInfo alloc_info = LvlInitStruct<VkDescriptorSetAllocateInfo>();
1537 alloc_info.descriptorSetCount = 2;
paul-lunarg6f2c6d62022-08-02 21:20:29 +02001538 alloc_info.descriptorPool = ds_pool.handle();
ziga-lunargfe657b02022-04-17 18:04:28 +02001539 alloc_info.pSetLayouts = set_layouts;
1540 m_errorMonitor->SetDesiredFailureMsg(kWarningBit, "UNASSIGNED-BestPractices-EmptyDescriptorPool");
paul-lunarg444ec622022-08-09 02:22:41 +02001541 vk::AllocateDescriptorSets(m_device->device(), &alloc_info, descriptor_sets);
ziga-lunargfe657b02022-04-17 18:04:28 +02001542 m_errorMonitor->VerifyFound();
1543}
paul-lunargd81e0342022-06-20 22:22:07 +02001544
1545TEST_F(VkBestPracticesLayerTest, RenderPassClearWithoutLoadOpClear) {
1546 TEST_DESCRIPTION("Test for clearing a RenderPass with non-zero clearValueCount without any VK_ATTACHMENT_LOAD_OP_CLEAR");
1547
paul-lunargd81e0342022-06-20 22:22:07 +02001548
1549 ASSERT_NO_FATAL_FAILURE(InitBestPracticesFramework());
1550 ASSERT_NO_FATAL_FAILURE(InitState());
1551
paul-lunarge32ec7b2022-06-23 16:22:51 +02001552 // Setup necessary objects correctly
paul-lunarge32ec7b2022-06-23 16:22:51 +02001553
paul-lunargd81e0342022-06-20 22:22:07 +02001554 // Bigger size to avoid small allocation best practices warning
1555 const unsigned int w = 1920;
1556 const unsigned int h = 1080;
1557
1558 // Setup Image
1559 VkImageCreateInfo image_info = LvlInitStruct<VkImageCreateInfo>();
1560 image_info.extent = {w, h, 1};
1561 image_info.format = VK_FORMAT_R8G8B8A8_UNORM;
1562 image_info.imageType = VK_IMAGE_TYPE_2D;
1563 image_info.tiling = VK_IMAGE_TILING_OPTIMAL;
1564 image_info.usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
1565 image_info.samples = VK_SAMPLE_COUNT_1_BIT;
1566 image_info.arrayLayers = 1;
1567 image_info.mipLevels = 1;
1568
1569 VkImageObj image(m_device);
1570 image.init(&image_info);
1571
1572 const auto image_view = image.targetView(image_info.format);
1573
1574 // Setup RenderPass
1575 VkAttachmentDescription attachment{};
1576 attachment.samples = VK_SAMPLE_COUNT_1_BIT;
1577 attachment.loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; // Specify that we do nothing with the contents of the attached image
1578 attachment.storeOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
1579 attachment.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
paul-lunarge32ec7b2022-06-23 16:22:51 +02001580 attachment.finalLayout = VK_IMAGE_LAYOUT_ATTACHMENT_OPTIMAL;
paul-lunargd81e0342022-06-20 22:22:07 +02001581 attachment.format = image_info.format;
1582
1583 VkAttachmentReference ar{};
1584 ar.attachment = 0;
paul-lunarge32ec7b2022-06-23 16:22:51 +02001585 ar.layout = VK_IMAGE_LAYOUT_ATTACHMENT_OPTIMAL;
paul-lunargd81e0342022-06-20 22:22:07 +02001586
1587 VkSubpassDescription spd{};
1588 spd.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS;
1589 spd.colorAttachmentCount = 1;
1590 spd.pColorAttachments = &ar;
1591
1592 VkRenderPassCreateInfo rp_info = LvlInitStruct<VkRenderPassCreateInfo>();
1593 rp_info.attachmentCount = 1;
1594 rp_info.pAttachments = &attachment;
1595 rp_info.subpassCount = 1;
1596 rp_info.pSubpasses = &spd;
1597
1598 vk_testing::RenderPass rp(*m_device, rp_info);
1599
1600 // Setup Framebuffer
1601 VkFramebufferCreateInfo fb_info = LvlInitStruct<VkFramebufferCreateInfo>();
1602 fb_info.width = w;
1603 fb_info.height = h;
1604 fb_info.layers = 1;
1605 fb_info.renderPass = rp.handle();
1606 fb_info.attachmentCount = 1;
1607 fb_info.pAttachments = &image_view;
1608
1609 vk_testing::Framebuffer fb(*m_device, fb_info);
1610
1611 m_commandBuffer->begin();
1612
1613 // Create a useless VkClearValue
1614 VkClearValue cv{};
1615 cv.color = VkClearColorValue{};
1616 std::fill(std::begin(cv.color.float32), std::begin(cv.color.float32) + 4, 0.0f);
1617
1618 VkRenderPassBeginInfo begin_info = LvlInitStruct<VkRenderPassBeginInfo>();
1619 begin_info.clearValueCount = 1; // Pass one clearValue, in conflict with attachment.loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE
1620 begin_info.pClearValues = &cv;
1621 begin_info.renderPass = rp.handle();
1622 begin_info.renderArea.extent.width = w;
1623 begin_info.renderArea.extent.height = h;
1624 begin_info.framebuffer = fb.handle();
1625
1626 // Setup finished
paul-lunargd81e0342022-06-20 22:22:07 +02001627
1628 // TEST :
1629
1630 m_errorMonitor->SetDesiredFailureMsg(kWarningBit, kVUID_BestPractices_ClearValueWithoutLoadOpClear);
1631
1632 // This should give a warning
1633 m_commandBuffer->BeginRenderPass(begin_info);
1634
1635 m_errorMonitor->VerifyFound();
1636
1637 m_commandBuffer->end();
1638}
paul-lunarge32ec7b2022-06-23 16:22:51 +02001639
1640
1641TEST_F(VkBestPracticesLayerTest, RenderPassClearValueCountHigherThanAttachmentCount) {
1642 TEST_DESCRIPTION("Test for beginning a RenderPass with VkRenderPassBeginInfo.clearValueCount > VkRenderPassCreateInfo.attachmentCount");
1643
1644 ASSERT_NO_FATAL_FAILURE(InitBestPracticesFramework());
1645 ASSERT_NO_FATAL_FAILURE(InitState());
1646
1647 // Setup necessary objects correctly
paul-lunarge32ec7b2022-06-23 16:22:51 +02001648
1649 // Bigger size to avoid small allocation best practices warning
1650 const unsigned int w = 1920;
1651 const unsigned int h = 1080;
1652
1653 // Setup Image
1654 VkImageCreateInfo image_info = LvlInitStruct<VkImageCreateInfo>();
1655 image_info.extent = {w, h, 1};
1656 image_info.format = VK_FORMAT_R8G8B8A8_UNORM;
1657 image_info.imageType = VK_IMAGE_TYPE_2D;
1658 image_info.tiling = VK_IMAGE_TILING_OPTIMAL;
1659 image_info.usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
1660 image_info.samples = VK_SAMPLE_COUNT_1_BIT;
1661 image_info.arrayLayers = 1;
1662 image_info.mipLevels = 1;
1663
1664 VkImageObj image(m_device);
1665 image.init(&image_info);
1666
1667 const auto image_view = image.targetView(image_info.format);
1668
1669 // Setup RenderPass
1670 VkAttachmentDescription attachment{};
1671 attachment.samples = VK_SAMPLE_COUNT_1_BIT;
1672 attachment.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
1673 attachment.storeOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
1674 attachment.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
paul-lunargce0a2062022-09-09 15:22:51 +02001675 attachment.finalLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
paul-lunarge32ec7b2022-06-23 16:22:51 +02001676 attachment.format = image_info.format;
1677
1678 VkAttachmentReference ar{};
1679 ar.attachment = 0;
paul-lunargce0a2062022-09-09 15:22:51 +02001680 ar.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
paul-lunarge32ec7b2022-06-23 16:22:51 +02001681
1682 VkSubpassDescription spd{};
1683 spd.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS;
1684 spd.colorAttachmentCount = 1;
1685 spd.pColorAttachments = &ar;
1686
1687 VkRenderPassCreateInfo rp_info = LvlInitStruct<VkRenderPassCreateInfo>();
1688 rp_info.attachmentCount = 1; // There is only one attachment
1689 rp_info.pAttachments = &attachment;
1690 rp_info.subpassCount = 1;
1691 rp_info.pSubpasses = &spd;
1692
1693 vk_testing::RenderPass rp(*m_device, rp_info);
1694
1695 // Setup Framebuffer
1696 VkFramebufferCreateInfo fb_info = LvlInitStruct<VkFramebufferCreateInfo>();
1697 fb_info.width = w;
1698 fb_info.height = h;
1699 fb_info.layers = 1;
1700 fb_info.renderPass = rp.handle();
1701 fb_info.attachmentCount = 1;
1702 fb_info.pAttachments = &image_view;
1703
1704 vk_testing::Framebuffer fb(*m_device, fb_info);
1705
1706 m_commandBuffer->begin();
1707
1708 // Create two VkClearValues
1709 VkClearValue cv[2];
1710
1711 // Create a useful VkClearValue
1712 cv[0].color = VkClearColorValue{};
1713 std::fill(std::begin(cv[0].color.float32), std::begin(cv[0].color.float32) + 4, 0.0f);
1714
1715 // Create a useless VkClearValue
1716 cv[1].color = VkClearColorValue{};
1717 std::fill(std::begin(cv[1].color.float32), std::begin(cv[1].color.float32) + 4, 0.0f);
1718
1719 VkRenderPassBeginInfo begin_info = LvlInitStruct<VkRenderPassBeginInfo>();
paul-lunargfc7ac122022-07-06 15:49:39 -06001720 begin_info.clearValueCount = 2; // Pass 2 clearValues, in conflict with VkRenderPassCreateInfo.attachmentCount == 1 meaning the
1721 // second clearValue will be ignored
paul-lunarge32ec7b2022-06-23 16:22:51 +02001722 begin_info.pClearValues = cv;
1723 begin_info.renderPass = rp.handle();
1724 begin_info.renderArea.extent.width = w;
1725 begin_info.renderArea.extent.height = h;
1726 begin_info.framebuffer = fb.handle();
1727
1728 // Setup finished
paul-lunarge32ec7b2022-06-23 16:22:51 +02001729
1730 // TEST :
1731
1732 m_errorMonitor->SetDesiredFailureMsg(kWarningBit, kVUID_BestPractices_ClearValueCountHigherThanAttachmentCount);
1733
1734 // This should give a warning
1735 m_commandBuffer->BeginRenderPass(begin_info);
1736
1737 m_errorMonitor->VerifyFound();
1738
1739 m_commandBuffer->end();
paul-lunargde56bc12022-06-27 18:57:48 +02001740}
1741
1742TEST_F(VkBestPracticesLayerTest, DontCareThenLoad) {
1743 TEST_DESCRIPTION("Test for storing an attachment with STORE_OP_DONT_CARE then loading with LOAD_OP_LOAD");
1744
1745 ASSERT_NO_FATAL_FAILURE(InitBestPracticesFramework());
1746 ASSERT_NO_FATAL_FAILURE(InitState());
1747
1748 // Setup necessary objects correctly
paul-lunargde56bc12022-06-27 18:57:48 +02001749
1750 const unsigned int w = 100;
1751 const unsigned int h = 100;
1752
1753 // Setup Image
1754 VkImageCreateInfo image_info = LvlInitStruct<VkImageCreateInfo>();
1755 image_info.extent = {w, h, 1};
1756 image_info.format = VK_FORMAT_R8G8B8A8_UNORM;
1757 image_info.imageType = VK_IMAGE_TYPE_2D;
1758 image_info.tiling = VK_IMAGE_TILING_OPTIMAL;
1759 image_info.usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
1760 image_info.samples = VK_SAMPLE_COUNT_1_BIT;
1761 image_info.arrayLayers = 1;
1762 image_info.mipLevels = 1;
1763
1764 VkImageObj image(m_device);
1765 image.init(&image_info);
1766
1767 const auto image_view = image.targetView(image_info.format);
1768
1769 // Setup first RenderPass
1770 VkAttachmentDescription attachment{};
1771 attachment.samples = VK_SAMPLE_COUNT_1_BIT;
1772 attachment.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR; // Clearing as only modification
1773 attachment.storeOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; // Dont care even though we will load afterwards
1774 attachment.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
paul-lunargce0a2062022-09-09 15:22:51 +02001775 attachment.finalLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
paul-lunargde56bc12022-06-27 18:57:48 +02001776 attachment.format = image_info.format;
1777
1778 VkAttachmentReference ar{};
1779 ar.attachment = 0;
paul-lunargce0a2062022-09-09 15:22:51 +02001780 ar.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
paul-lunargde56bc12022-06-27 18:57:48 +02001781
1782 VkSubpassDescription spd{};
1783 spd.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS;
1784 spd.colorAttachmentCount = 1;
1785 spd.pColorAttachments = &ar;
1786
1787 VkRenderPassCreateInfo rp_info = LvlInitStruct<VkRenderPassCreateInfo>();
1788 rp_info.attachmentCount = 1;
1789 rp_info.pAttachments = &attachment;
1790 rp_info.subpassCount = 1;
1791 rp_info.pSubpasses = &spd;
1792
1793 vk_testing::RenderPass rp1(*m_device, rp_info);
1794
1795 // Setup second RenderPass
1796 attachment.loadOp = VK_ATTACHMENT_LOAD_OP_LOAD; // Loading even though was stored with dont care
1797 attachment.storeOp = VK_ATTACHMENT_STORE_OP_STORE;
paul-lunargce0a2062022-09-09 15:22:51 +02001798 attachment.initialLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
1799 attachment.finalLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
paul-lunargde56bc12022-06-27 18:57:48 +02001800
1801 vk_testing::RenderPass rp2(*m_device, rp_info);
1802
1803 // Setup Framebuffer
1804 VkFramebufferCreateInfo fb_info = LvlInitStruct<VkFramebufferCreateInfo>();
1805 fb_info.width = w;
1806 fb_info.height = h;
1807 fb_info.layers = 1;
1808 fb_info.renderPass = rp1.handle();
1809 fb_info.attachmentCount = 1;
1810 fb_info.pAttachments = &image_view;
1811
1812 vk_testing::Framebuffer fb(*m_device, fb_info);
1813
1814 m_commandBuffer->begin();
1815
1816 // All white
1817 VkClearValue cv;
1818 cv.color = VkClearColorValue{};
1819 std::fill(std::begin(cv.color.float32), std::begin(cv.color.float32) + 4, 1.0f);
1820
1821 // Begin first renderpass
1822 VkRenderPassBeginInfo begin_info = LvlInitStruct<VkRenderPassBeginInfo>();
1823 begin_info.clearValueCount = 1;
1824 begin_info.pClearValues = &cv;
1825 begin_info.renderPass = rp1.handle();
1826 begin_info.renderArea.extent.width = w;
1827 begin_info.renderArea.extent.height = h;
1828 begin_info.framebuffer = fb.handle();
1829
1830 m_commandBuffer->BeginRenderPass(begin_info);
1831
1832 m_commandBuffer->EndRenderPass();
1833
1834 // Begin second renderpass
1835 begin_info.clearValueCount = 0;
1836 begin_info.pClearValues = nullptr;
1837 begin_info.renderPass = rp2.handle();
1838
1839 m_commandBuffer->BeginRenderPass(begin_info);
1840
1841 m_commandBuffer->EndRenderPass();
1842
1843 m_commandBuffer->end();
1844
1845 VkSubmitInfo submit_info = LvlInitStruct<VkSubmitInfo>();
1846 submit_info.commandBufferCount = 1;
1847 submit_info.pCommandBuffers = &m_commandBuffer->handle();
1848
1849 // Setup finished
paul-lunargde56bc12022-06-27 18:57:48 +02001850
1851 // TEST :
1852 m_errorMonitor->SetDesiredFailureMsg(kWarningBit, kVUID_BestPractices_StoreOpDontCareThenLoadOpLoad);
1853
1854 // This should give a warning
1855 vk::QueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
1856
1857 m_errorMonitor->VerifyFound();
1858
1859 vk::QueueWaitIdle(m_device->m_queue);
Jeremy Gebben018454b2022-07-08 14:48:50 -06001860}
paul-lunarg04e4acf2022-08-29 21:30:11 +02001861
1862TEST_F(VkBestPracticesLayerTest, LoadDeprecatedExtension) {
1863 TEST_DESCRIPTION("Test for loading a vk1.3 deprecated extension with a 1.3 instance on a 1.2 or less device");
1864
1865 SetTargetApiVersion(VK_API_VERSION_1_3);
1866
1867 ASSERT_NO_FATAL_FAILURE(InitBestPracticesFramework());
1868
1869 const char *extension = VK_KHR_SYNCHRONIZATION_2_EXTENSION_NAME;
1870
1871 VkDeviceQueueCreateInfo qci = LvlInitStruct<VkDeviceQueueCreateInfo>();
1872 qci.queueFamilyIndex = 0;
1873 float priority = 1;
1874 qci.pQueuePriorities = &priority;
1875 qci.queueCount = 1;
1876
1877 VkDeviceCreateInfo dev_info = LvlInitStruct<VkDeviceCreateInfo>();
1878 dev_info.queueCreateInfoCount = 1;
1879 dev_info.pQueueCreateInfos = &qci;
1880 dev_info.enabledExtensionCount = 1;
1881 dev_info.ppEnabledExtensionNames = &extension;
1882
1883 m_errorMonitor->SetDesiredFailureMsg(kWarningBit, "UNASSIGNED-BestPractices-vkCreateDevice-deprecated-extension");
paul-lunargd7c7ab22022-08-30 21:17:45 +02001884 // api version != device version
1885 m_errorMonitor->SetAllowedFailureMsg("UNASSIGNED-BestPractices-vkCreateDevice-API-version-mismatch");
paul-lunarg04e4acf2022-08-29 21:30:11 +02001886
1887 VkDevice device = VK_NULL_HANDLE;
1888 vk::CreateDevice(gpu(), &dev_info, nullptr, &device);
1889
1890 if (DeviceValidationVersion() >= VK_API_VERSION_1_3) {
1891 m_errorMonitor->VerifyFound();
1892 }
1893
1894 if (device) vk::DestroyDevice(device, nullptr);
paul-lunargc44a1ee2022-09-09 17:03:07 +02001895}
1896
1897TEST_F(VkBestPracticesLayerTest, ExclusiveImageMultiQueueUsage) {
1898 TEST_DESCRIPTION("Test for using a queue exclusive image on multiple queues");
1899
1900 ASSERT_NO_FATAL_FAILURE(InitBestPracticesFramework());
1901 ASSERT_NO_FATAL_FAILURE(InitState());
1902
1903 VkQueueObj *graphics_queue = m_device->GetDefaultQueue();
1904
1905 VkQueueObj *compute_queue = nullptr;
1906 for (uint32_t i = 0; i < m_device->compute_queues().size(); ++i) {
1907 auto cqi = m_device->compute_queues()[i];
1908 if (cqi->get_family_index() != graphics_queue->get_family_index()) {
1909 compute_queue = cqi;
1910 break;
1911 }
1912 }
1913
paul-lunargc44a1ee2022-09-09 17:03:07 +02001914 if (compute_queue == nullptr) {
1915 GTEST_SKIP() << "No separate queue family from graphics queue";
1916 }
1917
1918 // Setup necessary objects correctly
1919
1920 const unsigned int w = 100;
1921 const unsigned int h = 100;
1922
1923 // Setup Image
1924 VkImageCreateInfo image_info = LvlInitStruct<VkImageCreateInfo>();
1925 image_info.extent = {w, h, 1};
1926 image_info.format = VK_FORMAT_R8G8B8A8_UNORM;
1927 image_info.imageType = VK_IMAGE_TYPE_2D;
1928 image_info.tiling = VK_IMAGE_TILING_OPTIMAL;
1929 image_info.usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_STORAGE_BIT;
1930 image_info.samples = VK_SAMPLE_COUNT_1_BIT;
1931 image_info.arrayLayers = 1;
1932 image_info.mipLevels = 1;
1933
1934 VkImageObj image(m_device);
1935 image.init(&image_info);
1936
1937 const auto image_view = image.targetView(image_info.format);
1938
paul-lunargc27afe82022-09-07 19:24:19 +02001939 // Prepare graphics
1940
paul-lunargc44a1ee2022-09-09 17:03:07 +02001941 // Setup RenderPass
1942 VkAttachmentDescription attachment{};
1943 attachment.samples = VK_SAMPLE_COUNT_1_BIT;
paul-lunarg8696c6b2022-09-09 16:55:10 +02001944 attachment.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR; // Clearing so warning will not trigger on second pass
1945 attachment.storeOp = VK_ATTACHMENT_STORE_OP_STORE; // Store written image for next queue family
paul-lunargc44a1ee2022-09-09 17:03:07 +02001946 attachment.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
1947 attachment.finalLayout = VK_IMAGE_LAYOUT_GENERAL;
1948 attachment.format = image_info.format;
1949
1950 VkAttachmentReference ar{};
1951 ar.attachment = 0;
1952 ar.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
1953
1954 VkSubpassDescription spd{};
1955 spd.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS;
1956 spd.colorAttachmentCount = 1;
1957 spd.pColorAttachments = &ar;
1958
1959 VkRenderPassCreateInfo rp_info = LvlInitStruct<VkRenderPassCreateInfo>();
1960 rp_info.attachmentCount = 1;
1961 rp_info.pAttachments = &attachment;
1962 rp_info.subpassCount = 1;
1963 rp_info.pSubpasses = &spd;
1964
1965 vk_testing::RenderPass rp(*m_device, rp_info);
1966
1967 // Setup Framebuffer
1968 VkFramebufferCreateInfo fb_info = LvlInitStruct<VkFramebufferCreateInfo>();
1969 fb_info.width = w;
1970 fb_info.height = h;
1971 fb_info.layers = 1;
1972 fb_info.renderPass = rp.handle();
1973 fb_info.attachmentCount = 1;
1974 fb_info.pAttachments = &image_view;
1975
1976 vk_testing::Framebuffer fb(*m_device, fb_info);
1977
1978 VkCommandPoolObj graphics_pool(m_device, graphics_queue->get_family_index());
1979
1980 VkCommandBufferObj graphics_buffer(m_device, &graphics_pool, VK_COMMAND_BUFFER_LEVEL_PRIMARY, graphics_queue);
1981
paul-lunargc44a1ee2022-09-09 17:03:07 +02001982 VkClearValue cv;
1983 cv.color = VkClearColorValue{};
1984 std::fill(std::begin(cv.color.float32), std::begin(cv.color.float32) + 4, 1.0f);
1985
1986 VkRenderPassBeginInfo begin_info = LvlInitStruct<VkRenderPassBeginInfo>();
1987 begin_info.clearValueCount = 1;
1988 begin_info.pClearValues = &cv;
1989 begin_info.renderPass = rp.handle();
1990 begin_info.renderArea.extent.width = w;
1991 begin_info.renderArea.extent.height = h;
1992 begin_info.framebuffer = fb.handle();
1993
paul-lunargc27afe82022-09-07 19:24:19 +02001994 // Prepare compute
paul-lunargc44a1ee2022-09-09 17:03:07 +02001995
1996 const char *cs = R"glsl(#version 450
1997 layout(local_size_x=1, local_size_y=1) in;
1998 layout(set=0, binding=0, rgba32f) uniform image2D img;
1999 void main(){
paul-lunargc27afe82022-09-07 19:24:19 +02002000 vec4 v = imageLoad(img, ivec2(gl_GlobalInvocationID.xy));
paul-lunargc44a1ee2022-09-09 17:03:07 +02002001 }
2002 )glsl";
2003
2004 CreateComputePipelineHelper pipe(*this);
2005 pipe.InitInfo();
2006 pipe.cs_ = layer_data::make_unique<VkShaderObj>(this, cs, VK_SHADER_STAGE_COMPUTE_BIT);
2007 pipe.InitDescriptorSetInfo();
2008 pipe.dsl_bindings_[0].descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE;
2009 pipe.dsl_bindings_[0].stageFlags = VK_SHADER_STAGE_COMPUTE_BIT;
2010 pipe.InitState();
2011 pipe.CreateComputePipeline();
2012
2013 VkSamplerObj sampler(m_device);
2014
2015 pipe.descriptor_set_->WriteDescriptorImageInfo(0, image_view, sampler.handle(), VK_DESCRIPTOR_TYPE_STORAGE_IMAGE,
2016 VK_IMAGE_LAYOUT_GENERAL);
2017 pipe.descriptor_set_->UpdateDescriptorSets();
2018
2019 VkCommandPoolObj compute_pool(m_device, compute_queue->get_family_index());
2020
2021 VkCommandBufferObj compute_buffer(m_device, &compute_pool, VK_COMMAND_BUFFER_LEVEL_PRIMARY, compute_queue);
2022
paul-lunargc27afe82022-09-07 19:24:19 +02002023 // Record command buffers without queue transition
2024
2025 // Record graphics command buffer
2026 graphics_buffer.begin();
2027
2028 graphics_buffer.BeginRenderPass(begin_info);
2029
2030 graphics_buffer.EndRenderPass();
2031
2032 graphics_buffer.end();
2033
2034 graphics_buffer.QueueCommandBuffer();
2035
2036 // Record compute command buffer
paul-lunargc44a1ee2022-09-09 17:03:07 +02002037 compute_buffer.begin();
2038
paul-lunargc27afe82022-09-07 19:24:19 +02002039 vk::CmdBindPipeline(compute_buffer.handle(), VK_PIPELINE_BIND_POINT_COMPUTE, pipe.pipeline_);
2040
2041 vk::CmdBindDescriptorSets(compute_buffer.handle(), VK_PIPELINE_BIND_POINT_COMPUTE, pipe.pipeline_layout_.handle(), 0, 1,
2042 &pipe.descriptor_set_->set_, 0, nullptr);
2043
2044 vk::CmdDispatch(compute_buffer.handle(), w, h, 1);
2045
2046 compute_buffer.end();
2047
paul-lunarg670a5622022-09-09 13:48:22 +02002048 // Warning should trigger as we are potentially accessing undefined resources
2049 m_errorMonitor->SetDesiredFailureMsg(kWarningBit, "UNASSIGNED-BestPractices-ConcurrentUsageOfExclusiveImage");
paul-lunargc27afe82022-09-07 19:24:19 +02002050 compute_buffer.QueueCommandBuffer();
paul-lunarg670a5622022-09-09 13:48:22 +02002051 m_errorMonitor->VerifyFound();
paul-lunargc27afe82022-09-07 19:24:19 +02002052
2053 vk::ResetCommandPool(device(), graphics_pool.handle(), 0);
2054 vk::ResetCommandPool(device(), compute_pool.handle(), 0);
2055
2056 // Record command buffers with queue transition
2057
2058 // Queue transition barrier, same for release and acquire
2059 VkImageMemoryBarrier barrier = LvlInitStruct<VkImageMemoryBarrier>();
2060 barrier.image = image.handle();
2061 barrier.srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT; // only matters for release
2062 barrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT; // only matters for acquire
2063 barrier.oldLayout = VK_IMAGE_LAYOUT_GENERAL;
2064 barrier.newLayout = VK_IMAGE_LAYOUT_GENERAL;
2065 barrier.srcQueueFamilyIndex = graphics_queue->get_family_index();
2066 barrier.dstQueueFamilyIndex = compute_queue->get_family_index();
2067 barrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
2068 barrier.subresourceRange.levelCount = VK_REMAINING_MIP_LEVELS;
2069 barrier.subresourceRange.layerCount = VK_REMAINING_ARRAY_LAYERS;
2070
2071 // Record graphics command buffer
2072 graphics_buffer.begin();
2073
2074 graphics_buffer.BeginRenderPass(begin_info);
2075
2076 graphics_buffer.EndRenderPass();
2077
2078 vk::CmdPipelineBarrier(graphics_buffer.handle(), VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
2079 VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, VK_DEPENDENCY_BY_REGION_BIT, 0, nullptr, 0, nullptr, 1, &barrier);
2080
2081 graphics_buffer.end();
2082
2083 graphics_buffer.QueueCommandBuffer();
2084
2085 // Record compute command buffer
2086 compute_buffer.begin();
2087
2088 vk::CmdPipelineBarrier(compute_buffer.handle(), VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT,
2089 VK_DEPENDENCY_BY_REGION_BIT, 0, nullptr, 0, nullptr, 1, &barrier);
2090
2091 vk::CmdBindPipeline(compute_buffer.handle(), VK_PIPELINE_BIND_POINT_COMPUTE, pipe.pipeline_);
2092
paul-lunargc44a1ee2022-09-09 17:03:07 +02002093 vk::CmdBindDescriptorSets(compute_buffer.handle(), VK_PIPELINE_BIND_POINT_COMPUTE, pipe.pipeline_layout_.handle(), 0, 1,
2094 &pipe.descriptor_set_->set_, 0, nullptr);
2095
2096 vk::CmdDispatch(compute_buffer.handle(), w, h, 1);
2097
2098 compute_buffer.end();
2099
paul-lunarg670a5622022-09-09 13:48:22 +02002100 // Warning shouldn't trigger
2101 m_errorMonitor->SetDesiredFailureMsg(kWarningBit, "UNASSIGNED-BestPractices-ConcurrentUsageOfExclusiveImage");
paul-lunargc44a1ee2022-09-09 17:03:07 +02002102 compute_buffer.QueueCommandBuffer();
paul-lunarg670a5622022-09-09 13:48:22 +02002103 m_errorMonitor->Finish();
paul-lunarg04e4acf2022-08-29 21:30:11 +02002104}