1 /*
2 * Copyright (c) 2015-2021 The Khronos Group Inc.
3 * Copyright (c) 2015-2021 Valve Corporation
4 * Copyright (c) 2015-2021 LunarG, Inc.
5 * Modifications Copyright (C) 2020-2021 Advanced Micro Devices, Inc. All rights reserved.
6 *
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Author: Nathaniel Cesario <nathaniel@lunarg.com>
14 * Author: Nadav Geva <nadav.geva@amd.com>
15 */
16
17 #include "cast_utils.h"
18 #include "layer_validation_tests.h"
19
20 // Tests for AMD-specific best practices
21 const char *kEnableAMDValidation = "VALIDATION_CHECK_ENABLE_VENDOR_SPECIFIC_AMD";
22
23
24 // this is a very long test (~10 minutes)
25 // disabled for now
26 #ifdef AMD_LONG_RUNNING_TEST
TEST_F(VkAmdBestPracticesLayerTest,TooManyPipelines)27 TEST_F(VkAmdBestPracticesLayerTest, TooManyPipelines) {
28
29
30 InitBestPracticesFramework(kEnableAMDValidation);
31 InitState();
32
33 ASSERT_NO_FATAL_FAILURE(InitViewport());
34 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
35
36 // create 1 more than the warning limit for pipeline objects
37 const uint32_t warn_limit = 5001;
38 VkPipeline pipeline_Array[warn_limit + 1] = {};
39
40 for (int i = 0; i <= warn_limit; i++) {
41 // create a new pipeline helper so the cache won't be used
42 // also imitates a "just in time" pipeline creator pattern
43 if (i == 1) {
44 // check that the second pipeline helper cache was detected
45 m_errorMonitor->SetDesiredFailureMsg(kPerformanceWarningBit,
46 "UNASSIGNED-BestPractices-vkCreatePipelines-multiple-pipelines-caches");
47 }
48 CreatePipelineHelper pipe(*this);
49 pipe.InitInfo();
50 pipe.InitState();
51 pipe.CreateGraphicsPipeline();
52 pipeline_Array[i] = pipe.pipeline_;
53 if (i == 1) {
54 // change check to too many pipelines
55 m_errorMonitor->VerifyFound();
56 m_errorMonitor->SetDesiredFailureMsg(kPerformanceWarningBit,
57 "UNASSIGNED-BestPractices-CreatePipelines-TooManyPipelines");
58 }
59 }
60
61 m_errorMonitor->VerifyFound();
62 }
63 #endif
64
TEST_F(VkAmdBestPracticesLayerTest,UseMutableRT)65 TEST_F(VkAmdBestPracticesLayerTest, UseMutableRT) {
66 InitBestPracticesFramework(kEnableAMDValidation);
67 InitState();
68
69 ASSERT_NO_FATAL_FAILURE(InitViewport());
70 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
71
72 m_errorMonitor->SetDesiredFailureMsg(kPerformanceWarningBit,
73 "UNASSIGNED-BestPractices-vkImage-DontUseMutableRenderTargets");
74
75 // create a colot attachment image with mutable bit set
76 VkImageCreateInfo img_info = {VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
77 nullptr,
78 VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT,
79 VK_IMAGE_TYPE_1D,
80 VK_FORMAT_R8G8B8A8_UNORM,
81 {1, 1, 1},
82 1,
83 1,
84 VK_SAMPLE_COUNT_1_BIT,
85 VK_IMAGE_TILING_OPTIMAL,
86 VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT,
87 VK_SHARING_MODE_EXCLUSIVE,
88 0,
89 nullptr,
90 VK_IMAGE_LAYOUT_UNDEFINED};
91 VkImage test_image = VK_NULL_HANDLE;
92 vk::CreateImage(m_device->handle(), &img_info, nullptr, &test_image);
93 m_errorMonitor->VerifyFound();
94
95 m_errorMonitor->SetDesiredFailureMsg(kPerformanceWarningBit,
96 "UNASSIGNED-BestPractices-vkImage-DontUseMutableRenderTargets");
97 // create a depth attachment image with mutable bit set
98 img_info = {VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
99 nullptr,
100 VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT,
101 VK_IMAGE_TYPE_1D,
102 VK_FORMAT_R8G8B8A8_UNORM,
103 {1, 1, 1},
104 1,
105 1,
106 VK_SAMPLE_COUNT_1_BIT,
107 VK_IMAGE_TILING_OPTIMAL,
108 VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT,
109 VK_SHARING_MODE_EXCLUSIVE,
110 0,
111 nullptr,
112 VK_IMAGE_LAYOUT_UNDEFINED};
113 test_image = VK_NULL_HANDLE;
114 vk::CreateImage(m_device->handle(), &img_info, nullptr, &test_image);
115 m_errorMonitor->VerifyFound();
116
117 m_errorMonitor->SetDesiredFailureMsg(kPerformanceWarningBit,
118 "UNASSIGNED-BestPractices-vkImage-DontUseMutableRenderTargets");
119 // create a storage image with mutable bit set
120 img_info = {VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
121 nullptr,
122 VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT,
123 VK_IMAGE_TYPE_1D,
124 VK_FORMAT_R8G8B8A8_UNORM,
125 {1, 1, 1},
126 1,
127 1,
128 VK_SAMPLE_COUNT_1_BIT,
129 VK_IMAGE_TILING_OPTIMAL,
130 VK_IMAGE_USAGE_STORAGE_BIT,
131 VK_SHARING_MODE_EXCLUSIVE,
132 0,
133 nullptr,
134 VK_IMAGE_LAYOUT_UNDEFINED};
135 test_image = VK_NULL_HANDLE;
136 vk::CreateImage(m_device->handle(), &img_info, nullptr, &test_image);
137 m_errorMonitor->VerifyFound();
138 }
139
TEST_F(VkAmdBestPracticesLayerTest,UsageConcurentRT)140 TEST_F(VkAmdBestPracticesLayerTest, UsageConcurentRT) {
141 InitBestPracticesFramework(kEnableAMDValidation);
142 InitState();
143
144 ASSERT_NO_FATAL_FAILURE(InitViewport());
145 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
146
147 m_errorMonitor->SetDesiredFailureMsg(kPerformanceWarningBit,
148 "UNASSIGNED-BestPractices-vkImage-AvoidConcurrentRenderTargets");
149
150 // create a render target image with mutable bit set
151 VkImageCreateInfo img_info = {VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
152 nullptr,
153 0,
154 VK_IMAGE_TYPE_1D,
155 VK_FORMAT_R8G8B8A8_UNORM,
156 {1, 1, 1},
157 1,
158 1,
159 VK_SAMPLE_COUNT_1_BIT,
160 VK_IMAGE_TILING_OPTIMAL,
161 VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT,
162 VK_SHARING_MODE_CONCURRENT,
163 0,
164 nullptr,
165 VK_IMAGE_LAYOUT_UNDEFINED};
166 VkImage test_image = VK_NULL_HANDLE;
167 vk::CreateImage(m_device->handle(), &img_info, nullptr, &test_image);
168 m_errorMonitor->VerifyFound();
169
170 m_errorMonitor->SetDesiredFailureMsg(kPerformanceWarningBit,
171 "UNASSIGNED-BestPractices-vkImage-AvoidConcurrentRenderTargets");
172 // create a render target image with mutable bit set
173 img_info = {VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
174 nullptr,
175 0,
176 VK_IMAGE_TYPE_1D,
177 VK_FORMAT_R8G8B8A8_UNORM,
178 {1, 1, 1},
179 1,
180 1,
181 VK_SAMPLE_COUNT_1_BIT,
182 VK_IMAGE_TILING_OPTIMAL,
183 VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT,
184 VK_SHARING_MODE_CONCURRENT,
185 0,
186 nullptr,
187 VK_IMAGE_LAYOUT_UNDEFINED};
188 test_image = VK_NULL_HANDLE;
189 vk::CreateImage(m_device->handle(), &img_info, nullptr, &test_image);
190 m_errorMonitor->VerifyFound();
191 }
192
TEST_F(VkAmdBestPracticesLayerTest,UsageStorageRT)193 TEST_F(VkAmdBestPracticesLayerTest, UsageStorageRT) {
194 InitBestPracticesFramework(kEnableAMDValidation);
195 InitState();
196
197 ASSERT_NO_FATAL_FAILURE(InitViewport());
198 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
199
200 m_errorMonitor->SetDesiredFailureMsg(kPerformanceWarningBit,
201 "UNASSIGNED-BestPractices-vkImage-DontUseStorageRenderTargets");
202
203 // create a render target image with mutable bit set
204 VkImageCreateInfo img_info = {VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
205 nullptr,
206 0,
207 VK_IMAGE_TYPE_1D,
208 VK_FORMAT_R8G8B8A8_UNORM,
209 {1, 1, 1},
210 1,
211 1,
212 VK_SAMPLE_COUNT_1_BIT,
213 VK_IMAGE_TILING_OPTIMAL,
214 VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_STORAGE_BIT,
215 VK_SHARING_MODE_EXCLUSIVE,
216 0,
217 nullptr,
218 VK_IMAGE_LAYOUT_UNDEFINED};
219 VkImage test_image = VK_NULL_HANDLE;
220 vk::CreateImage(m_device->handle(), &img_info, nullptr, &test_image);
221 m_errorMonitor->VerifyFound();
222 }
223
TEST_F(VkAmdBestPracticesLayerTest,PrimitiveRestart)224 TEST_F(VkAmdBestPracticesLayerTest, PrimitiveRestart) {
225 InitBestPracticesFramework(kEnableAMDValidation);
226 InitState();
227
228 ASSERT_NO_FATAL_FAILURE(InitViewport());
229 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
230
231 m_errorMonitor->SetDesiredFailureMsg(kPerformanceWarningBit,
232 "UNASSIGNED-BestPractices-CreatePipelines-AvoidPrimitiveRestart");
233
234 CreatePipelineHelper pipe(*this);
235 pipe.InitInfo();
236 pipe.InitState();
237 pipe.ia_ci_.primitiveRestartEnable = true;
238 pipe.CreateGraphicsPipeline();
239
240 m_errorMonitor->VerifyFound();
241 }
242
TEST_F(VkAmdBestPracticesLayerTest,NumDynamicStates)243 TEST_F(VkAmdBestPracticesLayerTest, NumDynamicStates) {
244 InitBestPracticesFramework(kEnableAMDValidation);
245 InitState();
246
247 ASSERT_NO_FATAL_FAILURE(InitViewport());
248 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
249
250 m_errorMonitor->SetDesiredFailureMsg(kPerformanceWarningBit,
251 "UNASSIGNED-BestPractices-CreatePipelines-MinimizeNumDynamicStates");
252
253 // fill the dynamic array with the first 8 types in the enum
254 // imitates a case where the user have set most dynamic states unnecessarily
255 VkDynamicState dynamic_states_array[8] = {};
256 for (uint32_t i = 0; i < 8; i++) {
257 dynamic_states_array[i] = (VkDynamicState)i;
258 }
259
260 VkPipelineDynamicStateCreateInfo dynamic_state_info = {};
261 dynamic_state_info.sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO;
262 dynamic_state_info.dynamicStateCount = 8;
263 dynamic_state_info.pDynamicStates = dynamic_states_array;
264
265 CreatePipelineHelper pipe(*this);
266 pipe.InitInfo();
267 pipe.InitState();
268 pipe.dyn_state_ci_ = dynamic_state_info;
269 pipe.CreateGraphicsPipeline();
270
271 m_errorMonitor->VerifyFound();
272 }
273
TEST_F(VkAmdBestPracticesLayerTest,KeepLayoutSmall)274 TEST_F(VkAmdBestPracticesLayerTest, KeepLayoutSmall) {
275 // TODO: add dynamic buffer check as well
276 InitBestPracticesFramework(kEnableAMDValidation);
277 InitState();
278
279 ASSERT_NO_FATAL_FAILURE(InitViewport());
280 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
281
282 m_errorMonitor->SetDesiredFailureMsg(kPerformanceWarningBit,
283 "UNASSIGNED-BestPractices-CreatePipelinesLayout-KeepLayoutSmall");
284
285 // create a layout of 15 DWORDS (40 bytes push constants (10 DWORDS), a descriptor set (1 DWORD), and 2 dynamic buffers (4
286 // DWORDS)
287
288 uint32_t push_size_dwords = 10;
289 VkPushConstantRange push_range = {};
290 push_range.stageFlags = VK_SHADER_STAGE_ALL;
291 push_range.offset = 0;
292 push_range.size = 4 * push_size_dwords;
293
294 VkDescriptorSetLayoutBinding binding;
295 binding.binding = 0;
296 binding.descriptorCount = 2;
297 binding.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC;
298 binding.stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT;
299
300 VkDescriptorSetLayout DS_layout;
301
302 VkDescriptorSetLayoutCreateInfo DS_layout_info = {};
303 DS_layout_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
304 DS_layout_info.bindingCount = 1;
305 DS_layout_info.pBindings = &binding;
306
307 vk::CreateDescriptorSetLayout(m_device->device(), &DS_layout_info, nullptr, &DS_layout);
308
309 VkPipelineLayoutCreateInfo pipeline_layout_info = {};
310 pipeline_layout_info.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
311 pipeline_layout_info.setLayoutCount = 1;
312 pipeline_layout_info.pSetLayouts = &DS_layout;
313 pipeline_layout_info.pushConstantRangeCount = 1;
314 pipeline_layout_info.pPushConstantRanges = &push_range;
315
316 VkPipelineLayout test_pipeline_layout = VK_NULL_HANDLE;
317 vk::CreatePipelineLayout(m_device->handle(), &pipeline_layout_info, nullptr, &test_pipeline_layout);
318
319 m_errorMonitor->VerifyFound();
320 }
321
TEST_F(VkAmdBestPracticesLayerTest,CopyingDescriptors)322 TEST_F(VkAmdBestPracticesLayerTest, CopyingDescriptors) {
323 // TODO: add dynamic buffer check as well
324 InitBestPracticesFramework(kEnableAMDValidation);
325 InitState();
326
327 ASSERT_NO_FATAL_FAILURE(InitViewport());
328 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
329
330 m_errorMonitor->SetDesiredFailureMsg(kPerformanceWarningBit,
331 "UNASSIGNED-BestPractices-UpdateDescriptors-AvoidCopyingDescriptors");
332
333 VkDescriptorPoolSize ds_type_count = {};
334 ds_type_count.type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC;
335 ds_type_count.descriptorCount = 1;
336
337 VkDescriptorPoolCreateInfo ds_pool_ci = {};
338 ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
339 ds_pool_ci.pNext = NULL;
340 ds_pool_ci.maxSets = 1;
341 ds_pool_ci.poolSizeCount = 1;
342 ds_pool_ci.flags = VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT;
343 ds_pool_ci.pPoolSizes = &ds_type_count;
344
345 VkDescriptorPool ds_pool;
346 vk::CreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool);
347
348 VkDescriptorSetLayoutBinding dsl_binding = {};
349 dsl_binding.binding = 2;
350 dsl_binding.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC;
351 dsl_binding.descriptorCount = 1;
352 dsl_binding.stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT;
353 dsl_binding.pImmutableSamplers = NULL;
354
355 const VkDescriptorSetLayoutObj ds_layout(m_device, {dsl_binding});
356
357 VkDescriptorSet descriptor_sets[3] = {};
358 VkDescriptorSetAllocateInfo alloc_info = {};
359 alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
360 alloc_info.descriptorSetCount = 1;
361 alloc_info.descriptorPool = ds_pool;
362 alloc_info.pSetLayouts = &ds_layout.handle();
363 vk::AllocateDescriptorSets(m_device->device(), &alloc_info, &descriptor_sets[0]);
364 vk::AllocateDescriptorSets(m_device->device(), &alloc_info, &descriptor_sets[1]);
365
366 VkCopyDescriptorSet copy_info = {};
367 copy_info.sType = VK_STRUCTURE_TYPE_COPY_DESCRIPTOR_SET;
368 copy_info.descriptorCount = 1;
369 copy_info.srcSet = descriptor_sets[1];
370 copy_info.srcBinding = 2;
371 copy_info.srcArrayElement = 0;
372 copy_info.dstSet = descriptor_sets[0];
373 copy_info.dstBinding = 2;
374 copy_info.dstArrayElement = 0;
375
376 vk::UpdateDescriptorSets(m_device->handle(), 0, nullptr, 1, ©_info);
377
378 m_errorMonitor->VerifyFound();
379 }
380
TEST_F(VkAmdBestPracticesLayerTest,ClearImage)381 TEST_F(VkAmdBestPracticesLayerTest, ClearImage) {
382 TEST_DESCRIPTION("Test for validating usage of vkCmdClearAttachments");
383
384 InitBestPracticesFramework(kEnableAMDValidation);
385 InitState();
386 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
387
388 {
389 VkImageCreateInfo img_info = {VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
390 nullptr,
391 VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT,
392 VK_IMAGE_TYPE_1D,
393 VK_FORMAT_R8G8B8A8_UNORM,
394 {1, 1, 1},
395 1,
396 1,
397 VK_SAMPLE_COUNT_1_BIT,
398 VK_IMAGE_TILING_OPTIMAL,
399 VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT,
400 VK_SHARING_MODE_EXCLUSIVE,
401 0,
402 nullptr,
403 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL};
404 VkImageObj image_1D(m_device);
405 image_1D.init(&img_info);
406 ASSERT_TRUE(image_1D.initialized());
407
408 m_commandBuffer->begin();
409 m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
410
411 VkClearColorValue clear_value = {{0.0f, 0.0f, 0.0f, 0.0f}};
412 VkImageSubresourceRange image_range = {};
413 image_range.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
414 image_range.levelCount = 1;
415 image_range.layerCount = 1;
416
417 m_errorMonitor->SetDesiredFailureMsg(kPerformanceWarningBit,
418 "UNASSIGNED-BestPractices-ClearAttachment-ClearImage");
419
420 vk::CmdClearColorImage(m_commandBuffer->handle(), image_1D.handle(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &clear_value, 1,
421 &image_range);
422 m_errorMonitor->VerifyFound();
423
424 m_commandBuffer->EndRenderPass();
425 m_commandBuffer->end();
426 }
427
428 {
429 VkImageCreateInfo img_info = {VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
430 nullptr,
431 VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT,
432 VK_IMAGE_TYPE_1D,
433 VK_FORMAT_D32_SFLOAT_S8_UINT,
434 {1, 1, 1},
435 1,
436 1,
437 VK_SAMPLE_COUNT_1_BIT,
438 VK_IMAGE_TILING_OPTIMAL,
439 VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT,
440 VK_SHARING_MODE_EXCLUSIVE,
441 0,
442 nullptr,
443 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL};
444 VkImageObj image_1D(m_device);
445 image_1D.init(&img_info);
446 ASSERT_TRUE(image_1D.initialized());
447
448 m_commandBuffer->begin();
449 m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
450
451 VkClearDepthStencilValue clear_value = {0.0f, 0};
452 VkImageSubresourceRange image_range = {};
453 image_range.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT;
454 image_range.levelCount = 1;
455 image_range.layerCount = 1;
456
457 m_errorMonitor->SetDesiredFailureMsg(kPerformanceWarningBit,
458 "UNASSIGNED-BestPractices-ClearAttachment-ClearImage");
459
460 vk::CmdClearDepthStencilImage(m_commandBuffer->handle(), image_1D.handle(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
461 &clear_value, 1, &image_range);
462 m_errorMonitor->VerifyFound();
463
464 m_commandBuffer->EndRenderPass();
465 m_commandBuffer->end();
466 }
467 }
468
TEST_F(VkAmdBestPracticesLayerTest,ImageToImageCopy)469 TEST_F(VkAmdBestPracticesLayerTest, ImageToImageCopy) {
470 InitBestPracticesFramework(kEnableAMDValidation);
471 InitState();
472 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
473
474 VkImageCreateInfo img_info = {VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
475 nullptr,
476 0,
477 VK_IMAGE_TYPE_2D,
478 VK_FORMAT_R8G8B8A8_UNORM,
479 {1, 1, 1},
480 1,
481 1,
482 VK_SAMPLE_COUNT_1_BIT,
483 VK_IMAGE_TILING_OPTIMAL,
484 VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT,
485 VK_SHARING_MODE_EXCLUSIVE,
486 0,
487 nullptr,
488 VK_IMAGE_LAYOUT_UNDEFINED};
489 VkImageObj image1D_1(m_device);
490 image1D_1.init(&img_info);
491 ASSERT_TRUE(image1D_1.initialized());
492
493 img_info.tiling = VK_IMAGE_TILING_LINEAR;
494 img_info.usage = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
495
496 VkImageObj image_1D_2(m_device);
497 image_1D_2.init(&img_info);
498 if (!image_1D_2.initialized()) {
499 printf("%s Could not initilize Linear image, skipping image to image copy test\n", kSkipPrefix);
500 return;
501 }
502
503 m_commandBuffer->begin();
504 m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
505
506 image1D_1.SetLayout(VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL);
507 m_errorMonitor->SetDesiredFailureMsg(kPerformanceWarningBit,
508 "UNASSIGNED-BestPractices-vkImage-AvoidImageToImageCopy");
509
510 vk::CmdCopyImage(m_commandBuffer->handle(), image1D_1.handle(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, image_1D_2.handle(),
511 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 0, nullptr);
512 m_errorMonitor->VerifyFound();
513 }
514
TEST_F(VkAmdBestPracticesLayerTest,GeneralLayout)515 TEST_F(VkAmdBestPracticesLayerTest, GeneralLayout) {
516 InitBestPracticesFramework(kEnableAMDValidation);
517 InitState();
518 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
519
520 VkImageCreateInfo img_info = {VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
521 nullptr,
522 0,
523 VK_IMAGE_TYPE_2D,
524 VK_FORMAT_R8G8B8A8_UNORM,
525 {1024, 1024, 1},
526 1,
527 1,
528 VK_SAMPLE_COUNT_1_BIT,
529 VK_IMAGE_TILING_OPTIMAL,
530 VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT,
531 VK_SHARING_MODE_EXCLUSIVE,
532 0,
533 nullptr,
534 VK_IMAGE_LAYOUT_UNDEFINED};
535 VkImageObj image_1D(m_device);
536
537 m_errorMonitor->SetDesiredFailureMsg(kPerformanceWarningBit,
538 "UNASSIGNED-BestPractices-vkImage-AvoidGeneral");
539 m_errorMonitor->SetAllowedFailureMsg("UNASSIGNED-BestPractices-VkCommandBuffer-AvoidTinyCmdBuffers");
540
541 // the init function initializes to general layout
542 image_1D.init(&img_info);
543
544 m_errorMonitor->VerifyFound();
545 }
546
TEST_F(VkAmdBestPracticesLayerTest,RobustAccessOn)547 TEST_F(VkAmdBestPracticesLayerTest, RobustAccessOn) {
548 InitBestPracticesFramework(kEnableAMDValidation);
549 InitState();
550 m_errorMonitor->SetDesiredFailureMsg(kPerformanceWarningBit,
551 "UNASSIGNED-BestPractices-vkCreateDevice-RobustBufferAccess");
552
553 VkPhysicalDeviceFeatures features = {};
554 features.robustBufferAccess = true;
555
556 const float q_priority[] = {1.0f};
557 VkDeviceQueueCreateInfo queue_ci = {};
558 queue_ci.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
559 queue_ci.queueFamilyIndex = 0;
560 queue_ci.queueCount = 1;
561 queue_ci.pQueuePriorities = q_priority;
562
563 VkDeviceCreateInfo device_ci = {};
564 device_ci.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
565 device_ci.queueCreateInfoCount = 1;
566 device_ci.pQueueCreateInfos = &queue_ci;
567 device_ci.pEnabledFeatures = &features;
568
569 VkDevice test_device;
570 vk::CreateDevice(gpu(), &device_ci, nullptr, &test_device);
571
572 m_errorMonitor->VerifyFound();
573 }
574
TEST_F(VkAmdBestPracticesLayerTest,Barriers)575 TEST_F(VkAmdBestPracticesLayerTest, Barriers) {
576 InitBestPracticesFramework(kEnableAMDValidation);
577 InitState();
578 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
579
580 VkImageCreateInfo img_info = {VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
581 nullptr,
582 VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT,
583 VK_IMAGE_TYPE_1D,
584 VK_FORMAT_R8G8B8A8_UNORM,
585 {1, 1, 1},
586 1,
587 1,
588 VK_SAMPLE_COUNT_1_BIT,
589 VK_IMAGE_TILING_OPTIMAL,
590 VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT,
591 VK_SHARING_MODE_EXCLUSIVE,
592 0,
593 nullptr,
594 VK_IMAGE_LAYOUT_UNDEFINED};
595 VkImageObj image_1D(m_device);
596 image_1D.init(&img_info);
597 ASSERT_TRUE(image_1D.initialized());
598
599 m_commandBuffer->begin();
600 // check for read-to-read barrier
601 m_errorMonitor->SetDesiredFailureMsg(kPerformanceWarningBit,
602 "UNASSIGNED-BestPractices-PipelineBarrier-readToReadBarrier");
603 m_errorMonitor->SetAllowedFailureMsg("UNASSIGNED-BestPractices-CmdBuffer-backToBackBarrier"); // we already test for this above
604 image_1D.SetLayout(m_commandBuffer, VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
605 image_1D.SetLayout(m_commandBuffer, VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL);
606
607 m_errorMonitor->VerifyFound();
608
609 // check total number of barriers warning
610 uint32_t warn_Limit = 250;
611 for (uint32_t i = 0; i < warn_Limit; i++) {
612 image_1D.SetLayout(m_commandBuffer, VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
613 image_1D.SetLayout(m_commandBuffer, VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL);
614 }
615
616 m_errorMonitor->SetDesiredFailureMsg(kPerformanceWarningBit,
617 "UNASSIGNED-BestPractices-CmdBuffer-highBarrierCount");
618 m_errorMonitor->SetAllowedFailureMsg("UNASSIGNED-BestPractices-CmdBuffer-backToBackBarrier"); // we already test for this above
619 image_1D.SetLayout(m_commandBuffer, VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
620 m_errorMonitor->VerifyFound();
621 }
622
TEST_F(VkAmdBestPracticesLayerTest,NumberOfSubmissions)623 TEST_F(VkAmdBestPracticesLayerTest, NumberOfSubmissions) {
624 AddSurfaceInstanceExtension();
625
626 InitBestPracticesFramework(kEnableAMDValidation);
627 AddSwapchainDeviceExtension();
628
629 InitState();
630 ASSERT_NO_FATAL_FAILURE(InitViewport());
631 InitSwapchain();
632 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
633
634 VkImageCreateInfo img_info = {VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
635 nullptr,
636 VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT,
637 VK_IMAGE_TYPE_1D,
638 VK_FORMAT_R8G8B8A8_UNORM,
639 {1, 1, 1},
640 1,
641 1,
642 VK_SAMPLE_COUNT_1_BIT,
643 VK_IMAGE_TILING_OPTIMAL,
644 VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT,
645 VK_SHARING_MODE_EXCLUSIVE,
646 0,
647 nullptr,
648 VK_IMAGE_LAYOUT_UNDEFINED};
649 VkImageObj image_1D(m_device);
650 image_1D.init(&img_info);
651 ASSERT_TRUE(image_1D.initialized());
652
653 uint32_t warn_limit = 11;
654
655 for (uint32_t i = 0; i < warn_limit; i++) {
656 image_1D.SetLayout(VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
657 image_1D.SetLayout(VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_GENERAL);
658 }
659
660 VkPresentInfoKHR present_info = {};
661 present_info.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR;
662 present_info.waitSemaphoreCount = 0;
663 // presentInfo.pWaitSemaphores = &(m_RenderFinishedSemaphores[m_imageIndex]);
664 present_info.swapchainCount = 1;
665 present_info.pSwapchains = &m_swapchain;
666 present_info.pImageIndices = 0;
667 present_info.pResults = NULL;
668
669 m_errorMonitor->SetDesiredFailureMsg(kPerformanceWarningBit,
670 "UNASSIGNED-BestPractices-Submission-ReduceNumberOfSubmissions");
671
672 vk::QueuePresentKHR(m_device->GetDefaultQueue()->handle(), &present_info);
673
674 m_errorMonitor->VerifyFound();
675 }
676
TEST_F(VkAmdBestPracticesLayerTest,NumSyncPrimitives)677 TEST_F(VkAmdBestPracticesLayerTest, NumSyncPrimitives) {
678 InitBestPracticesFramework(kEnableAMDValidation);
679 InitState();
680 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
681
682 m_errorMonitor->SetDesiredFailureMsg(kPerformanceWarningBit,
683 "UNASSIGNED-BestPractices-SyncObjects-HighNumberOfFences");
684 uint32_t fence_warn_limit = 5;
685 for (uint32_t i = 0; i < fence_warn_limit; i++) {
686 VkFence testFence;
687 VkFenceCreateInfo fenceInfo = VkFenceObj::create_info();
688 vk::CreateFence(m_device->device(), &fenceInfo, nullptr, &testFence);
689 }
690 m_errorMonitor->VerifyFound();
691
692 m_errorMonitor->SetDesiredFailureMsg(kPerformanceWarningBit,
693 "UNASSIGNED-BestPractices-SyncObjects-HighNumberOfSemaphores");
694 uint32_t semaphore_warn_limit = 12;
695 for (uint32_t i = 0; i < semaphore_warn_limit; i++) {
696 VkSemaphore test_semaphore;
697 VkSemaphoreCreateInfo semaphore_create_info = {};
698 semaphore_create_info.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO;
699 vk::CreateSemaphore(m_device->device(), &semaphore_create_info, nullptr, &test_semaphore);
700 }
701
702 m_errorMonitor->VerifyFound();
703 }
704
TEST_F(VkAmdBestPracticesLayerTest,SecondaryCmdBuffer)705 TEST_F(VkAmdBestPracticesLayerTest, SecondaryCmdBuffer) {
706 InitBestPracticesFramework(kEnableAMDValidation);
707 InitState();
708
709 ASSERT_NO_FATAL_FAILURE(InitViewport());
710 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
711
712 VkPipelineMultisampleStateCreateInfo pipe_ms_state_ci = {};
713 pipe_ms_state_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO;
714 pipe_ms_state_ci.pNext = NULL;
715 pipe_ms_state_ci.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT;
716 pipe_ms_state_ci.sampleShadingEnable = 0;
717 pipe_ms_state_ci.minSampleShading = 1.0;
718 pipe_ms_state_ci.pSampleMask = NULL;
719
720 const float vbo_data[3] = {1.f, 0.f, 1.f};
721 VkVerticesObj vertex_buffer(m_device, 1, 1, sizeof(vbo_data), 1, vbo_data);
722
723 CreatePipelineHelper pipe(*this);
724 pipe.InitInfo();
725 pipe.pipe_ms_state_ci_ = pipe_ms_state_ci;
726 pipe.InitState();
727
728 vertex_buffer.AddVertexInputToPipeHelpr(&pipe);
729
730 pipe.CreateGraphicsPipeline();
731
732 VkCommandPoolObj pool(m_device, m_device->graphics_queue_node_index_);
733 VkCommandBufferObj secondary_cmd_buf(m_device, &pool, VK_COMMAND_BUFFER_LEVEL_SECONDARY);
734
735 // record a secondary command buffer
736 secondary_cmd_buf.begin();
737 secondary_cmd_buf.BeginRenderPass(m_renderPassBeginInfo);
738
739 vk::CmdBindPipeline(secondary_cmd_buf.handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.pipeline_);
740 vertex_buffer.BindVertexBuffers(secondary_cmd_buf.handle());
741 secondary_cmd_buf.Draw(1, 0, 0, 0);
742 secondary_cmd_buf.Draw(1, 0, 0, 0);
743 secondary_cmd_buf.Draw(1, 0, 0, 0);
744 secondary_cmd_buf.Draw(1, 0, 0, 0);
745
746 VkClearAttachment color_attachment;
747 color_attachment.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
748 color_attachment.clearValue.color.float32[0] = 1.0;
749 color_attachment.clearValue.color.float32[1] = 1.0;
750 color_attachment.clearValue.color.float32[2] = 1.0;
751 color_attachment.clearValue.color.float32[3] = 1.0;
752 color_attachment.colorAttachment = 0;
753 VkClearRect clear_rect = {{{0, 0}, {(uint32_t)m_width, (uint32_t)m_height}}, 0, 1};
754
755 m_errorMonitor->SetAllowedFailureMsg("UNASSIGNED-BestPractices-DrawState-ClearCmdBeforeDraw");
756
757 vk::CmdClearAttachments(secondary_cmd_buf.handle(), 1, &color_attachment, 1, &clear_rect);
758
759 secondary_cmd_buf.EndRenderPass();
760 secondary_cmd_buf.end();
761
762 m_commandBuffer->begin();
763 m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
764 m_errorMonitor->SetDesiredFailureMsg(kPerformanceWarningBit,
765 "UNASSIGNED-BestPractices-VkCommandBuffer-AvoidSecondaryCmdBuffers");
766
767 vk::CmdExecuteCommands(m_commandBuffer->handle(), 1, &secondary_cmd_buf.handle());
768
769 m_errorMonitor->VerifyFound();
770 }