blob: 6fdffc9c4ad8184889dd79f9991123dcc3e1989b [file] [log] [blame]
unknown088160a2019-05-23 17:43:13 -06001/*
sfricke-samsung6886c4b2021-01-16 08:37:35 -08002 * Copyright (c) 2015-2021 The Khronos Group Inc.
3 * Copyright (c) 2015-2021 Valve Corporation
4 * Copyright (c) 2015-2021 LunarG, Inc.
5 * Copyright (c) 2015-2021 Google, Inc.
Tobias Hector04f2ab22020-12-01 10:59:33 +00006 * Modifications Copyright (C) 2020 Advanced Micro Devices, Inc. All rights reserved.
unknown088160a2019-05-23 17:43:13 -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: Chia-I Wu <olvaffe@gmail.com>
15 * Author: Chris Forbes <chrisf@ijw.co.nz>
16 * Author: Courtney Goeltzenleuchter <courtney@LunarG.com>
17 * Author: Mark Lobodzinski <mark@lunarg.com>
18 * Author: Mike Stroyan <mike@LunarG.com>
19 * Author: Tobin Ehlis <tobine@google.com>
20 * Author: Tony Barbour <tony@LunarG.com>
21 * Author: Cody Northrop <cnorthrop@google.com>
22 * Author: Dave Houlton <daveh@lunarg.com>
23 * Author: Jeremy Kniager <jeremyk@lunarg.com>
24 * Author: Shannon McPherson <shannon@lunarg.com>
25 * Author: John Zulauf <jzulauf@lunarg.com>
Tobias Hector04f2ab22020-12-01 10:59:33 +000026 * Author: Tobias Hector <tobias.hector@amd.com>
unknown088160a2019-05-23 17:43:13 -060027 */
28
29#include "cast_utils.h"
30#include "layer_validation_tests.h"
31
32TEST_F(VkLayerTest, InvalidCommandPoolConsistency) {
33 TEST_DESCRIPTION("Allocate command buffers from one command pool and attempt to delete them from another.");
34
Mark Lobodzinski20310782020-02-28 14:25:17 -070035 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkFreeCommandBuffers-pCommandBuffers-parent");
unknown088160a2019-05-23 17:43:13 -060036
37 ASSERT_NO_FATAL_FAILURE(Init());
38 VkCommandPool command_pool_one;
39 VkCommandPool command_pool_two;
40
41 VkCommandPoolCreateInfo pool_create_info{};
42 pool_create_info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
43 pool_create_info.queueFamilyIndex = m_device->graphics_queue_node_index_;
44 pool_create_info.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT;
45
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -060046 vk::CreateCommandPool(m_device->device(), &pool_create_info, nullptr, &command_pool_one);
unknown088160a2019-05-23 17:43:13 -060047
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -060048 vk::CreateCommandPool(m_device->device(), &pool_create_info, nullptr, &command_pool_two);
unknown088160a2019-05-23 17:43:13 -060049
50 VkCommandBuffer cb;
51 VkCommandBufferAllocateInfo command_buffer_allocate_info{};
52 command_buffer_allocate_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
53 command_buffer_allocate_info.commandPool = command_pool_one;
54 command_buffer_allocate_info.commandBufferCount = 1;
55 command_buffer_allocate_info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -060056 vk::AllocateCommandBuffers(m_device->device(), &command_buffer_allocate_info, &cb);
unknown088160a2019-05-23 17:43:13 -060057
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -060058 vk::FreeCommandBuffers(m_device->device(), command_pool_two, 1, &cb);
unknown088160a2019-05-23 17:43:13 -060059
60 m_errorMonitor->VerifyFound();
61
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -060062 vk::DestroyCommandPool(m_device->device(), command_pool_one, NULL);
63 vk::DestroyCommandPool(m_device->device(), command_pool_two, NULL);
unknown088160a2019-05-23 17:43:13 -060064}
65
66TEST_F(VkLayerTest, InvalidSecondaryCommandBufferBarrier) {
67 TEST_DESCRIPTION("Add an invalid image barrier in a secondary command buffer");
68 ASSERT_NO_FATAL_FAILURE(Init());
69
70 // A renderpass with a single subpass that declared a self-dependency
71 VkAttachmentDescription attach[] = {
72 {0, VK_FORMAT_R8G8B8A8_UNORM, VK_SAMPLE_COUNT_1_BIT, VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE,
73 VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE, VK_IMAGE_LAYOUT_UNDEFINED,
74 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL},
75 };
76 VkAttachmentReference ref = {0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL};
77 VkSubpassDescription subpasses[] = {
78 {0, VK_PIPELINE_BIND_POINT_GRAPHICS, 0, nullptr, 1, &ref, nullptr, nullptr, 0, nullptr},
79 };
80 VkSubpassDependency dep = {0,
81 0,
82 VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
83 VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
84 VK_ACCESS_SHADER_WRITE_BIT,
85 VK_ACCESS_SHADER_WRITE_BIT,
86 VK_DEPENDENCY_BY_REGION_BIT};
87 VkRenderPassCreateInfo rpci = {VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, nullptr, 0, 1, attach, 1, subpasses, 1, &dep};
88 VkRenderPass rp;
89
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -060090 VkResult err = vk::CreateRenderPass(m_device->device(), &rpci, nullptr, &rp);
unknown088160a2019-05-23 17:43:13 -060091 ASSERT_VK_SUCCESS(err);
92
93 VkImageObj image(m_device);
94 image.Init(32, 32, 1, VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, VK_IMAGE_TILING_OPTIMAL, 0);
95 VkImageView imageView = image.targetView(VK_FORMAT_R8G8B8A8_UNORM);
96 // Second image that img_barrier will incorrectly use
97 VkImageObj image2(m_device);
98 image2.Init(32, 32, 1, VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, VK_IMAGE_TILING_OPTIMAL, 0);
99
100 VkFramebufferCreateInfo fbci = {VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, nullptr, 0, rp, 1, &imageView, 32, 32, 1};
101 VkFramebuffer fb;
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -0600102 err = vk::CreateFramebuffer(m_device->device(), &fbci, nullptr, &fb);
unknown088160a2019-05-23 17:43:13 -0600103 ASSERT_VK_SUCCESS(err);
104
105 m_commandBuffer->begin();
106
107 VkRenderPassBeginInfo rpbi = {VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,
108 nullptr,
109 rp,
110 fb,
111 {{
112 0,
113 0,
114 },
115 {32, 32}},
116 0,
117 nullptr};
118
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -0600119 vk::CmdBeginRenderPass(m_commandBuffer->handle(), &rpbi, VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS);
unknown088160a2019-05-23 17:43:13 -0600120
121 VkCommandPoolObj pool(m_device, m_device->graphics_queue_node_index_, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT);
122 VkCommandBufferObj secondary(m_device, &pool, VK_COMMAND_BUFFER_LEVEL_SECONDARY);
123
124 VkCommandBufferInheritanceInfo cbii = {VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO,
125 nullptr,
126 rp,
127 0,
128 VK_NULL_HANDLE, // Set to NULL FB handle intentionally to flesh out any errors
129 VK_FALSE,
130 0,
131 0};
132 VkCommandBufferBeginInfo cbbi = {VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, nullptr,
133 VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT | VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT,
134 &cbii};
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -0600135 vk::BeginCommandBuffer(secondary.handle(), &cbbi);
unknown088160a2019-05-23 17:43:13 -0600136 VkImageMemoryBarrier img_barrier = {};
137 img_barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
138 img_barrier.srcAccessMask = VK_ACCESS_SHADER_WRITE_BIT;
139 img_barrier.dstAccessMask = VK_ACCESS_SHADER_WRITE_BIT;
140 img_barrier.oldLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
141 img_barrier.newLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
142 img_barrier.image = image2.handle(); // Image mis-matches with FB image
143 img_barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
144 img_barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
145 img_barrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
146 img_barrier.subresourceRange.baseArrayLayer = 0;
147 img_barrier.subresourceRange.baseMipLevel = 0;
148 img_barrier.subresourceRange.layerCount = 1;
149 img_barrier.subresourceRange.levelCount = 1;
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -0600150 vk::CmdPipelineBarrier(secondary.handle(), VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
151 VK_DEPENDENCY_BY_REGION_BIT, 0, nullptr, 0, nullptr, 1, &img_barrier);
unknown088160a2019-05-23 17:43:13 -0600152 secondary.end();
153
Shannon McPherson93970b12020-06-12 14:34:35 -0600154 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdPipelineBarrier-image-04073");
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -0600155 vk::CmdExecuteCommands(m_commandBuffer->handle(), 1, &secondary.handle());
unknown088160a2019-05-23 17:43:13 -0600156 m_errorMonitor->VerifyFound();
157
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -0600158 vk::DestroyFramebuffer(m_device->device(), fb, nullptr);
159 vk::DestroyRenderPass(m_device->device(), rp, nullptr);
unknown088160a2019-05-23 17:43:13 -0600160}
161
162TEST_F(VkLayerTest, DynamicDepthBiasNotBound) {
163 TEST_DESCRIPTION(
164 "Run a simple draw calls to validate failure when Depth Bias dynamic state is required but not correctly bound.");
165
166 ASSERT_NO_FATAL_FAILURE(Init());
167 // Dynamic depth bias
Mark Lobodzinski20310782020-02-28 14:25:17 -0700168 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "Dynamic depth bias state not set for this command buffer");
unknown088160a2019-05-23 17:43:13 -0600169 VKTriangleTest(BsoFailDepthBias);
170 m_errorMonitor->VerifyFound();
171}
172
173TEST_F(VkLayerTest, DynamicLineWidthNotBound) {
174 TEST_DESCRIPTION(
175 "Run a simple draw calls to validate failure when Line Width dynamic state is required but not correctly bound.");
176
177 ASSERT_NO_FATAL_FAILURE(Init());
178 // Dynamic line width
Mark Lobodzinski20310782020-02-28 14:25:17 -0700179 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "Dynamic line width state not set for this command buffer");
unknown088160a2019-05-23 17:43:13 -0600180 VKTriangleTest(BsoFailLineWidth);
181 m_errorMonitor->VerifyFound();
182}
183
Jeff Bolzf390c6c2019-08-16 16:29:53 -0500184TEST_F(VkLayerTest, DynamicLineStippleNotBound) {
185 TEST_DESCRIPTION(
186 "Run a simple draw calls to validate failure when Line Stipple dynamic state is required but not correctly bound.");
187
188 if (InstanceExtensionSupported(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME)) {
189 m_instance_extension_names.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
190 } else {
191 printf("%s Did not find required instance extension %s; skipped.\n", kSkipPrefix,
192 VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
193 return;
194 }
Mark Lobodzinski09ce9c42020-03-06 10:02:44 -0700195 ASSERT_NO_FATAL_FAILURE(InitFramework(m_errorMonitor));
Jeff Bolzf390c6c2019-08-16 16:29:53 -0500196 std::array<const char *, 1> required_device_extensions = {{VK_EXT_LINE_RASTERIZATION_EXTENSION_NAME}};
197 for (auto device_extension : required_device_extensions) {
198 if (DeviceExtensionSupported(gpu(), nullptr, device_extension)) {
199 m_device_extension_names.push_back(device_extension);
200 } else {
201 printf("%s %s Extension not supported, skipping tests\n", kSkipPrefix, device_extension);
202 return;
203 }
204 }
205
206 PFN_vkGetPhysicalDeviceFeatures2KHR vkGetPhysicalDeviceFeatures2KHR =
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -0600207 (PFN_vkGetPhysicalDeviceFeatures2KHR)vk::GetInstanceProcAddr(instance(), "vkGetPhysicalDeviceFeatures2KHR");
Jeff Bolzf390c6c2019-08-16 16:29:53 -0500208 ASSERT_TRUE(vkGetPhysicalDeviceFeatures2KHR != nullptr);
209
Mark Lobodzinski07d0a612020-12-30 15:42:31 -0700210 auto line_rasterization_features = LvlInitStruct<VkPhysicalDeviceLineRasterizationFeaturesEXT>();
211 auto features2 = LvlInitStruct<VkPhysicalDeviceFeatures2KHR>(&line_rasterization_features);
Jeff Bolzf390c6c2019-08-16 16:29:53 -0500212 vkGetPhysicalDeviceFeatures2KHR(gpu(), &features2);
213
214 if (!line_rasterization_features.stippledBresenhamLines || !line_rasterization_features.bresenhamLines) {
215 printf("%sStipple Bresenham lines not supported; skipped.\n", kSkipPrefix);
216 return;
217 }
218
219 ASSERT_NO_FATAL_FAILURE(InitState(nullptr, &features2, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT));
220
Mark Lobodzinski20310782020-02-28 14:25:17 -0700221 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "Dynamic line stipple state not set for this command buffer");
Jeff Bolzf390c6c2019-08-16 16:29:53 -0500222 VKTriangleTest(BsoFailLineStipple);
223 m_errorMonitor->VerifyFound();
224}
225
unknown088160a2019-05-23 17:43:13 -0600226TEST_F(VkLayerTest, DynamicViewportNotBound) {
227 TEST_DESCRIPTION(
228 "Run a simple draw calls to validate failure when Viewport dynamic state is required but not correctly bound.");
229
230 ASSERT_NO_FATAL_FAILURE(Init());
231 // Dynamic viewport state
Mark Lobodzinski20310782020-02-28 14:25:17 -0700232 m_errorMonitor->SetDesiredFailureMsg(kErrorBit,
unknown088160a2019-05-23 17:43:13 -0600233 "Dynamic viewport(s) 0 are used by pipeline state object, but were not provided");
234 VKTriangleTest(BsoFailViewport);
235 m_errorMonitor->VerifyFound();
236}
237
238TEST_F(VkLayerTest, DynamicScissorNotBound) {
239 TEST_DESCRIPTION("Run a simple draw calls to validate failure when Scissor dynamic state is required but not correctly bound.");
240
241 ASSERT_NO_FATAL_FAILURE(Init());
242 // Dynamic scissor state
Mark Lobodzinski20310782020-02-28 14:25:17 -0700243 m_errorMonitor->SetDesiredFailureMsg(kErrorBit,
unknown088160a2019-05-23 17:43:13 -0600244 "Dynamic scissor(s) 0 are used by pipeline state object, but were not provided");
245 VKTriangleTest(BsoFailScissor);
246 m_errorMonitor->VerifyFound();
247}
248
249TEST_F(VkLayerTest, DynamicBlendConstantsNotBound) {
250 TEST_DESCRIPTION(
251 "Run a simple draw calls to validate failure when Blend Constants dynamic state is required but not correctly bound.");
252
253 ASSERT_NO_FATAL_FAILURE(Init());
254 // Dynamic blend constant state
Mark Lobodzinski20310782020-02-28 14:25:17 -0700255 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "Dynamic blend constants state not set for this command buffer");
unknown088160a2019-05-23 17:43:13 -0600256 VKTriangleTest(BsoFailBlend);
257 m_errorMonitor->VerifyFound();
258}
259
260TEST_F(VkLayerTest, DynamicDepthBoundsNotBound) {
261 TEST_DESCRIPTION(
262 "Run a simple draw calls to validate failure when Depth Bounds dynamic state is required but not correctly bound.");
263
264 ASSERT_NO_FATAL_FAILURE(Init());
265 if (!m_device->phy().features().depthBounds) {
266 printf("%s Device does not support depthBounds test; skipped.\n", kSkipPrefix);
267 return;
268 }
269 // Dynamic depth bounds
Mark Lobodzinski20310782020-02-28 14:25:17 -0700270 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "Dynamic depth bounds state not set for this command buffer");
unknown088160a2019-05-23 17:43:13 -0600271 VKTriangleTest(BsoFailDepthBounds);
272 m_errorMonitor->VerifyFound();
273}
274
275TEST_F(VkLayerTest, DynamicStencilReadNotBound) {
276 TEST_DESCRIPTION(
277 "Run a simple draw calls to validate failure when Stencil Read dynamic state is required but not correctly bound.");
278
279 ASSERT_NO_FATAL_FAILURE(Init());
280 // Dynamic stencil read mask
Mark Lobodzinski20310782020-02-28 14:25:17 -0700281 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "Dynamic stencil read mask state not set for this command buffer");
unknown088160a2019-05-23 17:43:13 -0600282 VKTriangleTest(BsoFailStencilReadMask);
283 m_errorMonitor->VerifyFound();
284}
285
286TEST_F(VkLayerTest, DynamicStencilWriteNotBound) {
287 TEST_DESCRIPTION(
288 "Run a simple draw calls to validate failure when Stencil Write dynamic state is required but not correctly bound.");
289
290 ASSERT_NO_FATAL_FAILURE(Init());
291 // Dynamic stencil write mask
Mark Lobodzinski20310782020-02-28 14:25:17 -0700292 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "Dynamic stencil write mask state not set for this command buffer");
unknown088160a2019-05-23 17:43:13 -0600293 VKTriangleTest(BsoFailStencilWriteMask);
294 m_errorMonitor->VerifyFound();
295}
296
297TEST_F(VkLayerTest, DynamicStencilRefNotBound) {
298 TEST_DESCRIPTION(
299 "Run a simple draw calls to validate failure when Stencil Ref dynamic state is required but not correctly bound.");
300
301 ASSERT_NO_FATAL_FAILURE(Init());
302 // Dynamic stencil reference
Mark Lobodzinski20310782020-02-28 14:25:17 -0700303 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "Dynamic stencil reference state not set for this command buffer");
unknown088160a2019-05-23 17:43:13 -0600304 VKTriangleTest(BsoFailStencilReference);
305 m_errorMonitor->VerifyFound();
306}
307
308TEST_F(VkLayerTest, IndexBufferNotBound) {
309 TEST_DESCRIPTION("Run an indexed draw call without an index buffer bound.");
310
311 ASSERT_NO_FATAL_FAILURE(Init());
Mark Lobodzinski20310782020-02-28 14:25:17 -0700312 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "Index buffer object not bound to this command buffer when Indexed ");
unknown088160a2019-05-23 17:43:13 -0600313 VKTriangleTest(BsoFailIndexBuffer);
314 m_errorMonitor->VerifyFound();
315}
316
317TEST_F(VkLayerTest, IndexBufferBadSize) {
318 TEST_DESCRIPTION("Run indexed draw call with bad index buffer size.");
319
320 ASSERT_NO_FATAL_FAILURE(Init(nullptr, nullptr, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT));
Tony-LunarG4490de42021-06-21 15:49:19 -0600321 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "vkCmdDrawIndexed(): index size ");
unknown088160a2019-05-23 17:43:13 -0600322 VKTriangleTest(BsoFailIndexBufferBadSize);
323 m_errorMonitor->VerifyFound();
324}
325
326TEST_F(VkLayerTest, IndexBufferBadOffset) {
327 TEST_DESCRIPTION("Run indexed draw call with bad index buffer offset.");
328
329 ASSERT_NO_FATAL_FAILURE(Init(nullptr, nullptr, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT));
Tony-LunarG4490de42021-06-21 15:49:19 -0600330 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "vkCmdDrawIndexed(): index size ");
unknown088160a2019-05-23 17:43:13 -0600331 VKTriangleTest(BsoFailIndexBufferBadOffset);
332 m_errorMonitor->VerifyFound();
333}
334
335TEST_F(VkLayerTest, IndexBufferBadBindSize) {
336 TEST_DESCRIPTION("Run bind index buffer with a size greater than the index buffer.");
337
338 ASSERT_NO_FATAL_FAILURE(Init(nullptr, nullptr, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT));
Tony-LunarG4490de42021-06-21 15:49:19 -0600339 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "vkCmdDrawIndexed(): index size ");
unknown088160a2019-05-23 17:43:13 -0600340 VKTriangleTest(BsoFailIndexBufferBadMapSize);
341 m_errorMonitor->VerifyFound();
342}
343
344TEST_F(VkLayerTest, IndexBufferBadBindOffset) {
345 TEST_DESCRIPTION("Run bind index buffer with an offset greater than the size of the index buffer.");
346
347 ASSERT_NO_FATAL_FAILURE(Init(nullptr, nullptr, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT));
Tony-LunarG4490de42021-06-21 15:49:19 -0600348 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "vkCmdDrawIndexed(): index size ");
unknown088160a2019-05-23 17:43:13 -0600349 VKTriangleTest(BsoFailIndexBufferBadMapOffset);
350 m_errorMonitor->VerifyFound();
351}
352
353TEST_F(VkLayerTest, MissingClearAttachment) {
354 TEST_DESCRIPTION("Points to a wrong colorAttachment index in a VkClearAttachment structure passed to vkCmdClearAttachments");
355 ASSERT_NO_FATAL_FAILURE(Init());
Mark Lobodzinski20310782020-02-28 14:25:17 -0700356 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdClearAttachments-aspectMask-02501");
unknown088160a2019-05-23 17:43:13 -0600357
358 VKTriangleTest(BsoFailCmdClearAttachments);
359 m_errorMonitor->VerifyFound();
360}
361
Mark Lobodzinskicd0204c2019-11-11 16:59:18 -0700362TEST_F(VkLayerTest, SecondaryCommandbufferAsPrimary) {
363 TEST_DESCRIPTION("Create a secondary command buffer and pass it to QueueSubmit.");
Mark Lobodzinski20310782020-02-28 14:25:17 -0700364 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkSubmitInfo-pCommandBuffers-00075");
Mark Lobodzinskicd0204c2019-11-11 16:59:18 -0700365
366 ASSERT_NO_FATAL_FAILURE(Init());
367
368 VkCommandBufferObj secondary(m_device, m_commandPool, VK_COMMAND_BUFFER_LEVEL_SECONDARY);
369 secondary.begin();
370 secondary.ClearAllBuffers(m_renderTargets, m_clear_color, nullptr, m_depth_clear_color, m_stencil_clear_color);
371 secondary.end();
372
373 VkSubmitInfo submit_info;
374 submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
375 submit_info.pNext = NULL;
376 submit_info.waitSemaphoreCount = 0;
377 submit_info.pWaitSemaphores = NULL;
378 submit_info.pWaitDstStageMask = NULL;
379 submit_info.commandBufferCount = 1;
380 submit_info.pCommandBuffers = &secondary.handle();
381 submit_info.signalSemaphoreCount = 0;
382 submit_info.pSignalSemaphores = NULL;
383
384 vk::QueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
385 m_errorMonitor->VerifyFound();
386}
387
Jeremy Gebben1db6edc2021-02-17 15:28:40 -0700388TEST_F(VkLayerTest, Sync2SecondaryCommandbufferAsPrimary) {
389 TEST_DESCRIPTION("Create a secondary command buffer and pass it to QueueSubmit2KHR.");
390 SetTargetApiVersion(VK_API_VERSION_1_2);
391 ASSERT_NO_FATAL_FAILURE(InitFramework());
392 if (DeviceExtensionSupported(gpu(), nullptr, VK_KHR_SYNCHRONIZATION_2_EXTENSION_NAME)) {
393 m_device_extension_names.push_back(VK_KHR_SYNCHRONIZATION_2_EXTENSION_NAME);
394 } else {
395 printf("%s Synchronization2 not supported, skipping test\n", kSkipPrefix);
396 return;
397 }
398
399 if (!CheckSynchronization2SupportAndInitState(this)) {
400 printf("%s Synchronization2 not supported, skipping test\n", kSkipPrefix);
401 return;
402 }
403 auto fpQueueSubmit2KHR = (PFN_vkQueueSubmit2KHR)vk::GetDeviceProcAddr(m_device->device(), "vkQueueSubmit2KHR");
404 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkCommandBufferSubmitInfoKHR-commandBuffer-03890");
405
406 VkCommandBufferObj secondary(m_device, m_commandPool, VK_COMMAND_BUFFER_LEVEL_SECONDARY);
407 secondary.begin();
408 secondary.ClearAllBuffers(m_renderTargets, m_clear_color, nullptr, m_depth_clear_color, m_stencil_clear_color);
409 secondary.end();
410
411 auto cb_info = lvl_init_struct<VkCommandBufferSubmitInfoKHR>();
412 cb_info.commandBuffer = secondary.handle();
413
414 auto submit_info = lvl_init_struct<VkSubmitInfo2KHR>();
415 submit_info.commandBufferInfoCount = 1;
416 submit_info.pCommandBufferInfos = &cb_info;
417
418 fpQueueSubmit2KHR(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
419 m_errorMonitor->VerifyFound();
420}
421
unknown088160a2019-05-23 17:43:13 -0600422TEST_F(VkLayerTest, CommandBufferTwoSubmits) {
Mark Lobodzinski20310782020-02-28 14:25:17 -0700423 m_errorMonitor->SetDesiredFailureMsg(kErrorBit,
unknown088160a2019-05-23 17:43:13 -0600424 "was begun w/ VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT set, but has been submitted");
425
426 ASSERT_NO_FATAL_FAILURE(Init());
427 ASSERT_NO_FATAL_FAILURE(InitViewport());
428 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
429
430 // We luck out b/c by default the framework creates CB w/ the
431 // VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT set
432 m_commandBuffer->begin();
433 m_commandBuffer->ClearAllBuffers(m_renderTargets, m_clear_color, nullptr, m_depth_clear_color, m_stencil_clear_color);
434 m_commandBuffer->end();
435
436 // Bypass framework since it does the waits automatically
437 VkResult err = VK_SUCCESS;
438 VkSubmitInfo submit_info;
439 submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
440 submit_info.pNext = NULL;
441 submit_info.waitSemaphoreCount = 0;
442 submit_info.pWaitSemaphores = NULL;
443 submit_info.pWaitDstStageMask = NULL;
444 submit_info.commandBufferCount = 1;
445 submit_info.pCommandBuffers = &m_commandBuffer->handle();
446 submit_info.signalSemaphoreCount = 0;
447 submit_info.pSignalSemaphores = NULL;
448
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -0600449 err = vk::QueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
unknown088160a2019-05-23 17:43:13 -0600450 ASSERT_VK_SUCCESS(err);
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -0600451 vk::QueueWaitIdle(m_device->m_queue);
unknown088160a2019-05-23 17:43:13 -0600452
453 // Cause validation error by re-submitting cmd buffer that should only be
454 // submitted once
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -0600455 err = vk::QueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
456 vk::QueueWaitIdle(m_device->m_queue);
unknown088160a2019-05-23 17:43:13 -0600457
458 m_errorMonitor->VerifyFound();
459}
460
Jeremy Gebben1db6edc2021-02-17 15:28:40 -0700461TEST_F(VkLayerTest, Sync2CommandBufferTwoSubmits) {
462 SetTargetApiVersion(VK_API_VERSION_1_2);
463 ASSERT_NO_FATAL_FAILURE(InitFramework());
464 if (DeviceExtensionSupported(gpu(), nullptr, VK_KHR_SYNCHRONIZATION_2_EXTENSION_NAME)) {
465 m_device_extension_names.push_back(VK_KHR_SYNCHRONIZATION_2_EXTENSION_NAME);
466 } else {
467 printf("%s Synchronization2 not supported, skipping test\n", kSkipPrefix);
468 return;
469 }
470
471 if (!CheckSynchronization2SupportAndInitState(this)) {
472 printf("%s Synchronization2 not supported, skipping test\n", kSkipPrefix);
473 return;
474 }
475 auto fpQueueSubmit2KHR = (PFN_vkQueueSubmit2KHR)vk::GetDeviceProcAddr(m_device->device(), "vkQueueSubmit2KHR");
476
477 m_errorMonitor->SetDesiredFailureMsg(kErrorBit,
478 "was begun w/ VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT set, but has been submitted");
479 ASSERT_NO_FATAL_FAILURE(InitViewport());
480 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
481
482 // We luck out b/c by default the framework creates CB w/ the
483 // VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT set
484 m_commandBuffer->begin();
485 m_commandBuffer->ClearAllBuffers(m_renderTargets, m_clear_color, nullptr, m_depth_clear_color, m_stencil_clear_color);
486 m_commandBuffer->end();
487
488 // Bypass framework since it does the waits automatically
489 VkResult err = VK_SUCCESS;
490 auto cb_info = lvl_init_struct<VkCommandBufferSubmitInfoKHR>();
491 cb_info.commandBuffer = m_commandBuffer->handle();
492
493 auto submit_info = lvl_init_struct<VkSubmitInfo2KHR>();
494 submit_info.commandBufferInfoCount = 1;
495 submit_info.pCommandBufferInfos = &cb_info;
496
497 err = fpQueueSubmit2KHR(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
498 ASSERT_VK_SUCCESS(err);
499 vk::QueueWaitIdle(m_device->m_queue);
500
501 // Cause validation error by re-submitting cmd buffer that should only be
502 // submitted once
503 err = fpQueueSubmit2KHR(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
504 vk::QueueWaitIdle(m_device->m_queue);
505
506 m_errorMonitor->VerifyFound();
507}
508
unknown088160a2019-05-23 17:43:13 -0600509TEST_F(VkLayerTest, InvalidPushConstants) {
510 ASSERT_NO_FATAL_FAILURE(Init());
511 ASSERT_NO_FATAL_FAILURE(InitViewport());
512 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
513
514 VkPipelineLayout pipeline_layout;
515 VkPushConstantRange pc_range = {};
516 VkPipelineLayoutCreateInfo pipeline_layout_ci = {};
517 pipeline_layout_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
518 pipeline_layout_ci.pushConstantRangeCount = 1;
519 pipeline_layout_ci.pPushConstantRanges = &pc_range;
520
521 //
522 // Check for invalid push constant ranges in pipeline layouts.
523 //
524 struct PipelineLayoutTestCase {
525 VkPushConstantRange const range;
526 char const *msg;
527 };
528
529 const uint32_t too_big = m_device->props.limits.maxPushConstantsSize + 0x4;
530 const std::array<PipelineLayoutTestCase, 10> range_tests = {{
sfricke-samsung51303fb2021-05-09 19:09:13 -0700531 {{VK_SHADER_STAGE_VERTEX_BIT, 0, 0}, "VUID-VkPushConstantRange-size-00296"},
532 {{VK_SHADER_STAGE_VERTEX_BIT, 0, 1}, "VUID-VkPushConstantRange-size-00297"},
533 {{VK_SHADER_STAGE_VERTEX_BIT, 4, 1}, "VUID-VkPushConstantRange-size-00297"},
534 {{VK_SHADER_STAGE_VERTEX_BIT, 4, 0}, "VUID-VkPushConstantRange-size-00296"},
535 {{VK_SHADER_STAGE_VERTEX_BIT, 1, 4}, "VUID-VkPushConstantRange-offset-00295"},
536 {{VK_SHADER_STAGE_VERTEX_BIT, 0, too_big}, "VUID-VkPushConstantRange-size-00298"},
537 {{VK_SHADER_STAGE_VERTEX_BIT, too_big, too_big}, "VUID-VkPushConstantRange-offset-00294"},
538 {{VK_SHADER_STAGE_VERTEX_BIT, too_big, 4}, "VUID-VkPushConstantRange-offset-00294"},
539 {{VK_SHADER_STAGE_VERTEX_BIT, 0xFFFFFFF0, 0x00000020}, "VUID-VkPushConstantRange-offset-00294"},
540 {{VK_SHADER_STAGE_VERTEX_BIT, 0x00000020, 0xFFFFFFF0}, "VUID-VkPushConstantRange-size-00298"},
unknown088160a2019-05-23 17:43:13 -0600541 }};
542
543 // Check for invalid offset and size
544 for (const auto &iter : range_tests) {
545 pc_range = iter.range;
Mark Lobodzinski20310782020-02-28 14:25:17 -0700546 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, iter.msg);
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -0600547 vk::CreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipeline_layout);
unknown088160a2019-05-23 17:43:13 -0600548 m_errorMonitor->VerifyFound();
549 }
550
551 // Check for invalid stage flag
552 pc_range.offset = 0;
553 pc_range.size = 16;
554 pc_range.stageFlags = 0;
sfricke-samsung51303fb2021-05-09 19:09:13 -0700555 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkPushConstantRange-stageFlags-requiredbitmask");
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -0600556 vk::CreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipeline_layout);
unknown088160a2019-05-23 17:43:13 -0600557 m_errorMonitor->VerifyFound();
558
559 // Check for duplicate stage flags in a list of push constant ranges.
560 // A shader can only have one push constant block and that block is mapped
561 // to the push constant range that has that shader's stage flag set.
562 // The shader's stage flag can only appear once in all the ranges, so the
563 // implementation can find the one and only range to map it to.
564 const uint32_t ranges_per_test = 5;
565 struct DuplicateStageFlagsTestCase {
566 VkPushConstantRange const ranges[ranges_per_test];
567 std::vector<char const *> const msg;
568 };
569 // Overlapping ranges are OK, but a stage flag can appear only once.
570 const std::array<DuplicateStageFlagsTestCase, 3> duplicate_stageFlags_tests = {
571 {
572 {{{VK_SHADER_STAGE_VERTEX_BIT, 0, 4},
573 {VK_SHADER_STAGE_VERTEX_BIT, 0, 4},
574 {VK_SHADER_STAGE_VERTEX_BIT, 0, 4},
575 {VK_SHADER_STAGE_VERTEX_BIT, 0, 4},
576 {VK_SHADER_STAGE_VERTEX_BIT, 0, 4}},
577 {
578 "vkCreatePipelineLayout() Duplicate stage flags found in ranges 0 and 1.",
579 "vkCreatePipelineLayout() Duplicate stage flags found in ranges 0 and 2.",
580 "vkCreatePipelineLayout() Duplicate stage flags found in ranges 0 and 3.",
581 "vkCreatePipelineLayout() Duplicate stage flags found in ranges 0 and 4.",
582 "vkCreatePipelineLayout() Duplicate stage flags found in ranges 1 and 2.",
583 "vkCreatePipelineLayout() Duplicate stage flags found in ranges 1 and 3.",
584 "vkCreatePipelineLayout() Duplicate stage flags found in ranges 1 and 4.",
585 "vkCreatePipelineLayout() Duplicate stage flags found in ranges 2 and 3.",
586 "vkCreatePipelineLayout() Duplicate stage flags found in ranges 2 and 4.",
587 "vkCreatePipelineLayout() Duplicate stage flags found in ranges 3 and 4.",
588 }},
589 {{{VK_SHADER_STAGE_VERTEX_BIT, 0, 4},
590 {VK_SHADER_STAGE_GEOMETRY_BIT, 0, 4},
591 {VK_SHADER_STAGE_FRAGMENT_BIT, 0, 4},
592 {VK_SHADER_STAGE_VERTEX_BIT, 0, 4},
593 {VK_SHADER_STAGE_GEOMETRY_BIT, 0, 4}},
594 {
595 "vkCreatePipelineLayout() Duplicate stage flags found in ranges 0 and 3.",
596 "vkCreatePipelineLayout() Duplicate stage flags found in ranges 1 and 4.",
597 }},
598 {{{VK_SHADER_STAGE_FRAGMENT_BIT, 0, 4},
599 {VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT, 0, 4},
600 {VK_SHADER_STAGE_VERTEX_BIT, 0, 4},
601 {VK_SHADER_STAGE_VERTEX_BIT, 0, 4},
602 {VK_SHADER_STAGE_GEOMETRY_BIT, 0, 4}},
603 {
604 "vkCreatePipelineLayout() Duplicate stage flags found in ranges 2 and 3.",
605 }},
606 },
607 };
608
609 for (const auto &iter : duplicate_stageFlags_tests) {
610 pipeline_layout_ci.pPushConstantRanges = iter.ranges;
611 pipeline_layout_ci.pushConstantRangeCount = ranges_per_test;
Mark Lobodzinski20310782020-02-28 14:25:17 -0700612 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, iter.msg.begin(), iter.msg.end());
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -0600613 vk::CreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipeline_layout);
unknown088160a2019-05-23 17:43:13 -0600614 m_errorMonitor->VerifyFound();
615 }
616
617 //
618 // CmdPushConstants tests
619 //
620
621 // Setup a pipeline layout with ranges: [0,32) [16,80)
622 const std::vector<VkPushConstantRange> pc_range2 = {{VK_SHADER_STAGE_VERTEX_BIT, 16, 64},
623 {VK_SHADER_STAGE_FRAGMENT_BIT, 0, 32}};
624 const VkPipelineLayoutObj pipeline_layout_obj(m_device, {}, pc_range2);
625
626 const uint8_t dummy_values[100] = {};
627
628 m_commandBuffer->begin();
629 m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
630
631 // Check for invalid stage flag
632 // Note that VU 00996 isn't reached due to parameter validation
sfricke-samsung51303fb2021-05-09 19:09:13 -0700633 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdPushConstants-stageFlags-requiredbitmask");
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -0600634 vk::CmdPushConstants(m_commandBuffer->handle(), pipeline_layout_obj.handle(), 0, 0, 16, dummy_values);
unknown088160a2019-05-23 17:43:13 -0600635 m_errorMonitor->VerifyFound();
636
637 // Positive tests for the overlapping ranges
638 m_errorMonitor->ExpectSuccess();
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -0600639 vk::CmdPushConstants(m_commandBuffer->handle(), pipeline_layout_obj.handle(), VK_SHADER_STAGE_FRAGMENT_BIT, 0, 16,
640 dummy_values);
unknown088160a2019-05-23 17:43:13 -0600641 m_errorMonitor->VerifyNotFound();
642 m_errorMonitor->ExpectSuccess();
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -0600643 vk::CmdPushConstants(m_commandBuffer->handle(), pipeline_layout_obj.handle(), VK_SHADER_STAGE_VERTEX_BIT, 32, 48, dummy_values);
unknown088160a2019-05-23 17:43:13 -0600644 m_errorMonitor->VerifyNotFound();
645 m_errorMonitor->ExpectSuccess();
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -0600646 vk::CmdPushConstants(m_commandBuffer->handle(), pipeline_layout_obj.handle(),
647 VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT, 16, 16, dummy_values);
unknown088160a2019-05-23 17:43:13 -0600648 m_errorMonitor->VerifyNotFound();
649
650 // Wrong cmd stages for extant range
651 // No range for all cmd stages -- "VUID-vkCmdPushConstants-offset-01795" VUID-vkCmdPushConstants-offset-01795
Mark Lobodzinski20310782020-02-28 14:25:17 -0700652 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdPushConstants-offset-01795");
unknown088160a2019-05-23 17:43:13 -0600653 // Missing cmd stages for found overlapping range -- "VUID-vkCmdPushConstants-offset-01796" VUID-vkCmdPushConstants-offset-01796
Mark Lobodzinski20310782020-02-28 14:25:17 -0700654 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdPushConstants-offset-01796");
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -0600655 vk::CmdPushConstants(m_commandBuffer->handle(), pipeline_layout_obj.handle(), VK_SHADER_STAGE_GEOMETRY_BIT, 0, 16,
656 dummy_values);
unknown088160a2019-05-23 17:43:13 -0600657 m_errorMonitor->VerifyFound();
658
659 // Wrong no extant range
Mark Lobodzinski20310782020-02-28 14:25:17 -0700660 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdPushConstants-offset-01795");
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -0600661 vk::CmdPushConstants(m_commandBuffer->handle(), pipeline_layout_obj.handle(), VK_SHADER_STAGE_FRAGMENT_BIT, 80, 4,
662 dummy_values);
unknown088160a2019-05-23 17:43:13 -0600663 m_errorMonitor->VerifyFound();
664
665 // Wrong overlapping extent
Mark Lobodzinski20310782020-02-28 14:25:17 -0700666 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdPushConstants-offset-01795");
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -0600667 vk::CmdPushConstants(m_commandBuffer->handle(), pipeline_layout_obj.handle(),
668 VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT, 0, 20, dummy_values);
unknown088160a2019-05-23 17:43:13 -0600669 m_errorMonitor->VerifyFound();
670
671 // Wrong stage flags for valid overlapping range
Mark Lobodzinski20310782020-02-28 14:25:17 -0700672 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdPushConstants-offset-01796");
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -0600673 vk::CmdPushConstants(m_commandBuffer->handle(), pipeline_layout_obj.handle(), VK_SHADER_STAGE_VERTEX_BIT, 16, 16, dummy_values);
unknown088160a2019-05-23 17:43:13 -0600674 m_errorMonitor->VerifyFound();
675
676 m_commandBuffer->EndRenderPass();
677 m_commandBuffer->end();
678}
679
680TEST_F(VkLayerTest, NoBeginCommandBuffer) {
sfricke-samsung946027b2021-04-20 22:44:36 -0700681 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkEndCommandBuffer-commandBuffer-00059");
unknown088160a2019-05-23 17:43:13 -0600682
683 ASSERT_NO_FATAL_FAILURE(Init());
684 VkCommandBufferObj commandBuffer(m_device, m_commandPool);
685 // Call EndCommandBuffer() w/o calling BeginCommandBuffer()
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -0600686 vk::EndCommandBuffer(commandBuffer.handle());
unknown088160a2019-05-23 17:43:13 -0600687
688 m_errorMonitor->VerifyFound();
689}
690
691TEST_F(VkLayerTest, SecondaryCommandBufferNullRenderpass) {
692 ASSERT_NO_FATAL_FAILURE(Init());
693
694 VkCommandBufferObj cb(m_device, m_commandPool, VK_COMMAND_BUFFER_LEVEL_SECONDARY);
695
696 // Force the failure by not setting the Renderpass and Framebuffer fields
697 VkCommandBufferInheritanceInfo cmd_buf_hinfo = {};
698 cmd_buf_hinfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO;
699
700 VkCommandBufferBeginInfo cmd_buf_info = {};
701 cmd_buf_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
702 cmd_buf_info.pNext = NULL;
703 cmd_buf_info.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT | VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT;
704 cmd_buf_info.pInheritanceInfo = &cmd_buf_hinfo;
705
Mark Lobodzinski20310782020-02-28 14:25:17 -0700706 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkCommandBufferBeginInfo-flags-00053");
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -0600707 vk::BeginCommandBuffer(cb.handle(), &cmd_buf_info);
unknown088160a2019-05-23 17:43:13 -0600708 m_errorMonitor->VerifyFound();
709}
710
711TEST_F(VkLayerTest, SecondaryCommandBufferRerecordedExplicitReset) {
712 ASSERT_NO_FATAL_FAILURE(Init());
713
Mark Lobodzinski20310782020-02-28 14:25:17 -0700714 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "was destroyed or rerecorded");
unknown088160a2019-05-23 17:43:13 -0600715
716 // A pool we can reset in.
717 VkCommandPoolObj pool(m_device, m_device->graphics_queue_node_index_, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT);
718 VkCommandBufferObj secondary(m_device, &pool, VK_COMMAND_BUFFER_LEVEL_SECONDARY);
719
720 secondary.begin();
721 secondary.end();
722
723 m_commandBuffer->begin();
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -0600724 vk::CmdExecuteCommands(m_commandBuffer->handle(), 1, &secondary.handle());
unknown088160a2019-05-23 17:43:13 -0600725
726 // rerecording of secondary
727 secondary.reset(); // explicit reset here.
728 secondary.begin();
729 secondary.end();
730
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -0600731 vk::CmdExecuteCommands(m_commandBuffer->handle(), 1, &secondary.handle());
unknown088160a2019-05-23 17:43:13 -0600732 m_errorMonitor->VerifyFound();
733}
734
735TEST_F(VkLayerTest, SecondaryCommandBufferRerecordedNoReset) {
736 ASSERT_NO_FATAL_FAILURE(Init());
737
Mark Lobodzinski20310782020-02-28 14:25:17 -0700738 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "was destroyed or rerecorded");
unknown088160a2019-05-23 17:43:13 -0600739
740 // A pool we can reset in.
741 VkCommandPoolObj pool(m_device, m_device->graphics_queue_node_index_, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT);
742 VkCommandBufferObj secondary(m_device, &pool, VK_COMMAND_BUFFER_LEVEL_SECONDARY);
743
744 secondary.begin();
745 secondary.end();
746
747 m_commandBuffer->begin();
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -0600748 vk::CmdExecuteCommands(m_commandBuffer->handle(), 1, &secondary.handle());
unknown088160a2019-05-23 17:43:13 -0600749
750 // rerecording of secondary
751 secondary.begin(); // implicit reset in begin
752 secondary.end();
753
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -0600754 vk::CmdExecuteCommands(m_commandBuffer->handle(), 1, &secondary.handle());
unknown088160a2019-05-23 17:43:13 -0600755 m_errorMonitor->VerifyFound();
756}
757
758TEST_F(VkLayerTest, CascadedInvalidation) {
759 ASSERT_NO_FATAL_FAILURE(Init());
760
761 VkEventCreateInfo eci = {VK_STRUCTURE_TYPE_EVENT_CREATE_INFO, nullptr, 0};
762 VkEvent event;
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -0600763 vk::CreateEvent(m_device->device(), &eci, nullptr, &event);
unknown088160a2019-05-23 17:43:13 -0600764
765 VkCommandBufferObj secondary(m_device, m_commandPool, VK_COMMAND_BUFFER_LEVEL_SECONDARY);
766 secondary.begin();
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -0600767 vk::CmdSetEvent(secondary.handle(), event, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT);
unknown088160a2019-05-23 17:43:13 -0600768 secondary.end();
769
770 m_commandBuffer->begin();
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -0600771 vk::CmdExecuteCommands(m_commandBuffer->handle(), 1, &secondary.handle());
unknown088160a2019-05-23 17:43:13 -0600772 m_commandBuffer->end();
773
774 // destroying the event should invalidate both primary and secondary CB
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -0600775 vk::DestroyEvent(m_device->device(), event, nullptr);
unknown088160a2019-05-23 17:43:13 -0600776
Mark Lobodzinski20310782020-02-28 14:25:17 -0700777 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "UNASSIGNED-CoreValidation-DrawState-InvalidCommandBuffer-VkEvent");
unknown088160a2019-05-23 17:43:13 -0600778 m_commandBuffer->QueueCommandBuffer(false);
779 m_errorMonitor->VerifyFound();
780}
781
782TEST_F(VkLayerTest, CommandBufferResetErrors) {
783 // Cause error due to Begin while recording CB
784 // Then cause 2 errors for attempting to reset CB w/o having
785 // VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT set for the pool from
786 // which CBs were allocated. Note that this bit is off by default.
Mark Lobodzinski20310782020-02-28 14:25:17 -0700787 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkBeginCommandBuffer-commandBuffer-00049");
unknown088160a2019-05-23 17:43:13 -0600788
789 ASSERT_NO_FATAL_FAILURE(Init());
790
791 // Calls AllocateCommandBuffers
792 VkCommandBufferObj commandBuffer(m_device, m_commandPool);
793
794 // Force the failure by setting the Renderpass and Framebuffer fields with (fake) data
795 VkCommandBufferInheritanceInfo cmd_buf_hinfo = {};
796 cmd_buf_hinfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO;
797 VkCommandBufferBeginInfo cmd_buf_info = {};
798 cmd_buf_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
799 cmd_buf_info.pNext = NULL;
800 cmd_buf_info.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT;
801 cmd_buf_info.pInheritanceInfo = &cmd_buf_hinfo;
802
803 // Begin CB to transition to recording state
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -0600804 vk::BeginCommandBuffer(commandBuffer.handle(), &cmd_buf_info);
unknown088160a2019-05-23 17:43:13 -0600805 // Can't re-begin. This should trigger error
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -0600806 vk::BeginCommandBuffer(commandBuffer.handle(), &cmd_buf_info);
unknown088160a2019-05-23 17:43:13 -0600807 m_errorMonitor->VerifyFound();
808
Mark Lobodzinski20310782020-02-28 14:25:17 -0700809 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkResetCommandBuffer-commandBuffer-00046");
unknown088160a2019-05-23 17:43:13 -0600810 VkCommandBufferResetFlags flags = 0; // Don't care about flags for this test
811 // Reset attempt will trigger error due to incorrect CommandPool state
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -0600812 vk::ResetCommandBuffer(commandBuffer.handle(), flags);
unknown088160a2019-05-23 17:43:13 -0600813 m_errorMonitor->VerifyFound();
814
Mark Lobodzinski20310782020-02-28 14:25:17 -0700815 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkBeginCommandBuffer-commandBuffer-00050");
unknown088160a2019-05-23 17:43:13 -0600816 // Transition CB to RECORDED state
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -0600817 vk::EndCommandBuffer(commandBuffer.handle());
unknown088160a2019-05-23 17:43:13 -0600818 // Now attempting to Begin will implicitly reset, which triggers error
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -0600819 vk::BeginCommandBuffer(commandBuffer.handle(), &cmd_buf_info);
unknown088160a2019-05-23 17:43:13 -0600820 m_errorMonitor->VerifyFound();
821}
822
sfricke-samsungae9f00a2020-05-28 20:48:49 -0700823TEST_F(VkLayerTest, CommandBufferPrimaryFlags) {
824 ASSERT_NO_FATAL_FAILURE(Init());
825
826 // Calls AllocateCommandBuffers
827 VkCommandBufferObj commandBuffer(m_device, m_commandPool);
828
829 VkCommandBufferBeginInfo cmd_buf_info = {};
830 cmd_buf_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
831 cmd_buf_info.pNext = NULL;
832 cmd_buf_info.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT | VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT;
833
834 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkBeginCommandBuffer-commandBuffer-02840");
835 vk::BeginCommandBuffer(commandBuffer.handle(), &cmd_buf_info);
836 m_errorMonitor->VerifyFound();
837}
838
unknown088160a2019-05-23 17:43:13 -0600839TEST_F(VkLayerTest, ClearColorAttachmentsOutsideRenderPass) {
840 // Call CmdClearAttachmentss outside of an active RenderPass
841
Mark Lobodzinski20310782020-02-28 14:25:17 -0700842 m_errorMonitor->SetDesiredFailureMsg(kErrorBit,
unknown088160a2019-05-23 17:43:13 -0600843 "vkCmdClearAttachments(): This call must be issued inside an active render pass");
844
845 ASSERT_NO_FATAL_FAILURE(Init());
846 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
847
848 // Start no RenderPass
849 m_commandBuffer->begin();
850
851 VkClearAttachment color_attachment;
852 color_attachment.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
853 color_attachment.clearValue.color.float32[0] = 0;
854 color_attachment.clearValue.color.float32[1] = 0;
855 color_attachment.clearValue.color.float32[2] = 0;
856 color_attachment.clearValue.color.float32[3] = 0;
857 color_attachment.colorAttachment = 0;
Mark Lobodzinskid5447512019-06-28 09:56:36 -0600858 VkClearRect clear_rect = {{{0, 0}, {32, 32}}, 0, 1};
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -0600859 vk::CmdClearAttachments(m_commandBuffer->handle(), 1, &color_attachment, 1, &clear_rect);
unknown088160a2019-05-23 17:43:13 -0600860
861 m_errorMonitor->VerifyFound();
862}
863
Mark Lobodzinski7d7da062019-06-27 16:01:39 -0600864TEST_F(VkLayerTest, ClearColorAttachmentsZeroLayercount) {
865 TEST_DESCRIPTION("Call CmdClearAttachments with a pRect having a layerCount of zero.");
866
Mark Lobodzinski20310782020-02-28 14:25:17 -0700867 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdClearAttachments-layerCount-01934");
Mark Lobodzinski7d7da062019-06-27 16:01:39 -0600868
869 ASSERT_NO_FATAL_FAILURE(Init());
870 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
871
872 m_commandBuffer->begin();
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -0600873 vk::CmdBeginRenderPass(m_commandBuffer->handle(), &renderPassBeginInfo(), VK_SUBPASS_CONTENTS_INLINE);
Mark Lobodzinski7d7da062019-06-27 16:01:39 -0600874
875 VkClearAttachment color_attachment;
876 color_attachment.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
877 color_attachment.clearValue.color.float32[0] = 0;
878 color_attachment.clearValue.color.float32[1] = 0;
879 color_attachment.clearValue.color.float32[2] = 0;
880 color_attachment.clearValue.color.float32[3] = 0;
881 color_attachment.colorAttachment = 0;
882 VkClearRect clear_rect = {{{0, 0}, {32, 32}}};
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -0600883 vk::CmdClearAttachments(m_commandBuffer->handle(), 1, &color_attachment, 1, &clear_rect);
Mark Lobodzinski7d7da062019-06-27 16:01:39 -0600884
885 m_errorMonitor->VerifyFound();
886}
887
sfricke-samsungf0f3d8b2020-04-25 02:20:47 -0700888TEST_F(VkLayerTest, ClearColorAttachmentsZeroExtent) {
889 TEST_DESCRIPTION("Call CmdClearAttachments with a pRect having a rect2D extent of zero.");
890
891 ASSERT_NO_FATAL_FAILURE(Init());
892 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
893
894 m_commandBuffer->begin();
895 vk::CmdBeginRenderPass(m_commandBuffer->handle(), &renderPassBeginInfo(), VK_SUBPASS_CONTENTS_INLINE);
896
897 VkClearAttachment color_attachment;
898 color_attachment.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
899 color_attachment.clearValue.color.float32[0] = 0;
900 color_attachment.clearValue.color.float32[1] = 0;
901 color_attachment.clearValue.color.float32[2] = 0;
902 color_attachment.clearValue.color.float32[3] = 0;
903 color_attachment.colorAttachment = 0;
904 VkClearRect clear_rect = {};
905 clear_rect.rect.offset = {0, 0};
906 clear_rect.baseArrayLayer = 0;
907 clear_rect.layerCount = 1;
908
909 clear_rect.rect.extent = {0, 1};
910 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdClearAttachments-rect-02682");
911 vk::CmdClearAttachments(m_commandBuffer->handle(), 1, &color_attachment, 1, &clear_rect);
912 m_errorMonitor->VerifyFound();
913
914 clear_rect.rect.extent = {1, 0};
915 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdClearAttachments-rect-02683");
916 vk::CmdClearAttachments(m_commandBuffer->handle(), 1, &color_attachment, 1, &clear_rect);
917 m_errorMonitor->VerifyFound();
918}
919
sfricke-samsung6141db32020-10-26 03:31:38 -0700920TEST_F(VkLayerTest, ClearAttachmentsInvalidAspectMasks) {
921 TEST_DESCRIPTION("Check VkClearAttachment invalid aspect masks.");
922
923 ASSERT_NO_FATAL_FAILURE(Init());
924 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
925
926 m_commandBuffer->begin();
927 vk::CmdBeginRenderPass(m_commandBuffer->handle(), &renderPassBeginInfo(), VK_SUBPASS_CONTENTS_INLINE);
928
929 VkClearAttachment attachment;
930 attachment.clearValue.color.float32[0] = 0;
931 attachment.clearValue.color.float32[1] = 0;
932 attachment.clearValue.color.float32[2] = 0;
933 attachment.clearValue.color.float32[3] = 0;
934 attachment.colorAttachment = 0;
935 VkClearRect clear_rect = {};
936 clear_rect.rect.offset = {0, 0};
937 clear_rect.rect.extent = {1, 1};
938 clear_rect.baseArrayLayer = 0;
939 clear_rect.layerCount = 1;
940
941 attachment.aspectMask = VK_IMAGE_ASPECT_METADATA_BIT;
942 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkClearAttachment-aspectMask-00020");
943 vk::CmdClearAttachments(m_commandBuffer->handle(), 1, &attachment, 1, &clear_rect);
944 m_errorMonitor->VerifyFound();
945
946 attachment.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT | VK_IMAGE_ASPECT_METADATA_BIT;
947 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkClearAttachment-aspectMask-00020");
948 vk::CmdClearAttachments(m_commandBuffer->handle(), 1, &attachment, 1, &clear_rect);
949 m_errorMonitor->VerifyFound();
950
951 attachment.aspectMask = VK_IMAGE_ASPECT_MEMORY_PLANE_1_BIT_EXT;
952 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkClearAttachment-aspectMask-02246");
953 vk::CmdClearAttachments(m_commandBuffer->handle(), 1, &attachment, 1, &clear_rect);
954 m_errorMonitor->VerifyFound();
955
956 attachment.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT | VK_IMAGE_ASPECT_MEMORY_PLANE_2_BIT_EXT;
957 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkClearAttachment-aspectMask-02246");
958 vk::CmdClearAttachments(m_commandBuffer->handle(), 1, &attachment, 1, &clear_rect);
959 m_errorMonitor->VerifyFound();
960}
961
sfricke-samsung91f4a542020-10-21 00:29:17 -0700962TEST_F(VkLayerTest, ClearAttachmentsImplicitCheck) {
963 TEST_DESCRIPTION("Check VkClearAttachment implicit VUs.");
964
965 ASSERT_NO_FATAL_FAILURE(Init());
966 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
967
968 m_commandBuffer->begin();
969 vk::CmdBeginRenderPass(m_commandBuffer->handle(), &renderPassBeginInfo(), VK_SUBPASS_CONTENTS_INLINE);
970
971 VkClearAttachment color_attachment;
972 color_attachment.clearValue.color.float32[0] = 0;
973 color_attachment.clearValue.color.float32[1] = 0;
974 color_attachment.clearValue.color.float32[2] = 0;
975 color_attachment.clearValue.color.float32[3] = 0;
976 color_attachment.colorAttachment = 0;
977 VkClearRect clear_rect = {};
978 clear_rect.rect.offset = {0, 0};
979 clear_rect.rect.extent = {1, 1};
980 clear_rect.baseArrayLayer = 0;
981 clear_rect.layerCount = 1;
982
983 color_attachment.aspectMask = 0;
984 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkClearAttachment-aspectMask-requiredbitmask");
985 vk::CmdClearAttachments(m_commandBuffer->handle(), 1, &color_attachment, 1, &clear_rect);
986 m_errorMonitor->VerifyFound();
987
988 color_attachment.aspectMask = 0xffffffff;
989 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkClearAttachment-aspectMask-parameter");
990 vk::CmdClearAttachments(m_commandBuffer->handle(), 1, &color_attachment, 1, &clear_rect);
991 m_errorMonitor->VerifyFound();
992}
993
sfricke-samsung87b09512020-10-26 03:35:42 -0700994TEST_F(VkLayerTest, ClearColorAttachmentsDepthStencil) {
995 TEST_DESCRIPTION("Call CmdClearAttachments with invalid depth/stencil aspect masks.");
996
997 ASSERT_NO_FATAL_FAILURE(Init());
998 // Creates a color attachment
999 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
1000
1001 m_commandBuffer->begin();
1002 vk::CmdBeginRenderPass(m_commandBuffer->handle(), &renderPassBeginInfo(), VK_SUBPASS_CONTENTS_INLINE);
1003
1004 VkClearAttachment attachment;
1005 attachment.clearValue.color.float32[0] = 0;
1006 attachment.clearValue.color.float32[1] = 0;
1007 attachment.clearValue.color.float32[2] = 0;
1008 attachment.clearValue.color.float32[3] = 0;
1009 attachment.colorAttachment = 0;
1010 VkClearRect clear_rect = {};
1011 clear_rect.rect.offset = {0, 0};
1012 clear_rect.rect.extent = {1, 1};
1013 clear_rect.baseArrayLayer = 0;
1014 clear_rect.layerCount = 1;
1015
1016 m_errorMonitor->ExpectSuccess();
1017 attachment.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
1018 vk::CmdClearAttachments(m_commandBuffer->handle(), 1, &attachment, 1, &clear_rect);
1019 m_errorMonitor->VerifyNotFound();
1020
1021 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdClearAttachments-aspectMask-02502");
1022 attachment.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT;
1023 vk::CmdClearAttachments(m_commandBuffer->handle(), 1, &attachment, 1, &clear_rect);
1024 m_errorMonitor->VerifyFound();
1025
1026 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdClearAttachments-aspectMask-02503");
1027 attachment.aspectMask = VK_IMAGE_ASPECT_STENCIL_BIT;
1028 vk::CmdClearAttachments(m_commandBuffer->handle(), 1, &attachment, 1, &clear_rect);
1029 m_errorMonitor->VerifyFound();
1030}
1031
unknown088160a2019-05-23 17:43:13 -06001032TEST_F(VkLayerTest, ExecuteCommandsPrimaryCB) {
1033 TEST_DESCRIPTION("Attempt vkCmdExecuteCommands with a primary command buffer (should only be secondary)");
1034
1035 ASSERT_NO_FATAL_FAILURE(Init());
1036 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
1037
1038 // An empty primary command buffer
1039 VkCommandBufferObj cb(m_device, m_commandPool);
1040 cb.begin();
1041 cb.end();
1042
1043 m_commandBuffer->begin();
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06001044 vk::CmdBeginRenderPass(m_commandBuffer->handle(), &renderPassBeginInfo(), VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS);
unknown088160a2019-05-23 17:43:13 -06001045 VkCommandBuffer handle = cb.handle();
1046
Mark Lobodzinski20310782020-02-28 14:25:17 -07001047 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdExecuteCommands-pCommandBuffers-00088");
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06001048 vk::CmdExecuteCommands(m_commandBuffer->handle(), 1, &handle);
unknown088160a2019-05-23 17:43:13 -06001049 m_errorMonitor->VerifyFound();
1050
1051 m_errorMonitor->SetUnexpectedError("All elements of pCommandBuffers must not be in the pending state");
1052
1053 m_commandBuffer->EndRenderPass();
1054 m_commandBuffer->end();
1055}
1056
Petr Kraus8e53cf02020-01-03 05:30:04 +01001057TEST_F(VkLayerTest, ExecuteCommandsToSecondaryCB) {
1058 TEST_DESCRIPTION("Attempt vkCmdExecuteCommands to a Secondary command buffer");
1059
1060 ASSERT_NO_FATAL_FAILURE(Init());
1061
1062 VkCommandBufferObj main_cb(m_device, m_commandPool, VK_COMMAND_BUFFER_LEVEL_SECONDARY);
1063 VkCommandBufferObj secondary_cb(m_device, m_commandPool, VK_COMMAND_BUFFER_LEVEL_SECONDARY);
1064 secondary_cb.begin();
1065 secondary_cb.end();
1066
1067 main_cb.begin();
Mark Lobodzinski20310782020-02-28 14:25:17 -07001068 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdExecuteCommands-bufferlevel");
Petr Kraus8e53cf02020-01-03 05:30:04 +01001069 vk::CmdExecuteCommands(main_cb.handle(), 1, &secondary_cb.handle());
1070 m_errorMonitor->VerifyFound();
1071}
1072
unknown088160a2019-05-23 17:43:13 -06001073TEST_F(VkLayerTest, InvalidVertexAttributeAlignment) {
1074 TEST_DESCRIPTION("Check for proper aligment of attribAddress which depends on a bound pipeline and on a bound vertex buffer");
1075
1076 ASSERT_NO_FATAL_FAILURE(Init());
1077 ASSERT_NO_FATAL_FAILURE(InitViewport());
1078 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
1079
1080 const VkPipelineLayoutObj pipeline_layout(m_device);
1081
1082 struct VboEntry {
1083 uint16_t input0[2];
1084 uint32_t input1;
1085 float input2[4];
1086 };
1087
1088 const unsigned vbo_entry_count = 3;
1089 const VboEntry vbo_data[vbo_entry_count] = {};
1090
1091 VkConstantBufferObj vbo(m_device, static_cast<int>(sizeof(VboEntry) * vbo_entry_count),
1092 reinterpret_cast<const void *>(vbo_data), VK_BUFFER_USAGE_VERTEX_BUFFER_BIT);
1093
1094 VkVertexInputBindingDescription input_binding;
1095 input_binding.binding = 0;
1096 input_binding.stride = sizeof(VboEntry);
1097 input_binding.inputRate = VK_VERTEX_INPUT_RATE_VERTEX;
1098
1099 VkVertexInputAttributeDescription input_attribs[3];
1100
1101 input_attribs[0].binding = 0;
1102 // Location switch between attrib[0] and attrib[1] is intentional
1103 input_attribs[0].location = 1;
1104 input_attribs[0].format = VK_FORMAT_A8B8G8R8_UNORM_PACK32;
1105 input_attribs[0].offset = offsetof(VboEntry, input1);
1106
1107 input_attribs[1].binding = 0;
1108 input_attribs[1].location = 0;
1109 input_attribs[1].format = VK_FORMAT_R16G16_UNORM;
1110 input_attribs[1].offset = offsetof(VboEntry, input0);
1111
1112 input_attribs[2].binding = 0;
1113 input_attribs[2].location = 2;
1114 input_attribs[2].format = VK_FORMAT_R32G32B32A32_SFLOAT;
1115 input_attribs[2].offset = offsetof(VboEntry, input2);
1116
1117 char const *vsSource =
1118 "#version 450\n"
1119 "\n"
1120 "layout(location = 0) in vec2 input0;"
1121 "layout(location = 1) in vec4 input1;"
1122 "layout(location = 2) in vec4 input2;"
1123 "\n"
1124 "void main(){\n"
1125 " gl_Position = input1 + input2;\n"
1126 " gl_Position.xy += input0;\n"
1127 "}\n";
unknown088160a2019-05-23 17:43:13 -06001128
1129 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
locke-lunarg8e2c91b2019-06-11 17:53:26 -06001130 VkShaderObj fs(m_device, bindStateFragShaderText, VK_SHADER_STAGE_FRAGMENT_BIT, this);
unknown088160a2019-05-23 17:43:13 -06001131
1132 VkPipelineObj pipe1(m_device);
1133 pipe1.AddDefaultColorAttachment();
1134 pipe1.AddShader(&vs);
1135 pipe1.AddShader(&fs);
1136 pipe1.AddVertexInputBindings(&input_binding, 1);
1137 pipe1.AddVertexInputAttribs(&input_attribs[0], 3);
1138 pipe1.SetViewport(m_viewports);
1139 pipe1.SetScissor(m_scissors);
1140 pipe1.CreateVKPipeline(pipeline_layout.handle(), renderPass());
1141
1142 input_binding.stride = 6;
1143
1144 VkPipelineObj pipe2(m_device);
1145 pipe2.AddDefaultColorAttachment();
1146 pipe2.AddShader(&vs);
1147 pipe2.AddShader(&fs);
1148 pipe2.AddVertexInputBindings(&input_binding, 1);
1149 pipe2.AddVertexInputAttribs(&input_attribs[0], 3);
1150 pipe2.SetViewport(m_viewports);
1151 pipe2.SetScissor(m_scissors);
1152 pipe2.CreateVKPipeline(pipeline_layout.handle(), renderPass());
1153
1154 m_commandBuffer->begin();
1155 m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
1156
1157 // Test with invalid buffer offset
1158 VkDeviceSize offset = 1;
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06001159 vk::CmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe1.handle());
1160 vk::CmdBindVertexBuffers(m_commandBuffer->handle(), 0, 1, &vbo.handle(), &offset);
Mark Lobodzinski20310782020-02-28 14:25:17 -07001161 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "Invalid attribAddress alignment for vertex attribute 0");
1162 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "Invalid attribAddress alignment for vertex attribute 1");
1163 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "Invalid attribAddress alignment for vertex attribute 2");
unknown088160a2019-05-23 17:43:13 -06001164 m_commandBuffer->Draw(1, 0, 0, 0);
1165 m_errorMonitor->VerifyFound();
1166
1167 // Test with invalid buffer stride
1168 offset = 0;
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06001169 vk::CmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe2.handle());
1170 vk::CmdBindVertexBuffers(m_commandBuffer->handle(), 0, 1, &vbo.handle(), &offset);
Mark Lobodzinski20310782020-02-28 14:25:17 -07001171 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "Invalid attribAddress alignment for vertex attribute 0");
unknown088160a2019-05-23 17:43:13 -06001172 // Attribute[1] is aligned properly even with a wrong stride
Mark Lobodzinski20310782020-02-28 14:25:17 -07001173 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "Invalid attribAddress alignment for vertex attribute 2");
unknown088160a2019-05-23 17:43:13 -06001174 m_commandBuffer->Draw(1, 0, 0, 0);
1175 m_errorMonitor->VerifyFound();
1176
1177 m_commandBuffer->EndRenderPass();
1178 m_commandBuffer->end();
1179}
1180
1181TEST_F(VkLayerTest, NonSimultaneousSecondaryMarksPrimary) {
1182 ASSERT_NO_FATAL_FAILURE(Init());
locke-lunarg77b9f7c2019-06-18 00:06:03 -06001183 const char *simultaneous_use_message = "UNASSIGNED-CoreValidation-DrawState-InvalidCommandBufferSimultaneousUse";
unknown088160a2019-05-23 17:43:13 -06001184
1185 VkCommandBufferObj secondary(m_device, m_commandPool, VK_COMMAND_BUFFER_LEVEL_SECONDARY);
1186
1187 secondary.begin();
1188 secondary.end();
1189
1190 VkCommandBufferBeginInfo cbbi = {
1191 VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,
1192 nullptr,
1193 VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT,
1194 nullptr,
1195 };
1196
1197 m_commandBuffer->begin(&cbbi);
Mark Lobodzinski20310782020-02-28 14:25:17 -07001198 m_errorMonitor->SetDesiredFailureMsg(kWarningBit, simultaneous_use_message);
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06001199 vk::CmdExecuteCommands(m_commandBuffer->handle(), 1, &secondary.handle());
unknown088160a2019-05-23 17:43:13 -06001200 m_errorMonitor->VerifyFound();
1201 m_commandBuffer->end();
1202}
1203
1204TEST_F(VkLayerTest, SimultaneousUseSecondaryTwoExecutes) {
1205 ASSERT_NO_FATAL_FAILURE(Init());
1206
John Zulauff1640d12019-08-13 15:39:58 -06001207 const char *simultaneous_use_message = "VUID-vkCmdExecuteCommands-pCommandBuffers-00092";
unknown088160a2019-05-23 17:43:13 -06001208
1209 VkCommandBufferObj secondary(m_device, m_commandPool, VK_COMMAND_BUFFER_LEVEL_SECONDARY);
1210
1211 VkCommandBufferInheritanceInfo inh = {
1212 VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO,
1213 nullptr,
1214 };
1215 VkCommandBufferBeginInfo cbbi = {VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, nullptr, 0, &inh};
1216
1217 secondary.begin(&cbbi);
1218 secondary.end();
1219
1220 m_commandBuffer->begin();
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06001221 vk::CmdExecuteCommands(m_commandBuffer->handle(), 1, &secondary.handle());
Mark Lobodzinski20310782020-02-28 14:25:17 -07001222 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, simultaneous_use_message);
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06001223 vk::CmdExecuteCommands(m_commandBuffer->handle(), 1, &secondary.handle());
unknown088160a2019-05-23 17:43:13 -06001224 m_errorMonitor->VerifyFound();
1225 m_commandBuffer->end();
1226}
1227
1228TEST_F(VkLayerTest, SimultaneousUseSecondarySingleExecute) {
1229 ASSERT_NO_FATAL_FAILURE(Init());
1230
1231 // variation on previous test executing the same CB twice in the same
1232 // CmdExecuteCommands call
1233
John Zulauff1640d12019-08-13 15:39:58 -06001234 const char *simultaneous_use_message = "VUID-vkCmdExecuteCommands-pCommandBuffers-00093";
unknown088160a2019-05-23 17:43:13 -06001235
1236 VkCommandBufferObj secondary(m_device, m_commandPool, VK_COMMAND_BUFFER_LEVEL_SECONDARY);
1237
1238 VkCommandBufferInheritanceInfo inh = {
1239 VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO,
1240 nullptr,
1241 };
1242 VkCommandBufferBeginInfo cbbi = {VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, nullptr, 0, &inh};
1243
1244 secondary.begin(&cbbi);
1245 secondary.end();
1246
1247 m_commandBuffer->begin();
1248 VkCommandBuffer cbs[] = {secondary.handle(), secondary.handle()};
Mark Lobodzinski20310782020-02-28 14:25:17 -07001249 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, simultaneous_use_message);
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06001250 vk::CmdExecuteCommands(m_commandBuffer->handle(), 2, cbs);
unknown088160a2019-05-23 17:43:13 -06001251 m_errorMonitor->VerifyFound();
1252 m_commandBuffer->end();
1253}
1254
1255TEST_F(VkLayerTest, SimultaneousUseOneShot) {
1256 TEST_DESCRIPTION("Submit the same command buffer twice in one submit looking for simultaneous use and one time submit errors");
1257 const char *simultaneous_use_message = "is already in use and is not marked for simultaneous use";
1258 const char *one_shot_message = "VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT set, but has been submitted";
1259 ASSERT_NO_FATAL_FAILURE(Init());
1260
1261 VkCommandBuffer cmd_bufs[2];
1262 VkCommandBufferAllocateInfo alloc_info;
1263 alloc_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
1264 alloc_info.pNext = NULL;
1265 alloc_info.commandBufferCount = 2;
1266 alloc_info.commandPool = m_commandPool->handle();
1267 alloc_info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06001268 vk::AllocateCommandBuffers(m_device->device(), &alloc_info, cmd_bufs);
unknown088160a2019-05-23 17:43:13 -06001269
1270 VkCommandBufferBeginInfo cb_binfo;
1271 cb_binfo.pNext = NULL;
1272 cb_binfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
1273 cb_binfo.pInheritanceInfo = VK_NULL_HANDLE;
1274 cb_binfo.flags = 0;
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06001275 vk::BeginCommandBuffer(cmd_bufs[0], &cb_binfo);
unknown088160a2019-05-23 17:43:13 -06001276 VkViewport viewport = {0, 0, 16, 16, 0, 1};
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06001277 vk::CmdSetViewport(cmd_bufs[0], 0, 1, &viewport);
1278 vk::EndCommandBuffer(cmd_bufs[0]);
unknown088160a2019-05-23 17:43:13 -06001279 VkCommandBuffer duplicates[2] = {cmd_bufs[0], cmd_bufs[0]};
1280
1281 VkSubmitInfo submit_info = {};
1282 submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
1283 submit_info.commandBufferCount = 2;
1284 submit_info.pCommandBuffers = duplicates;
Mark Lobodzinski20310782020-02-28 14:25:17 -07001285 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, simultaneous_use_message);
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06001286 vk::QueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
unknown088160a2019-05-23 17:43:13 -06001287 m_errorMonitor->VerifyFound();
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06001288 vk::QueueWaitIdle(m_device->m_queue);
unknown088160a2019-05-23 17:43:13 -06001289
1290 // Set one time use and now look for one time submit
1291 duplicates[0] = duplicates[1] = cmd_bufs[1];
1292 cb_binfo.flags = VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT | VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT;
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06001293 vk::BeginCommandBuffer(cmd_bufs[1], &cb_binfo);
1294 vk::CmdSetViewport(cmd_bufs[1], 0, 1, &viewport);
1295 vk::EndCommandBuffer(cmd_bufs[1]);
Mark Lobodzinski20310782020-02-28 14:25:17 -07001296 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, one_shot_message);
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06001297 vk::QueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
unknown088160a2019-05-23 17:43:13 -06001298 m_errorMonitor->VerifyFound();
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06001299 vk::QueueWaitIdle(m_device->m_queue);
unknown088160a2019-05-23 17:43:13 -06001300}
1301
1302TEST_F(VkLayerTest, DrawTimeImageViewTypeMismatchWithPipeline) {
1303 TEST_DESCRIPTION(
1304 "Test that an error is produced when an image view type does not match the dimensionality declared in the shader");
1305
Mark Lobodzinski20310782020-02-28 14:25:17 -07001306 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "requires an image view of type VK_IMAGE_VIEW_TYPE_3D");
unknown088160a2019-05-23 17:43:13 -06001307
1308 ASSERT_NO_FATAL_FAILURE(Init());
1309 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
1310
unknown088160a2019-05-23 17:43:13 -06001311 char const *fsSource =
1312 "#version 450\n"
1313 "\n"
1314 "layout(set=0, binding=0) uniform sampler3D s;\n"
1315 "layout(location=0) out vec4 color;\n"
1316 "void main() {\n"
1317 " color = texture(s, vec3(0));\n"
1318 "}\n";
locke-lunarg8e2c91b2019-06-11 17:53:26 -06001319 VkShaderObj vs(m_device, bindStateVertShaderText, VK_SHADER_STAGE_VERTEX_BIT, this);
unknown088160a2019-05-23 17:43:13 -06001320 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
1321
1322 VkPipelineObj pipe(m_device);
1323 pipe.AddShader(&vs);
1324 pipe.AddShader(&fs);
1325 pipe.AddDefaultColorAttachment();
1326
1327 VkTextureObj texture(m_device, nullptr);
1328 VkSamplerObj sampler(m_device);
1329
1330 VkDescriptorSetObj descriptorSet(m_device);
1331 descriptorSet.AppendSamplerTexture(&sampler, &texture);
1332 descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
1333
1334 VkResult err = pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass());
1335 ASSERT_VK_SUCCESS(err);
1336
1337 m_commandBuffer->begin();
1338 m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
1339
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06001340 vk::CmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.handle());
unknown088160a2019-05-23 17:43:13 -06001341 m_commandBuffer->BindDescriptorSet(descriptorSet);
1342
1343 VkViewport viewport = {0, 0, 16, 16, 0, 1};
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06001344 vk::CmdSetViewport(m_commandBuffer->handle(), 0, 1, &viewport);
unknown088160a2019-05-23 17:43:13 -06001345 VkRect2D scissor = {{0, 0}, {16, 16}};
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06001346 vk::CmdSetScissor(m_commandBuffer->handle(), 0, 1, &scissor);
unknown088160a2019-05-23 17:43:13 -06001347
1348 // error produced here.
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06001349 vk::CmdDraw(m_commandBuffer->handle(), 3, 1, 0, 0);
unknown088160a2019-05-23 17:43:13 -06001350
1351 m_errorMonitor->VerifyFound();
1352
1353 m_commandBuffer->EndRenderPass();
1354 m_commandBuffer->end();
1355}
1356
1357TEST_F(VkLayerTest, DrawTimeImageMultisampleMismatchWithPipeline) {
1358 TEST_DESCRIPTION(
1359 "Test that an error is produced when a multisampled images are consumed via singlesample images types in the shader, or "
1360 "vice versa.");
1361
Mark Lobodzinski20310782020-02-28 14:25:17 -07001362 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "requires bound image to have multiple samples");
unknown088160a2019-05-23 17:43:13 -06001363
1364 ASSERT_NO_FATAL_FAILURE(Init());
1365 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
1366
unknown088160a2019-05-23 17:43:13 -06001367 char const *fsSource =
1368 "#version 450\n"
1369 "\n"
1370 "layout(set=0, binding=0) uniform sampler2DMS s;\n"
1371 "layout(location=0) out vec4 color;\n"
1372 "void main() {\n"
1373 " color = texelFetch(s, ivec2(0), 0);\n"
1374 "}\n";
locke-lunarg8e2c91b2019-06-11 17:53:26 -06001375 VkShaderObj vs(m_device, bindStateVertShaderText, VK_SHADER_STAGE_VERTEX_BIT, this);
unknown088160a2019-05-23 17:43:13 -06001376 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
1377
1378 VkPipelineObj pipe(m_device);
1379 pipe.AddShader(&vs);
1380 pipe.AddShader(&fs);
1381 pipe.AddDefaultColorAttachment();
1382
1383 VkTextureObj texture(m_device, nullptr); // THIS LINE CAUSES CRASH ON MALI
1384 VkSamplerObj sampler(m_device);
1385
1386 VkDescriptorSetObj descriptorSet(m_device);
1387 descriptorSet.AppendSamplerTexture(&sampler, &texture);
1388 descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
1389
1390 VkResult err = pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass());
1391 ASSERT_VK_SUCCESS(err);
1392
1393 m_commandBuffer->begin();
1394 m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
1395
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06001396 vk::CmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.handle());
unknown088160a2019-05-23 17:43:13 -06001397 m_commandBuffer->BindDescriptorSet(descriptorSet);
1398
1399 VkViewport viewport = {0, 0, 16, 16, 0, 1};
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06001400 vk::CmdSetViewport(m_commandBuffer->handle(), 0, 1, &viewport);
unknown088160a2019-05-23 17:43:13 -06001401 VkRect2D scissor = {{0, 0}, {16, 16}};
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06001402 vk::CmdSetScissor(m_commandBuffer->handle(), 0, 1, &scissor);
unknown088160a2019-05-23 17:43:13 -06001403
1404 // error produced here.
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06001405 vk::CmdDraw(m_commandBuffer->handle(), 3, 1, 0, 0);
unknown088160a2019-05-23 17:43:13 -06001406
1407 m_errorMonitor->VerifyFound();
1408
1409 m_commandBuffer->EndRenderPass();
1410 m_commandBuffer->end();
1411}
1412
1413TEST_F(VkLayerTest, DrawTimeImageComponentTypeMismatchWithPipeline) {
1414 TEST_DESCRIPTION(
1415 "Test that an error is produced when the component type of an imageview disagrees with the type in the shader.");
1416
Mark Lobodzinski20310782020-02-28 14:25:17 -07001417 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "SINT component type, but bound descriptor");
unknown088160a2019-05-23 17:43:13 -06001418
1419 ASSERT_NO_FATAL_FAILURE(Init());
1420 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
1421
unknown088160a2019-05-23 17:43:13 -06001422 char const *fsSource =
1423 "#version 450\n"
1424 "\n"
1425 "layout(set=0, binding=0) uniform isampler2D s;\n"
1426 "layout(location=0) out vec4 color;\n"
1427 "void main() {\n"
1428 " color = texelFetch(s, ivec2(0), 0);\n"
1429 "}\n";
locke-lunarg8e2c91b2019-06-11 17:53:26 -06001430 VkShaderObj vs(m_device, bindStateVertShaderText, VK_SHADER_STAGE_VERTEX_BIT, this);
unknown088160a2019-05-23 17:43:13 -06001431 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
1432
1433 VkPipelineObj pipe(m_device);
1434 pipe.AddShader(&vs);
1435 pipe.AddShader(&fs);
1436 pipe.AddDefaultColorAttachment();
1437
1438 VkTextureObj texture(m_device, nullptr); // UNORM texture by default, incompatible with isampler2D
1439 VkSamplerObj sampler(m_device);
1440
1441 VkDescriptorSetObj descriptorSet(m_device);
1442 descriptorSet.AppendSamplerTexture(&sampler, &texture);
1443 descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
1444
1445 VkResult err = pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass());
1446 ASSERT_VK_SUCCESS(err);
1447
1448 m_commandBuffer->begin();
1449 m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
1450
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06001451 vk::CmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.handle());
unknown088160a2019-05-23 17:43:13 -06001452 m_commandBuffer->BindDescriptorSet(descriptorSet);
1453
1454 VkViewport viewport = {0, 0, 16, 16, 0, 1};
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06001455 vk::CmdSetViewport(m_commandBuffer->handle(), 0, 1, &viewport);
unknown088160a2019-05-23 17:43:13 -06001456 VkRect2D scissor = {{0, 0}, {16, 16}};
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06001457 vk::CmdSetScissor(m_commandBuffer->handle(), 0, 1, &scissor);
unknown088160a2019-05-23 17:43:13 -06001458
1459 // error produced here.
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06001460 vk::CmdDraw(m_commandBuffer->handle(), 3, 1, 0, 0);
unknown088160a2019-05-23 17:43:13 -06001461
1462 m_errorMonitor->VerifyFound();
1463
1464 m_commandBuffer->EndRenderPass();
1465 m_commandBuffer->end();
1466}
1467
unknown088160a2019-05-23 17:43:13 -06001468TEST_F(VkLayerTest, CopyImageLayerCountMismatch) {
1469 TEST_DESCRIPTION(
1470 "Try to copy between images with the source subresource having a different layerCount than the destination subresource");
sfricke-samsung30b094c2020-05-30 11:42:11 -07001471 ASSERT_NO_FATAL_FAILURE(InitFramework(m_errorMonitor));
1472 bool maintenance1 = false;
1473 if (DeviceExtensionSupported(gpu(), nullptr, VK_KHR_MAINTENANCE1_EXTENSION_NAME)) {
1474 m_device_extension_names.push_back(VK_KHR_MAINTENANCE1_EXTENSION_NAME);
1475 maintenance1 = true;
1476 }
1477 ASSERT_NO_FATAL_FAILURE(InitState());
1478
1479 VkFormat image_format = VK_FORMAT_B8G8R8A8_UNORM;
1480 VkFormatProperties format_props;
1481 vk::GetPhysicalDeviceFormatProperties(m_device->phy().handle(), image_format, &format_props);
1482 if ((format_props.optimalTilingFeatures & (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)) == 0) {
1483 printf("%s Transfer for format is not supported.\n", kSkipPrefix);
1484 return;
1485 }
unknown088160a2019-05-23 17:43:13 -06001486
1487 // Create two images to copy between
1488 VkImageObj src_image_obj(m_device);
1489 VkImageObj dst_image_obj(m_device);
1490
1491 VkImageCreateInfo image_create_info = {};
1492 image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
1493 image_create_info.pNext = NULL;
1494 image_create_info.imageType = VK_IMAGE_TYPE_2D;
sfricke-samsung30b094c2020-05-30 11:42:11 -07001495 image_create_info.format = image_format;
unknown088160a2019-05-23 17:43:13 -06001496 image_create_info.extent.width = 32;
1497 image_create_info.extent.height = 32;
1498 image_create_info.extent.depth = 1;
1499 image_create_info.mipLevels = 1;
1500 image_create_info.arrayLayers = 4;
1501 image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
1502 image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL;
1503 image_create_info.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
1504 image_create_info.flags = 0;
1505
1506 src_image_obj.init(&image_create_info);
1507 ASSERT_TRUE(src_image_obj.initialized());
1508
1509 image_create_info.usage = VK_IMAGE_USAGE_TRANSFER_DST_BIT;
1510 dst_image_obj.init(&image_create_info);
1511 ASSERT_TRUE(dst_image_obj.initialized());
1512
1513 m_commandBuffer->begin();
1514 VkImageCopy copyRegion;
1515 copyRegion.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
1516 copyRegion.srcSubresource.mipLevel = 0;
1517 copyRegion.srcSubresource.baseArrayLayer = 0;
1518 copyRegion.srcSubresource.layerCount = 1;
1519 copyRegion.srcOffset.x = 0;
1520 copyRegion.srcOffset.y = 0;
1521 copyRegion.srcOffset.z = 0;
1522 copyRegion.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
1523 copyRegion.dstSubresource.mipLevel = 0;
1524 copyRegion.dstSubresource.baseArrayLayer = 0;
1525 // Introduce failure by forcing the dst layerCount to differ from src
1526 copyRegion.dstSubresource.layerCount = 3;
1527 copyRegion.dstOffset.x = 0;
1528 copyRegion.dstOffset.y = 0;
1529 copyRegion.dstOffset.z = 0;
1530 copyRegion.extent.width = 1;
1531 copyRegion.extent.height = 1;
1532 copyRegion.extent.depth = 1;
1533
sfricke-samsung30b094c2020-05-30 11:42:11 -07001534 const char *vuid = (maintenance1 == true) ? "VUID-VkImageCopy-extent-00140" : "VUID-VkImageCopy-layerCount-00138";
1535 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, vuid);
unknown088160a2019-05-23 17:43:13 -06001536 m_commandBuffer->CopyImage(src_image_obj.image(), VK_IMAGE_LAYOUT_GENERAL, dst_image_obj.image(), VK_IMAGE_LAYOUT_GENERAL, 1,
1537 &copyRegion);
1538 m_errorMonitor->VerifyFound();
1539}
1540
1541TEST_F(VkLayerTest, CompressedImageMipCopyTests) {
1542 TEST_DESCRIPTION("Image/Buffer copies for higher mip levels");
1543
Jeff Leger465acf52020-10-12 18:07:16 -04001544 ASSERT_NO_FATAL_FAILURE(InitFramework(m_errorMonitor));
1545
1546 bool copy_commands2 = false;
1547 if (DeviceExtensionSupported(gpu(), nullptr, VK_KHR_COPY_COMMANDS_2_EXTENSION_NAME)) {
1548 m_device_extension_names.push_back(VK_KHR_COPY_COMMANDS_2_EXTENSION_NAME);
1549 copy_commands2 = true;
1550 }
1551 ASSERT_NO_FATAL_FAILURE(InitState());
1552
1553 PFN_vkCmdCopyBufferToImage2KHR vkCmdCopyBufferToImage2Function = nullptr;
Jeff Leger465acf52020-10-12 18:07:16 -04001554 if (copy_commands2) {
1555 vkCmdCopyBufferToImage2Function =
1556 (PFN_vkCmdCopyBufferToImage2KHR)vk::GetDeviceProcAddr(m_device->handle(), "vkCmdCopyBufferToImage2KHR");
Jeff Leger465acf52020-10-12 18:07:16 -04001557 }
unknown088160a2019-05-23 17:43:13 -06001558
1559 VkPhysicalDeviceFeatures device_features = {};
1560 ASSERT_NO_FATAL_FAILURE(GetPhysicalDeviceFeatures(&device_features));
1561 VkFormat compressed_format = VK_FORMAT_UNDEFINED;
1562 if (device_features.textureCompressionBC) {
1563 compressed_format = VK_FORMAT_BC3_SRGB_BLOCK;
1564 } else if (device_features.textureCompressionETC2) {
1565 compressed_format = VK_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK;
1566 } else if (device_features.textureCompressionASTC_LDR) {
1567 compressed_format = VK_FORMAT_ASTC_4x4_UNORM_BLOCK;
1568 } else {
1569 printf("%s No compressed formats supported - CompressedImageMipCopyTests skipped.\n", kSkipPrefix);
1570 return;
1571 }
1572
1573 VkImageCreateInfo ci;
1574 ci.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
1575 ci.pNext = NULL;
1576 ci.flags = 0;
1577 ci.imageType = VK_IMAGE_TYPE_2D;
1578 ci.format = compressed_format;
1579 ci.extent = {32, 32, 1};
1580 ci.mipLevels = 6;
1581 ci.arrayLayers = 1;
1582 ci.samples = VK_SAMPLE_COUNT_1_BIT;
1583 ci.tiling = VK_IMAGE_TILING_OPTIMAL;
1584 ci.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
1585 ci.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
1586 ci.queueFamilyIndexCount = 0;
1587 ci.pQueueFamilyIndices = NULL;
1588 ci.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
1589
1590 VkImageObj image(m_device);
1591 image.init(&ci);
1592 ASSERT_TRUE(image.initialized());
1593
1594 VkImageObj odd_image(m_device);
1595 ci.extent = {31, 32, 1}; // Mips are [31,32] [15,16] [7,8] [3,4], [1,2] [1,1]
1596 odd_image.init(&ci);
1597 ASSERT_TRUE(odd_image.initialized());
1598
1599 // Allocate buffers
1600 VkMemoryPropertyFlags reqs = 0;
1601 VkBufferObj buffer_1024, buffer_64, buffer_16, buffer_8;
1602 buffer_1024.init_as_src_and_dst(*m_device, 1024, reqs);
1603 buffer_64.init_as_src_and_dst(*m_device, 64, reqs);
1604 buffer_16.init_as_src_and_dst(*m_device, 16, reqs);
1605 buffer_8.init_as_src_and_dst(*m_device, 8, reqs);
1606
1607 VkBufferImageCopy region = {};
1608 region.bufferRowLength = 0;
1609 region.bufferImageHeight = 0;
1610 region.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
1611 region.imageSubresource.layerCount = 1;
1612 region.imageOffset = {0, 0, 0};
1613 region.bufferOffset = 0;
1614
1615 // start recording
1616 m_commandBuffer->begin();
1617
locke-lunargdf00db02020-03-04 19:00:57 -07001618 VkMemoryBarrier mem_barriers[3];
Mark Lobodzinski07d0a612020-12-30 15:42:31 -07001619 mem_barriers[0] = LvlInitStruct<VkMemoryBarrier>();
locke-lunargdf00db02020-03-04 19:00:57 -07001620 mem_barriers[0].srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
1621 mem_barriers[0].dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
Mark Lobodzinski07d0a612020-12-30 15:42:31 -07001622 mem_barriers[1] = LvlInitStruct<VkMemoryBarrier>();
locke-lunargdf00db02020-03-04 19:00:57 -07001623 mem_barriers[1].srcAccessMask = VK_ACCESS_TRANSFER_READ_BIT;
1624 mem_barriers[1].dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
Mark Lobodzinski07d0a612020-12-30 15:42:31 -07001625 mem_barriers[2] = LvlInitStruct<VkMemoryBarrier>();
locke-lunargdf00db02020-03-04 19:00:57 -07001626 mem_barriers[2].srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
1627 mem_barriers[2].dstAccessMask = VK_ACCESS_TRANSFER_READ_BIT;
1628
unknown088160a2019-05-23 17:43:13 -06001629 // Mip level copies that work - 5 levels
1630 m_errorMonitor->ExpectSuccess();
1631
1632 // Mip 0 should fit in 1k buffer - 1k texels @ 1b each
1633 region.imageExtent = {32, 32, 1};
1634 region.imageSubresource.mipLevel = 0;
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06001635 vk::CmdCopyImageToBuffer(m_commandBuffer->handle(), image.handle(), VK_IMAGE_LAYOUT_GENERAL, buffer_1024.handle(), 1, &region);
locke-lunargdf00db02020-03-04 19:00:57 -07001636
1637 vk::CmdPipelineBarrier(m_commandBuffer->handle(), VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, 1,
1638 &mem_barriers[2], 0, nullptr, 0, nullptr);
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06001639 vk::CmdCopyBufferToImage(m_commandBuffer->handle(), buffer_1024.handle(), image.handle(), VK_IMAGE_LAYOUT_GENERAL, 1, &region);
unknown088160a2019-05-23 17:43:13 -06001640
1641 // Mip 2 should fit in 64b buffer - 64 texels @ 1b each
1642 region.imageExtent = {8, 8, 1};
1643 region.imageSubresource.mipLevel = 2;
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06001644 vk::CmdCopyImageToBuffer(m_commandBuffer->handle(), image.handle(), VK_IMAGE_LAYOUT_GENERAL, buffer_64.handle(), 1, &region);
locke-lunargdf00db02020-03-04 19:00:57 -07001645
1646 vk::CmdPipelineBarrier(m_commandBuffer->handle(), VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, 2,
1647 &mem_barriers[1], 0, nullptr, 0, nullptr);
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06001648 vk::CmdCopyBufferToImage(m_commandBuffer->handle(), buffer_64.handle(), image.handle(), VK_IMAGE_LAYOUT_GENERAL, 1, &region);
unknown088160a2019-05-23 17:43:13 -06001649
1650 // Mip 3 should fit in 16b buffer - 16 texels @ 1b each
1651 region.imageExtent = {4, 4, 1};
1652 region.imageSubresource.mipLevel = 3;
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06001653 vk::CmdCopyImageToBuffer(m_commandBuffer->handle(), image.handle(), VK_IMAGE_LAYOUT_GENERAL, buffer_16.handle(), 1, &region);
locke-lunargdf00db02020-03-04 19:00:57 -07001654
1655 vk::CmdPipelineBarrier(m_commandBuffer->handle(), VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, 2,
1656 &mem_barriers[1], 0, nullptr, 0, nullptr);
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06001657 vk::CmdCopyBufferToImage(m_commandBuffer->handle(), buffer_16.handle(), image.handle(), VK_IMAGE_LAYOUT_GENERAL, 1, &region);
unknown088160a2019-05-23 17:43:13 -06001658
1659 // Mip 4&5 should fit in 16b buffer with no complaint - 4 & 1 texels @ 1b each
1660 region.imageExtent = {2, 2, 1};
1661 region.imageSubresource.mipLevel = 4;
locke-lunargdf00db02020-03-04 19:00:57 -07001662
1663 vk::CmdPipelineBarrier(m_commandBuffer->handle(), VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, 1,
1664 &mem_barriers[0], 0, nullptr, 0, nullptr);
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06001665 vk::CmdCopyImageToBuffer(m_commandBuffer->handle(), image.handle(), VK_IMAGE_LAYOUT_GENERAL, buffer_16.handle(), 1, &region);
locke-lunargdf00db02020-03-04 19:00:57 -07001666
1667 vk::CmdPipelineBarrier(m_commandBuffer->handle(), VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, 2,
1668 &mem_barriers[1], 0, nullptr, 0, nullptr);
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06001669 vk::CmdCopyBufferToImage(m_commandBuffer->handle(), buffer_16.handle(), image.handle(), VK_IMAGE_LAYOUT_GENERAL, 1, &region);
unknown088160a2019-05-23 17:43:13 -06001670
1671 region.imageExtent = {1, 1, 1};
1672 region.imageSubresource.mipLevel = 5;
locke-lunargdf00db02020-03-04 19:00:57 -07001673
1674 vk::CmdPipelineBarrier(m_commandBuffer->handle(), VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, 1,
1675 &mem_barriers[0], 0, nullptr, 0, nullptr);
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06001676 vk::CmdCopyImageToBuffer(m_commandBuffer->handle(), image.handle(), VK_IMAGE_LAYOUT_GENERAL, buffer_16.handle(), 1, &region);
locke-lunargdf00db02020-03-04 19:00:57 -07001677
1678 vk::CmdPipelineBarrier(m_commandBuffer->handle(), VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, 2,
1679 &mem_barriers[1], 0, nullptr, 0, nullptr);
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06001680 vk::CmdCopyBufferToImage(m_commandBuffer->handle(), buffer_16.handle(), image.handle(), VK_IMAGE_LAYOUT_GENERAL, 1, &region);
unknown088160a2019-05-23 17:43:13 -06001681 m_errorMonitor->VerifyNotFound();
1682
1683 // Buffer must accommodate a full compressed block, regardless of texel count
Mark Lobodzinski20310782020-02-28 14:25:17 -07001684 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdCopyImageToBuffer-pRegions-00183");
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06001685 vk::CmdCopyImageToBuffer(m_commandBuffer->handle(), image.handle(), VK_IMAGE_LAYOUT_GENERAL, buffer_8.handle(), 1, &region);
unknown088160a2019-05-23 17:43:13 -06001686 m_errorMonitor->VerifyFound();
Mark Lobodzinski20310782020-02-28 14:25:17 -07001687 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdCopyBufferToImage-pRegions-00171");
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06001688 vk::CmdCopyBufferToImage(m_commandBuffer->handle(), buffer_8.handle(), image.handle(), VK_IMAGE_LAYOUT_GENERAL, 1, &region);
unknown088160a2019-05-23 17:43:13 -06001689 m_errorMonitor->VerifyFound();
1690
1691 // Copy width < compressed block size, but not the full mip width
1692 region.imageExtent = {1, 2, 1};
1693 region.imageSubresource.mipLevel = 4;
sfricke-samsung88ac6fe2020-10-24 10:00:13 -07001694 // width not a multiple of compressed block width
1695 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdCopyImageToBuffer-imageExtent-00207");
Mark Lobodzinski20310782020-02-28 14:25:17 -07001696 m_errorMonitor->SetDesiredFailureMsg(kErrorBit,
unknown088160a2019-05-23 17:43:13 -06001697 "VUID-vkCmdCopyImageToBuffer-imageOffset-01794"); // image transfer granularity
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06001698 vk::CmdCopyImageToBuffer(m_commandBuffer->handle(), image.handle(), VK_IMAGE_LAYOUT_GENERAL, buffer_16.handle(), 1, &region);
unknown088160a2019-05-23 17:43:13 -06001699 m_errorMonitor->VerifyFound();
Jeff Leger465acf52020-10-12 18:07:16 -04001700
sfricke-samsung88ac6fe2020-10-24 10:00:13 -07001701 m_errorMonitor->SetDesiredFailureMsg(
1702 kErrorBit, "VUID-vkCmdCopyBufferToImage-imageExtent-00207"); // width not a multiple of compressed block width
Mark Lobodzinski20310782020-02-28 14:25:17 -07001703 m_errorMonitor->SetDesiredFailureMsg(kErrorBit,
unknown088160a2019-05-23 17:43:13 -06001704 "VUID-vkCmdCopyBufferToImage-imageOffset-01793"); // image transfer granularity
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06001705 vk::CmdCopyBufferToImage(m_commandBuffer->handle(), buffer_16.handle(), image.handle(), VK_IMAGE_LAYOUT_GENERAL, 1, &region);
unknown088160a2019-05-23 17:43:13 -06001706 m_errorMonitor->VerifyFound();
1707
1708 // Copy height < compressed block size but not the full mip height
1709 region.imageExtent = {2, 1, 1};
sfricke-samsung88ac6fe2020-10-24 10:00:13 -07001710 m_errorMonitor->SetDesiredFailureMsg(
1711 kErrorBit, "VUID-vkCmdCopyImageToBuffer-imageExtent-00208"); // height not a multiple of compressed block width
Mark Lobodzinski20310782020-02-28 14:25:17 -07001712 m_errorMonitor->SetDesiredFailureMsg(kErrorBit,
unknown088160a2019-05-23 17:43:13 -06001713 "VUID-vkCmdCopyImageToBuffer-imageOffset-01794"); // image transfer granularity
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06001714 vk::CmdCopyImageToBuffer(m_commandBuffer->handle(), image.handle(), VK_IMAGE_LAYOUT_GENERAL, buffer_16.handle(), 1, &region);
unknown088160a2019-05-23 17:43:13 -06001715 m_errorMonitor->VerifyFound();
Jeff Leger465acf52020-10-12 18:07:16 -04001716
sfricke-samsung88ac6fe2020-10-24 10:00:13 -07001717 m_errorMonitor->SetDesiredFailureMsg(
1718 kErrorBit, "VUID-vkCmdCopyBufferToImage-imageExtent-00208"); // height not a multiple of compressed block width
Mark Lobodzinski20310782020-02-28 14:25:17 -07001719 m_errorMonitor->SetDesiredFailureMsg(kErrorBit,
unknown088160a2019-05-23 17:43:13 -06001720 "VUID-vkCmdCopyBufferToImage-imageOffset-01793"); // image transfer granularity
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06001721 vk::CmdCopyBufferToImage(m_commandBuffer->handle(), buffer_16.handle(), image.handle(), VK_IMAGE_LAYOUT_GENERAL, 1, &region);
unknown088160a2019-05-23 17:43:13 -06001722 m_errorMonitor->VerifyFound();
1723
1724 // Offsets must be multiple of compressed block size
1725 region.imageOffset = {1, 1, 0};
1726 region.imageExtent = {1, 1, 1};
sfricke-samsung88ac6fe2020-10-24 10:00:13 -07001727 // imageOffset not a multiple of block size
1728 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdCopyImageToBuffer-imageOffset-00205");
Mark Lobodzinski20310782020-02-28 14:25:17 -07001729 m_errorMonitor->SetDesiredFailureMsg(kErrorBit,
unknown088160a2019-05-23 17:43:13 -06001730 "VUID-vkCmdCopyImageToBuffer-imageOffset-01794"); // image transfer granularity
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06001731 vk::CmdCopyImageToBuffer(m_commandBuffer->handle(), image.handle(), VK_IMAGE_LAYOUT_GENERAL, buffer_16.handle(), 1, &region);
unknown088160a2019-05-23 17:43:13 -06001732 m_errorMonitor->VerifyFound();
Jeff Leger465acf52020-10-12 18:07:16 -04001733
sfricke-samsung88ac6fe2020-10-24 10:00:13 -07001734 m_errorMonitor->SetDesiredFailureMsg(
1735 kErrorBit, "VUID-vkCmdCopyBufferToImage-imageOffset-00205"); // imageOffset not a multiple of block size
Mark Lobodzinski20310782020-02-28 14:25:17 -07001736 m_errorMonitor->SetDesiredFailureMsg(kErrorBit,
unknown088160a2019-05-23 17:43:13 -06001737 "VUID-vkCmdCopyBufferToImage-imageOffset-01793"); // image transfer granularity
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06001738 vk::CmdCopyBufferToImage(m_commandBuffer->handle(), buffer_16.handle(), image.handle(), VK_IMAGE_LAYOUT_GENERAL, 1, &region);
unknown088160a2019-05-23 17:43:13 -06001739 m_errorMonitor->VerifyFound();
1740
Jeff Leger465acf52020-10-12 18:07:16 -04001741 // Equivalent test using KHR_copy_commands2
1742 if (copy_commands2 && vkCmdCopyBufferToImage2Function) {
1743 const VkBufferImageCopy2KHR region2 = {VK_STRUCTURE_TYPE_BUFFER_IMAGE_COPY_2_KHR,
1744 NULL,
1745 region.bufferOffset,
1746 region.bufferRowLength,
1747 region.bufferImageHeight,
1748 region.imageSubresource,
1749 region.imageOffset,
1750 region.imageExtent};
1751 const VkCopyBufferToImageInfo2KHR copy_buffer_to_image_info2 = {VK_STRUCTURE_TYPE_COPY_BUFFER_TO_IMAGE_INFO_2_KHR,
1752 NULL,
1753 buffer_16.handle(),
1754 image.handle(),
1755 VK_IMAGE_LAYOUT_GENERAL,
1756 1,
1757 &region2};
sfricke-samsung88ac6fe2020-10-24 10:00:13 -07001758 m_errorMonitor->SetDesiredFailureMsg(
1759 kErrorBit, "VUID-VkCopyBufferToImageInfo2KHR-imageOffset-00205"); // imageOffset not a multiple of block size
Jeff Leger465acf52020-10-12 18:07:16 -04001760 m_errorMonitor->SetDesiredFailureMsg(kErrorBit,
1761 "VUID-VkCopyBufferToImageInfo2KHR-imageOffset-01793"); // image transfer granularity
1762 vkCmdCopyBufferToImage2Function(m_commandBuffer->handle(), &copy_buffer_to_image_info2);
1763 m_errorMonitor->VerifyFound();
1764 }
1765
unknown088160a2019-05-23 17:43:13 -06001766 // Offset + extent width = mip width - should succeed
1767 region.imageOffset = {4, 4, 0};
1768 region.imageExtent = {3, 4, 1};
1769 region.imageSubresource.mipLevel = 2;
1770 m_errorMonitor->ExpectSuccess();
locke-lunargdf00db02020-03-04 19:00:57 -07001771
1772 vk::CmdPipelineBarrier(m_commandBuffer->handle(), VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, 1,
1773 &mem_barriers[0], 0, nullptr, 0, nullptr);
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06001774 vk::CmdCopyImageToBuffer(m_commandBuffer->handle(), odd_image.handle(), VK_IMAGE_LAYOUT_GENERAL, buffer_16.handle(), 1,
1775 &region);
locke-lunargdf00db02020-03-04 19:00:57 -07001776
1777 vk::CmdPipelineBarrier(m_commandBuffer->handle(), VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, 2,
1778 &mem_barriers[1], 0, nullptr, 0, nullptr);
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06001779 vk::CmdCopyBufferToImage(m_commandBuffer->handle(), buffer_16.handle(), odd_image.handle(), VK_IMAGE_LAYOUT_GENERAL, 1,
1780 &region);
unknown088160a2019-05-23 17:43:13 -06001781 m_errorMonitor->VerifyNotFound();
1782
unknown088160a2019-05-23 17:43:13 -06001783 // Offset + extent width < mip width and not a multiple of block width - should fail
1784 region.imageExtent = {3, 3, 1};
sfricke-samsung88ac6fe2020-10-24 10:00:13 -07001785 m_errorMonitor->SetDesiredFailureMsg(
1786 kErrorBit, "VUID-vkCmdCopyImageToBuffer-imageExtent-00208"); // offset+extent not a multiple of block width
Mark Lobodzinski20310782020-02-28 14:25:17 -07001787 m_errorMonitor->SetDesiredFailureMsg(kErrorBit,
unknown088160a2019-05-23 17:43:13 -06001788 "VUID-vkCmdCopyImageToBuffer-imageOffset-01794"); // image transfer granularity
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06001789 vk::CmdCopyImageToBuffer(m_commandBuffer->handle(), odd_image.handle(), VK_IMAGE_LAYOUT_GENERAL, buffer_16.handle(), 1,
1790 &region);
unknown088160a2019-05-23 17:43:13 -06001791 m_errorMonitor->VerifyFound();
sfricke-samsung88ac6fe2020-10-24 10:00:13 -07001792 m_errorMonitor->SetDesiredFailureMsg(
1793 kErrorBit, "VUID-vkCmdCopyBufferToImage-imageExtent-00208"); // offset+extent not a multiple of block width
Mark Lobodzinski20310782020-02-28 14:25:17 -07001794 m_errorMonitor->SetDesiredFailureMsg(kErrorBit,
unknown088160a2019-05-23 17:43:13 -06001795 "VUID-vkCmdCopyBufferToImage-imageOffset-01793"); // image transfer granularity
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06001796 vk::CmdCopyBufferToImage(m_commandBuffer->handle(), buffer_16.handle(), odd_image.handle(), VK_IMAGE_LAYOUT_GENERAL, 1,
1797 &region);
unknown088160a2019-05-23 17:43:13 -06001798 m_errorMonitor->VerifyFound();
1799}
1800
1801TEST_F(VkLayerTest, ImageBufferCopyTests) {
1802 TEST_DESCRIPTION("Image to buffer and buffer to image tests");
sfricke-samsung6d97e562020-01-07 22:01:00 -08001803
1804 // Enable KHR multiplane req'd extensions for multi-planar copy tests
1805 bool mp_extensions = InstanceExtensionSupported(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME,
1806 VK_KHR_GET_MEMORY_REQUIREMENTS_2_SPEC_VERSION);
1807 if (mp_extensions) {
1808 m_instance_extension_names.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
1809 }
Mark Lobodzinski09ce9c42020-03-06 10:02:44 -07001810 ASSERT_NO_FATAL_FAILURE(InitFramework(m_errorMonitor, nullptr));
sfricke-samsung6d97e562020-01-07 22:01:00 -08001811 mp_extensions = mp_extensions && DeviceExtensionSupported(gpu(), nullptr, VK_KHR_MAINTENANCE1_EXTENSION_NAME);
1812 mp_extensions = mp_extensions && DeviceExtensionSupported(gpu(), nullptr, VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME);
1813 mp_extensions = mp_extensions && DeviceExtensionSupported(gpu(), nullptr, VK_KHR_BIND_MEMORY_2_EXTENSION_NAME);
1814 mp_extensions = mp_extensions && DeviceExtensionSupported(gpu(), nullptr, VK_KHR_SAMPLER_YCBCR_CONVERSION_EXTENSION_NAME);
1815 if (mp_extensions) {
1816 m_device_extension_names.push_back(VK_KHR_MAINTENANCE1_EXTENSION_NAME);
1817 m_device_extension_names.push_back(VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME);
1818 m_device_extension_names.push_back(VK_KHR_BIND_MEMORY_2_EXTENSION_NAME);
1819 m_device_extension_names.push_back(VK_KHR_SAMPLER_YCBCR_CONVERSION_EXTENSION_NAME);
1820 }
1821 ASSERT_NO_FATAL_FAILURE(InitState());
unknown088160a2019-05-23 17:43:13 -06001822
1823 // Bail if any dimension of transfer granularity is 0.
1824 auto index = m_device->graphics_queue_node_index_;
1825 auto queue_family_properties = m_device->phy().queue_properties();
1826 if ((queue_family_properties[index].minImageTransferGranularity.depth == 0) ||
1827 (queue_family_properties[index].minImageTransferGranularity.width == 0) ||
1828 (queue_family_properties[index].minImageTransferGranularity.height == 0)) {
1829 printf("%s Subresource copies are disallowed when xfer granularity (x|y|z) is 0. Skipped.\n", kSkipPrefix);
1830 return;
1831 }
1832
sfricke-samsung6d97e562020-01-07 22:01:00 -08001833 // All VkImageObj must be defined here as if defined inside below scopes will cause image memory to be deleted when out of scope
1834 // and invalidates the entire command buffer. This prevents from having to reset the commmand buffer every scope rgba
Mark Lobodzinski20310782020-02-28 14:25:17 -07001835 VkImageObj image_64k(m_device); // 128^2 texels, 64k
1836 VkImageObj image_16k(m_device); // 64^2 texels, 16k
sfricke-samsung6d97e562020-01-07 22:01:00 -08001837 // depth stencil
unknown088160a2019-05-23 17:43:13 -06001838 VkImageObj image_16k_depth(m_device); // 64^2 texels, depth, 16k
1839 VkImageObj ds_image_4D_1S(m_device); // 256^2 texels, 512kb (256k depth, 64k stencil, 192k pack)
1840 VkImageObj ds_image_3D_1S(m_device); // 256^2 texels, 256kb (192k depth, 64k stencil)
1841 VkImageObj ds_image_2D(m_device); // 256^2 texels, 128k (128k depth)
1842 VkImageObj ds_image_1S(m_device); // 256^2 texels, 64k (64k stencil)
sfricke-samsung6d97e562020-01-07 22:01:00 -08001843 // compression
1844 VkImageObj image_16k_4x4comp(m_device); // 128^2 texels as 32^2 compressed (4x4) blocks, 16k
1845 VkImageObj image_NPOT_4x4comp(m_device); // 130^2 texels as 33^2 compressed (4x4) blocks
1846 // multi-planar
1847 VkImageObj image_multi_planar(m_device); // 128^2 texels in plane_0 and 64^2 texels in plane_1
unknown088160a2019-05-23 17:43:13 -06001848
sfricke-samsung6d97e562020-01-07 22:01:00 -08001849 // Verify R8G8B8A8_UINT format is supported for transfer
1850 bool missing_rgba_support = false;
1851 VkFormatProperties props = {0, 0, 0};
1852 vk::GetPhysicalDeviceFormatProperties(m_device->phy().handle(), VK_FORMAT_R8G8B8A8_UINT, &props);
1853 missing_rgba_support |= (props.bufferFeatures == 0 && props.linearTilingFeatures == 0 && props.optimalTilingFeatures == 0);
1854 missing_rgba_support |= (props.optimalTilingFeatures & VK_FORMAT_FEATURE_TRANSFER_SRC_BIT) == 0;
1855 missing_rgba_support |= (props.optimalTilingFeatures & VK_FORMAT_FEATURE_TRANSFER_DST_BIT) == 0;
1856
1857 if (!missing_rgba_support) {
1858 image_64k.Init(128, 128, 1, VK_FORMAT_R8G8B8A8_UINT,
1859 VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT,
1860 VK_IMAGE_TILING_OPTIMAL, 0);
1861 ASSERT_TRUE(image_64k.initialized());
1862
1863 image_16k.Init(64, 64, 1, VK_FORMAT_R8G8B8A8_UINT,
1864 VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT,
1865 VK_IMAGE_TILING_OPTIMAL, 0);
1866 ASSERT_TRUE(image_16k.initialized());
1867 }
unknown088160a2019-05-23 17:43:13 -06001868
1869 // Verify all needed Depth/Stencil formats are supported
1870 bool missing_ds_support = false;
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06001871 vk::GetPhysicalDeviceFormatProperties(m_device->phy().handle(), VK_FORMAT_D32_SFLOAT_S8_UINT, &props);
unknown088160a2019-05-23 17:43:13 -06001872 missing_ds_support |= (props.bufferFeatures == 0 && props.linearTilingFeatures == 0 && props.optimalTilingFeatures == 0);
1873 missing_ds_support |= (props.optimalTilingFeatures & VK_FORMAT_FEATURE_TRANSFER_SRC_BIT) == 0;
1874 missing_ds_support |= (props.optimalTilingFeatures & VK_FORMAT_FEATURE_TRANSFER_DST_BIT) == 0;
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06001875 vk::GetPhysicalDeviceFormatProperties(m_device->phy().handle(), VK_FORMAT_D24_UNORM_S8_UINT, &props);
unknown088160a2019-05-23 17:43:13 -06001876 missing_ds_support |= (props.bufferFeatures == 0 && props.linearTilingFeatures == 0 && props.optimalTilingFeatures == 0);
1877 missing_ds_support |= (props.optimalTilingFeatures & VK_FORMAT_FEATURE_TRANSFER_SRC_BIT) == 0;
1878 missing_ds_support |= (props.optimalTilingFeatures & VK_FORMAT_FEATURE_TRANSFER_DST_BIT) == 0;
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06001879 vk::GetPhysicalDeviceFormatProperties(m_device->phy().handle(), VK_FORMAT_D16_UNORM, &props);
unknown088160a2019-05-23 17:43:13 -06001880 missing_ds_support |= (props.bufferFeatures == 0 && props.linearTilingFeatures == 0 && props.optimalTilingFeatures == 0);
1881 missing_ds_support |= (props.optimalTilingFeatures & VK_FORMAT_FEATURE_TRANSFER_SRC_BIT) == 0;
1882 missing_ds_support |= (props.optimalTilingFeatures & VK_FORMAT_FEATURE_TRANSFER_DST_BIT) == 0;
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06001883 vk::GetPhysicalDeviceFormatProperties(m_device->phy().handle(), VK_FORMAT_S8_UINT, &props);
unknown088160a2019-05-23 17:43:13 -06001884 missing_ds_support |= (props.bufferFeatures == 0 && props.linearTilingFeatures == 0 && props.optimalTilingFeatures == 0);
1885 missing_ds_support |= (props.optimalTilingFeatures & VK_FORMAT_FEATURE_TRANSFER_SRC_BIT) == 0;
1886 missing_ds_support |= (props.optimalTilingFeatures & VK_FORMAT_FEATURE_TRANSFER_DST_BIT) == 0;
1887
1888 if (!missing_ds_support) {
1889 image_16k_depth.Init(64, 64, 1, VK_FORMAT_D24_UNORM_S8_UINT,
1890 VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT, VK_IMAGE_TILING_OPTIMAL, 0);
1891 ASSERT_TRUE(image_16k_depth.initialized());
1892
1893 ds_image_4D_1S.Init(
1894 256, 256, 1, VK_FORMAT_D32_SFLOAT_S8_UINT,
1895 VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT,
1896 VK_IMAGE_TILING_OPTIMAL, 0);
1897 ASSERT_TRUE(ds_image_4D_1S.initialized());
1898
1899 ds_image_3D_1S.Init(
1900 256, 256, 1, VK_FORMAT_D24_UNORM_S8_UINT,
1901 VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT,
1902 VK_IMAGE_TILING_OPTIMAL, 0);
1903 ASSERT_TRUE(ds_image_3D_1S.initialized());
1904
1905 ds_image_2D.Init(
1906 256, 256, 1, VK_FORMAT_D16_UNORM,
1907 VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT,
1908 VK_IMAGE_TILING_OPTIMAL, 0);
1909 ASSERT_TRUE(ds_image_2D.initialized());
1910
1911 ds_image_1S.Init(
1912 256, 256, 1, VK_FORMAT_S8_UINT,
1913 VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT,
1914 VK_IMAGE_TILING_OPTIMAL, 0);
1915 ASSERT_TRUE(ds_image_1S.initialized());
1916 }
1917
1918 // Allocate buffers
1919 VkBufferObj buffer_256k, buffer_128k, buffer_64k, buffer_16k;
1920 VkMemoryPropertyFlags reqs = 0;
1921 buffer_256k.init_as_src_and_dst(*m_device, 262144, reqs); // 256k
1922 buffer_128k.init_as_src_and_dst(*m_device, 131072, reqs); // 128k
1923 buffer_64k.init_as_src_and_dst(*m_device, 65536, reqs); // 64k
1924 buffer_16k.init_as_src_and_dst(*m_device, 16384, reqs); // 16k
1925
1926 VkBufferImageCopy region = {};
1927 region.bufferRowLength = 0;
1928 region.bufferImageHeight = 0;
1929 region.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
1930 region.imageSubresource.layerCount = 1;
1931 region.imageOffset = {0, 0, 0};
1932 region.imageExtent = {64, 64, 1};
1933 region.bufferOffset = 0;
1934
locke-lunargdf00db02020-03-04 19:00:57 -07001935 VkMemoryBarrier mem_barriers[3];
Mark Lobodzinski07d0a612020-12-30 15:42:31 -07001936 mem_barriers[0] = LvlInitStruct<VkMemoryBarrier>();
locke-lunargdf00db02020-03-04 19:00:57 -07001937 mem_barriers[0].srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
1938 mem_barriers[0].dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
Mark Lobodzinski07d0a612020-12-30 15:42:31 -07001939 mem_barriers[1] = LvlInitStruct<VkMemoryBarrier>();
locke-lunargdf00db02020-03-04 19:00:57 -07001940 mem_barriers[1].srcAccessMask = VK_ACCESS_TRANSFER_READ_BIT;
1941 mem_barriers[1].dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
Mark Lobodzinski07d0a612020-12-30 15:42:31 -07001942 mem_barriers[2] = LvlInitStruct<VkMemoryBarrier>();
locke-lunargdf00db02020-03-04 19:00:57 -07001943 mem_barriers[2].srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
1944 mem_barriers[2].dstAccessMask = VK_ACCESS_TRANSFER_READ_BIT;
1945
sfricke-samsung6d97e562020-01-07 22:01:00 -08001946 if (missing_rgba_support) {
1947 printf("%s R8G8B8A8_UINT transfer unsupported - skipping RGBA tests.\n", kSkipPrefix);
unknown088160a2019-05-23 17:43:13 -06001948
sfricke-samsung6d97e562020-01-07 22:01:00 -08001949 // start recording for future tests
1950 m_commandBuffer->begin();
1951 } else {
1952 // attempt copies before putting command buffer in recording state
Mark Lobodzinski20310782020-02-28 14:25:17 -07001953 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdCopyBufferToImage-commandBuffer-recording");
sfricke-samsung6d97e562020-01-07 22:01:00 -08001954 vk::CmdCopyBufferToImage(m_commandBuffer->handle(), buffer_64k.handle(), image_64k.handle(), VK_IMAGE_LAYOUT_GENERAL, 1,
1955 &region);
unknown088160a2019-05-23 17:43:13 -06001956 m_errorMonitor->VerifyFound();
1957
Mark Lobodzinski20310782020-02-28 14:25:17 -07001958 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdCopyImageToBuffer-commandBuffer-recording");
sfricke-samsung6d97e562020-01-07 22:01:00 -08001959 vk::CmdCopyImageToBuffer(m_commandBuffer->handle(), image_64k.handle(), VK_IMAGE_LAYOUT_GENERAL, buffer_64k.handle(), 1,
1960 &region);
1961 m_errorMonitor->VerifyFound();
1962
1963 // start recording
1964 m_commandBuffer->begin();
1965
1966 // successful copies
1967 m_errorMonitor->ExpectSuccess();
1968 vk::CmdCopyImageToBuffer(m_commandBuffer->handle(), image_16k.handle(), VK_IMAGE_LAYOUT_GENERAL, buffer_16k.handle(), 1,
1969 &region);
locke-lunargdf00db02020-03-04 19:00:57 -07001970
1971 vk::CmdPipelineBarrier(m_commandBuffer->handle(), VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, 1,
1972 &mem_barriers[2], 0, nullptr, 0, nullptr);
sfricke-samsung6d97e562020-01-07 22:01:00 -08001973 vk::CmdCopyBufferToImage(m_commandBuffer->handle(), buffer_16k.handle(), image_16k.handle(), VK_IMAGE_LAYOUT_GENERAL, 1,
1974 &region);
1975 region.imageOffset.x = 16; // 16k copy, offset requires larger image
locke-lunargdf00db02020-03-04 19:00:57 -07001976
1977 vk::CmdPipelineBarrier(m_commandBuffer->handle(), VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, 1,
1978 &mem_barriers[0], 0, nullptr, 0, nullptr);
sfricke-samsung6d97e562020-01-07 22:01:00 -08001979 vk::CmdCopyImageToBuffer(m_commandBuffer->handle(), image_64k.handle(), VK_IMAGE_LAYOUT_GENERAL, buffer_16k.handle(), 1,
1980 &region);
1981 region.imageExtent.height = 78; // > 16k copy requires larger buffer & image
locke-lunargdf00db02020-03-04 19:00:57 -07001982
1983 vk::CmdPipelineBarrier(m_commandBuffer->handle(), VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, 1,
1984 &mem_barriers[1], 0, nullptr, 0, nullptr);
sfricke-samsung6d97e562020-01-07 22:01:00 -08001985 vk::CmdCopyBufferToImage(m_commandBuffer->handle(), buffer_64k.handle(), image_64k.handle(), VK_IMAGE_LAYOUT_GENERAL, 1,
1986 &region);
1987 region.imageOffset.x = 0;
1988 region.imageExtent.height = 64;
1989 region.bufferOffset = 256; // 16k copy with buffer offset, requires larger buffer
locke-lunargdf00db02020-03-04 19:00:57 -07001990
1991 vk::CmdPipelineBarrier(m_commandBuffer->handle(), VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, 2,
1992 &mem_barriers[1], 0, nullptr, 0, nullptr);
sfricke-samsung6d97e562020-01-07 22:01:00 -08001993 vk::CmdCopyImageToBuffer(m_commandBuffer->handle(), image_16k.handle(), VK_IMAGE_LAYOUT_GENERAL, buffer_64k.handle(), 1,
1994 &region);
1995 m_errorMonitor->VerifyNotFound();
1996
1997 // image/buffer too small (extent too large) on copy to image
1998 region.imageExtent = {65, 64, 1};
Mark Lobodzinski20310782020-02-28 14:25:17 -07001999 m_errorMonitor->SetDesiredFailureMsg(kErrorBit,
sfricke-samsung6d97e562020-01-07 22:01:00 -08002000 "VUID-vkCmdCopyBufferToImage-pRegions-00171"); // buffer too small
2001 vk::CmdCopyBufferToImage(m_commandBuffer->handle(), buffer_16k.handle(), image_64k.handle(), VK_IMAGE_LAYOUT_GENERAL, 1,
2002 &region);
2003 m_errorMonitor->VerifyFound();
2004
Shannon McPherson2c793ba2020-08-28 12:13:24 -06002005 m_errorMonitor->SetUnexpectedError("VUID-vkCmdCopyBufferToImage-imageOffset-00197");
Mark Lobodzinski20310782020-02-28 14:25:17 -07002006 m_errorMonitor->SetDesiredFailureMsg(kErrorBit,
sfricke-samsung6d97e562020-01-07 22:01:00 -08002007 "VUID-vkCmdCopyBufferToImage-pRegions-00172"); // image too small
2008 vk::CmdCopyBufferToImage(m_commandBuffer->handle(), buffer_64k.handle(), image_16k.handle(), VK_IMAGE_LAYOUT_GENERAL, 1,
2009 &region);
2010 m_errorMonitor->VerifyFound();
2011
2012 // image/buffer too small (offset) on copy to image
2013 region.imageExtent = {64, 64, 1};
2014 region.imageOffset = {0, 4, 0};
Mark Lobodzinski20310782020-02-28 14:25:17 -07002015 m_errorMonitor->SetDesiredFailureMsg(kErrorBit,
sfricke-samsung6d97e562020-01-07 22:01:00 -08002016 "VUID-vkCmdCopyBufferToImage-pRegions-00171"); // buffer too small
2017 vk::CmdCopyBufferToImage(m_commandBuffer->handle(), buffer_16k.handle(), image_64k.handle(), VK_IMAGE_LAYOUT_GENERAL, 1,
2018 &region);
2019 m_errorMonitor->VerifyFound();
2020
Shannon McPherson2c793ba2020-08-28 12:13:24 -06002021 m_errorMonitor->SetUnexpectedError("VUID-vkCmdCopyBufferToImage-imageOffset-00197");
2022 m_errorMonitor->SetUnexpectedError("VUID-vkCmdCopyBufferToImage-imageOffset-00198");
Mark Lobodzinski20310782020-02-28 14:25:17 -07002023 m_errorMonitor->SetDesiredFailureMsg(kErrorBit,
sfricke-samsung6d97e562020-01-07 22:01:00 -08002024 "VUID-vkCmdCopyBufferToImage-pRegions-00172"); // image too small
2025 vk::CmdCopyBufferToImage(m_commandBuffer->handle(), buffer_64k.handle(), image_16k.handle(), VK_IMAGE_LAYOUT_GENERAL, 1,
2026 &region);
2027 m_errorMonitor->VerifyFound();
2028
2029 // image/buffer too small on copy to buffer
2030 region.imageExtent = {64, 64, 1};
2031 region.imageOffset = {0, 0, 0};
2032 region.bufferOffset = 4;
Mark Lobodzinski20310782020-02-28 14:25:17 -07002033 m_errorMonitor->SetDesiredFailureMsg(kErrorBit,
sfricke-samsung6d97e562020-01-07 22:01:00 -08002034 "VUID-vkCmdCopyImageToBuffer-pRegions-00183"); // buffer too small
2035 vk::CmdCopyImageToBuffer(m_commandBuffer->handle(), image_64k.handle(), VK_IMAGE_LAYOUT_GENERAL, buffer_16k.handle(), 1,
2036 &region);
2037 m_errorMonitor->VerifyFound();
2038
2039 region.imageExtent = {64, 65, 1};
2040 region.bufferOffset = 0;
sfricke-samsung88ac6fe2020-10-24 10:00:13 -07002041 m_errorMonitor->SetUnexpectedError("VUID-vkCmdCopyImageToBuffer-imageOffset-00198");
Mark Lobodzinski20310782020-02-28 14:25:17 -07002042 m_errorMonitor->SetDesiredFailureMsg(kErrorBit,
sfricke-samsung6d97e562020-01-07 22:01:00 -08002043 "VUID-vkCmdCopyImageToBuffer-pRegions-00182"); // image too small
2044 vk::CmdCopyImageToBuffer(m_commandBuffer->handle(), image_16k.handle(), VK_IMAGE_LAYOUT_GENERAL, buffer_64k.handle(), 1,
2045 &region);
2046 m_errorMonitor->VerifyFound();
2047
2048 // buffer size OK but rowlength causes loose packing
Mark Lobodzinski20310782020-02-28 14:25:17 -07002049 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdCopyImageToBuffer-pRegions-00183");
sfricke-samsung6d97e562020-01-07 22:01:00 -08002050 region.imageExtent = {64, 64, 1};
2051 region.bufferRowLength = 68;
2052 vk::CmdCopyImageToBuffer(m_commandBuffer->handle(), image_16k.handle(), VK_IMAGE_LAYOUT_GENERAL, buffer_16k.handle(), 1,
2053 &region);
2054 m_errorMonitor->VerifyFound();
2055
2056 // An extent with zero area should produce a warning, but no error
Mark Lobodzinski20310782020-02-28 14:25:17 -07002057 m_errorMonitor->SetDesiredFailureMsg(kWarningBit | kErrorBit, "} has zero area");
sfricke-samsung6d97e562020-01-07 22:01:00 -08002058 region.imageExtent.width = 0;
2059 vk::CmdCopyImageToBuffer(m_commandBuffer->handle(), image_16k.handle(), VK_IMAGE_LAYOUT_GENERAL, buffer_16k.handle(), 1,
2060 &region);
2061 m_errorMonitor->VerifyFound();
2062
2063 // aspect bits
2064 region.imageExtent = {64, 64, 1};
2065 region.bufferRowLength = 0;
2066 region.bufferImageHeight = 0;
2067 if (!missing_ds_support) {
Mark Lobodzinski20310782020-02-28 14:25:17 -07002068 m_errorMonitor->SetDesiredFailureMsg(kErrorBit,
sfricke-samsung6d97e562020-01-07 22:01:00 -08002069 "VUID-VkBufferImageCopy-aspectMask-00212"); // more than 1 aspect bit set
2070 region.imageSubresource.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT;
2071 vk::CmdCopyImageToBuffer(m_commandBuffer->handle(), image_16k_depth.handle(), VK_IMAGE_LAYOUT_GENERAL,
2072 buffer_16k.handle(), 1, &region);
2073 m_errorMonitor->VerifyFound();
2074
Mark Lobodzinski20310782020-02-28 14:25:17 -07002075 m_errorMonitor->SetDesiredFailureMsg(kErrorBit,
sfricke-samsung88ac6fe2020-10-24 10:00:13 -07002076 "VUID-vkCmdCopyImageToBuffer-aspectMask-00211"); // different mis-matched aspect
sfricke-samsung6d97e562020-01-07 22:01:00 -08002077 region.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
2078 vk::CmdCopyImageToBuffer(m_commandBuffer->handle(), image_16k_depth.handle(), VK_IMAGE_LAYOUT_GENERAL,
2079 buffer_16k.handle(), 1, &region);
2080 m_errorMonitor->VerifyFound();
2081 }
2082
Mark Lobodzinski20310782020-02-28 14:25:17 -07002083 m_errorMonitor->SetDesiredFailureMsg(kErrorBit,
sfricke-samsung88ac6fe2020-10-24 10:00:13 -07002084 "VUID-vkCmdCopyImageToBuffer-aspectMask-00211"); // mis-matched aspect
sfricke-samsung6d97e562020-01-07 22:01:00 -08002085 region.imageSubresource.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT;
2086 vk::CmdCopyImageToBuffer(m_commandBuffer->handle(), image_16k.handle(), VK_IMAGE_LAYOUT_GENERAL, buffer_16k.handle(), 1,
2087 &region);
2088 m_errorMonitor->VerifyFound();
unknown088160a2019-05-23 17:43:13 -06002089 region.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
sfricke-samsung6d97e562020-01-07 22:01:00 -08002090
2091 // Out-of-range mip levels should fail
2092 region.imageSubresource.mipLevel = image_16k.create_info().mipLevels + 1;
Mark Lobodzinski20310782020-02-28 14:25:17 -07002093 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdCopyImageToBuffer-imageSubresource-01703");
sfricke-samsung88ac6fe2020-10-24 10:00:13 -07002094 m_errorMonitor->SetUnexpectedError("VUID-vkCmdCopyImageToBuffer-imageOffset-00197");
2095 m_errorMonitor->SetUnexpectedError("VUID-vkCmdCopyImageToBuffer-imageOffset-00198");
2096 m_errorMonitor->SetUnexpectedError("VUID-vkCmdCopyImageToBuffer-imageOffset-00200");
sfricke-samsung6d97e562020-01-07 22:01:00 -08002097 m_errorMonitor->SetDesiredFailureMsg(
Mark Lobodzinski20310782020-02-28 14:25:17 -07002098 kErrorBit,
sfricke-samsung6d97e562020-01-07 22:01:00 -08002099 "VUID-vkCmdCopyImageToBuffer-pRegions-00182"); // unavoidable "region exceeds image bounds" for non-existent mip
2100 vk::CmdCopyImageToBuffer(m_commandBuffer->handle(), image_16k.handle(), VK_IMAGE_LAYOUT_GENERAL, buffer_16k.handle(), 1,
2101 &region);
2102 m_errorMonitor->VerifyFound();
Mark Lobodzinski20310782020-02-28 14:25:17 -07002103 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdCopyBufferToImage-imageSubresource-01701");
Shannon McPherson2c793ba2020-08-28 12:13:24 -06002104 m_errorMonitor->SetUnexpectedError("VUID-vkCmdCopyBufferToImage-imageOffset-00197");
2105 m_errorMonitor->SetUnexpectedError("VUID-vkCmdCopyBufferToImage-imageOffset-00198");
2106 m_errorMonitor->SetUnexpectedError("VUID-vkCmdCopyBufferToImage-imageOffset-00200");
sfricke-samsung6d97e562020-01-07 22:01:00 -08002107 m_errorMonitor->SetDesiredFailureMsg(
Mark Lobodzinski20310782020-02-28 14:25:17 -07002108 kErrorBit,
sfricke-samsung6d97e562020-01-07 22:01:00 -08002109 "VUID-vkCmdCopyBufferToImage-pRegions-00172"); // unavoidable "region exceeds image bounds" for non-existent mip
2110 vk::CmdCopyBufferToImage(m_commandBuffer->handle(), buffer_16k.handle(), image_16k.handle(), VK_IMAGE_LAYOUT_GENERAL, 1,
2111 &region);
2112 m_errorMonitor->VerifyFound();
2113 region.imageSubresource.mipLevel = 0;
2114
2115 // Out-of-range array layers should fail
2116 region.imageSubresource.baseArrayLayer = image_16k.create_info().arrayLayers;
2117 region.imageSubresource.layerCount = 1;
Mark Lobodzinski20310782020-02-28 14:25:17 -07002118 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdCopyImageToBuffer-imageSubresource-01704");
sfricke-samsung6d97e562020-01-07 22:01:00 -08002119 vk::CmdCopyImageToBuffer(m_commandBuffer->handle(), image_16k.handle(), VK_IMAGE_LAYOUT_GENERAL, buffer_16k.handle(), 1,
2120 &region);
2121 m_errorMonitor->VerifyFound();
Mark Lobodzinski20310782020-02-28 14:25:17 -07002122 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdCopyBufferToImage-imageSubresource-01702");
sfricke-samsung6d97e562020-01-07 22:01:00 -08002123 vk::CmdCopyBufferToImage(m_commandBuffer->handle(), buffer_16k.handle(), image_16k.handle(), VK_IMAGE_LAYOUT_GENERAL, 1,
2124 &region);
2125 m_errorMonitor->VerifyFound();
2126 region.imageSubresource.baseArrayLayer = 0;
2127
2128 // Layout mismatch should fail
Mark Lobodzinski20310782020-02-28 14:25:17 -07002129 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdCopyImageToBuffer-srcImageLayout-00189");
sfricke-samsung6d97e562020-01-07 22:01:00 -08002130 vk::CmdCopyImageToBuffer(m_commandBuffer->handle(), image_16k.handle(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
2131 buffer_16k.handle(), 1, &region);
2132 m_errorMonitor->VerifyFound();
Mark Lobodzinski20310782020-02-28 14:25:17 -07002133 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdCopyBufferToImage-dstImageLayout-00180");
sfricke-samsung6d97e562020-01-07 22:01:00 -08002134 vk::CmdCopyBufferToImage(m_commandBuffer->handle(), buffer_16k.handle(), image_16k.handle(),
2135 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &region);
unknown088160a2019-05-23 17:43:13 -06002136 m_errorMonitor->VerifyFound();
2137 }
2138
unknown088160a2019-05-23 17:43:13 -06002139 // Test Depth/Stencil copies
2140 if (missing_ds_support) {
2141 printf("%s Depth / Stencil formats unsupported - skipping D/S tests.\n", kSkipPrefix);
2142 } else {
2143 VkBufferImageCopy ds_region = {};
2144 ds_region.bufferOffset = 0;
2145 ds_region.bufferRowLength = 0;
2146 ds_region.bufferImageHeight = 0;
2147 ds_region.imageSubresource.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT;
2148 ds_region.imageSubresource.mipLevel = 0;
2149 ds_region.imageSubresource.baseArrayLayer = 0;
2150 ds_region.imageSubresource.layerCount = 1;
2151 ds_region.imageOffset = {0, 0, 0};
2152 ds_region.imageExtent = {256, 256, 1};
2153
2154 // Depth copies that should succeed
2155 m_errorMonitor->ExpectSuccess(); // Extract 4b depth per texel, pack into 256k buffer
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06002156 vk::CmdCopyImageToBuffer(m_commandBuffer->handle(), ds_image_4D_1S.handle(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
2157 buffer_256k.handle(), 1, &ds_region);
unknown088160a2019-05-23 17:43:13 -06002158 m_errorMonitor->VerifyNotFound();
2159
2160 m_errorMonitor->ExpectSuccess(); // Extract 3b depth per texel, pack (loose) into 256k buffer
locke-lunargdf00db02020-03-04 19:00:57 -07002161 vk::CmdPipelineBarrier(m_commandBuffer->handle(), VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, 1,
2162 &mem_barriers[0], 0, nullptr, 0, nullptr);
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06002163 vk::CmdCopyImageToBuffer(m_commandBuffer->handle(), ds_image_3D_1S.handle(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
2164 buffer_256k.handle(), 1, &ds_region);
unknown088160a2019-05-23 17:43:13 -06002165 m_errorMonitor->VerifyNotFound();
2166
2167 m_errorMonitor->ExpectSuccess(); // Copy 2b depth per texel, into 128k buffer
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06002168 vk::CmdCopyImageToBuffer(m_commandBuffer->handle(), ds_image_2D.handle(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
2169 buffer_128k.handle(), 1, &ds_region);
unknown088160a2019-05-23 17:43:13 -06002170 m_errorMonitor->VerifyNotFound();
2171
2172 // Depth copies that should fail
2173 ds_region.bufferOffset = 4;
2174 m_errorMonitor->SetDesiredFailureMsg(
Mark Lobodzinski20310782020-02-28 14:25:17 -07002175 kErrorBit,
unknown088160a2019-05-23 17:43:13 -06002176 "VUID-vkCmdCopyImageToBuffer-pRegions-00183"); // Extract 4b depth per texel, pack into 256k buffer
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06002177 vk::CmdCopyImageToBuffer(m_commandBuffer->handle(), ds_image_4D_1S.handle(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
2178 buffer_256k.handle(), 1, &ds_region);
unknown088160a2019-05-23 17:43:13 -06002179 m_errorMonitor->VerifyFound();
2180
2181 m_errorMonitor->SetDesiredFailureMsg(
Mark Lobodzinski20310782020-02-28 14:25:17 -07002182 kErrorBit,
locke-lunarg00710512020-06-01 13:56:49 -06002183 "VUID-vkCmdCopyImageToBuffer-pRegions-00183"); // Extract 3b depth per texel, pack (loose) into 128k buffer
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06002184 vk::CmdCopyImageToBuffer(m_commandBuffer->handle(), ds_image_3D_1S.handle(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
locke-lunarg00710512020-06-01 13:56:49 -06002185 buffer_128k.handle(), 1, &ds_region);
unknown088160a2019-05-23 17:43:13 -06002186 m_errorMonitor->VerifyFound();
2187
2188 m_errorMonitor->SetDesiredFailureMsg(
Mark Lobodzinski20310782020-02-28 14:25:17 -07002189 kErrorBit,
unknown088160a2019-05-23 17:43:13 -06002190 "VUID-vkCmdCopyImageToBuffer-pRegions-00183"); // Copy 2b depth per texel, into 128k buffer
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06002191 vk::CmdCopyImageToBuffer(m_commandBuffer->handle(), ds_image_2D.handle(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
2192 buffer_128k.handle(), 1, &ds_region);
unknown088160a2019-05-23 17:43:13 -06002193 m_errorMonitor->VerifyFound();
2194
sfricke-samsung5a019492021-01-25 10:32:08 -08002195 ds_region.bufferOffset = 5;
2196 ds_region.imageExtent = {64, 64, 1}; // need smaller so offset works
2197 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdCopyImageToBuffer-srcImage-04053");
2198 vk::CmdCopyImageToBuffer(m_commandBuffer->handle(), ds_image_2D.handle(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
2199 buffer_128k.handle(), 1, &ds_region);
2200 m_errorMonitor->VerifyFound();
2201 ds_region.imageExtent = {256, 256, 1};
2202
unknown088160a2019-05-23 17:43:13 -06002203 // Stencil copies that should succeed
2204 ds_region.bufferOffset = 0;
2205 ds_region.imageSubresource.aspectMask = VK_IMAGE_ASPECT_STENCIL_BIT;
2206 m_errorMonitor->ExpectSuccess(); // Extract 1b stencil per texel, pack into 64k buffer
locke-lunargdf00db02020-03-04 19:00:57 -07002207 vk::CmdPipelineBarrier(m_commandBuffer->handle(), VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, 1,
2208 &mem_barriers[0], 0, nullptr, 0, nullptr);
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06002209 vk::CmdCopyImageToBuffer(m_commandBuffer->handle(), ds_image_4D_1S.handle(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
2210 buffer_64k.handle(), 1, &ds_region);
unknown088160a2019-05-23 17:43:13 -06002211 m_errorMonitor->VerifyNotFound();
2212
2213 m_errorMonitor->ExpectSuccess(); // Extract 1b stencil per texel, pack into 64k buffer
locke-lunargdf00db02020-03-04 19:00:57 -07002214 vk::CmdPipelineBarrier(m_commandBuffer->handle(), VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, 1,
2215 &mem_barriers[0], 0, nullptr, 0, nullptr);
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06002216 vk::CmdCopyImageToBuffer(m_commandBuffer->handle(), ds_image_3D_1S.handle(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
2217 buffer_64k.handle(), 1, &ds_region);
unknown088160a2019-05-23 17:43:13 -06002218 m_errorMonitor->VerifyNotFound();
2219
2220 m_errorMonitor->ExpectSuccess(); // Copy 1b depth per texel, into 64k buffer
locke-lunargdf00db02020-03-04 19:00:57 -07002221 vk::CmdPipelineBarrier(m_commandBuffer->handle(), VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, 1,
2222 &mem_barriers[0], 0, nullptr, 0, nullptr);
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06002223 vk::CmdCopyImageToBuffer(m_commandBuffer->handle(), ds_image_1S.handle(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
2224 buffer_64k.handle(), 1, &ds_region);
unknown088160a2019-05-23 17:43:13 -06002225 m_errorMonitor->VerifyNotFound();
2226
2227 // Stencil copies that should fail
2228 m_errorMonitor->SetDesiredFailureMsg(
Mark Lobodzinski20310782020-02-28 14:25:17 -07002229 kErrorBit,
unknown088160a2019-05-23 17:43:13 -06002230 "VUID-vkCmdCopyImageToBuffer-pRegions-00183"); // Extract 1b stencil per texel, pack into 64k buffer
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06002231 vk::CmdCopyImageToBuffer(m_commandBuffer->handle(), ds_image_4D_1S.handle(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
2232 buffer_16k.handle(), 1, &ds_region);
unknown088160a2019-05-23 17:43:13 -06002233 m_errorMonitor->VerifyFound();
2234
2235 m_errorMonitor->SetDesiredFailureMsg(
Mark Lobodzinski20310782020-02-28 14:25:17 -07002236 kErrorBit,
unknown088160a2019-05-23 17:43:13 -06002237 "VUID-vkCmdCopyImageToBuffer-pRegions-00183"); // Extract 1b stencil per texel, pack into 64k buffer
2238 ds_region.bufferRowLength = 260;
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06002239 vk::CmdCopyImageToBuffer(m_commandBuffer->handle(), ds_image_3D_1S.handle(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
2240 buffer_64k.handle(), 1, &ds_region);
unknown088160a2019-05-23 17:43:13 -06002241 m_errorMonitor->VerifyFound();
2242
2243 ds_region.bufferRowLength = 0;
2244 ds_region.bufferOffset = 4;
2245 m_errorMonitor->SetDesiredFailureMsg(
Mark Lobodzinski20310782020-02-28 14:25:17 -07002246 kErrorBit,
unknown088160a2019-05-23 17:43:13 -06002247 "VUID-vkCmdCopyImageToBuffer-pRegions-00183"); // Copy 1b depth per texel, into 64k buffer
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06002248 vk::CmdCopyImageToBuffer(m_commandBuffer->handle(), ds_image_1S.handle(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
2249 buffer_64k.handle(), 1, &ds_region);
unknown088160a2019-05-23 17:43:13 -06002250 m_errorMonitor->VerifyFound();
2251 }
2252
2253 // Test compressed formats, if supported
sfricke-samsung6d97e562020-01-07 22:01:00 -08002254 // Support here requires both feature bit for compression and picked format supports transfer feature bits
unknown088160a2019-05-23 17:43:13 -06002255 VkPhysicalDeviceFeatures device_features = {};
2256 ASSERT_NO_FATAL_FAILURE(GetPhysicalDeviceFeatures(&device_features));
2257 if (!(device_features.textureCompressionBC || device_features.textureCompressionETC2 ||
2258 device_features.textureCompressionASTC_LDR)) {
2259 printf("%s No compressed formats supported - block compression tests skipped.\n", kSkipPrefix);
2260 } else {
sfricke-samsung6d97e562020-01-07 22:01:00 -08002261 // Verify transfer support for each compression format used blow
2262 bool missing_bc_support = false;
2263 bool missing_etc_support = false;
2264 bool missing_astc_support = false;
2265 bool missing_compression_support = false;
2266
2267 vk::GetPhysicalDeviceFormatProperties(m_device->phy().handle(), VK_FORMAT_BC3_SRGB_BLOCK, &props);
2268 missing_bc_support |= (props.bufferFeatures == 0 && props.linearTilingFeatures == 0 && props.optimalTilingFeatures == 0);
2269 missing_bc_support |= (props.optimalTilingFeatures & VK_FORMAT_FEATURE_TRANSFER_SRC_BIT) == 0;
2270 missing_bc_support |= (props.optimalTilingFeatures & VK_FORMAT_FEATURE_TRANSFER_DST_BIT) == 0;
2271
2272 vk::GetPhysicalDeviceFormatProperties(m_device->phy().handle(), VK_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK, &props);
2273 missing_etc_support |= (props.bufferFeatures == 0 && props.linearTilingFeatures == 0 && props.optimalTilingFeatures == 0);
2274 missing_etc_support |= (props.optimalTilingFeatures & VK_FORMAT_FEATURE_TRANSFER_SRC_BIT) == 0;
2275 missing_etc_support |= (props.optimalTilingFeatures & VK_FORMAT_FEATURE_TRANSFER_DST_BIT) == 0;
2276
2277 vk::GetPhysicalDeviceFormatProperties(m_device->phy().handle(), VK_FORMAT_ASTC_4x4_UNORM_BLOCK, &props);
2278 missing_astc_support |= (props.bufferFeatures == 0 && props.linearTilingFeatures == 0 && props.optimalTilingFeatures == 0);
2279 missing_astc_support |= (props.optimalTilingFeatures & VK_FORMAT_FEATURE_TRANSFER_SRC_BIT) == 0;
2280 missing_astc_support |= (props.optimalTilingFeatures & VK_FORMAT_FEATURE_TRANSFER_DST_BIT) == 0;
2281
2282 if (device_features.textureCompressionBC && (!missing_bc_support)) {
unknown088160a2019-05-23 17:43:13 -06002283 image_16k_4x4comp.Init(128, 128, 1, VK_FORMAT_BC3_SRGB_BLOCK, VK_IMAGE_USAGE_TRANSFER_SRC_BIT, VK_IMAGE_TILING_OPTIMAL,
2284 0);
2285 image_NPOT_4x4comp.Init(130, 130, 1, VK_FORMAT_BC3_SRGB_BLOCK, VK_IMAGE_USAGE_TRANSFER_SRC_BIT, VK_IMAGE_TILING_OPTIMAL,
2286 0);
sfricke-samsung6d97e562020-01-07 22:01:00 -08002287 } else if (device_features.textureCompressionETC2 && (!missing_etc_support)) {
unknown088160a2019-05-23 17:43:13 -06002288 image_16k_4x4comp.Init(128, 128, 1, VK_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK, VK_IMAGE_USAGE_TRANSFER_SRC_BIT,
2289 VK_IMAGE_TILING_OPTIMAL, 0);
2290 image_NPOT_4x4comp.Init(130, 130, 1, VK_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK, VK_IMAGE_USAGE_TRANSFER_SRC_BIT,
2291 VK_IMAGE_TILING_OPTIMAL, 0);
sfricke-samsung6d97e562020-01-07 22:01:00 -08002292 } else if (device_features.textureCompressionASTC_LDR && (!missing_astc_support)) {
unknown088160a2019-05-23 17:43:13 -06002293 image_16k_4x4comp.Init(128, 128, 1, VK_FORMAT_ASTC_4x4_UNORM_BLOCK, VK_IMAGE_USAGE_TRANSFER_SRC_BIT,
2294 VK_IMAGE_TILING_OPTIMAL, 0);
2295 image_NPOT_4x4comp.Init(130, 130, 1, VK_FORMAT_ASTC_4x4_UNORM_BLOCK, VK_IMAGE_USAGE_TRANSFER_SRC_BIT,
2296 VK_IMAGE_TILING_OPTIMAL, 0);
sfricke-samsung6d97e562020-01-07 22:01:00 -08002297 } else {
2298 missing_compression_support = true;
unknown088160a2019-05-23 17:43:13 -06002299 }
unknown088160a2019-05-23 17:43:13 -06002300
sfricke-samsung6d97e562020-01-07 22:01:00 -08002301 if (missing_compression_support) {
2302 printf("%s No compressed formats transfers bits are supported - block compression tests skipped.\n", kSkipPrefix);
2303 } else {
2304 ASSERT_TRUE(image_16k_4x4comp.initialized());
sfricke-samsung3a10b922020-05-13 23:23:16 -07002305 std::string vuid;
sfricke-samsung6d97e562020-01-07 22:01:00 -08002306 // Just fits
locke-lunargdf00db02020-03-04 19:00:57 -07002307 vk::CmdPipelineBarrier(m_commandBuffer->handle(), VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, 1,
2308 &mem_barriers[0], 0, nullptr, 0, nullptr);
sfricke-samsung6d97e562020-01-07 22:01:00 -08002309 m_errorMonitor->ExpectSuccess();
2310 region.imageExtent = {128, 128, 1};
2311 vk::CmdCopyImageToBuffer(m_commandBuffer->handle(), image_16k_4x4comp.handle(), VK_IMAGE_LAYOUT_GENERAL,
2312 buffer_16k.handle(), 1, &region);
2313 m_errorMonitor->VerifyNotFound();
unknown088160a2019-05-23 17:43:13 -06002314
sfricke-samsung6d97e562020-01-07 22:01:00 -08002315 // with offset, too big for buffer
Mark Lobodzinski20310782020-02-28 14:25:17 -07002316 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdCopyImageToBuffer-pRegions-00183");
sfricke-samsung6d97e562020-01-07 22:01:00 -08002317 region.bufferOffset = 16;
2318 vk::CmdCopyImageToBuffer(m_commandBuffer->handle(), image_16k_4x4comp.handle(), VK_IMAGE_LAYOUT_GENERAL,
2319 buffer_16k.handle(), 1, &region);
2320 m_errorMonitor->VerifyFound();
2321 region.bufferOffset = 0;
unknown088160a2019-05-23 17:43:13 -06002322
sfricke-samsung6d97e562020-01-07 22:01:00 -08002323 // extents that are not a multiple of compressed block size
sfricke-samsung88ac6fe2020-10-24 10:00:13 -07002324 m_errorMonitor->SetDesiredFailureMsg(
2325 kErrorBit, "VUID-vkCmdCopyImageToBuffer-imageExtent-00207"); // extent width not a multiple of block size
Mark Lobodzinski20310782020-02-28 14:25:17 -07002326 m_errorMonitor->SetDesiredFailureMsg(kErrorBit,
sfricke-samsung6d97e562020-01-07 22:01:00 -08002327 "VUID-vkCmdCopyImageToBuffer-imageOffset-01794"); // image transfer granularity
2328 region.imageExtent.width = 66;
2329 vk::CmdCopyImageToBuffer(m_commandBuffer->handle(), image_NPOT_4x4comp.handle(), VK_IMAGE_LAYOUT_GENERAL,
2330 buffer_16k.handle(), 1, &region);
2331 m_errorMonitor->VerifyFound();
2332 region.imageExtent.width = 128;
unknown088160a2019-05-23 17:43:13 -06002333
sfricke-samsung88ac6fe2020-10-24 10:00:13 -07002334 m_errorMonitor->SetDesiredFailureMsg(
2335 kErrorBit, "VUID-vkCmdCopyImageToBuffer-imageExtent-00208"); // extent height not a multiple of block size
Mark Lobodzinski20310782020-02-28 14:25:17 -07002336 m_errorMonitor->SetDesiredFailureMsg(kErrorBit,
sfricke-samsung6d97e562020-01-07 22:01:00 -08002337 "VUID-vkCmdCopyImageToBuffer-imageOffset-01794"); // image transfer granularity
2338 region.imageExtent.height = 2;
2339 vk::CmdCopyImageToBuffer(m_commandBuffer->handle(), image_NPOT_4x4comp.handle(), VK_IMAGE_LAYOUT_GENERAL,
2340 buffer_16k.handle(), 1, &region);
2341 m_errorMonitor->VerifyFound();
2342 region.imageExtent.height = 128;
unknown088160a2019-05-23 17:43:13 -06002343
sfricke-samsung6d97e562020-01-07 22:01:00 -08002344 // TODO: All available compressed formats are 2D, with block depth of 1. Unable to provoke VU_01277.
unknown088160a2019-05-23 17:43:13 -06002345
sfricke-samsung6d97e562020-01-07 22:01:00 -08002346 // non-multiple extents are allowed if at the far edge of a non-block-multiple image - these should pass
2347 m_errorMonitor->ExpectSuccess();
2348 region.imageExtent.width = 66;
2349 region.imageOffset.x = 64;
locke-lunargdf00db02020-03-04 19:00:57 -07002350 vk::CmdPipelineBarrier(m_commandBuffer->handle(), VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, 1,
2351 &mem_barriers[0], 0, nullptr, 0, nullptr);
sfricke-samsung6d97e562020-01-07 22:01:00 -08002352 vk::CmdCopyImageToBuffer(m_commandBuffer->handle(), image_NPOT_4x4comp.handle(), VK_IMAGE_LAYOUT_GENERAL,
2353 buffer_16k.handle(), 1, &region);
2354 region.imageExtent.width = 16;
2355 region.imageOffset.x = 0;
2356 region.imageExtent.height = 2;
2357 region.imageOffset.y = 128;
locke-lunargdf00db02020-03-04 19:00:57 -07002358 vk::CmdPipelineBarrier(m_commandBuffer->handle(), VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, 1,
2359 &mem_barriers[0], 0, nullptr, 0, nullptr);
sfricke-samsung6d97e562020-01-07 22:01:00 -08002360 vk::CmdCopyImageToBuffer(m_commandBuffer->handle(), image_NPOT_4x4comp.handle(), VK_IMAGE_LAYOUT_GENERAL,
2361 buffer_16k.handle(), 1, &region);
2362 m_errorMonitor->VerifyNotFound();
2363 region.imageOffset = {0, 0, 0};
unknown088160a2019-05-23 17:43:13 -06002364
sfricke-samsung6d97e562020-01-07 22:01:00 -08002365 // buffer offset must be a multiple of texel block size (16)
sfricke-samsung88ac6fe2020-10-24 10:00:13 -07002366 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdCopyImageToBuffer-bufferOffset-00206");
Shannon McPherson2c793ba2020-08-28 12:13:24 -06002367 vuid =
sfricke-samsung88ac6fe2020-10-24 10:00:13 -07002368 mp_extensions ? "VUID-vkCmdCopyImageToBuffer-bufferOffset-01558" : "VUID-vkCmdCopyImageToBuffer-bufferOffset-00193";
sfricke-samsung125d2b42020-05-28 06:32:43 -07002369 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, vuid);
sfricke-samsung6d97e562020-01-07 22:01:00 -08002370 region.imageExtent = {64, 64, 1};
2371 region.bufferOffset = 24;
2372 vk::CmdCopyImageToBuffer(m_commandBuffer->handle(), image_16k_4x4comp.handle(), VK_IMAGE_LAYOUT_GENERAL,
2373 buffer_16k.handle(), 1, &region);
2374 m_errorMonitor->VerifyFound();
unknown088160a2019-05-23 17:43:13 -06002375
sfricke-samsung6d97e562020-01-07 22:01:00 -08002376 // rowlength not a multiple of block width (4)
sfricke-samsung88ac6fe2020-10-24 10:00:13 -07002377 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdCopyImageToBuffer-bufferRowLength-00203");
sfricke-samsung6d97e562020-01-07 22:01:00 -08002378 region.bufferOffset = 0;
2379 region.bufferRowLength = 130;
2380 region.bufferImageHeight = 0;
2381 vk::CmdCopyImageToBuffer(m_commandBuffer->handle(), image_16k_4x4comp.handle(), VK_IMAGE_LAYOUT_GENERAL,
2382 buffer_64k.handle(), 1, &region);
2383 m_errorMonitor->VerifyFound();
2384
2385 // imageheight not a multiple of block height (4)
sfricke-samsung88ac6fe2020-10-24 10:00:13 -07002386 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdCopyImageToBuffer-bufferImageHeight-00204");
sfricke-samsung6d97e562020-01-07 22:01:00 -08002387 region.bufferRowLength = 0;
2388 region.bufferImageHeight = 130;
2389 vk::CmdCopyImageToBuffer(m_commandBuffer->handle(), image_16k_4x4comp.handle(), VK_IMAGE_LAYOUT_GENERAL,
2390 buffer_64k.handle(), 1, &region);
2391 m_errorMonitor->VerifyFound();
2392 }
2393 }
2394
2395 // Test multi-planar formats, if supported
2396 if (!mp_extensions) {
2397 printf("%s multi-planar extensions not supported; skipped.\n", kSkipPrefix);
2398 } else {
2399 // Try to use G8_B8R8_2PLANE_420_UNORM because need 2-plane format for some tests and likely supported due to copy support
2400 // being required with samplerYcbcrConversion feature
2401 bool missing_mp_support = false;
2402 vk::GetPhysicalDeviceFormatProperties(m_device->phy().handle(), VK_FORMAT_G8_B8R8_2PLANE_420_UNORM, &props);
2403 missing_mp_support |= (props.bufferFeatures == 0 && props.linearTilingFeatures == 0 && props.optimalTilingFeatures == 0);
2404 missing_mp_support |= (props.optimalTilingFeatures & VK_FORMAT_FEATURE_TRANSFER_SRC_BIT) == 0;
2405 missing_mp_support |= (props.optimalTilingFeatures & VK_FORMAT_FEATURE_TRANSFER_DST_BIT) == 0;
2406
2407 if (missing_mp_support) {
2408 printf("%s VK_FORMAT_G8_B8R8_2PLANE_420_UNORM transfer not supported; skipped.\n", kSkipPrefix);
2409 } else {
2410 VkBufferImageCopy mp_region = {};
2411 mp_region.bufferOffset = 0;
2412 mp_region.bufferRowLength = 0;
2413 mp_region.bufferImageHeight = 0;
2414 mp_region.imageSubresource.mipLevel = 0;
2415 mp_region.imageSubresource.baseArrayLayer = 0;
2416 mp_region.imageSubresource.layerCount = 1;
2417 mp_region.imageOffset = {0, 0, 0};
2418 mp_region.imageExtent = {128, 128, 1};
2419
2420 // YUV420 means 1/2 width and height so plane_0 is 128x128 and plane_1 is 64x64 here
2421 image_multi_planar.Init(128, 128, 1, VK_FORMAT_G8_B8R8_2PLANE_420_UNORM, VK_IMAGE_USAGE_TRANSFER_DST_BIT,
2422 VK_IMAGE_TILING_OPTIMAL, 0);
2423 ASSERT_TRUE(image_multi_planar.initialized());
2424
2425 // Copies into a mutli-planar image aspect properly
2426 m_errorMonitor->ExpectSuccess();
2427 mp_region.imageSubresource.aspectMask = VK_IMAGE_ASPECT_PLANE_0_BIT;
locke-lunargdf00db02020-03-04 19:00:57 -07002428 vk::CmdPipelineBarrier(m_commandBuffer->handle(), VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, 1,
2429 &mem_barriers[2], 0, nullptr, 0, nullptr);
sfricke-samsung6d97e562020-01-07 22:01:00 -08002430 vk::CmdCopyBufferToImage(m_commandBuffer->handle(), buffer_16k.handle(), image_multi_planar.handle(),
2431 VK_IMAGE_LAYOUT_GENERAL, 1, &mp_region);
2432 m_errorMonitor->VerifyNotFound();
2433
2434 // uses plane_2 without being 3 planar format
Shannon McPherson2c793ba2020-08-28 12:13:24 -06002435 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdCopyBufferToImage-aspectMask-01560");
sfricke-samsung6d97e562020-01-07 22:01:00 -08002436 mp_region.imageSubresource.aspectMask = VK_IMAGE_ASPECT_PLANE_2_BIT;
2437 vk::CmdCopyBufferToImage(m_commandBuffer->handle(), buffer_16k.handle(), image_multi_planar.handle(),
2438 VK_IMAGE_LAYOUT_GENERAL, 1, &mp_region);
2439 m_errorMonitor->VerifyFound();
2440
2441 // uses single-plane aspect mask
Shannon McPherson2c793ba2020-08-28 12:13:24 -06002442 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdCopyBufferToImage-aspectMask-01560");
sfricke-samsung6d97e562020-01-07 22:01:00 -08002443 mp_region.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
2444 vk::CmdCopyBufferToImage(m_commandBuffer->handle(), buffer_16k.handle(), image_multi_planar.handle(),
2445 VK_IMAGE_LAYOUT_GENERAL, 1, &mp_region);
2446 m_errorMonitor->VerifyFound();
sfricke-samsungb616d3f2020-06-03 22:00:34 -07002447
2448 // buffer offset must be a multiple of texel block size for VK_FORMAT_R8G8_UNORM (2)
Shannon McPherson2c793ba2020-08-28 12:13:24 -06002449 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdCopyBufferToImage-bufferOffset-01559");
sfricke-samsungb616d3f2020-06-03 22:00:34 -07002450 mp_region.imageSubresource.aspectMask = VK_IMAGE_ASPECT_PLANE_1_BIT;
2451 mp_region.bufferOffset = 5;
2452 mp_region.imageExtent = {8, 8, 1};
2453 vk::CmdCopyBufferToImage(m_commandBuffer->handle(), buffer_16k.handle(), image_multi_planar.handle(),
2454 VK_IMAGE_LAYOUT_GENERAL, 1, &mp_region);
2455 m_errorMonitor->VerifyFound();
sfricke-samsung6d97e562020-01-07 22:01:00 -08002456 }
unknown088160a2019-05-23 17:43:13 -06002457 }
2458}
2459
2460TEST_F(VkLayerTest, MiscImageLayerTests) {
2461 TEST_DESCRIPTION("Image-related tests that don't belong elsewhere");
2462
2463 ASSERT_NO_FATAL_FAILURE(Init());
2464
2465 // TODO: Ideally we should check if a format is supported, before using it.
2466 VkImageObj image(m_device);
2467 image.Init(128, 128, 1, VK_FORMAT_R16G16B16A16_UINT, VK_IMAGE_USAGE_TRANSFER_DST_BIT, VK_IMAGE_TILING_OPTIMAL, 0); // 64bpp
2468 ASSERT_TRUE(image.initialized());
2469 VkBufferObj buffer;
2470 VkMemoryPropertyFlags reqs = 0;
2471 buffer.init_as_src(*m_device, 128 * 128 * 8, reqs);
2472 VkBufferImageCopy region = {};
2473 region.bufferRowLength = 128;
2474 region.bufferImageHeight = 128;
2475 region.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
2476 // layerCount can't be 0 - Expect MISMATCHED_IMAGE_ASPECT
2477 region.imageSubresource.layerCount = 1;
2478 region.imageExtent.height = 4;
2479 region.imageExtent.width = 4;
2480 region.imageExtent.depth = 1;
2481
2482 VkImageObj image2(m_device);
2483 image2.Init(128, 128, 1, VK_FORMAT_R8G8_UNORM, VK_IMAGE_USAGE_TRANSFER_DST_BIT, VK_IMAGE_TILING_OPTIMAL, 0); // 16bpp
2484 ASSERT_TRUE(image2.initialized());
2485 VkBufferObj buffer2;
2486 VkMemoryPropertyFlags reqs2 = 0;
2487 buffer2.init_as_src(*m_device, 128 * 128 * 2, reqs2);
unknown088160a2019-05-23 17:43:13 -06002488 m_commandBuffer->begin();
2489
2490 // Image must have offset.z of 0 and extent.depth of 1
2491 // Introduce failure by setting imageExtent.depth to 0
2492 region.imageExtent.depth = 0;
Shannon McPherson2c793ba2020-08-28 12:13:24 -06002493 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdCopyBufferToImage-srcImage-00201");
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06002494 vk::CmdCopyBufferToImage(m_commandBuffer->handle(), buffer.handle(), image.handle(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1,
2495 &region);
unknown088160a2019-05-23 17:43:13 -06002496 m_errorMonitor->VerifyFound();
2497
2498 region.imageExtent.depth = 1;
2499
2500 // Image must have offset.z of 0 and extent.depth of 1
2501 // Introduce failure by setting imageOffset.z to 4
2502 // Note: Also (unavoidably) triggers 'region exceeds image' #1228
2503 region.imageOffset.z = 4;
Shannon McPherson2c793ba2020-08-28 12:13:24 -06002504 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdCopyBufferToImage-srcImage-00201");
2505 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdCopyBufferToImage-imageOffset-00200");
Mark Lobodzinski20310782020-02-28 14:25:17 -07002506 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdCopyBufferToImage-pRegions-00172");
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06002507 vk::CmdCopyBufferToImage(m_commandBuffer->handle(), buffer.handle(), image.handle(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1,
2508 &region);
unknown088160a2019-05-23 17:43:13 -06002509 m_errorMonitor->VerifyFound();
2510
2511 region.imageOffset.z = 0;
2512 // BufferOffset must be a multiple of the calling command's VkImage parameter's texel size
2513 // Introduce failure by setting bufferOffset to 1 and 1/2 texels
2514 region.bufferOffset = 4;
Shannon McPherson2c793ba2020-08-28 12:13:24 -06002515 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdCopyBufferToImage-bufferOffset-00193");
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06002516 vk::CmdCopyBufferToImage(m_commandBuffer->handle(), buffer.handle(), image.handle(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1,
2517 &region);
unknown088160a2019-05-23 17:43:13 -06002518 m_errorMonitor->VerifyFound();
2519
unknown088160a2019-05-23 17:43:13 -06002520 // BufferRowLength must be 0, or greater than or equal to the width member of imageExtent
2521 region.bufferOffset = 0;
2522 region.imageExtent.height = 128;
2523 region.imageExtent.width = 128;
2524 // Introduce failure by setting bufferRowLength > 0 but less than width
2525 region.bufferRowLength = 64;
Mark Lobodzinski20310782020-02-28 14:25:17 -07002526 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkBufferImageCopy-bufferRowLength-00195");
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06002527 vk::CmdCopyBufferToImage(m_commandBuffer->handle(), buffer.handle(), image.handle(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1,
2528 &region);
unknown088160a2019-05-23 17:43:13 -06002529 m_errorMonitor->VerifyFound();
2530
2531 // BufferImageHeight must be 0, or greater than or equal to the height member of imageExtent
2532 region.bufferRowLength = 128;
2533 // Introduce failure by setting bufferRowHeight > 0 but less than height
2534 region.bufferImageHeight = 64;
Mark Lobodzinski20310782020-02-28 14:25:17 -07002535 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkBufferImageCopy-bufferImageHeight-00196");
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06002536 vk::CmdCopyBufferToImage(m_commandBuffer->handle(), buffer.handle(), image.handle(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1,
2537 &region);
unknown088160a2019-05-23 17:43:13 -06002538 m_errorMonitor->VerifyFound();
2539
2540 region.bufferImageHeight = 128;
2541 VkImageObj intImage1(m_device);
2542 intImage1.Init(128, 128, 1, VK_FORMAT_R8_UNORM, VK_IMAGE_USAGE_TRANSFER_SRC_BIT, VK_IMAGE_TILING_OPTIMAL, 0);
2543 intImage1.SetLayout(VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_GENERAL);
2544 VkImageObj intImage2(m_device);
2545 intImage2.Init(128, 128, 1, VK_FORMAT_R8_UNORM, VK_IMAGE_USAGE_TRANSFER_DST_BIT, VK_IMAGE_TILING_OPTIMAL, 0);
2546 intImage2.SetLayout(VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_GENERAL);
2547 VkImageBlit blitRegion = {};
2548 blitRegion.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
2549 blitRegion.srcSubresource.baseArrayLayer = 0;
2550 blitRegion.srcSubresource.layerCount = 1;
2551 blitRegion.srcSubresource.mipLevel = 0;
2552 blitRegion.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
2553 blitRegion.dstSubresource.baseArrayLayer = 0;
2554 blitRegion.dstSubresource.layerCount = 1;
2555 blitRegion.dstSubresource.mipLevel = 0;
2556 blitRegion.srcOffsets[0] = {128, 0, 0};
2557 blitRegion.srcOffsets[1] = {128, 128, 1};
2558 blitRegion.dstOffsets[0] = {0, 128, 0};
2559 blitRegion.dstOffsets[1] = {128, 128, 1};
2560
2561 // Look for NULL-blit warning
Mark Lobodzinski20310782020-02-28 14:25:17 -07002562 m_errorMonitor->SetDesiredFailureMsg(kWarningBit, "vkCmdBlitImage(): pRegions[0].srcOffsets specify a zero-volume area.");
2563 m_errorMonitor->SetDesiredFailureMsg(kWarningBit, "vkCmdBlitImage(): pRegions[0].dstOffsets specify a zero-volume area.");
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06002564 vk::CmdBlitImage(m_commandBuffer->handle(), intImage1.handle(), intImage1.Layout(), intImage2.handle(), intImage2.Layout(), 1,
2565 &blitRegion, VK_FILTER_LINEAR);
unknown088160a2019-05-23 17:43:13 -06002566 m_errorMonitor->VerifyFound();
2567}
2568
2569TEST_F(VkLayerTest, CopyImageTypeExtentMismatch) {
2570 // Image copy tests where format type and extents don't match
Jeff Leger465acf52020-10-12 18:07:16 -04002571 ASSERT_NO_FATAL_FAILURE(InitFramework(m_errorMonitor));
2572
2573 bool copy_commands2 = false;
2574 if (DeviceExtensionSupported(gpu(), nullptr, VK_KHR_COPY_COMMANDS_2_EXTENSION_NAME)) {
2575 m_device_extension_names.push_back(VK_KHR_COPY_COMMANDS_2_EXTENSION_NAME);
2576 copy_commands2 = true;
2577 }
2578 ASSERT_NO_FATAL_FAILURE(InitState());
2579
2580 PFN_vkCmdCopyImage2KHR vkCmdCopyImage2Function = nullptr;
2581 if (copy_commands2) {
2582 vkCmdCopyImage2Function = (PFN_vkCmdCopyImage2KHR)vk::GetDeviceProcAddr(m_device->handle(), "vkCmdCopyImage2KHR");
2583 }
unknown088160a2019-05-23 17:43:13 -06002584
sfricke-samsung30b094c2020-05-30 11:42:11 -07002585 // Tests are designed to run without Maintenance1 which was promoted in 1.1
2586 if (DeviceValidationVersion() >= VK_API_VERSION_1_1) {
2587 printf("%s Tests for 1.0 only, test skipped.\n", kSkipPrefix);
2588 return;
2589 }
2590
unknown088160a2019-05-23 17:43:13 -06002591 VkImageCreateInfo ci;
2592 ci.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
2593 ci.pNext = NULL;
2594 ci.flags = 0;
2595 ci.imageType = VK_IMAGE_TYPE_1D;
2596 ci.format = VK_FORMAT_R8G8B8A8_UNORM;
2597 ci.extent = {32, 1, 1};
2598 ci.mipLevels = 1;
2599 ci.arrayLayers = 1;
2600 ci.samples = VK_SAMPLE_COUNT_1_BIT;
2601 ci.tiling = VK_IMAGE_TILING_OPTIMAL;
2602 ci.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
2603 ci.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
2604 ci.queueFamilyIndexCount = 0;
2605 ci.pQueueFamilyIndices = NULL;
2606 ci.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
2607
2608 // Create 1D image
2609 VkImageObj image_1D(m_device);
2610 image_1D.init(&ci);
2611 ASSERT_TRUE(image_1D.initialized());
2612
2613 // 2D image
2614 ci.imageType = VK_IMAGE_TYPE_2D;
2615 ci.extent = {32, 32, 1};
2616 VkImageObj image_2D(m_device);
2617 image_2D.init(&ci);
2618 ASSERT_TRUE(image_2D.initialized());
2619
2620 // 3D image
2621 ci.imageType = VK_IMAGE_TYPE_3D;
2622 ci.extent = {32, 32, 8};
2623 VkImageObj image_3D(m_device);
2624 image_3D.init(&ci);
2625 ASSERT_TRUE(image_3D.initialized());
2626
2627 // 2D image array
2628 ci.imageType = VK_IMAGE_TYPE_2D;
2629 ci.extent = {32, 32, 1};
2630 ci.arrayLayers = 8;
2631 VkImageObj image_2D_array(m_device);
2632 image_2D_array.init(&ci);
2633 ASSERT_TRUE(image_2D_array.initialized());
2634
2635 m_commandBuffer->begin();
2636
2637 VkImageCopy copy_region;
2638 copy_region.extent = {32, 1, 1};
2639 copy_region.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
2640 copy_region.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
2641 copy_region.srcSubresource.mipLevel = 0;
2642 copy_region.dstSubresource.mipLevel = 0;
2643 copy_region.srcSubresource.baseArrayLayer = 0;
2644 copy_region.dstSubresource.baseArrayLayer = 0;
2645 copy_region.srcSubresource.layerCount = 1;
2646 copy_region.dstSubresource.layerCount = 1;
2647 copy_region.srcOffset = {0, 0, 0};
2648 copy_region.dstOffset = {0, 0, 0};
2649
2650 // Sanity check
2651 m_errorMonitor->ExpectSuccess();
2652 m_commandBuffer->CopyImage(image_1D.image(), VK_IMAGE_LAYOUT_GENERAL, image_2D.image(), VK_IMAGE_LAYOUT_GENERAL, 1,
2653 &copy_region);
2654 m_errorMonitor->VerifyNotFound();
2655
Jeff Leger465acf52020-10-12 18:07:16 -04002656 // Equivalent sanity check using KHR_copy_commands2
2657 if (copy_commands2 && vkCmdCopyImage2Function) {
2658 const VkImageCopy2KHR region2 = {VK_STRUCTURE_TYPE_IMAGE_COPY_2_KHR,
2659 NULL,
2660 copy_region.srcSubresource,
2661 copy_region.srcOffset,
2662 copy_region.dstSubresource,
2663 copy_region.dstOffset,
2664 copy_region.extent};
2665 const VkCopyImageInfo2KHR copy_image_info2 = {VK_STRUCTURE_TYPE_COPY_IMAGE_INFO_2_KHR,
2666 NULL,
2667 image_1D.image(),
2668 VK_IMAGE_LAYOUT_GENERAL,
2669 image_2D.image(),
2670 VK_IMAGE_LAYOUT_GENERAL,
2671 1,
2672 &region2};
2673 m_errorMonitor->ExpectSuccess();
2674 vkCmdCopyImage2Function(m_commandBuffer->handle(), &copy_image_info2);
2675 m_errorMonitor->VerifyNotFound();
2676 }
2677
unknown088160a2019-05-23 17:43:13 -06002678 // 1D texture w/ offset.y > 0. Source = VU 09c00124, dest = 09c00130
2679 copy_region.srcOffset.y = 1;
Shannon McPherson2c793ba2020-08-28 12:13:24 -06002680 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdCopyImage-srcImage-00146");
2681 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdCopyImage-srcOffset-00145"); // also y-dim overrun
unknown088160a2019-05-23 17:43:13 -06002682 m_commandBuffer->CopyImage(image_1D.image(), VK_IMAGE_LAYOUT_GENERAL, image_2D.image(), VK_IMAGE_LAYOUT_GENERAL, 1,
2683 &copy_region);
2684 m_errorMonitor->VerifyFound();
Jeff Leger465acf52020-10-12 18:07:16 -04002685
2686 // Equivalent test using KHR_copy_commands2
2687 if (copy_commands2 && vkCmdCopyImage2Function) {
2688 const VkImageCopy2KHR region2 = {VK_STRUCTURE_TYPE_IMAGE_COPY_2_KHR,
2689 NULL,
2690 copy_region.srcSubresource,
2691 copy_region.srcOffset,
2692 copy_region.dstSubresource,
2693 copy_region.dstOffset,
2694 copy_region.extent};
2695 const VkCopyImageInfo2KHR copy_image_info2 = {VK_STRUCTURE_TYPE_COPY_IMAGE_INFO_2_KHR,
2696 NULL,
2697 image_1D.image(),
2698 VK_IMAGE_LAYOUT_GENERAL,
2699 image_2D.image(),
2700 VK_IMAGE_LAYOUT_GENERAL,
2701 1,
2702 &region2};
2703 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkCopyImageInfo2KHR-srcImage-00146");
2704 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkCopyImageInfo2KHR-srcOffset-00145"); // also y-dim overrun
2705 vkCmdCopyImage2Function(m_commandBuffer->handle(), &copy_image_info2);
2706 m_errorMonitor->VerifyFound();
2707 }
2708
unknown088160a2019-05-23 17:43:13 -06002709 copy_region.srcOffset.y = 0;
2710 copy_region.dstOffset.y = 1;
Shannon McPherson2c793ba2020-08-28 12:13:24 -06002711 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdCopyImage-dstImage-00152");
2712 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdCopyImage-dstOffset-00151"); // also y-dim overrun
unknown088160a2019-05-23 17:43:13 -06002713 m_commandBuffer->CopyImage(image_2D.image(), VK_IMAGE_LAYOUT_GENERAL, image_1D.image(), VK_IMAGE_LAYOUT_GENERAL, 1,
2714 &copy_region);
2715 m_errorMonitor->VerifyFound();
Jeff Leger465acf52020-10-12 18:07:16 -04002716
2717 // Equivalent test using KHR_copy_commands2
2718 if (copy_commands2 && vkCmdCopyImage2Function) {
2719 const VkImageCopy2KHR region2 = {VK_STRUCTURE_TYPE_IMAGE_COPY_2_KHR,
2720 NULL,
2721 copy_region.srcSubresource,
2722 copy_region.srcOffset,
2723 copy_region.dstSubresource,
2724 copy_region.dstOffset,
2725 copy_region.extent};
2726 const VkCopyImageInfo2KHR copy_image_info2 = {VK_STRUCTURE_TYPE_COPY_IMAGE_INFO_2_KHR,
2727 NULL,
2728 image_2D.image(),
2729 VK_IMAGE_LAYOUT_GENERAL,
2730 image_1D.image(),
2731 VK_IMAGE_LAYOUT_GENERAL,
2732 1,
2733 &region2};
2734 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkCopyImageInfo2KHR-dstImage-00152");
2735 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkCopyImageInfo2KHR-dstOffset-00151"); // also y-dim overrun
2736 vkCmdCopyImage2Function(m_commandBuffer->handle(), &copy_image_info2);
2737 m_errorMonitor->VerifyFound();
2738 }
2739
unknown088160a2019-05-23 17:43:13 -06002740 copy_region.dstOffset.y = 0;
2741
2742 // 1D texture w/ extent.height > 1. Source = VU 09c00124, dest = 09c00130
2743 copy_region.extent.height = 2;
Shannon McPherson2c793ba2020-08-28 12:13:24 -06002744 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdCopyImage-srcImage-00146");
2745 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdCopyImage-srcOffset-00145"); // also y-dim overrun
unknown088160a2019-05-23 17:43:13 -06002746 m_commandBuffer->CopyImage(image_1D.image(), VK_IMAGE_LAYOUT_GENERAL, image_2D.image(), VK_IMAGE_LAYOUT_GENERAL, 1,
2747 &copy_region);
2748 m_errorMonitor->VerifyFound();
Jeff Leger465acf52020-10-12 18:07:16 -04002749
2750 // Equivalent test using KHR_copy_commands2
2751 if (copy_commands2 && vkCmdCopyImage2Function) {
2752 const VkImageCopy2KHR region2 = {VK_STRUCTURE_TYPE_IMAGE_COPY_2_KHR,
2753 NULL,
2754 copy_region.srcSubresource,
2755 copy_region.srcOffset,
2756 copy_region.dstSubresource,
2757 copy_region.dstOffset,
2758 copy_region.extent};
2759 const VkCopyImageInfo2KHR copy_image_info2 = {VK_STRUCTURE_TYPE_COPY_IMAGE_INFO_2_KHR,
2760 NULL,
2761 image_1D.image(),
2762 VK_IMAGE_LAYOUT_GENERAL,
2763 image_2D.image(),
2764 VK_IMAGE_LAYOUT_GENERAL,
2765 1,
2766 &region2};
2767 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkCopyImageInfo2KHR-srcImage-00146");
2768 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkCopyImageInfo2KHR-srcOffset-00145"); // also y-dim overrun
2769 vkCmdCopyImage2Function(m_commandBuffer->handle(), &copy_image_info2);
2770 m_errorMonitor->VerifyFound();
2771 }
2772
Shannon McPherson2c793ba2020-08-28 12:13:24 -06002773 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdCopyImage-dstImage-00152");
2774 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdCopyImage-dstOffset-00151"); // also y-dim overrun
unknown088160a2019-05-23 17:43:13 -06002775 m_commandBuffer->CopyImage(image_2D.image(), VK_IMAGE_LAYOUT_GENERAL, image_1D.image(), VK_IMAGE_LAYOUT_GENERAL, 1,
2776 &copy_region);
2777 m_errorMonitor->VerifyFound();
Jeff Leger465acf52020-10-12 18:07:16 -04002778
2779 // Equivalent test using KHR_copy_commands2
2780 if (copy_commands2 && vkCmdCopyImage2Function) {
2781 const VkImageCopy2KHR region2 = {VK_STRUCTURE_TYPE_IMAGE_COPY_2_KHR,
2782 NULL,
2783 copy_region.srcSubresource,
2784 copy_region.srcOffset,
2785 copy_region.dstSubresource,
2786 copy_region.dstOffset,
2787 copy_region.extent};
2788 const VkCopyImageInfo2KHR copy_image_info2 = {VK_STRUCTURE_TYPE_COPY_IMAGE_INFO_2_KHR,
2789 NULL,
2790 image_2D.image(),
2791 VK_IMAGE_LAYOUT_GENERAL,
2792 image_1D.image(),
2793 VK_IMAGE_LAYOUT_GENERAL,
2794 1,
2795 &region2};
2796 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkCopyImageInfo2KHR-dstImage-00152");
2797 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkCopyImageInfo2KHR-dstOffset-00151"); // also y-dim overrun
2798 vkCmdCopyImage2Function(m_commandBuffer->handle(), &copy_image_info2);
2799 m_errorMonitor->VerifyFound();
2800 }
2801
unknown088160a2019-05-23 17:43:13 -06002802 copy_region.extent.height = 1;
2803
2804 // 1D texture w/ offset.z > 0. Source = VU 09c00df2, dest = 09c00df4
2805 copy_region.srcOffset.z = 1;
Shannon McPherson2c793ba2020-08-28 12:13:24 -06002806 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdCopyImage-srcImage-01785");
2807 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdCopyImage-srcOffset-00147"); // also z-dim overrun
unknown088160a2019-05-23 17:43:13 -06002808 m_commandBuffer->CopyImage(image_1D.image(), VK_IMAGE_LAYOUT_GENERAL, image_2D.image(), VK_IMAGE_LAYOUT_GENERAL, 1,
2809 &copy_region);
2810 m_errorMonitor->VerifyFound();
2811 copy_region.srcOffset.z = 0;
2812 copy_region.dstOffset.z = 1;
Shannon McPherson2c793ba2020-08-28 12:13:24 -06002813 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdCopyImage-dstImage-01786");
2814 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdCopyImage-dstOffset-00153"); // also z-dim overrun
unknown088160a2019-05-23 17:43:13 -06002815 m_commandBuffer->CopyImage(image_2D.image(), VK_IMAGE_LAYOUT_GENERAL, image_1D.image(), VK_IMAGE_LAYOUT_GENERAL, 1,
2816 &copy_region);
2817 m_errorMonitor->VerifyFound();
2818 copy_region.dstOffset.z = 0;
2819
2820 // 1D texture w/ extent.depth > 1. Source = VU 09c00df2, dest = 09c00df4
2821 copy_region.extent.depth = 2;
Shannon McPherson2c793ba2020-08-28 12:13:24 -06002822 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdCopyImage-srcImage-01785");
Mark Lobodzinski20310782020-02-28 14:25:17 -07002823 m_errorMonitor->SetDesiredFailureMsg(kErrorBit,
Shannon McPherson2c793ba2020-08-28 12:13:24 -06002824 "VUID-vkCmdCopyImage-srcOffset-00147"); // also z-dim overrun (src)
Mark Lobodzinski20310782020-02-28 14:25:17 -07002825 m_errorMonitor->SetDesiredFailureMsg(kErrorBit,
Shannon McPherson2c793ba2020-08-28 12:13:24 -06002826 "VUID-vkCmdCopyImage-dstOffset-00153"); // also z-dim overrun (dst)
Mark Lobodzinski20310782020-02-28 14:25:17 -07002827 m_errorMonitor->SetDesiredFailureMsg(kErrorBit,
Shannon McPherson2c793ba2020-08-28 12:13:24 -06002828 "VUID-vkCmdCopyImage-srcImage-01789"); // 2D needs to be 1 pre-Vulkan 1.1
unknown088160a2019-05-23 17:43:13 -06002829 m_commandBuffer->CopyImage(image_1D.image(), VK_IMAGE_LAYOUT_GENERAL, image_2D.image(), VK_IMAGE_LAYOUT_GENERAL, 1,
2830 &copy_region);
2831 m_errorMonitor->VerifyFound();
Shannon McPherson2c793ba2020-08-28 12:13:24 -06002832 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdCopyImage-dstImage-01786");
Mark Lobodzinski20310782020-02-28 14:25:17 -07002833 m_errorMonitor->SetDesiredFailureMsg(kErrorBit,
Shannon McPherson2c793ba2020-08-28 12:13:24 -06002834 "VUID-vkCmdCopyImage-srcOffset-00147"); // also z-dim overrun (src)
Mark Lobodzinski20310782020-02-28 14:25:17 -07002835 m_errorMonitor->SetDesiredFailureMsg(kErrorBit,
Shannon McPherson2c793ba2020-08-28 12:13:24 -06002836 "VUID-vkCmdCopyImage-dstOffset-00153"); // also z-dim overrun (dst)
Mark Lobodzinski20310782020-02-28 14:25:17 -07002837 m_errorMonitor->SetDesiredFailureMsg(kErrorBit,
Shannon McPherson2c793ba2020-08-28 12:13:24 -06002838 "VUID-vkCmdCopyImage-srcImage-01789"); // 2D needs to be 1 pre-Vulkan 1.1
unknown088160a2019-05-23 17:43:13 -06002839 m_commandBuffer->CopyImage(image_2D.image(), VK_IMAGE_LAYOUT_GENERAL, image_1D.image(), VK_IMAGE_LAYOUT_GENERAL, 1,
2840 &copy_region);
2841 m_errorMonitor->VerifyFound();
2842 copy_region.extent.depth = 1;
2843
2844 // 2D texture w/ offset.z > 0. Source = VU 09c00df6, dest = 09c00df8
2845 copy_region.extent = {16, 16, 1};
2846 copy_region.srcOffset.z = 4;
Shannon McPherson2c793ba2020-08-28 12:13:24 -06002847 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdCopyImage-srcImage-01787");
Mark Lobodzinski20310782020-02-28 14:25:17 -07002848 m_errorMonitor->SetDesiredFailureMsg(kErrorBit,
Shannon McPherson2c793ba2020-08-28 12:13:24 -06002849 "VUID-vkCmdCopyImage-srcOffset-00147"); // also z-dim overrun (src)
unknown088160a2019-05-23 17:43:13 -06002850 m_commandBuffer->CopyImage(image_2D.image(), VK_IMAGE_LAYOUT_GENERAL, image_3D.image(), VK_IMAGE_LAYOUT_GENERAL, 1,
2851 &copy_region);
2852 m_errorMonitor->VerifyFound();
2853 copy_region.srcOffset.z = 0;
2854 copy_region.dstOffset.z = 1;
Shannon McPherson2c793ba2020-08-28 12:13:24 -06002855 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdCopyImage-dstImage-01788");
Mark Lobodzinski20310782020-02-28 14:25:17 -07002856 m_errorMonitor->SetDesiredFailureMsg(kErrorBit,
Shannon McPherson2c793ba2020-08-28 12:13:24 -06002857 "VUID-vkCmdCopyImage-dstOffset-00153"); // also z-dim overrun (dst)
unknown088160a2019-05-23 17:43:13 -06002858 m_commandBuffer->CopyImage(image_3D.image(), VK_IMAGE_LAYOUT_GENERAL, image_2D.image(), VK_IMAGE_LAYOUT_GENERAL, 1,
2859 &copy_region);
2860 m_errorMonitor->VerifyFound();
2861 copy_region.dstOffset.z = 0;
2862
2863 // 3D texture accessing an array layer other than 0. VU 09c0011a
2864 copy_region.extent = {4, 4, 1};
2865 copy_region.srcSubresource.baseArrayLayer = 1;
Shannon McPherson2c793ba2020-08-28 12:13:24 -06002866 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdCopyImage-srcImage-00139");
Mark Lobodzinski20310782020-02-28 14:25:17 -07002867 m_errorMonitor->SetDesiredFailureMsg(kErrorBit,
unknown088160a2019-05-23 17:43:13 -06002868 "VUID-vkCmdCopyImage-srcSubresource-01698"); // also 'too many layers'
2869 m_commandBuffer->CopyImage(image_3D.image(), VK_IMAGE_LAYOUT_GENERAL, image_2D.image(), VK_IMAGE_LAYOUT_GENERAL, 1,
2870 &copy_region);
2871 m_errorMonitor->VerifyFound();
sfricke-samsung211ee9c2020-02-13 23:38:39 -08002872 copy_region.srcSubresource.baseArrayLayer = 0;
2873
unknown088160a2019-05-23 17:43:13 -06002874 m_commandBuffer->end();
2875}
2876
2877TEST_F(VkLayerTest, CopyImageTypeExtentMismatchMaintenance1) {
2878 // Image copy tests where format type and extents don't match and the Maintenance1 extension is enabled
Mark Lobodzinski09ce9c42020-03-06 10:02:44 -07002879 ASSERT_NO_FATAL_FAILURE(InitFramework(m_errorMonitor));
unknown088160a2019-05-23 17:43:13 -06002880 if (DeviceExtensionSupported(gpu(), nullptr, VK_KHR_MAINTENANCE1_EXTENSION_NAME)) {
2881 m_device_extension_names.push_back(VK_KHR_MAINTENANCE1_EXTENSION_NAME);
2882 } else {
2883 printf("%s Maintenance1 extension cannot be enabled, test skipped.\n", kSkipPrefix);
2884 return;
2885 }
2886 ASSERT_NO_FATAL_FAILURE(InitState());
2887
2888 VkFormat image_format = VK_FORMAT_R8G8B8A8_UNORM;
2889 VkFormatProperties format_props;
2890 // TODO: Remove this check if or when devsim handles extensions.
2891 // The chosen format has mandatory support the transfer src and dst format features when Maitenance1 is enabled. However, our
2892 // use of devsim and the mock ICD violate this guarantee.
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06002893 vk::GetPhysicalDeviceFormatProperties(m_device->phy().handle(), image_format, &format_props);
unknown088160a2019-05-23 17:43:13 -06002894 if (!(format_props.optimalTilingFeatures & VK_FORMAT_FEATURE_TRANSFER_SRC_BIT)) {
2895 printf("%s Maintenance1 extension is not supported.\n", kSkipPrefix);
2896 return;
2897 }
2898
2899 VkImageCreateInfo ci;
2900 ci.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
2901 ci.pNext = NULL;
2902 ci.flags = 0;
2903 ci.imageType = VK_IMAGE_TYPE_1D;
2904 ci.format = image_format;
2905 ci.extent = {32, 1, 1};
2906 ci.mipLevels = 1;
2907 ci.arrayLayers = 1;
2908 ci.samples = VK_SAMPLE_COUNT_1_BIT;
2909 ci.tiling = VK_IMAGE_TILING_OPTIMAL;
2910 ci.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
2911 ci.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
2912 ci.queueFamilyIndexCount = 0;
2913 ci.pQueueFamilyIndices = NULL;
2914 ci.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
2915
2916 // Create 1D image
2917 VkImageObj image_1D(m_device);
2918 image_1D.init(&ci);
2919 ASSERT_TRUE(image_1D.initialized());
2920
2921 // 2D image
2922 ci.imageType = VK_IMAGE_TYPE_2D;
2923 ci.extent = {32, 32, 1};
2924 VkImageObj image_2D(m_device);
2925 image_2D.init(&ci);
2926 ASSERT_TRUE(image_2D.initialized());
2927
2928 // 3D image
2929 ci.imageType = VK_IMAGE_TYPE_3D;
2930 ci.extent = {32, 32, 8};
2931 VkImageObj image_3D(m_device);
2932 image_3D.init(&ci);
2933 ASSERT_TRUE(image_3D.initialized());
2934
2935 // 2D image array
2936 ci.imageType = VK_IMAGE_TYPE_2D;
2937 ci.extent = {32, 32, 1};
2938 ci.arrayLayers = 8;
2939 VkImageObj image_2D_array(m_device);
2940 image_2D_array.init(&ci);
2941 ASSERT_TRUE(image_2D_array.initialized());
2942
sfricke-samsung211ee9c2020-02-13 23:38:39 -08002943 // second 2D image array
2944 ci.imageType = VK_IMAGE_TYPE_2D;
2945 ci.extent = {32, 32, 1};
2946 ci.arrayLayers = 8;
2947 VkImageObj image_2D_array_2(m_device);
2948 image_2D_array_2.init(&ci);
2949 ASSERT_TRUE(image_2D_array_2.initialized());
2950
unknown088160a2019-05-23 17:43:13 -06002951 m_commandBuffer->begin();
2952
2953 VkImageCopy copy_region;
2954 copy_region.extent = {32, 1, 1};
2955 copy_region.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
2956 copy_region.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
2957 copy_region.srcSubresource.mipLevel = 0;
2958 copy_region.dstSubresource.mipLevel = 0;
2959 copy_region.srcSubresource.baseArrayLayer = 0;
2960 copy_region.dstSubresource.baseArrayLayer = 0;
2961 copy_region.srcSubresource.layerCount = 1;
2962 copy_region.dstSubresource.layerCount = 1;
2963 copy_region.srcOffset = {0, 0, 0};
2964 copy_region.dstOffset = {0, 0, 0};
2965
2966 // Copy from layer not present
2967 copy_region.srcSubresource.baseArrayLayer = 4;
2968 copy_region.srcSubresource.layerCount = 6;
Mark Lobodzinski20310782020-02-28 14:25:17 -07002969 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdCopyImage-srcSubresource-01698");
unknown088160a2019-05-23 17:43:13 -06002970 m_commandBuffer->CopyImage(image_2D_array.image(), VK_IMAGE_LAYOUT_GENERAL, image_3D.image(), VK_IMAGE_LAYOUT_GENERAL, 1,
2971 &copy_region);
2972 m_errorMonitor->VerifyFound();
2973 copy_region.srcSubresource.baseArrayLayer = 0;
2974 copy_region.srcSubresource.layerCount = 1;
2975
2976 // Copy to layer not present
2977 copy_region.dstSubresource.baseArrayLayer = 1;
2978 copy_region.dstSubresource.layerCount = 8;
Mark Lobodzinski20310782020-02-28 14:25:17 -07002979 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdCopyImage-dstSubresource-01699");
unknown088160a2019-05-23 17:43:13 -06002980 m_commandBuffer->CopyImage(image_3D.image(), VK_IMAGE_LAYOUT_GENERAL, image_2D_array.image(), VK_IMAGE_LAYOUT_GENERAL, 1,
2981 &copy_region);
2982 m_errorMonitor->VerifyFound();
sfricke-samsung211ee9c2020-02-13 23:38:39 -08002983 copy_region.dstSubresource.baseArrayLayer = 0;
unknown088160a2019-05-23 17:43:13 -06002984 copy_region.dstSubresource.layerCount = 1;
2985
sfricke-samsung211ee9c2020-02-13 23:38:39 -08002986 // both 2D and extent.depth not 1
2987 // Need two 2D array images to prevent other errors
2988 copy_region.extent = {4, 1, 2};
Shannon McPherson2c793ba2020-08-28 12:13:24 -06002989 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdCopyImage-srcImage-01790");
sfricke-samsung211ee9c2020-02-13 23:38:39 -08002990 m_commandBuffer->CopyImage(image_2D_array.image(), VK_IMAGE_LAYOUT_GENERAL, image_2D_array_2.image(), VK_IMAGE_LAYOUT_GENERAL,
2991 1, &copy_region);
2992 m_errorMonitor->VerifyFound();
2993 copy_region.extent = {32, 1, 1};
2994
2995 // 2D src / 3D dst and depth not equal to src layerCount
2996 copy_region.extent = {4, 1, 2};
Shannon McPherson2c793ba2020-08-28 12:13:24 -06002997 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdCopyImage-srcImage-01791");
Mark Lobodzinski20310782020-02-28 14:25:17 -07002998 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkImageCopy-extent-00140");
sfricke-samsung211ee9c2020-02-13 23:38:39 -08002999 m_commandBuffer->CopyImage(image_2D_array.image(), VK_IMAGE_LAYOUT_GENERAL, image_3D.image(), VK_IMAGE_LAYOUT_GENERAL, 1,
3000 &copy_region);
3001 m_errorMonitor->VerifyFound();
3002 copy_region.extent = {32, 1, 1};
3003
3004 // 3D src / 2D dst and depth not equal to dst layerCount
3005 copy_region.extent = {4, 1, 2};
Shannon McPherson2c793ba2020-08-28 12:13:24 -06003006 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdCopyImage-dstImage-01792");
Mark Lobodzinski20310782020-02-28 14:25:17 -07003007 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkImageCopy-extent-00140");
sfricke-samsung211ee9c2020-02-13 23:38:39 -08003008 m_commandBuffer->CopyImage(image_3D.image(), VK_IMAGE_LAYOUT_GENERAL, image_2D_array.image(), VK_IMAGE_LAYOUT_GENERAL, 1,
3009 &copy_region);
3010 m_errorMonitor->VerifyFound();
3011 copy_region.extent = {32, 1, 1};
3012
unknown088160a2019-05-23 17:43:13 -06003013 m_commandBuffer->end();
3014}
3015
3016TEST_F(VkLayerTest, CopyImageCompressedBlockAlignment) {
3017 // Image copy tests on compressed images with block alignment errors
3018 SetTargetApiVersion(VK_API_VERSION_1_1);
3019 ASSERT_NO_FATAL_FAILURE(Init());
3020
3021 // Select a compressed format and verify support
3022 VkPhysicalDeviceFeatures device_features = {};
3023 ASSERT_NO_FATAL_FAILURE(GetPhysicalDeviceFeatures(&device_features));
3024 VkFormat compressed_format = VK_FORMAT_UNDEFINED;
3025 if (device_features.textureCompressionBC) {
3026 compressed_format = VK_FORMAT_BC3_SRGB_BLOCK;
3027 } else if (device_features.textureCompressionETC2) {
3028 compressed_format = VK_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK;
3029 } else if (device_features.textureCompressionASTC_LDR) {
3030 compressed_format = VK_FORMAT_ASTC_4x4_UNORM_BLOCK;
3031 }
3032
3033 VkImageCreateInfo ci;
3034 ci.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
3035 ci.pNext = NULL;
3036 ci.flags = 0;
3037 ci.imageType = VK_IMAGE_TYPE_2D;
3038 ci.format = compressed_format;
3039 ci.extent = {64, 64, 1};
3040 ci.mipLevels = 1;
3041 ci.arrayLayers = 1;
3042 ci.samples = VK_SAMPLE_COUNT_1_BIT;
3043 ci.tiling = VK_IMAGE_TILING_OPTIMAL;
3044 ci.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
3045 ci.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
3046 ci.queueFamilyIndexCount = 0;
3047 ci.pQueueFamilyIndices = NULL;
3048 ci.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
3049
3050 VkImageFormatProperties img_prop = {};
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06003051 if (VK_SUCCESS != vk::GetPhysicalDeviceImageFormatProperties(m_device->phy().handle(), ci.format, ci.imageType, ci.tiling,
3052 ci.usage, ci.flags, &img_prop)) {
unknown088160a2019-05-23 17:43:13 -06003053 printf("%s No compressed formats supported - CopyImageCompressedBlockAlignment skipped.\n", kSkipPrefix);
3054 return;
3055 }
3056
3057 // Create images
3058 VkImageObj image_1(m_device);
3059 image_1.init(&ci);
3060 ASSERT_TRUE(image_1.initialized());
3061
3062 ci.extent = {62, 62, 1}; // slightly smaller and not divisible by block size
3063 VkImageObj image_2(m_device);
3064 image_2.init(&ci);
3065 ASSERT_TRUE(image_2.initialized());
3066
3067 m_commandBuffer->begin();
3068
3069 VkImageCopy copy_region;
3070 copy_region.extent = {48, 48, 1};
3071 copy_region.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
3072 copy_region.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
3073 copy_region.srcSubresource.mipLevel = 0;
3074 copy_region.dstSubresource.mipLevel = 0;
3075 copy_region.srcSubresource.baseArrayLayer = 0;
3076 copy_region.dstSubresource.baseArrayLayer = 0;
3077 copy_region.srcSubresource.layerCount = 1;
3078 copy_region.dstSubresource.layerCount = 1;
3079 copy_region.srcOffset = {0, 0, 0};
3080 copy_region.dstOffset = {0, 0, 0};
3081
3082 // Sanity check
3083 m_errorMonitor->ExpectSuccess();
3084 m_commandBuffer->CopyImage(image_1.image(), VK_IMAGE_LAYOUT_GENERAL, image_2.image(), VK_IMAGE_LAYOUT_GENERAL, 1, &copy_region);
3085 m_errorMonitor->VerifyNotFound();
3086
3087 std::string vuid;
3088 bool ycbcr = (DeviceExtensionEnabled(VK_KHR_SAMPLER_YCBCR_CONVERSION_EXTENSION_NAME) ||
3089 (DeviceValidationVersion() >= VK_API_VERSION_1_1));
3090
3091 // Src, Dest offsets must be multiples of compressed block sizes {4, 4, 1}
3092 // Image transfer granularity gets set to compressed block size, so an ITG error is also (unavoidably) triggered.
Shannon McPherson2c793ba2020-08-28 12:13:24 -06003093 vuid = ycbcr ? "VUID-vkCmdCopyImage-srcImage-01727" : "VUID-vkCmdCopyImage-srcImage-01727";
unknown088160a2019-05-23 17:43:13 -06003094 copy_region.srcOffset = {2, 4, 0}; // source width
Mark Lobodzinski20310782020-02-28 14:25:17 -07003095 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, vuid);
3096 m_errorMonitor->SetDesiredFailureMsg(kErrorBit,
unknown088160a2019-05-23 17:43:13 -06003097 "VUID-vkCmdCopyImage-srcOffset-01783"); // srcOffset image transfer granularity
3098 m_commandBuffer->CopyImage(image_1.image(), VK_IMAGE_LAYOUT_GENERAL, image_2.image(), VK_IMAGE_LAYOUT_GENERAL, 1, &copy_region);
3099 m_errorMonitor->VerifyFound();
3100 copy_region.srcOffset = {12, 1, 0}; // source height
Mark Lobodzinski20310782020-02-28 14:25:17 -07003101 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, vuid);
3102 m_errorMonitor->SetDesiredFailureMsg(kErrorBit,
unknown088160a2019-05-23 17:43:13 -06003103 "VUID-vkCmdCopyImage-srcOffset-01783"); // srcOffset image transfer granularity
3104 m_commandBuffer->CopyImage(image_1.image(), VK_IMAGE_LAYOUT_GENERAL, image_2.image(), VK_IMAGE_LAYOUT_GENERAL, 1, &copy_region);
3105 m_errorMonitor->VerifyFound();
3106 copy_region.srcOffset = {0, 0, 0};
3107
Shannon McPherson2c793ba2020-08-28 12:13:24 -06003108 vuid = ycbcr ? "VUID-vkCmdCopyImage-dstImage-01731" : "VUID-vkCmdCopyImage-dstImage-01731";
unknown088160a2019-05-23 17:43:13 -06003109 copy_region.dstOffset = {1, 0, 0}; // dest width
Mark Lobodzinski20310782020-02-28 14:25:17 -07003110 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, vuid);
3111 m_errorMonitor->SetDesiredFailureMsg(kErrorBit,
unknown088160a2019-05-23 17:43:13 -06003112 "VUID-vkCmdCopyImage-dstOffset-01784"); // dstOffset image transfer granularity
3113 m_commandBuffer->CopyImage(image_1.image(), VK_IMAGE_LAYOUT_GENERAL, image_2.image(), VK_IMAGE_LAYOUT_GENERAL, 1, &copy_region);
3114 m_errorMonitor->VerifyFound();
3115 copy_region.dstOffset = {4, 1, 0}; // dest height
Mark Lobodzinski20310782020-02-28 14:25:17 -07003116 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, vuid);
3117 m_errorMonitor->SetDesiredFailureMsg(kErrorBit,
unknown088160a2019-05-23 17:43:13 -06003118 "VUID-vkCmdCopyImage-dstOffset-01784"); // dstOffset image transfer granularity
3119 m_commandBuffer->CopyImage(image_1.image(), VK_IMAGE_LAYOUT_GENERAL, image_2.image(), VK_IMAGE_LAYOUT_GENERAL, 1, &copy_region);
3120 m_errorMonitor->VerifyFound();
3121 copy_region.dstOffset = {0, 0, 0};
3122
3123 // Copy extent must be multiples of compressed block sizes {4, 4, 1} if not full width/height
Shannon McPherson2c793ba2020-08-28 12:13:24 -06003124 vuid = ycbcr ? "VUID-vkCmdCopyImage-srcImage-01728" : "VUID-vkCmdCopyImage-srcImage-01728";
unknown088160a2019-05-23 17:43:13 -06003125 copy_region.extent = {62, 60, 1}; // source width
Mark Lobodzinski20310782020-02-28 14:25:17 -07003126 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, vuid);
3127 m_errorMonitor->SetDesiredFailureMsg(kErrorBit,
unknown088160a2019-05-23 17:43:13 -06003128 "VUID-vkCmdCopyImage-srcOffset-01783"); // src extent image transfer granularity
3129 m_commandBuffer->CopyImage(image_1.image(), VK_IMAGE_LAYOUT_GENERAL, image_2.image(), VK_IMAGE_LAYOUT_GENERAL, 1, &copy_region);
3130 m_errorMonitor->VerifyFound();
Shannon McPherson2c793ba2020-08-28 12:13:24 -06003131 vuid = ycbcr ? "VUID-vkCmdCopyImage-srcImage-01729" : "VUID-vkCmdCopyImage-srcImage-01729";
unknown088160a2019-05-23 17:43:13 -06003132 copy_region.extent = {60, 62, 1}; // source height
Mark Lobodzinski20310782020-02-28 14:25:17 -07003133 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, vuid);
3134 m_errorMonitor->SetDesiredFailureMsg(kErrorBit,
unknown088160a2019-05-23 17:43:13 -06003135 "VUID-vkCmdCopyImage-srcOffset-01783"); // src extent image transfer granularity
3136 m_commandBuffer->CopyImage(image_1.image(), VK_IMAGE_LAYOUT_GENERAL, image_2.image(), VK_IMAGE_LAYOUT_GENERAL, 1, &copy_region);
3137 m_errorMonitor->VerifyFound();
3138
Shannon McPherson2c793ba2020-08-28 12:13:24 -06003139 vuid = ycbcr ? "VUID-vkCmdCopyImage-dstImage-01732" : "VUID-vkCmdCopyImage-dstImage-01732";
unknown088160a2019-05-23 17:43:13 -06003140 copy_region.extent = {62, 60, 1}; // dest width
Mark Lobodzinski20310782020-02-28 14:25:17 -07003141 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, vuid);
3142 m_errorMonitor->SetDesiredFailureMsg(kErrorBit,
unknown088160a2019-05-23 17:43:13 -06003143 "VUID-vkCmdCopyImage-dstOffset-01784"); // dst extent image transfer granularity
3144 m_commandBuffer->CopyImage(image_2.image(), VK_IMAGE_LAYOUT_GENERAL, image_1.image(), VK_IMAGE_LAYOUT_GENERAL, 1, &copy_region);
3145 m_errorMonitor->VerifyFound();
Shannon McPherson2c793ba2020-08-28 12:13:24 -06003146 vuid = ycbcr ? "VUID-vkCmdCopyImage-dstImage-01733" : "VUID-vkCmdCopyImage-dstImage-01733";
unknown088160a2019-05-23 17:43:13 -06003147 copy_region.extent = {60, 62, 1}; // dest height
Mark Lobodzinski20310782020-02-28 14:25:17 -07003148 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, vuid);
3149 m_errorMonitor->SetDesiredFailureMsg(kErrorBit,
unknown088160a2019-05-23 17:43:13 -06003150 "VUID-vkCmdCopyImage-dstOffset-01784"); // dst extent image transfer granularity
3151 m_commandBuffer->CopyImage(image_2.image(), VK_IMAGE_LAYOUT_GENERAL, image_1.image(), VK_IMAGE_LAYOUT_GENERAL, 1, &copy_region);
3152 m_errorMonitor->VerifyFound();
3153
Shannon McPherson2c793ba2020-08-28 12:13:24 -06003154 // Note: "VUID-vkCmdCopyImage-srcImage-01730", "VUID-vkCmdCopyImage-dstImage-01734", "VUID-vkCmdCopyImage-srcImage-01730",
3155 // "VUID-vkCmdCopyImage-dstImage-01734"
unknown088160a2019-05-23 17:43:13 -06003156 // There are currently no supported compressed formats with a block depth other than 1,
3157 // so impossible to create a 'not a multiple' condition for depth.
3158 m_commandBuffer->end();
3159}
3160
3161TEST_F(VkLayerTest, CopyImageSinglePlane422Alignment) {
3162 // Image copy tests on single-plane _422 formats with block alignment errors
3163
3164 // Enable KHR multiplane req'd extensions
3165 bool mp_extensions = InstanceExtensionSupported(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME,
3166 VK_KHR_GET_MEMORY_REQUIREMENTS_2_SPEC_VERSION);
3167 if (mp_extensions) {
3168 m_instance_extension_names.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
3169 }
Mark Lobodzinski09ce9c42020-03-06 10:02:44 -07003170 ASSERT_NO_FATAL_FAILURE(InitFramework(m_errorMonitor));
unknown088160a2019-05-23 17:43:13 -06003171 mp_extensions = mp_extensions && DeviceExtensionSupported(gpu(), nullptr, VK_KHR_MAINTENANCE1_EXTENSION_NAME);
3172 mp_extensions = mp_extensions && DeviceExtensionSupported(gpu(), nullptr, VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME);
3173 mp_extensions = mp_extensions && DeviceExtensionSupported(gpu(), nullptr, VK_KHR_BIND_MEMORY_2_EXTENSION_NAME);
3174 mp_extensions = mp_extensions && DeviceExtensionSupported(gpu(), nullptr, VK_KHR_SAMPLER_YCBCR_CONVERSION_EXTENSION_NAME);
3175 if (mp_extensions) {
3176 m_device_extension_names.push_back(VK_KHR_MAINTENANCE1_EXTENSION_NAME);
3177 m_device_extension_names.push_back(VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME);
3178 m_device_extension_names.push_back(VK_KHR_BIND_MEMORY_2_EXTENSION_NAME);
3179 m_device_extension_names.push_back(VK_KHR_SAMPLER_YCBCR_CONVERSION_EXTENSION_NAME);
3180 } else {
3181 printf("%s test requires KHR multiplane extensions, not available. Skipping.\n", kSkipPrefix);
3182 return;
3183 }
3184 ASSERT_NO_FATAL_FAILURE(InitState());
3185
3186 // Select a _422 format and verify support
3187 VkImageCreateInfo ci = {};
3188 ci.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
3189 ci.pNext = NULL;
3190 ci.flags = 0;
3191 ci.imageType = VK_IMAGE_TYPE_2D;
3192 ci.format = VK_FORMAT_G8B8G8R8_422_UNORM_KHR;
3193 ci.tiling = VK_IMAGE_TILING_OPTIMAL;
3194 ci.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
3195 ci.mipLevels = 1;
3196 ci.arrayLayers = 1;
3197 ci.samples = VK_SAMPLE_COUNT_1_BIT;
3198 ci.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
3199 ci.queueFamilyIndexCount = 0;
3200 ci.pQueueFamilyIndices = NULL;
3201 ci.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
3202
3203 // Verify formats
3204 VkFormatFeatureFlags features = VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT;
3205 bool supported = ImageFormatAndFeaturesSupported(instance(), gpu(), ci, features);
3206 if (!supported) {
3207 printf("%s Single-plane _422 image format not supported. Skipping test.\n", kSkipPrefix);
3208 return; // Assume there's low ROI on searching for different mp formats
3209 }
3210
3211 // Create images
3212 ci.extent = {64, 64, 1};
3213 VkImageObj image_422(m_device);
3214 image_422.init(&ci);
3215 ASSERT_TRUE(image_422.initialized());
3216
3217 ci.extent = {64, 64, 1};
3218 ci.format = VK_FORMAT_R8G8B8A8_UNORM;
3219 VkImageObj image_ucmp(m_device);
3220 image_ucmp.init(&ci);
3221 ASSERT_TRUE(image_ucmp.initialized());
3222
3223 m_commandBuffer->begin();
3224
3225 VkImageCopy copy_region;
3226 copy_region.extent = {48, 48, 1};
3227 copy_region.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
3228 copy_region.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
3229 copy_region.srcSubresource.mipLevel = 0;
3230 copy_region.dstSubresource.mipLevel = 0;
3231 copy_region.srcSubresource.baseArrayLayer = 0;
3232 copy_region.dstSubresource.baseArrayLayer = 0;
3233 copy_region.srcSubresource.layerCount = 1;
3234 copy_region.dstSubresource.layerCount = 1;
3235 copy_region.srcOffset = {0, 0, 0};
3236 copy_region.dstOffset = {0, 0, 0};
3237
3238 // Src offsets must be multiples of compressed block sizes
3239 copy_region.srcOffset = {3, 4, 0}; // source offset x
Shannon McPherson2c793ba2020-08-28 12:13:24 -06003240 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdCopyImage-srcImage-01727");
Mark Lobodzinski20310782020-02-28 14:25:17 -07003241 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdCopyImage-srcOffset-01783");
unknown088160a2019-05-23 17:43:13 -06003242 m_commandBuffer->CopyImage(image_422.image(), VK_IMAGE_LAYOUT_GENERAL, image_ucmp.image(), VK_IMAGE_LAYOUT_GENERAL, 1,
3243 &copy_region);
3244 m_errorMonitor->VerifyFound();
3245 copy_region.srcOffset = {0, 0, 0};
3246
3247 // Dst offsets must be multiples of compressed block sizes
3248 copy_region.dstOffset = {1, 0, 0};
Shannon McPherson2c793ba2020-08-28 12:13:24 -06003249 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdCopyImage-dstImage-01731");
Mark Lobodzinski20310782020-02-28 14:25:17 -07003250 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdCopyImage-dstOffset-01784");
Shannon McPherson2c793ba2020-08-28 12:13:24 -06003251 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdCopyImage-dstOffset-00150");
unknown088160a2019-05-23 17:43:13 -06003252 m_commandBuffer->CopyImage(image_ucmp.image(), VK_IMAGE_LAYOUT_GENERAL, image_422.image(), VK_IMAGE_LAYOUT_GENERAL, 1,
3253 &copy_region);
3254 m_errorMonitor->VerifyFound();
3255 copy_region.dstOffset = {0, 0, 0};
3256
3257 // Copy extent must be multiples of compressed block sizes if not full width/height
3258 copy_region.extent = {31, 60, 1}; // 422 source, extent.x
Shannon McPherson2c793ba2020-08-28 12:13:24 -06003259 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdCopyImage-srcImage-01728");
Mark Lobodzinski20310782020-02-28 14:25:17 -07003260 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdCopyImage-srcOffset-01783");
unknown088160a2019-05-23 17:43:13 -06003261 m_commandBuffer->CopyImage(image_422.image(), VK_IMAGE_LAYOUT_GENERAL, image_ucmp.image(), VK_IMAGE_LAYOUT_GENERAL, 1,
3262 &copy_region);
3263 m_errorMonitor->VerifyFound();
3264
unknown357e1782019-09-25 17:57:40 -06003265 // 422 dest
unknown088160a2019-05-23 17:43:13 -06003266 m_commandBuffer->CopyImage(image_ucmp.image(), VK_IMAGE_LAYOUT_GENERAL, image_422.image(), VK_IMAGE_LAYOUT_GENERAL, 1,
3267 &copy_region);
unknown357e1782019-09-25 17:57:40 -06003268 m_errorMonitor->VerifyNotFound();
unknown088160a2019-05-23 17:43:13 -06003269 copy_region.dstOffset = {0, 0, 0};
3270
3271 m_commandBuffer->end();
3272}
3273
3274TEST_F(VkLayerTest, CopyImageMultiplaneAspectBits) {
3275 // Image copy tests on multiplane images with aspect errors
3276
3277 // Enable KHR multiplane req'd extensions
3278 bool mp_extensions = InstanceExtensionSupported(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME,
3279 VK_KHR_GET_MEMORY_REQUIREMENTS_2_SPEC_VERSION);
3280 if (mp_extensions) {
3281 m_instance_extension_names.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
3282 }
Mark Lobodzinski09ce9c42020-03-06 10:02:44 -07003283 ASSERT_NO_FATAL_FAILURE(InitFramework(m_errorMonitor));
unknown088160a2019-05-23 17:43:13 -06003284 mp_extensions = mp_extensions && DeviceExtensionSupported(gpu(), nullptr, VK_KHR_MAINTENANCE1_EXTENSION_NAME);
3285 mp_extensions = mp_extensions && DeviceExtensionSupported(gpu(), nullptr, VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME);
3286 mp_extensions = mp_extensions && DeviceExtensionSupported(gpu(), nullptr, VK_KHR_BIND_MEMORY_2_EXTENSION_NAME);
3287 mp_extensions = mp_extensions && DeviceExtensionSupported(gpu(), nullptr, VK_KHR_SAMPLER_YCBCR_CONVERSION_EXTENSION_NAME);
3288 if (mp_extensions) {
3289 m_device_extension_names.push_back(VK_KHR_MAINTENANCE1_EXTENSION_NAME);
3290 m_device_extension_names.push_back(VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME);
3291 m_device_extension_names.push_back(VK_KHR_BIND_MEMORY_2_EXTENSION_NAME);
3292 m_device_extension_names.push_back(VK_KHR_SAMPLER_YCBCR_CONVERSION_EXTENSION_NAME);
3293 } else {
3294 printf("%s test requires KHR multiplane extensions, not available. Skipping.\n", kSkipPrefix);
3295 return;
3296 }
3297 ASSERT_NO_FATAL_FAILURE(InitState());
3298
3299 // Select multi-plane formats and verify support
3300 VkFormat mp3_format = VK_FORMAT_G8_B8_R8_3PLANE_422_UNORM_KHR;
3301 VkFormat mp2_format = VK_FORMAT_G8_B8R8_2PLANE_422_UNORM_KHR;
3302
3303 VkImageCreateInfo ci = {};
3304 ci.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
3305 ci.pNext = NULL;
3306 ci.flags = 0;
3307 ci.imageType = VK_IMAGE_TYPE_2D;
3308 ci.format = mp2_format;
3309 ci.extent = {256, 256, 1};
3310 ci.tiling = VK_IMAGE_TILING_OPTIMAL;
3311 ci.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
3312 ci.mipLevels = 1;
3313 ci.arrayLayers = 1;
3314 ci.samples = VK_SAMPLE_COUNT_1_BIT;
3315 ci.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
3316 ci.queueFamilyIndexCount = 0;
3317 ci.pQueueFamilyIndices = NULL;
3318 ci.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
3319
3320 // Verify formats
3321 VkFormatFeatureFlags features = VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT;
3322 bool supported = ImageFormatAndFeaturesSupported(instance(), gpu(), ci, features);
3323 ci.format = VK_FORMAT_D24_UNORM_S8_UINT;
3324 supported = supported && ImageFormatAndFeaturesSupported(instance(), gpu(), ci, features);
3325 ci.format = mp3_format;
3326 supported = supported && ImageFormatAndFeaturesSupported(instance(), gpu(), ci, features);
3327 if (!supported) {
3328 printf("%s Multiplane image formats or optimally tiled depth-stencil buffers not supported. Skipping test.\n",
3329 kSkipPrefix);
3330 return; // Assume there's low ROI on searching for different mp formats
3331 }
3332
3333 // Create images
3334 VkImageObj mp3_image(m_device);
3335 mp3_image.init(&ci);
3336 ASSERT_TRUE(mp3_image.initialized());
3337
3338 ci.format = mp2_format;
3339 VkImageObj mp2_image(m_device);
3340 mp2_image.init(&ci);
3341 ASSERT_TRUE(mp2_image.initialized());
3342
3343 ci.format = VK_FORMAT_D24_UNORM_S8_UINT;
3344 VkImageObj sp_image(m_device);
3345 sp_image.init(&ci);
3346 ASSERT_TRUE(sp_image.initialized());
3347
3348 m_commandBuffer->begin();
3349
3350 VkImageCopy copy_region;
3351 copy_region.extent = {128, 128, 1};
3352 copy_region.srcSubresource.aspectMask = VK_IMAGE_ASPECT_PLANE_2_BIT_KHR;
3353 copy_region.dstSubresource.aspectMask = VK_IMAGE_ASPECT_PLANE_2_BIT_KHR;
3354 copy_region.srcSubresource.mipLevel = 0;
3355 copy_region.dstSubresource.mipLevel = 0;
3356 copy_region.srcSubresource.baseArrayLayer = 0;
3357 copy_region.dstSubresource.baseArrayLayer = 0;
3358 copy_region.srcSubresource.layerCount = 1;
3359 copy_region.dstSubresource.layerCount = 1;
3360 copy_region.srcOffset = {0, 0, 0};
3361 copy_region.dstOffset = {0, 0, 0};
3362
Shannon McPherson2c793ba2020-08-28 12:13:24 -06003363 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdCopyImage-srcImage-01552");
unknown088160a2019-05-23 17:43:13 -06003364 m_commandBuffer->CopyImage(mp2_image.image(), VK_IMAGE_LAYOUT_GENERAL, mp3_image.image(), VK_IMAGE_LAYOUT_GENERAL, 1,
3365 &copy_region);
3366 m_errorMonitor->VerifyFound();
3367
unknown088160a2019-05-23 17:43:13 -06003368 copy_region.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
3369 copy_region.dstSubresource.aspectMask = VK_IMAGE_ASPECT_PLANE_0_BIT_KHR;
Shannon McPherson2c793ba2020-08-28 12:13:24 -06003370 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdCopyImage-srcImage-01553");
unknown088160a2019-05-23 17:43:13 -06003371 m_commandBuffer->CopyImage(mp3_image.image(), VK_IMAGE_LAYOUT_GENERAL, mp2_image.image(), VK_IMAGE_LAYOUT_GENERAL, 1,
3372 &copy_region);
3373 m_errorMonitor->VerifyFound();
3374
3375 copy_region.srcSubresource.aspectMask = VK_IMAGE_ASPECT_PLANE_1_BIT_KHR;
3376 copy_region.dstSubresource.aspectMask = VK_IMAGE_ASPECT_PLANE_2_BIT_KHR;
Shannon McPherson2c793ba2020-08-28 12:13:24 -06003377 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdCopyImage-dstImage-01554");
unknown088160a2019-05-23 17:43:13 -06003378 m_commandBuffer->CopyImage(mp3_image.image(), VK_IMAGE_LAYOUT_GENERAL, mp2_image.image(), VK_IMAGE_LAYOUT_GENERAL, 1,
3379 &copy_region);
3380 m_errorMonitor->VerifyFound();
3381
3382 copy_region.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
Shannon McPherson2c793ba2020-08-28 12:13:24 -06003383 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdCopyImage-dstImage-01555");
unknown088160a2019-05-23 17:43:13 -06003384 m_commandBuffer->CopyImage(mp2_image.image(), VK_IMAGE_LAYOUT_GENERAL, mp3_image.image(), VK_IMAGE_LAYOUT_GENERAL, 1,
3385 &copy_region);
3386 m_errorMonitor->VerifyFound();
3387
3388 copy_region.dstSubresource.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT;
Shannon McPherson2c793ba2020-08-28 12:13:24 -06003389 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdCopyImage-srcImage-01556");
sfricke-samsung99dc12c2020-04-23 01:52:01 -07003390 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdCopyImage-None-01549"); // since also non-compatiable
unknown088160a2019-05-23 17:43:13 -06003391 m_commandBuffer->CopyImage(mp2_image.image(), VK_IMAGE_LAYOUT_GENERAL, sp_image.image(), VK_IMAGE_LAYOUT_GENERAL, 1,
3392 &copy_region);
3393 m_errorMonitor->VerifyFound();
3394
3395 copy_region.srcSubresource.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT;
3396 copy_region.dstSubresource.aspectMask = VK_IMAGE_ASPECT_PLANE_2_BIT_KHR;
Shannon McPherson2c793ba2020-08-28 12:13:24 -06003397 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdCopyImage-dstImage-01557");
sfricke-samsung99dc12c2020-04-23 01:52:01 -07003398 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdCopyImage-None-01549"); // since also non-compatiable
unknown088160a2019-05-23 17:43:13 -06003399 m_commandBuffer->CopyImage(sp_image.image(), VK_IMAGE_LAYOUT_GENERAL, mp3_image.image(), VK_IMAGE_LAYOUT_GENERAL, 1,
3400 &copy_region);
3401 m_errorMonitor->VerifyFound();
3402
3403 m_commandBuffer->end();
3404}
3405
3406TEST_F(VkLayerTest, CopyImageSrcSizeExceeded) {
3407 // Image copy with source region specified greater than src image size
3408 ASSERT_NO_FATAL_FAILURE(Init());
3409
3410 // Create images with full mip chain
3411 VkImageCreateInfo ci;
3412 ci.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
3413 ci.pNext = NULL;
3414 ci.flags = 0;
3415 ci.imageType = VK_IMAGE_TYPE_3D;
3416 ci.format = VK_FORMAT_R8G8B8A8_UNORM;
3417 ci.extent = {32, 32, 8};
3418 ci.mipLevels = 6;
3419 ci.arrayLayers = 1;
3420 ci.samples = VK_SAMPLE_COUNT_1_BIT;
3421 ci.tiling = VK_IMAGE_TILING_OPTIMAL;
3422 ci.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
3423 ci.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
3424 ci.queueFamilyIndexCount = 0;
3425 ci.pQueueFamilyIndices = NULL;
3426 ci.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
3427
3428 VkImageObj src_image(m_device);
3429 src_image.init(&ci);
3430 ASSERT_TRUE(src_image.initialized());
3431
3432 // Dest image with one more mip level
3433 ci.extent = {64, 64, 16};
3434 ci.mipLevels = 7;
3435 ci.usage = VK_IMAGE_USAGE_TRANSFER_DST_BIT;
3436 VkImageObj dst_image(m_device);
3437 dst_image.init(&ci);
3438 ASSERT_TRUE(dst_image.initialized());
3439
3440 m_commandBuffer->begin();
3441
3442 VkImageCopy copy_region;
3443 copy_region.extent = {32, 32, 8};
3444 copy_region.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
3445 copy_region.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
3446 copy_region.srcSubresource.mipLevel = 0;
3447 copy_region.dstSubresource.mipLevel = 0;
3448 copy_region.srcSubresource.baseArrayLayer = 0;
3449 copy_region.dstSubresource.baseArrayLayer = 0;
3450 copy_region.srcSubresource.layerCount = 1;
3451 copy_region.dstSubresource.layerCount = 1;
3452 copy_region.srcOffset = {0, 0, 0};
3453 copy_region.dstOffset = {0, 0, 0};
3454
3455 m_errorMonitor->ExpectSuccess();
3456 m_commandBuffer->CopyImage(src_image.image(), VK_IMAGE_LAYOUT_GENERAL, dst_image.image(), VK_IMAGE_LAYOUT_GENERAL, 1,
3457 &copy_region);
3458 m_errorMonitor->VerifyNotFound();
3459
3460 // Source exceeded in x-dim, VU 01202
3461 copy_region.srcOffset.x = 4;
Shannon McPherson2c793ba2020-08-28 12:13:24 -06003462 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdCopyImage-srcOffset-00144");
unknown088160a2019-05-23 17:43:13 -06003463 m_commandBuffer->CopyImage(src_image.image(), VK_IMAGE_LAYOUT_GENERAL, dst_image.image(), VK_IMAGE_LAYOUT_GENERAL, 1,
3464 &copy_region);
3465 m_errorMonitor->VerifyFound();
3466
3467 // Source exceeded in y-dim, VU 01203
3468 copy_region.srcOffset.x = 0;
3469 copy_region.extent.height = 48;
Shannon McPherson2c793ba2020-08-28 12:13:24 -06003470 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdCopyImage-srcOffset-00145");
unknown088160a2019-05-23 17:43:13 -06003471 m_commandBuffer->CopyImage(src_image.image(), VK_IMAGE_LAYOUT_GENERAL, dst_image.image(), VK_IMAGE_LAYOUT_GENERAL, 1,
3472 &copy_region);
3473 m_errorMonitor->VerifyFound();
3474
3475 // Source exceeded in z-dim, VU 01204
3476 copy_region.extent = {4, 4, 4};
3477 copy_region.srcSubresource.mipLevel = 2;
Shannon McPherson2c793ba2020-08-28 12:13:24 -06003478 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdCopyImage-srcOffset-00147");
unknown088160a2019-05-23 17:43:13 -06003479 m_commandBuffer->CopyImage(src_image.image(), VK_IMAGE_LAYOUT_GENERAL, dst_image.image(), VK_IMAGE_LAYOUT_GENERAL, 1,
3480 &copy_region);
3481 m_errorMonitor->VerifyFound();
3482
3483 m_commandBuffer->end();
3484}
3485
3486TEST_F(VkLayerTest, CopyImageDstSizeExceeded) {
3487 // Image copy with dest region specified greater than dest image size
3488 ASSERT_NO_FATAL_FAILURE(Init());
3489
3490 // Create images with full mip chain
3491 VkImageCreateInfo ci;
3492 ci.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
3493 ci.pNext = NULL;
3494 ci.flags = 0;
3495 ci.imageType = VK_IMAGE_TYPE_3D;
3496 ci.format = VK_FORMAT_R8G8B8A8_UNORM;
3497 ci.extent = {32, 32, 8};
3498 ci.mipLevels = 6;
3499 ci.arrayLayers = 1;
3500 ci.samples = VK_SAMPLE_COUNT_1_BIT;
3501 ci.tiling = VK_IMAGE_TILING_OPTIMAL;
3502 ci.usage = VK_IMAGE_USAGE_TRANSFER_DST_BIT;
3503 ci.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
3504 ci.queueFamilyIndexCount = 0;
3505 ci.pQueueFamilyIndices = NULL;
3506 ci.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
3507
3508 VkImageObj dst_image(m_device);
3509 dst_image.init(&ci);
3510 ASSERT_TRUE(dst_image.initialized());
3511
3512 // Src image with one more mip level
3513 ci.extent = {64, 64, 16};
3514 ci.mipLevels = 7;
3515 ci.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
3516 VkImageObj src_image(m_device);
3517 src_image.init(&ci);
3518 ASSERT_TRUE(src_image.initialized());
3519
3520 m_commandBuffer->begin();
3521
3522 VkImageCopy copy_region;
3523 copy_region.extent = {32, 32, 8};
3524 copy_region.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
3525 copy_region.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
3526 copy_region.srcSubresource.mipLevel = 0;
3527 copy_region.dstSubresource.mipLevel = 0;
3528 copy_region.srcSubresource.baseArrayLayer = 0;
3529 copy_region.dstSubresource.baseArrayLayer = 0;
3530 copy_region.srcSubresource.layerCount = 1;
3531 copy_region.dstSubresource.layerCount = 1;
3532 copy_region.srcOffset = {0, 0, 0};
3533 copy_region.dstOffset = {0, 0, 0};
3534
3535 m_errorMonitor->ExpectSuccess();
3536 m_commandBuffer->CopyImage(src_image.image(), VK_IMAGE_LAYOUT_GENERAL, dst_image.image(), VK_IMAGE_LAYOUT_GENERAL, 1,
3537 &copy_region);
3538 m_errorMonitor->VerifyNotFound();
3539
3540 // Dest exceeded in x-dim, VU 01205
3541 copy_region.dstOffset.x = 4;
Shannon McPherson2c793ba2020-08-28 12:13:24 -06003542 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdCopyImage-dstOffset-00150");
unknown088160a2019-05-23 17:43:13 -06003543 m_commandBuffer->CopyImage(src_image.image(), VK_IMAGE_LAYOUT_GENERAL, dst_image.image(), VK_IMAGE_LAYOUT_GENERAL, 1,
3544 &copy_region);
3545 m_errorMonitor->VerifyFound();
3546
3547 // Dest exceeded in y-dim, VU 01206
3548 copy_region.dstOffset.x = 0;
3549 copy_region.extent.height = 48;
Shannon McPherson2c793ba2020-08-28 12:13:24 -06003550 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdCopyImage-dstOffset-00151");
unknown088160a2019-05-23 17:43:13 -06003551 m_commandBuffer->CopyImage(src_image.image(), VK_IMAGE_LAYOUT_GENERAL, dst_image.image(), VK_IMAGE_LAYOUT_GENERAL, 1,
3552 &copy_region);
3553 m_errorMonitor->VerifyFound();
3554
3555 // Dest exceeded in z-dim, VU 01207
3556 copy_region.extent = {4, 4, 4};
3557 copy_region.dstSubresource.mipLevel = 2;
Shannon McPherson2c793ba2020-08-28 12:13:24 -06003558 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdCopyImage-dstOffset-00153");
unknown088160a2019-05-23 17:43:13 -06003559 m_commandBuffer->CopyImage(src_image.image(), VK_IMAGE_LAYOUT_GENERAL, dst_image.image(), VK_IMAGE_LAYOUT_GENERAL, 1,
3560 &copy_region);
3561 m_errorMonitor->VerifyFound();
3562
3563 m_commandBuffer->end();
3564}
3565
sfricke-samsung8ceaaea2020-03-07 14:08:08 -08003566TEST_F(VkLayerTest, CopyImageMultiPlaneSizeExceeded) {
3567 TEST_DESCRIPTION("Image Copy for multi-planar format that exceed size of plane for both src and dst");
3568
3569 // Enable KHR multiplane req'd extensions
3570 bool mp_extensions = InstanceExtensionSupported(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME,
3571 VK_KHR_GET_MEMORY_REQUIREMENTS_2_SPEC_VERSION);
3572 if (mp_extensions == true) {
3573 m_instance_extension_names.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
3574 }
3575 ASSERT_NO_FATAL_FAILURE(InitFramework(m_errorMonitor));
3576 mp_extensions = mp_extensions && DeviceExtensionSupported(gpu(), nullptr, VK_KHR_MAINTENANCE1_EXTENSION_NAME);
3577 mp_extensions = mp_extensions && DeviceExtensionSupported(gpu(), nullptr, VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME);
3578 mp_extensions = mp_extensions && DeviceExtensionSupported(gpu(), nullptr, VK_KHR_BIND_MEMORY_2_EXTENSION_NAME);
3579 mp_extensions = mp_extensions && DeviceExtensionSupported(gpu(), nullptr, VK_KHR_SAMPLER_YCBCR_CONVERSION_EXTENSION_NAME);
3580 if (mp_extensions == true) {
3581 m_device_extension_names.push_back(VK_KHR_MAINTENANCE1_EXTENSION_NAME);
3582 m_device_extension_names.push_back(VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME);
3583 m_device_extension_names.push_back(VK_KHR_BIND_MEMORY_2_EXTENSION_NAME);
3584 m_device_extension_names.push_back(VK_KHR_SAMPLER_YCBCR_CONVERSION_EXTENSION_NAME);
3585 } else {
3586 printf("%s test requires KHR multiplane extensions, not available. Skipping.\n", kSkipPrefix);
3587 return;
3588 }
3589 ASSERT_NO_FATAL_FAILURE(InitState());
3590
sfricke-samsung99dc12c2020-04-23 01:52:01 -07003591 // Try to use VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM because need multi-plane format for some tests and likely supported due to
3592 // copy support being required with samplerYcbcrConversion feature
sfricke-samsung8ceaaea2020-03-07 14:08:08 -08003593 VkFormatProperties props = {0, 0, 0};
3594 bool missing_format_support = false;
sfricke-samsung99dc12c2020-04-23 01:52:01 -07003595 vk::GetPhysicalDeviceFormatProperties(m_device->phy().handle(), VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM, &props);
sfricke-samsung8ceaaea2020-03-07 14:08:08 -08003596 missing_format_support |= (props.bufferFeatures == 0 && props.linearTilingFeatures == 0 && props.optimalTilingFeatures == 0);
3597 missing_format_support |= (props.optimalTilingFeatures & VK_FORMAT_FEATURE_TRANSFER_SRC_BIT) == 0;
3598 missing_format_support |= (props.optimalTilingFeatures & VK_FORMAT_FEATURE_TRANSFER_DST_BIT) == 0;
3599
3600 if (missing_format_support == true) {
sfricke-samsung99dc12c2020-04-23 01:52:01 -07003601 printf("%s VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM transfer not supported; skipped.\n", kSkipPrefix);
sfricke-samsung8ceaaea2020-03-07 14:08:08 -08003602 return;
3603 }
3604
3605 // 128^2 texels in plane_0 and 64^2 texels in plane_1
3606 VkImageObj src_image(m_device);
3607 VkImageObj dst_image(m_device);
sfricke-samsung99dc12c2020-04-23 01:52:01 -07003608 src_image.Init(128, 128, 1, VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM, VK_IMAGE_USAGE_TRANSFER_SRC_BIT, VK_IMAGE_TILING_OPTIMAL, 0);
sfricke-samsung8ceaaea2020-03-07 14:08:08 -08003609 ASSERT_TRUE(src_image.initialized());
sfricke-samsung99dc12c2020-04-23 01:52:01 -07003610 dst_image.Init(128, 128, 1, VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM, VK_IMAGE_USAGE_TRANSFER_DST_BIT, VK_IMAGE_TILING_OPTIMAL, 0);
sfricke-samsung8ceaaea2020-03-07 14:08:08 -08003611 ASSERT_TRUE(dst_image.initialized());
3612
3613 VkImageCopy copy_region = {};
3614 copy_region.extent = {64, 64, 1}; // Size of plane 1
3615 copy_region.srcSubresource.aspectMask = VK_IMAGE_ASPECT_PLANE_1_BIT;
3616 copy_region.dstSubresource.aspectMask = VK_IMAGE_ASPECT_PLANE_1_BIT;
3617 copy_region.srcSubresource.mipLevel = 0;
3618 copy_region.dstSubresource.mipLevel = 0;
3619 copy_region.srcSubresource.baseArrayLayer = 0;
3620 copy_region.dstSubresource.baseArrayLayer = 0;
3621 copy_region.srcSubresource.layerCount = 1;
3622 copy_region.dstSubresource.layerCount = 1;
3623 copy_region.srcOffset = {0, 0, 0};
3624 copy_region.dstOffset = {0, 0, 0};
3625 VkImageCopy original_region = copy_region;
3626
3627 m_commandBuffer->begin();
3628
3629 // Should be able to do a 64x64 copy from plane 1 -> Plane 1
3630 m_errorMonitor->ExpectSuccess();
3631 m_commandBuffer->CopyImage(src_image.image(), VK_IMAGE_LAYOUT_GENERAL, dst_image.image(), VK_IMAGE_LAYOUT_GENERAL, 1,
3632 &copy_region);
3633 m_errorMonitor->VerifyNotFound();
3634
3635 // Should be able to do a 64x64 copy from plane 0 -> Plane 0
3636 copy_region.srcSubresource.aspectMask = VK_IMAGE_ASPECT_PLANE_0_BIT;
3637 copy_region.dstSubresource.aspectMask = VK_IMAGE_ASPECT_PLANE_0_BIT;
3638 m_errorMonitor->ExpectSuccess();
3639 m_commandBuffer->CopyImage(src_image.image(), VK_IMAGE_LAYOUT_GENERAL, dst_image.image(), VK_IMAGE_LAYOUT_GENERAL, 1,
3640 &copy_region);
3641 m_errorMonitor->VerifyNotFound();
3642
Mark Lobodzinski07d0a612020-12-30 15:42:31 -07003643 VkMemoryBarrier mem_barrier = LvlInitStruct<VkMemoryBarrier>();
locke-lunargdf00db02020-03-04 19:00:57 -07003644 mem_barrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
3645 mem_barrier.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
3646
sfricke-samsung8ceaaea2020-03-07 14:08:08 -08003647 // Should be able to do a 64x64 copy from plane 0 -> Plane 1
3648 copy_region.srcSubresource.aspectMask = VK_IMAGE_ASPECT_PLANE_0_BIT;
3649 copy_region.dstSubresource.aspectMask = VK_IMAGE_ASPECT_PLANE_1_BIT;
3650 m_errorMonitor->ExpectSuccess();
locke-lunargdf00db02020-03-04 19:00:57 -07003651 vk::CmdPipelineBarrier(m_commandBuffer->handle(), VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, 1,
3652 &mem_barrier, 0, nullptr, 0, nullptr);
sfricke-samsung8ceaaea2020-03-07 14:08:08 -08003653 m_commandBuffer->CopyImage(src_image.image(), VK_IMAGE_LAYOUT_GENERAL, dst_image.image(), VK_IMAGE_LAYOUT_GENERAL, 1,
3654 &copy_region);
3655 m_errorMonitor->VerifyNotFound();
3656
3657 // Should be able to do a 64x64 copy from plane 0 -> Plane 1
3658 copy_region.srcSubresource.aspectMask = VK_IMAGE_ASPECT_PLANE_1_BIT;
3659 copy_region.dstSubresource.aspectMask = VK_IMAGE_ASPECT_PLANE_0_BIT;
3660 m_errorMonitor->ExpectSuccess();
locke-lunargdf00db02020-03-04 19:00:57 -07003661 vk::CmdPipelineBarrier(m_commandBuffer->handle(), VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, 1,
3662 &mem_barrier, 0, nullptr, 0, nullptr);
sfricke-samsung8ceaaea2020-03-07 14:08:08 -08003663 m_commandBuffer->CopyImage(src_image.image(), VK_IMAGE_LAYOUT_GENERAL, dst_image.image(), VK_IMAGE_LAYOUT_GENERAL, 1,
3664 &copy_region);
3665 m_errorMonitor->VerifyNotFound();
3666
3667 // Should be able to do a 128x64 copy from plane 0 -> Plane 0
3668 copy_region.extent = {128, 64, 1};
3669 copy_region.srcSubresource.aspectMask = VK_IMAGE_ASPECT_PLANE_0_BIT;
3670 copy_region.dstSubresource.aspectMask = VK_IMAGE_ASPECT_PLANE_0_BIT;
3671 m_errorMonitor->ExpectSuccess();
locke-lunargdf00db02020-03-04 19:00:57 -07003672 vk::CmdPipelineBarrier(m_commandBuffer->handle(), VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, 1,
3673 &mem_barrier, 0, nullptr, 0, nullptr);
sfricke-samsung8ceaaea2020-03-07 14:08:08 -08003674 m_commandBuffer->CopyImage(src_image.image(), VK_IMAGE_LAYOUT_GENERAL, dst_image.image(), VK_IMAGE_LAYOUT_GENERAL, 1,
3675 &copy_region);
3676 m_errorMonitor->VerifyNotFound();
3677
3678 // 128x64 copy from plane 0 -> Plane 1
3679 copy_region.extent = {128, 64, 1};
3680 copy_region.srcSubresource.aspectMask = VK_IMAGE_ASPECT_PLANE_0_BIT;
3681 copy_region.dstSubresource.aspectMask = VK_IMAGE_ASPECT_PLANE_1_BIT;
Shannon McPherson2c793ba2020-08-28 12:13:24 -06003682 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdCopyImage-dstOffset-00150");
sfricke-samsung8ceaaea2020-03-07 14:08:08 -08003683 m_commandBuffer->CopyImage(src_image.image(), VK_IMAGE_LAYOUT_GENERAL, dst_image.image(), VK_IMAGE_LAYOUT_GENERAL, 1,
3684 &copy_region);
3685 m_errorMonitor->VerifyFound();
3686
3687 // 128x64 copy from plane 1 -> Plane 0
3688 copy_region.extent = {128, 64, 1};
3689 copy_region.srcSubresource.aspectMask = VK_IMAGE_ASPECT_PLANE_1_BIT;
3690 copy_region.dstSubresource.aspectMask = VK_IMAGE_ASPECT_PLANE_0_BIT;
Shannon McPherson2c793ba2020-08-28 12:13:24 -06003691 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdCopyImage-srcOffset-00144");
sfricke-samsung8ceaaea2020-03-07 14:08:08 -08003692 m_commandBuffer->CopyImage(src_image.image(), VK_IMAGE_LAYOUT_GENERAL, dst_image.image(), VK_IMAGE_LAYOUT_GENERAL, 1,
3693 &copy_region);
3694 m_errorMonitor->VerifyFound();
3695
3696 // src exceeded in y-dim from offset
3697 copy_region = original_region;
3698 copy_region.srcOffset.y = 4;
Shannon McPherson2c793ba2020-08-28 12:13:24 -06003699 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdCopyImage-srcOffset-00145");
sfricke-samsung8ceaaea2020-03-07 14:08:08 -08003700 m_commandBuffer->CopyImage(src_image.image(), VK_IMAGE_LAYOUT_GENERAL, dst_image.image(), VK_IMAGE_LAYOUT_GENERAL, 1,
3701 &copy_region);
3702 m_errorMonitor->VerifyFound();
3703
3704 // dst exceeded in y-dim from offset
3705 copy_region = original_region;
3706 copy_region.dstOffset.y = 4;
Shannon McPherson2c793ba2020-08-28 12:13:24 -06003707 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdCopyImage-dstOffset-00151");
sfricke-samsung8ceaaea2020-03-07 14:08:08 -08003708 m_commandBuffer->CopyImage(src_image.image(), VK_IMAGE_LAYOUT_GENERAL, dst_image.image(), VK_IMAGE_LAYOUT_GENERAL, 1,
3709 &copy_region);
3710 m_errorMonitor->VerifyFound();
3711
3712 m_commandBuffer->end();
3713}
3714
unknown088160a2019-05-23 17:43:13 -06003715TEST_F(VkLayerTest, CopyImageFormatSizeMismatch) {
sfricke-samsung51067b22020-04-30 21:41:17 -07003716 if (!EnableDeviceProfileLayer()) {
3717 printf("%s Failed to enable device profile layer.\n", kSkipPrefix);
3718 return;
3719 }
unknown088160a2019-05-23 17:43:13 -06003720
sfricke-samsung8ceaaea2020-03-07 14:08:08 -08003721 // Enable KHR multiplane req'd extensions
3722 bool mp_extensions = InstanceExtensionSupported(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME,
3723 VK_KHR_GET_MEMORY_REQUIREMENTS_2_SPEC_VERSION);
3724 if (mp_extensions == true) {
3725 m_instance_extension_names.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
3726 }
3727 ASSERT_NO_FATAL_FAILURE(InitFramework(m_errorMonitor));
3728 mp_extensions = mp_extensions && DeviceExtensionSupported(gpu(), nullptr, VK_KHR_MAINTENANCE1_EXTENSION_NAME);
3729 mp_extensions = mp_extensions && DeviceExtensionSupported(gpu(), nullptr, VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME);
3730 mp_extensions = mp_extensions && DeviceExtensionSupported(gpu(), nullptr, VK_KHR_BIND_MEMORY_2_EXTENSION_NAME);
3731 mp_extensions = mp_extensions && DeviceExtensionSupported(gpu(), nullptr, VK_KHR_SAMPLER_YCBCR_CONVERSION_EXTENSION_NAME);
3732 if (mp_extensions == true) {
3733 m_device_extension_names.push_back(VK_KHR_MAINTENANCE1_EXTENSION_NAME);
3734 m_device_extension_names.push_back(VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME);
3735 m_device_extension_names.push_back(VK_KHR_BIND_MEMORY_2_EXTENSION_NAME);
3736 m_device_extension_names.push_back(VK_KHR_SAMPLER_YCBCR_CONVERSION_EXTENSION_NAME);
3737 }
3738 ASSERT_NO_FATAL_FAILURE(InitState());
unknown088160a2019-05-23 17:43:13 -06003739
sfricke-samsung51067b22020-04-30 21:41:17 -07003740 PFN_vkSetPhysicalDeviceFormatPropertiesEXT fpvkSetPhysicalDeviceFormatPropertiesEXT = nullptr;
3741 PFN_vkGetOriginalPhysicalDeviceFormatPropertiesEXT fpvkGetOriginalPhysicalDeviceFormatPropertiesEXT = nullptr;
sfricke-samsungdce5f692020-03-07 13:59:31 -08003742
sfricke-samsung51067b22020-04-30 21:41:17 -07003743 // Load required functions
3744 if (!LoadDeviceProfileLayer(fpvkSetPhysicalDeviceFormatPropertiesEXT, fpvkGetOriginalPhysicalDeviceFormatPropertiesEXT)) {
3745 printf("%s Failed to device profile layer.\n", kSkipPrefix);
3746 return;
3747 }
3748
3749 // Set transfer for all potential used formats
3750 VkFormatProperties format_props;
3751 fpvkGetOriginalPhysicalDeviceFormatPropertiesEXT(gpu(), VK_FORMAT_R8_UNORM, &format_props);
3752 format_props.optimalTilingFeatures |= (VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT);
3753 fpvkSetPhysicalDeviceFormatPropertiesEXT(gpu(), VK_FORMAT_R8_UNORM, format_props);
3754
3755 fpvkGetOriginalPhysicalDeviceFormatPropertiesEXT(gpu(), VK_FORMAT_R8_UINT, &format_props);
3756 format_props.optimalTilingFeatures |= (VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT);
3757 fpvkSetPhysicalDeviceFormatPropertiesEXT(gpu(), VK_FORMAT_R8_UINT, format_props);
unknown088160a2019-05-23 17:43:13 -06003758
3759 VkImageCreateInfo image_create_info = {};
3760 image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
3761 image_create_info.pNext = NULL;
3762 image_create_info.imageType = VK_IMAGE_TYPE_2D;
unknown088160a2019-05-23 17:43:13 -06003763 image_create_info.extent.width = 32;
3764 image_create_info.extent.height = 32;
3765 image_create_info.extent.depth = 1;
3766 image_create_info.mipLevels = 1;
3767 image_create_info.arrayLayers = 1;
3768 image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
sfricke-samsung51067b22020-04-30 21:41:17 -07003769 image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL;
3770 image_create_info.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
unknown088160a2019-05-23 17:43:13 -06003771 image_create_info.flags = 0;
3772
sfricke-samsung51067b22020-04-30 21:41:17 -07003773 image_create_info.format = VK_FORMAT_R8_UNORM;
3774 VkImageObj image_8b_unorm(m_device);
3775 image_8b_unorm.init(&image_create_info);
unknown088160a2019-05-23 17:43:13 -06003776
sfricke-samsung51067b22020-04-30 21:41:17 -07003777 image_create_info.format = VK_FORMAT_R8_UINT;
3778 VkImageObj image_8b_uint(m_device);
3779 image_8b_uint.init(&image_create_info);
3780
3781 // First try to test two single plane mismatch
3782 {
3783 fpvkGetOriginalPhysicalDeviceFormatPropertiesEXT(gpu(), VK_FORMAT_R8G8B8A8_UNORM, &format_props);
3784 format_props.optimalTilingFeatures |= (VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT);
3785 fpvkSetPhysicalDeviceFormatPropertiesEXT(gpu(), VK_FORMAT_R8G8B8A8_UNORM, format_props);
3786
3787 image_create_info.format = VK_FORMAT_R8G8B8A8_UNORM;
3788 VkImageObj image_32b_unorm(m_device);
3789 image_32b_unorm.init(&image_create_info);
3790
3791 m_commandBuffer->begin();
3792 VkImageCopy copyRegion;
3793 copyRegion.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
3794 copyRegion.srcSubresource.mipLevel = 0;
3795 copyRegion.srcSubresource.baseArrayLayer = 0;
3796 copyRegion.srcSubresource.layerCount = 1;
3797 copyRegion.srcOffset.x = 0;
3798 copyRegion.srcOffset.y = 0;
3799 copyRegion.srcOffset.z = 0;
3800 copyRegion.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
3801 copyRegion.dstSubresource.mipLevel = 0;
3802 copyRegion.dstSubresource.baseArrayLayer = 0;
3803 copyRegion.dstSubresource.layerCount = 1;
3804 copyRegion.dstOffset.x = 0;
3805 copyRegion.dstOffset.y = 0;
3806 copyRegion.dstOffset.z = 0;
3807 copyRegion.extent.width = 1;
3808 copyRegion.extent.height = 1;
3809 copyRegion.extent.depth = 1;
3810
3811 // Sanity check between two 8bit formats
3812 m_errorMonitor->ExpectSuccess();
3813 m_commandBuffer->CopyImage(image_8b_unorm.handle(), VK_IMAGE_LAYOUT_GENERAL, image_8b_uint.handle(),
3814 VK_IMAGE_LAYOUT_GENERAL, 1, &copyRegion);
3815 m_errorMonitor->VerifyNotFound();
3816
3817 const char *vuid = (mp_extensions) ? "VUID-vkCmdCopyImage-srcImage-01548" : "VUID-vkCmdCopyImage-srcImage-00135";
3818 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, vuid);
3819 m_commandBuffer->CopyImage(image_8b_unorm.handle(), VK_IMAGE_LAYOUT_GENERAL, image_32b_unorm.handle(),
3820 VK_IMAGE_LAYOUT_GENERAL, 1, &copyRegion);
3821 m_errorMonitor->VerifyFound();
3822
3823 // Swap src and dst
3824 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, vuid);
3825 m_commandBuffer->CopyImage(image_32b_unorm.handle(), VK_IMAGE_LAYOUT_GENERAL, image_8b_unorm.handle(),
3826 VK_IMAGE_LAYOUT_GENERAL, 1, &copyRegion);
3827 m_errorMonitor->VerifyFound();
3828
3829 m_commandBuffer->end();
unknown088160a2019-05-23 17:43:13 -06003830 }
3831
sfricke-samsung51067b22020-04-30 21:41:17 -07003832 // DstImage is a mismatched plane of a multi-planar format
3833 if (mp_extensions == false) {
3834 printf("%s No multi-planar support; section of tests skipped.\n", kSkipPrefix);
3835 } else {
3836 fpvkGetOriginalPhysicalDeviceFormatPropertiesEXT(gpu(), VK_FORMAT_G8_B8R8_2PLANE_420_UNORM, &format_props);
3837 format_props.optimalTilingFeatures |= (VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT);
3838 fpvkSetPhysicalDeviceFormatPropertiesEXT(gpu(), VK_FORMAT_G8_B8R8_2PLANE_420_UNORM, format_props);
unknown088160a2019-05-23 17:43:13 -06003839
sfricke-samsung51067b22020-04-30 21:41:17 -07003840 image_create_info.format = VK_FORMAT_G8_B8R8_2PLANE_420_UNORM;
3841 VkImageObj image_8b_16b_420_unorm(m_device);
3842 image_8b_16b_420_unorm.init(&image_create_info);
unknown088160a2019-05-23 17:43:13 -06003843
sfricke-samsung51067b22020-04-30 21:41:17 -07003844 m_commandBuffer->begin();
3845 VkImageCopy copyRegion;
3846 copyRegion.srcSubresource.mipLevel = 0;
3847 copyRegion.srcSubresource.baseArrayLayer = 0;
3848 copyRegion.srcSubresource.layerCount = 1;
3849 copyRegion.srcOffset.x = 0;
3850 copyRegion.srcOffset.y = 0;
3851 copyRegion.srcOffset.z = 0;
3852 copyRegion.dstSubresource.mipLevel = 0;
3853 copyRegion.dstSubresource.baseArrayLayer = 0;
3854 copyRegion.dstSubresource.layerCount = 1;
3855 copyRegion.dstOffset.x = 0;
3856 copyRegion.dstOffset.y = 0;
3857 copyRegion.dstOffset.z = 0;
3858 copyRegion.extent.width = 1;
3859 copyRegion.extent.height = 1;
3860 copyRegion.extent.depth = 1;
unknown088160a2019-05-23 17:43:13 -06003861
sfricke-samsung51067b22020-04-30 21:41:17 -07003862 // First test single-plane -> multi-plan
3863 copyRegion.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
3864 copyRegion.dstSubresource.aspectMask = VK_IMAGE_ASPECT_PLANE_0_BIT;
unknown088160a2019-05-23 17:43:13 -06003865
sfricke-samsung51067b22020-04-30 21:41:17 -07003866 // Plane 0 is VK_FORMAT_R8_UNORM so this should succeed
3867 m_errorMonitor->ExpectSuccess();
3868 m_commandBuffer->CopyImage(image_8b_unorm.handle(), VK_IMAGE_LAYOUT_GENERAL, image_8b_16b_420_unorm.handle(),
3869 VK_IMAGE_LAYOUT_GENERAL, 1, &copyRegion);
3870 m_errorMonitor->VerifyNotFound();
unknown088160a2019-05-23 17:43:13 -06003871
locke-lunargdf00db02020-03-04 19:00:57 -07003872 image_8b_16b_420_unorm.ImageMemoryBarrier(m_commandBuffer, VK_IMAGE_ASPECT_PLANE_0_BIT, VK_ACCESS_TRANSFER_WRITE_BIT,
3873 VK_ACCESS_TRANSFER_WRITE_BIT, VK_IMAGE_LAYOUT_GENERAL);
3874
sfricke-samsung51067b22020-04-30 21:41:17 -07003875 // Make sure no false postiives if Compatible format
3876 m_errorMonitor->ExpectSuccess();
3877 m_commandBuffer->CopyImage(image_8b_uint.handle(), VK_IMAGE_LAYOUT_GENERAL, image_8b_16b_420_unorm.handle(),
3878 VK_IMAGE_LAYOUT_GENERAL, 1, &copyRegion);
3879 m_errorMonitor->VerifyNotFound();
unknown088160a2019-05-23 17:43:13 -06003880
sfricke-samsung51067b22020-04-30 21:41:17 -07003881 // Plane 1 is VK_FORMAT_R8G8_UNORM so this should fail
3882 copyRegion.dstSubresource.aspectMask = VK_IMAGE_ASPECT_PLANE_1_BIT;
3883 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdCopyImage-None-01549");
3884 m_commandBuffer->CopyImage(image_8b_unorm.handle(), VK_IMAGE_LAYOUT_GENERAL, image_8b_16b_420_unorm.handle(),
3885 VK_IMAGE_LAYOUT_GENERAL, 1, &copyRegion);
3886 m_errorMonitor->VerifyFound();
unknown088160a2019-05-23 17:43:13 -06003887
sfricke-samsung51067b22020-04-30 21:41:17 -07003888 // Same tests but swap src and dst
3889 copyRegion.srcSubresource.aspectMask = VK_IMAGE_ASPECT_PLANE_0_BIT;
3890 copyRegion.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
sfricke-samsungdce5f692020-03-07 13:59:31 -08003891
locke-lunargdf00db02020-03-04 19:00:57 -07003892 image_8b_unorm.ImageMemoryBarrier(m_commandBuffer, VK_IMAGE_ASPECT_COLOR_BIT, VK_ACCESS_TRANSFER_READ_BIT,
3893 VK_ACCESS_TRANSFER_WRITE_BIT, VK_IMAGE_LAYOUT_GENERAL);
3894 image_8b_16b_420_unorm.ImageMemoryBarrier(m_commandBuffer, VK_IMAGE_ASPECT_PLANE_0_BIT, VK_ACCESS_TRANSFER_WRITE_BIT,
3895 VK_ACCESS_TRANSFER_READ_BIT, VK_IMAGE_LAYOUT_GENERAL);
3896
sfricke-samsung51067b22020-04-30 21:41:17 -07003897 m_errorMonitor->ExpectSuccess();
3898 m_commandBuffer->CopyImage(image_8b_16b_420_unorm.handle(), VK_IMAGE_LAYOUT_GENERAL, image_8b_unorm.handle(),
3899 VK_IMAGE_LAYOUT_GENERAL, 1, &copyRegion);
3900 m_errorMonitor->VerifyNotFound();
3901
locke-lunargdf00db02020-03-04 19:00:57 -07003902 image_8b_16b_420_unorm.ImageMemoryBarrier(m_commandBuffer, VK_IMAGE_ASPECT_PLANE_0_BIT, VK_ACCESS_TRANSFER_WRITE_BIT,
3903 VK_ACCESS_TRANSFER_READ_BIT, VK_IMAGE_LAYOUT_GENERAL);
3904
sfricke-samsung51067b22020-04-30 21:41:17 -07003905 m_errorMonitor->ExpectSuccess();
3906 m_commandBuffer->CopyImage(image_8b_16b_420_unorm.handle(), VK_IMAGE_LAYOUT_GENERAL, image_8b_uint.handle(),
3907 VK_IMAGE_LAYOUT_GENERAL, 1, &copyRegion);
3908 m_errorMonitor->VerifyNotFound();
3909
3910 copyRegion.srcSubresource.aspectMask = VK_IMAGE_ASPECT_PLANE_1_BIT;
3911 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdCopyImage-None-01549");
3912 m_commandBuffer->CopyImage(image_8b_16b_420_unorm.handle(), VK_IMAGE_LAYOUT_GENERAL, image_8b_unorm.handle(),
3913 VK_IMAGE_LAYOUT_GENERAL, 1, &copyRegion);
3914 m_errorMonitor->VerifyFound();
3915
3916 m_commandBuffer->end();
3917 }
unknown088160a2019-05-23 17:43:13 -06003918}
3919
3920TEST_F(VkLayerTest, CopyImageDepthStencilFormatMismatch) {
3921 ASSERT_NO_FATAL_FAILURE(Init());
3922 auto depth_format = FindSupportedDepthStencilFormat(gpu());
3923 if (!depth_format) {
3924 printf("%s Couldn't depth stencil image format.\n", kSkipPrefix);
3925 return;
3926 }
3927
3928 VkFormatProperties properties;
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06003929 vk::GetPhysicalDeviceFormatProperties(m_device->phy().handle(), VK_FORMAT_D32_SFLOAT, &properties);
unknown088160a2019-05-23 17:43:13 -06003930 if (properties.optimalTilingFeatures == 0) {
3931 printf("%s Image format not supported; skipped.\n", kSkipPrefix);
3932 return;
3933 }
3934
3935 VkImageObj srcImage(m_device);
3936 srcImage.Init(32, 32, 1, VK_FORMAT_D32_SFLOAT, VK_IMAGE_USAGE_TRANSFER_SRC_BIT, VK_IMAGE_TILING_OPTIMAL);
3937 ASSERT_TRUE(srcImage.initialized());
3938 VkImageObj dstImage(m_device);
3939 dstImage.Init(32, 32, 1, depth_format, VK_IMAGE_USAGE_TRANSFER_DST_BIT, VK_IMAGE_TILING_OPTIMAL);
3940 ASSERT_TRUE(dstImage.initialized());
3941
3942 // Create two images of different types and try to copy between them
3943
3944 m_commandBuffer->begin();
3945 VkImageCopy copyRegion;
3946 copyRegion.srcSubresource.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT;
3947 copyRegion.srcSubresource.mipLevel = 0;
3948 copyRegion.srcSubresource.baseArrayLayer = 0;
3949 copyRegion.srcSubresource.layerCount = 1;
3950 copyRegion.srcOffset.x = 0;
3951 copyRegion.srcOffset.y = 0;
3952 copyRegion.srcOffset.z = 0;
3953 copyRegion.dstSubresource.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT;
3954 copyRegion.dstSubresource.mipLevel = 0;
3955 copyRegion.dstSubresource.baseArrayLayer = 0;
3956 copyRegion.dstSubresource.layerCount = 1;
3957 copyRegion.dstOffset.x = 0;
3958 copyRegion.dstOffset.y = 0;
3959 copyRegion.dstOffset.z = 0;
3960 copyRegion.extent.width = 1;
3961 copyRegion.extent.height = 1;
3962 copyRegion.extent.depth = 1;
3963
sfricke-samsung99dc12c2020-04-23 01:52:01 -07003964 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdCopyImage-srcImage-00135");
unknown088160a2019-05-23 17:43:13 -06003965 m_commandBuffer->CopyImage(srcImage.handle(), VK_IMAGE_LAYOUT_GENERAL, dstImage.handle(), VK_IMAGE_LAYOUT_GENERAL, 1,
3966 &copyRegion);
3967 m_commandBuffer->end();
3968
3969 m_errorMonitor->VerifyFound();
3970}
3971
3972TEST_F(VkLayerTest, CopyImageSampleCountMismatch) {
3973 TEST_DESCRIPTION("Image copies with sample count mis-matches");
3974
3975 ASSERT_NO_FATAL_FAILURE(Init());
3976
3977 VkImageFormatProperties image_format_properties;
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06003978 vk::GetPhysicalDeviceImageFormatProperties(gpu(), VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_TYPE_2D, VK_IMAGE_TILING_OPTIMAL,
3979 VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT, 0,
3980 &image_format_properties);
unknown088160a2019-05-23 17:43:13 -06003981
3982 if ((0 == (VK_SAMPLE_COUNT_2_BIT & image_format_properties.sampleCounts)) ||
3983 (0 == (VK_SAMPLE_COUNT_4_BIT & image_format_properties.sampleCounts))) {
3984 printf("%s Image multi-sample support not found; skipped.\n", kSkipPrefix);
3985 return;
3986 }
3987
3988 VkImageCreateInfo ci;
3989 ci.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
3990 ci.pNext = NULL;
3991 ci.flags = 0;
3992 ci.imageType = VK_IMAGE_TYPE_2D;
3993 ci.format = VK_FORMAT_R8G8B8A8_UNORM;
3994 ci.extent = {128, 128, 1};
3995 ci.mipLevels = 1;
3996 ci.arrayLayers = 1;
3997 ci.samples = VK_SAMPLE_COUNT_1_BIT;
3998 ci.tiling = VK_IMAGE_TILING_OPTIMAL;
3999 ci.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
4000 ci.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
4001 ci.queueFamilyIndexCount = 0;
4002 ci.pQueueFamilyIndices = NULL;
4003 ci.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
4004
4005 VkImageObj image1(m_device);
4006 image1.init(&ci);
4007 ASSERT_TRUE(image1.initialized());
4008
4009 ci.samples = VK_SAMPLE_COUNT_2_BIT;
4010 VkImageObj image2(m_device);
4011 image2.init(&ci);
4012 ASSERT_TRUE(image2.initialized());
4013
4014 ci.samples = VK_SAMPLE_COUNT_4_BIT;
4015 VkImageObj image4(m_device);
4016 image4.init(&ci);
4017 ASSERT_TRUE(image4.initialized());
4018
4019 m_commandBuffer->begin();
4020
4021 VkImageCopy copyRegion;
4022 copyRegion.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
4023 copyRegion.srcSubresource.mipLevel = 0;
4024 copyRegion.srcSubresource.baseArrayLayer = 0;
4025 copyRegion.srcSubresource.layerCount = 1;
4026 copyRegion.srcOffset = {0, 0, 0};
4027 copyRegion.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
4028 copyRegion.dstSubresource.mipLevel = 0;
4029 copyRegion.dstSubresource.baseArrayLayer = 0;
4030 copyRegion.dstSubresource.layerCount = 1;
4031 copyRegion.dstOffset = {0, 0, 0};
4032 copyRegion.extent = {128, 128, 1};
4033
4034 // Copy a single sample image to/from a multi-sample image
Mark Lobodzinski20310782020-02-28 14:25:17 -07004035 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdCopyImage-srcImage-00136");
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06004036 vk::CmdCopyImage(m_commandBuffer->handle(), image1.handle(), VK_IMAGE_LAYOUT_GENERAL, image4.handle(), VK_IMAGE_LAYOUT_GENERAL,
4037 1, &copyRegion);
unknown088160a2019-05-23 17:43:13 -06004038 m_errorMonitor->VerifyFound();
4039
Mark Lobodzinski20310782020-02-28 14:25:17 -07004040 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdCopyImage-srcImage-00136");
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06004041 vk::CmdCopyImage(m_commandBuffer->handle(), image2.handle(), VK_IMAGE_LAYOUT_GENERAL, image1.handle(), VK_IMAGE_LAYOUT_GENERAL,
4042 1, &copyRegion);
unknown088160a2019-05-23 17:43:13 -06004043 m_errorMonitor->VerifyFound();
4044
4045 // Copy between multi-sample images with different sample counts
Mark Lobodzinski20310782020-02-28 14:25:17 -07004046 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdCopyImage-srcImage-00136");
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06004047 vk::CmdCopyImage(m_commandBuffer->handle(), image2.handle(), VK_IMAGE_LAYOUT_GENERAL, image4.handle(), VK_IMAGE_LAYOUT_GENERAL,
4048 1, &copyRegion);
unknown088160a2019-05-23 17:43:13 -06004049 m_errorMonitor->VerifyFound();
4050
Mark Lobodzinski20310782020-02-28 14:25:17 -07004051 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdCopyImage-srcImage-00136");
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06004052 vk::CmdCopyImage(m_commandBuffer->handle(), image4.handle(), VK_IMAGE_LAYOUT_GENERAL, image2.handle(), VK_IMAGE_LAYOUT_GENERAL,
4053 1, &copyRegion);
unknown088160a2019-05-23 17:43:13 -06004054 m_errorMonitor->VerifyFound();
4055
4056 m_commandBuffer->end();
4057}
4058
4059TEST_F(VkLayerTest, CopyImageAspectMismatch) {
4060 TEST_DESCRIPTION("Image copies with aspect mask errors");
sfricke-samsung99dc12c2020-04-23 01:52:01 -07004061
4062 if (!EnableDeviceProfileLayer()) {
4063 printf("%s Failed to enable device profile layer.\n", kSkipPrefix);
4064 return;
4065 }
4066
4067 bool mp_extensions = InstanceExtensionSupported(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME, 1);
4068 if (mp_extensions) {
4069 m_instance_extension_names.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
4070 }
4071
4072 ASSERT_NO_FATAL_FAILURE(InitFramework(m_errorMonitor));
4073 mp_extensions = mp_extensions && DeviceExtensionSupported(gpu(), nullptr, VK_KHR_MAINTENANCE1_EXTENSION_NAME);
4074 mp_extensions = mp_extensions && DeviceExtensionSupported(gpu(), nullptr, VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME);
4075 mp_extensions = mp_extensions && DeviceExtensionSupported(gpu(), nullptr, VK_KHR_BIND_MEMORY_2_EXTENSION_NAME);
4076 mp_extensions = mp_extensions && DeviceExtensionSupported(gpu(), nullptr, VK_KHR_SAMPLER_YCBCR_CONVERSION_EXTENSION_NAME);
4077 if (mp_extensions) {
4078 m_device_extension_names.push_back(VK_KHR_MAINTENANCE1_EXTENSION_NAME);
4079 m_device_extension_names.push_back(VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME);
4080 m_device_extension_names.push_back(VK_KHR_BIND_MEMORY_2_EXTENSION_NAME);
4081 m_device_extension_names.push_back(VK_KHR_SAMPLER_YCBCR_CONVERSION_EXTENSION_NAME);
4082 }
4083 ASSERT_NO_FATAL_FAILURE(InitState());
4084
4085 PFN_vkSetPhysicalDeviceFormatPropertiesEXT fpvkSetPhysicalDeviceFormatPropertiesEXT = nullptr;
4086 PFN_vkGetOriginalPhysicalDeviceFormatPropertiesEXT fpvkGetOriginalPhysicalDeviceFormatPropertiesEXT = nullptr;
4087
4088 if (!LoadDeviceProfileLayer(fpvkSetPhysicalDeviceFormatPropertiesEXT, fpvkGetOriginalPhysicalDeviceFormatPropertiesEXT)) {
4089 printf("%s Required extensions are not avaiable.\n", kSkipPrefix);
4090 return;
4091 }
4092
unknown088160a2019-05-23 17:43:13 -06004093 auto ds_format = FindSupportedDepthStencilFormat(gpu());
4094 if (!ds_format) {
4095 printf("%s Couldn't find depth stencil format.\n", kSkipPrefix);
4096 return;
4097 }
4098
sfricke-samsung99dc12c2020-04-23 01:52:01 -07004099 // Add Transfer support for all used formats
4100 VkFormatProperties formatProps;
4101 fpvkGetOriginalPhysicalDeviceFormatPropertiesEXT(gpu(), VK_FORMAT_R32_SFLOAT, &formatProps);
4102 formatProps.optimalTilingFeatures |= (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT);
4103 fpvkSetPhysicalDeviceFormatPropertiesEXT(gpu(), VK_FORMAT_R32_SFLOAT, formatProps);
4104 fpvkGetOriginalPhysicalDeviceFormatPropertiesEXT(gpu(), VK_FORMAT_D32_SFLOAT, &formatProps);
4105 formatProps.optimalTilingFeatures |= (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT);
4106 fpvkSetPhysicalDeviceFormatPropertiesEXT(gpu(), VK_FORMAT_R32_SFLOAT, formatProps);
4107 fpvkGetOriginalPhysicalDeviceFormatPropertiesEXT(gpu(), ds_format, &formatProps);
4108 formatProps.optimalTilingFeatures |= (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT);
4109 fpvkSetPhysicalDeviceFormatPropertiesEXT(gpu(), ds_format, formatProps);
4110
unknown088160a2019-05-23 17:43:13 -06004111 VkImageObj color_image(m_device), ds_image(m_device), depth_image(m_device);
4112 color_image.Init(128, 128, 1, VK_FORMAT_R32_SFLOAT, VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT);
4113 depth_image.Init(128, 128, 1, VK_FORMAT_D32_SFLOAT, VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT,
4114 VK_IMAGE_TILING_OPTIMAL, 0);
4115 ds_image.Init(128, 128, 1, ds_format, VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT,
4116 VK_IMAGE_TILING_OPTIMAL, 0);
4117 ASSERT_TRUE(color_image.initialized());
4118 ASSERT_TRUE(depth_image.initialized());
4119 ASSERT_TRUE(ds_image.initialized());
4120
4121 VkImageCopy copyRegion;
4122 copyRegion.srcSubresource.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT;
4123 copyRegion.srcSubresource.mipLevel = 0;
4124 copyRegion.srcSubresource.baseArrayLayer = 0;
4125 copyRegion.srcSubresource.layerCount = 1;
4126 copyRegion.srcOffset = {0, 0, 0};
4127 copyRegion.dstSubresource.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT;
4128 copyRegion.dstSubresource.mipLevel = 0;
4129 copyRegion.dstSubresource.baseArrayLayer = 0;
4130 copyRegion.dstSubresource.layerCount = 1;
4131 copyRegion.dstOffset = {64, 0, 0};
4132 copyRegion.extent = {64, 128, 1};
4133
4134 // Submitting command before command buffer is in recording state
Mark Lobodzinski20310782020-02-28 14:25:17 -07004135 m_errorMonitor->SetDesiredFailureMsg(kErrorBit,
unknown088160a2019-05-23 17:43:13 -06004136 "You must call vkBeginCommandBuffer"); // "VUID-vkCmdCopyImage-commandBuffer-recording");
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06004137 vk::CmdCopyImage(m_commandBuffer->handle(), depth_image.handle(), VK_IMAGE_LAYOUT_GENERAL, depth_image.handle(),
4138 VK_IMAGE_LAYOUT_GENERAL, 1, &copyRegion);
unknown088160a2019-05-23 17:43:13 -06004139 m_errorMonitor->VerifyFound();
4140
4141 m_commandBuffer->begin();
4142
4143 // Src and dest aspect masks don't match
4144 copyRegion.dstSubresource.aspectMask = VK_IMAGE_ASPECT_STENCIL_BIT;
Shannon McPherson2c793ba2020-08-28 12:13:24 -06004145 const char *vuid = mp_extensions ? "VUID-vkCmdCopyImage-srcImage-01551" : "VUID-VkImageCopy-aspectMask-00137";
Mark Lobodzinski20310782020-02-28 14:25:17 -07004146 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, vuid);
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06004147 vk::CmdCopyImage(m_commandBuffer->handle(), ds_image.handle(), VK_IMAGE_LAYOUT_GENERAL, ds_image.handle(),
4148 VK_IMAGE_LAYOUT_GENERAL, 1, &copyRegion);
unknown088160a2019-05-23 17:43:13 -06004149 m_errorMonitor->VerifyFound();
4150 copyRegion.dstSubresource.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT;
4151
4152 // Illegal combinations of aspect bits
4153 copyRegion.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT | VK_IMAGE_ASPECT_DEPTH_BIT; // color must be alone
4154 copyRegion.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
Mark Lobodzinski20310782020-02-28 14:25:17 -07004155 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkImageSubresourceLayers-aspectMask-00167");
unknown088160a2019-05-23 17:43:13 -06004156 // These aspect/format mismatches are redundant but unavoidable here
Shannon McPherson2c793ba2020-08-28 12:13:24 -06004157 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdCopyImage-aspectMask-00142");
Mark Lobodzinski20310782020-02-28 14:25:17 -07004158 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, vuid);
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06004159 vk::CmdCopyImage(m_commandBuffer->handle(), color_image.handle(), VK_IMAGE_LAYOUT_GENERAL, color_image.handle(),
4160 VK_IMAGE_LAYOUT_GENERAL, 1, &copyRegion);
unknown088160a2019-05-23 17:43:13 -06004161 m_errorMonitor->VerifyFound();
4162 // same test for dstSubresource
4163 copyRegion.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
4164 copyRegion.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT | VK_IMAGE_ASPECT_DEPTH_BIT; // color must be alone
Mark Lobodzinski20310782020-02-28 14:25:17 -07004165 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkImageSubresourceLayers-aspectMask-00167");
unknown088160a2019-05-23 17:43:13 -06004166 // These aspect/format mismatches are redundant but unavoidable here
Shannon McPherson2c793ba2020-08-28 12:13:24 -06004167 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdCopyImage-aspectMask-00143");
Mark Lobodzinski20310782020-02-28 14:25:17 -07004168 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, vuid);
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06004169 vk::CmdCopyImage(m_commandBuffer->handle(), color_image.handle(), VK_IMAGE_LAYOUT_GENERAL, color_image.handle(),
4170 VK_IMAGE_LAYOUT_GENERAL, 1, &copyRegion);
unknown088160a2019-05-23 17:43:13 -06004171 m_errorMonitor->VerifyFound();
4172
4173 // Metadata aspect is illegal
4174 copyRegion.srcSubresource.aspectMask = VK_IMAGE_ASPECT_METADATA_BIT;
4175 copyRegion.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
Mark Lobodzinski20310782020-02-28 14:25:17 -07004176 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkImageSubresourceLayers-aspectMask-00168");
unknown088160a2019-05-23 17:43:13 -06004177 // These aspect/format mismatches are redundant but unavoidable here
Mark Lobodzinski20310782020-02-28 14:25:17 -07004178 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, vuid);
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06004179 vk::CmdCopyImage(m_commandBuffer->handle(), color_image.handle(), VK_IMAGE_LAYOUT_GENERAL, color_image.handle(),
4180 VK_IMAGE_LAYOUT_GENERAL, 1, &copyRegion);
unknown088160a2019-05-23 17:43:13 -06004181 m_errorMonitor->VerifyFound();
4182 // same test for dstSubresource
4183 copyRegion.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
4184 copyRegion.dstSubresource.aspectMask = VK_IMAGE_ASPECT_METADATA_BIT;
Mark Lobodzinski20310782020-02-28 14:25:17 -07004185 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkImageSubresourceLayers-aspectMask-00168");
unknown088160a2019-05-23 17:43:13 -06004186 // These aspect/format mismatches are redundant but unavoidable here
Mark Lobodzinski20310782020-02-28 14:25:17 -07004187 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, vuid);
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06004188 vk::CmdCopyImage(m_commandBuffer->handle(), color_image.handle(), VK_IMAGE_LAYOUT_GENERAL, color_image.handle(),
4189 VK_IMAGE_LAYOUT_GENERAL, 1, &copyRegion);
unknown088160a2019-05-23 17:43:13 -06004190 m_errorMonitor->VerifyFound();
4191
sfricke-samsung6141db32020-10-26 03:31:38 -07004192 // Aspect Memory Plane mask is illegal
4193 copyRegion.srcSubresource.aspectMask = VK_IMAGE_ASPECT_MEMORY_PLANE_2_BIT_EXT;
4194 copyRegion.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
4195 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkImageSubresourceLayers-aspectMask-02247");
4196 // These aspect/format mismatches are redundant but unavoidable here
4197 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, vuid);
4198 vk::CmdCopyImage(m_commandBuffer->handle(), color_image.handle(), VK_IMAGE_LAYOUT_GENERAL, color_image.handle(),
4199 VK_IMAGE_LAYOUT_GENERAL, 1, &copyRegion);
4200 m_errorMonitor->VerifyFound();
4201
unknown088160a2019-05-23 17:43:13 -06004202 copyRegion.srcSubresource.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT;
4203 copyRegion.dstSubresource.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT;
sfricke-samsung99dc12c2020-04-23 01:52:01 -07004204 const char *compatible_vuid = mp_extensions ? "VUID-vkCmdCopyImage-srcImage-01548" : "VUID-vkCmdCopyImage-srcImage-00135";
unknown088160a2019-05-23 17:43:13 -06004205
4206 // Aspect mask doesn't match source image format
Shannon McPherson2c793ba2020-08-28 12:13:24 -06004207 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdCopyImage-aspectMask-00142");
unknown088160a2019-05-23 17:43:13 -06004208 // Again redundant but unavoidable
sfricke-samsung99dc12c2020-04-23 01:52:01 -07004209 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, compatible_vuid);
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06004210 vk::CmdCopyImage(m_commandBuffer->handle(), color_image.handle(), VK_IMAGE_LAYOUT_GENERAL, depth_image.handle(),
4211 VK_IMAGE_LAYOUT_GENERAL, 1, &copyRegion);
unknown088160a2019-05-23 17:43:13 -06004212 m_errorMonitor->VerifyFound();
4213
4214 // Aspect mask doesn't match dest image format
4215 copyRegion.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
4216 copyRegion.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
Shannon McPherson2c793ba2020-08-28 12:13:24 -06004217 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdCopyImage-aspectMask-00143");
unknown088160a2019-05-23 17:43:13 -06004218 // Again redundant but unavoidable
sfricke-samsung99dc12c2020-04-23 01:52:01 -07004219 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, compatible_vuid);
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06004220 vk::CmdCopyImage(m_commandBuffer->handle(), color_image.handle(), VK_IMAGE_LAYOUT_GENERAL, depth_image.handle(),
4221 VK_IMAGE_LAYOUT_GENERAL, 1, &copyRegion);
unknown088160a2019-05-23 17:43:13 -06004222 m_errorMonitor->VerifyFound();
4223
4224 m_commandBuffer->end();
4225}
4226
4227TEST_F(VkLayerTest, ResolveImageLowSampleCount) {
sfricke-samsungc26350e2020-05-30 12:31:31 -07004228 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdResolveImage-srcImage-00257");
unknown088160a2019-05-23 17:43:13 -06004229
4230 ASSERT_NO_FATAL_FAILURE(Init());
4231
4232 // Create two images of sample count 1 and try to Resolve between them
4233
4234 VkImageCreateInfo image_create_info = {};
4235 image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
4236 image_create_info.pNext = NULL;
4237 image_create_info.imageType = VK_IMAGE_TYPE_2D;
4238 image_create_info.format = VK_FORMAT_B8G8R8A8_UNORM;
4239 image_create_info.extent.width = 32;
4240 image_create_info.extent.height = 1;
4241 image_create_info.extent.depth = 1;
4242 image_create_info.mipLevels = 1;
4243 image_create_info.arrayLayers = 1;
4244 image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
4245 image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL;
4246 image_create_info.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
4247 image_create_info.flags = 0;
4248
4249 VkImageObj srcImage(m_device);
4250 srcImage.init(&image_create_info);
4251 ASSERT_TRUE(srcImage.initialized());
4252
4253 VkImageObj dstImage(m_device);
4254 dstImage.init(&image_create_info);
4255 ASSERT_TRUE(dstImage.initialized());
4256
4257 m_commandBuffer->begin();
4258 VkImageResolve resolveRegion;
4259 resolveRegion.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
4260 resolveRegion.srcSubresource.mipLevel = 0;
4261 resolveRegion.srcSubresource.baseArrayLayer = 0;
4262 resolveRegion.srcSubresource.layerCount = 1;
4263 resolveRegion.srcOffset.x = 0;
4264 resolveRegion.srcOffset.y = 0;
4265 resolveRegion.srcOffset.z = 0;
4266 resolveRegion.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
4267 resolveRegion.dstSubresource.mipLevel = 0;
4268 resolveRegion.dstSubresource.baseArrayLayer = 0;
4269 resolveRegion.dstSubresource.layerCount = 1;
4270 resolveRegion.dstOffset.x = 0;
4271 resolveRegion.dstOffset.y = 0;
4272 resolveRegion.dstOffset.z = 0;
4273 resolveRegion.extent.width = 1;
4274 resolveRegion.extent.height = 1;
4275 resolveRegion.extent.depth = 1;
4276 m_commandBuffer->ResolveImage(srcImage.handle(), VK_IMAGE_LAYOUT_GENERAL, dstImage.handle(), VK_IMAGE_LAYOUT_GENERAL, 1,
4277 &resolveRegion);
4278 m_commandBuffer->end();
4279
4280 m_errorMonitor->VerifyFound();
4281}
4282
4283TEST_F(VkLayerTest, ResolveImageHighSampleCount) {
sfricke-samsungc26350e2020-05-30 12:31:31 -07004284 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdResolveImage-dstImage-00259");
unknown088160a2019-05-23 17:43:13 -06004285
4286 ASSERT_NO_FATAL_FAILURE(Init());
4287
4288 // Create two images of sample count 4 and try to Resolve between them
4289
4290 VkImageCreateInfo image_create_info = {};
4291 image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
4292 image_create_info.pNext = NULL;
4293 image_create_info.imageType = VK_IMAGE_TYPE_2D;
4294 image_create_info.format = VK_FORMAT_B8G8R8A8_UNORM;
4295 image_create_info.extent.width = 32;
4296 image_create_info.extent.height = 1;
4297 image_create_info.extent.depth = 1;
4298 image_create_info.mipLevels = 1;
4299 image_create_info.arrayLayers = 1;
4300 image_create_info.samples = VK_SAMPLE_COUNT_4_BIT;
4301 image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL;
4302 // Note: Some implementations expect color attachment usage for any
4303 // multisample surface
4304 image_create_info.usage =
4305 VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
4306 image_create_info.flags = 0;
4307
4308 VkImageObj srcImage(m_device);
4309 srcImage.init(&image_create_info);
4310 ASSERT_TRUE(srcImage.initialized());
4311
4312 VkImageObj dstImage(m_device);
4313 dstImage.init(&image_create_info);
4314 ASSERT_TRUE(dstImage.initialized());
4315
4316 m_commandBuffer->begin();
4317 // Need memory barrier to VK_IMAGE_LAYOUT_GENERAL for source and dest?
4318 // VK_IMAGE_LAYOUT_UNDEFINED = 0,
4319 // VK_IMAGE_LAYOUT_GENERAL = 1,
4320 VkImageResolve resolveRegion;
4321 resolveRegion.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
4322 resolveRegion.srcSubresource.mipLevel = 0;
4323 resolveRegion.srcSubresource.baseArrayLayer = 0;
4324 resolveRegion.srcSubresource.layerCount = 1;
4325 resolveRegion.srcOffset.x = 0;
4326 resolveRegion.srcOffset.y = 0;
4327 resolveRegion.srcOffset.z = 0;
4328 resolveRegion.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
4329 resolveRegion.dstSubresource.mipLevel = 0;
4330 resolveRegion.dstSubresource.baseArrayLayer = 0;
4331 resolveRegion.dstSubresource.layerCount = 1;
4332 resolveRegion.dstOffset.x = 0;
4333 resolveRegion.dstOffset.y = 0;
4334 resolveRegion.dstOffset.z = 0;
4335 resolveRegion.extent.width = 1;
4336 resolveRegion.extent.height = 1;
4337 resolveRegion.extent.depth = 1;
4338 m_commandBuffer->ResolveImage(srcImage.handle(), VK_IMAGE_LAYOUT_GENERAL, dstImage.handle(), VK_IMAGE_LAYOUT_GENERAL, 1,
4339 &resolveRegion);
4340 m_commandBuffer->end();
4341
4342 m_errorMonitor->VerifyFound();
4343}
4344
4345TEST_F(VkLayerTest, ResolveImageFormatMismatch) {
sfricke-samsungc26350e2020-05-30 12:31:31 -07004346 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdResolveImage-srcImage-01386");
unknown088160a2019-05-23 17:43:13 -06004347
4348 ASSERT_NO_FATAL_FAILURE(Init());
4349
4350 // Create two images of different types and try to copy between them
locke-lunarg8e2c91b2019-06-11 17:53:26 -06004351 VkImageObj srcImage(m_device);
4352 VkImageObj dstImage(m_device);
unknown088160a2019-05-23 17:43:13 -06004353
4354 VkImageCreateInfo image_create_info = {};
4355 image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
4356 image_create_info.pNext = NULL;
4357 image_create_info.imageType = VK_IMAGE_TYPE_2D;
4358 image_create_info.format = VK_FORMAT_B8G8R8A8_UNORM;
4359 image_create_info.extent.width = 32;
4360 image_create_info.extent.height = 1;
4361 image_create_info.extent.depth = 1;
4362 image_create_info.mipLevels = 1;
4363 image_create_info.arrayLayers = 1;
sfricke-samsungf46582f2021-03-31 02:02:37 -07004364 image_create_info.samples = VK_SAMPLE_COUNT_4_BIT; // guarantee support from sampledImageColorSampleCounts
unknown088160a2019-05-23 17:43:13 -06004365 image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL;
4366 // Note: Some implementations expect color attachment usage for any
4367 // multisample surface
4368 image_create_info.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
4369 image_create_info.flags = 0;
locke-lunarg8e2c91b2019-06-11 17:53:26 -06004370 srcImage.init(&image_create_info);
unknown088160a2019-05-23 17:43:13 -06004371
4372 // Set format to something other than source image
4373 image_create_info.format = VK_FORMAT_R32_SFLOAT;
4374 // Note: Some implementations expect color attachment usage for any
4375 // multisample surface
4376 image_create_info.usage = VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
4377 image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
locke-lunarg8e2c91b2019-06-11 17:53:26 -06004378 dstImage.init(&image_create_info);
unknown088160a2019-05-23 17:43:13 -06004379
4380 m_commandBuffer->begin();
4381 // Need memory barrier to VK_IMAGE_LAYOUT_GENERAL for source and dest?
4382 // VK_IMAGE_LAYOUT_UNDEFINED = 0,
4383 // VK_IMAGE_LAYOUT_GENERAL = 1,
4384 VkImageResolve resolveRegion;
4385 resolveRegion.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
4386 resolveRegion.srcSubresource.mipLevel = 0;
4387 resolveRegion.srcSubresource.baseArrayLayer = 0;
4388 resolveRegion.srcSubresource.layerCount = 1;
4389 resolveRegion.srcOffset.x = 0;
4390 resolveRegion.srcOffset.y = 0;
4391 resolveRegion.srcOffset.z = 0;
4392 resolveRegion.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
4393 resolveRegion.dstSubresource.mipLevel = 0;
4394 resolveRegion.dstSubresource.baseArrayLayer = 0;
4395 resolveRegion.dstSubresource.layerCount = 1;
4396 resolveRegion.dstOffset.x = 0;
4397 resolveRegion.dstOffset.y = 0;
4398 resolveRegion.dstOffset.z = 0;
4399 resolveRegion.extent.width = 1;
4400 resolveRegion.extent.height = 1;
4401 resolveRegion.extent.depth = 1;
locke-lunarg8e2c91b2019-06-11 17:53:26 -06004402 m_commandBuffer->ResolveImage(srcImage.handle(), VK_IMAGE_LAYOUT_GENERAL, dstImage.handle(), VK_IMAGE_LAYOUT_GENERAL, 1,
4403 &resolveRegion);
unknown088160a2019-05-23 17:43:13 -06004404 m_commandBuffer->end();
4405
4406 m_errorMonitor->VerifyFound();
unknown088160a2019-05-23 17:43:13 -06004407}
4408
4409TEST_F(VkLayerTest, ResolveImageTypeMismatch) {
sfricke-samsungc26350e2020-05-30 12:31:31 -07004410 m_errorMonitor->SetDesiredFailureMsg(kWarningBit, "UNASSIGNED-CoreValidation-DrawState-MismatchedImageType");
unknown088160a2019-05-23 17:43:13 -06004411
4412 ASSERT_NO_FATAL_FAILURE(Init());
4413
4414 // Create two images of different types and try to copy between them
locke-lunarg8e2c91b2019-06-11 17:53:26 -06004415 VkImageObj srcImage(m_device);
4416 VkImageObj dstImage(m_device);
unknown088160a2019-05-23 17:43:13 -06004417
4418 VkImageCreateInfo image_create_info = {};
4419 image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
4420 image_create_info.pNext = NULL;
4421 image_create_info.imageType = VK_IMAGE_TYPE_2D;
4422 image_create_info.format = VK_FORMAT_B8G8R8A8_UNORM;
4423 image_create_info.extent.width = 32;
4424 image_create_info.extent.height = 1;
4425 image_create_info.extent.depth = 1;
4426 image_create_info.mipLevels = 1;
4427 image_create_info.arrayLayers = 1;
sfricke-samsungf46582f2021-03-31 02:02:37 -07004428 image_create_info.samples = VK_SAMPLE_COUNT_4_BIT; // guarantee support from sampledImageColorSampleCounts
unknown088160a2019-05-23 17:43:13 -06004429 image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL;
4430 // Note: Some implementations expect color attachment usage for any
4431 // multisample surface
4432 image_create_info.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
4433 image_create_info.flags = 0;
locke-lunarg8e2c91b2019-06-11 17:53:26 -06004434 srcImage.init(&image_create_info);
unknown088160a2019-05-23 17:43:13 -06004435
4436 image_create_info.imageType = VK_IMAGE_TYPE_1D;
4437 // Note: Some implementations expect color attachment usage for any
4438 // multisample surface
4439 image_create_info.usage = VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
4440 image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
locke-lunarg8e2c91b2019-06-11 17:53:26 -06004441 dstImage.init(&image_create_info);
unknown088160a2019-05-23 17:43:13 -06004442
4443 m_commandBuffer->begin();
4444 // Need memory barrier to VK_IMAGE_LAYOUT_GENERAL for source and dest?
4445 // VK_IMAGE_LAYOUT_UNDEFINED = 0,
4446 // VK_IMAGE_LAYOUT_GENERAL = 1,
4447 VkImageResolve resolveRegion;
4448 resolveRegion.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
4449 resolveRegion.srcSubresource.mipLevel = 0;
4450 resolveRegion.srcSubresource.baseArrayLayer = 0;
4451 resolveRegion.srcSubresource.layerCount = 1;
4452 resolveRegion.srcOffset.x = 0;
4453 resolveRegion.srcOffset.y = 0;
4454 resolveRegion.srcOffset.z = 0;
4455 resolveRegion.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
4456 resolveRegion.dstSubresource.mipLevel = 0;
4457 resolveRegion.dstSubresource.baseArrayLayer = 0;
4458 resolveRegion.dstSubresource.layerCount = 1;
4459 resolveRegion.dstOffset.x = 0;
4460 resolveRegion.dstOffset.y = 0;
4461 resolveRegion.dstOffset.z = 0;
4462 resolveRegion.extent.width = 1;
4463 resolveRegion.extent.height = 1;
4464 resolveRegion.extent.depth = 1;
locke-lunarg8e2c91b2019-06-11 17:53:26 -06004465 m_commandBuffer->ResolveImage(srcImage.handle(), VK_IMAGE_LAYOUT_GENERAL, dstImage.handle(), VK_IMAGE_LAYOUT_GENERAL, 1,
4466 &resolveRegion);
unknown088160a2019-05-23 17:43:13 -06004467 m_commandBuffer->end();
4468
4469 m_errorMonitor->VerifyFound();
unknown088160a2019-05-23 17:43:13 -06004470}
4471
4472TEST_F(VkLayerTest, ResolveImageLayoutMismatch) {
4473 ASSERT_NO_FATAL_FAILURE(Init());
4474
4475 // Create two images of different types and try to copy between them
4476 VkImageObj srcImage(m_device);
4477 VkImageObj dstImage(m_device);
4478
4479 VkImageCreateInfo image_create_info = {};
4480 image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
4481 image_create_info.pNext = NULL;
4482 image_create_info.imageType = VK_IMAGE_TYPE_2D;
4483 image_create_info.format = VK_FORMAT_B8G8R8A8_UNORM;
4484 image_create_info.extent.width = 32;
4485 image_create_info.extent.height = 32;
4486 image_create_info.extent.depth = 1;
4487 image_create_info.mipLevels = 1;
4488 image_create_info.arrayLayers = 1;
sfricke-samsungf46582f2021-03-31 02:02:37 -07004489 image_create_info.samples = VK_SAMPLE_COUNT_4_BIT; // guarantee support from sampledImageColorSampleCounts
unknown088160a2019-05-23 17:43:13 -06004490 image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL;
4491 image_create_info.usage =
4492 VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
4493 // Note: Some implementations expect color attachment usage for any
4494 // multisample surface
4495 image_create_info.flags = 0;
4496 srcImage.init(&image_create_info);
4497 ASSERT_TRUE(srcImage.initialized());
4498
4499 // Note: Some implementations expect color attachment usage for any
4500 // multisample surface
4501 image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
4502 dstImage.init(&image_create_info);
4503 ASSERT_TRUE(dstImage.initialized());
4504
4505 m_commandBuffer->begin();
4506 // source image must have valid contents before resolve
4507 VkClearColorValue clear_color = {{0, 0, 0, 0}};
4508 VkImageSubresourceRange subresource = {};
4509 subresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
4510 subresource.layerCount = 1;
4511 subresource.levelCount = 1;
4512 srcImage.SetLayout(m_commandBuffer, VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
4513 m_commandBuffer->ClearColorImage(srcImage.image(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &clear_color, 1, &subresource);
4514 srcImage.SetLayout(m_commandBuffer, VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL);
4515 dstImage.SetLayout(m_commandBuffer, VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
4516
4517 VkImageResolve resolveRegion;
4518 resolveRegion.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
4519 resolveRegion.srcSubresource.mipLevel = 0;
4520 resolveRegion.srcSubresource.baseArrayLayer = 0;
4521 resolveRegion.srcSubresource.layerCount = 1;
4522 resolveRegion.srcOffset.x = 0;
4523 resolveRegion.srcOffset.y = 0;
4524 resolveRegion.srcOffset.z = 0;
4525 resolveRegion.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
4526 resolveRegion.dstSubresource.mipLevel = 0;
4527 resolveRegion.dstSubresource.baseArrayLayer = 0;
4528 resolveRegion.dstSubresource.layerCount = 1;
4529 resolveRegion.dstOffset.x = 0;
4530 resolveRegion.dstOffset.y = 0;
4531 resolveRegion.dstOffset.z = 0;
4532 resolveRegion.extent.width = 1;
4533 resolveRegion.extent.height = 1;
4534 resolveRegion.extent.depth = 1;
4535 // source image layout mismatch
Mark Lobodzinski20310782020-02-28 14:25:17 -07004536 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdResolveImage-srcImageLayout-00260");
unknown088160a2019-05-23 17:43:13 -06004537 m_commandBuffer->ResolveImage(srcImage.image(), VK_IMAGE_LAYOUT_GENERAL, dstImage.image(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
4538 1, &resolveRegion);
4539 m_errorMonitor->VerifyFound();
4540 // dst image layout mismatch
Mark Lobodzinski20310782020-02-28 14:25:17 -07004541 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdResolveImage-dstImageLayout-00262");
unknown088160a2019-05-23 17:43:13 -06004542 m_commandBuffer->ResolveImage(srcImage.image(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, dstImage.image(), VK_IMAGE_LAYOUT_GENERAL,
4543 1, &resolveRegion);
4544 m_errorMonitor->VerifyFound();
4545 m_commandBuffer->end();
4546}
4547
4548TEST_F(VkLayerTest, ResolveInvalidSubresource) {
Jeff Leger465acf52020-10-12 18:07:16 -04004549 ASSERT_NO_FATAL_FAILURE(InitFramework(m_errorMonitor));
4550
4551 bool copy_commands2 = false;
4552 if (DeviceExtensionSupported(gpu(), nullptr, VK_KHR_COPY_COMMANDS_2_EXTENSION_NAME)) {
4553 m_device_extension_names.push_back(VK_KHR_COPY_COMMANDS_2_EXTENSION_NAME);
4554 copy_commands2 = true;
4555 }
4556 ASSERT_NO_FATAL_FAILURE(InitState());
4557
4558 PFN_vkCmdResolveImage2KHR vkCmdResolveImage2Function = nullptr;
4559 if (copy_commands2) {
4560 vkCmdResolveImage2Function = (PFN_vkCmdResolveImage2KHR)vk::GetDeviceProcAddr(m_device->handle(), "vkCmdResolveImage2KHR");
4561 }
unknown088160a2019-05-23 17:43:13 -06004562
4563 // Create two images of different types and try to copy between them
4564 VkImageObj srcImage(m_device);
4565 VkImageObj dstImage(m_device);
4566
4567 VkImageCreateInfo image_create_info = {};
4568 image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
4569 image_create_info.pNext = NULL;
4570 image_create_info.imageType = VK_IMAGE_TYPE_2D;
4571 image_create_info.format = VK_FORMAT_B8G8R8A8_UNORM;
4572 image_create_info.extent.width = 32;
4573 image_create_info.extent.height = 32;
4574 image_create_info.extent.depth = 1;
4575 image_create_info.mipLevels = 1;
4576 image_create_info.arrayLayers = 1;
sfricke-samsungf46582f2021-03-31 02:02:37 -07004577 image_create_info.samples = VK_SAMPLE_COUNT_4_BIT; // guarantee support from sampledImageColorSampleCounts
unknown088160a2019-05-23 17:43:13 -06004578 image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL;
4579 image_create_info.usage =
4580 VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
4581 // Note: Some implementations expect color attachment usage for any
4582 // multisample surface
4583 image_create_info.flags = 0;
4584 srcImage.init(&image_create_info);
4585 ASSERT_TRUE(srcImage.initialized());
4586
4587 // Note: Some implementations expect color attachment usage for any
4588 // multisample surface
4589 image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
4590 dstImage.init(&image_create_info);
4591 ASSERT_TRUE(dstImage.initialized());
4592
4593 m_commandBuffer->begin();
4594 // source image must have valid contents before resolve
4595 VkClearColorValue clear_color = {{0, 0, 0, 0}};
4596 VkImageSubresourceRange subresource = {};
4597 subresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
4598 subresource.layerCount = 1;
4599 subresource.levelCount = 1;
4600 srcImage.SetLayout(m_commandBuffer, VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
4601 m_commandBuffer->ClearColorImage(srcImage.image(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &clear_color, 1, &subresource);
4602 srcImage.SetLayout(m_commandBuffer, VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL);
4603 dstImage.SetLayout(m_commandBuffer, VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
4604
4605 VkImageResolve resolveRegion;
4606 resolveRegion.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
4607 resolveRegion.srcSubresource.mipLevel = 0;
4608 resolveRegion.srcSubresource.baseArrayLayer = 0;
4609 resolveRegion.srcSubresource.layerCount = 1;
4610 resolveRegion.srcOffset.x = 0;
4611 resolveRegion.srcOffset.y = 0;
4612 resolveRegion.srcOffset.z = 0;
4613 resolveRegion.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
4614 resolveRegion.dstSubresource.mipLevel = 0;
4615 resolveRegion.dstSubresource.baseArrayLayer = 0;
4616 resolveRegion.dstSubresource.layerCount = 1;
4617 resolveRegion.dstOffset.x = 0;
4618 resolveRegion.dstOffset.y = 0;
4619 resolveRegion.dstOffset.z = 0;
4620 resolveRegion.extent.width = 1;
4621 resolveRegion.extent.height = 1;
4622 resolveRegion.extent.depth = 1;
4623 // invalid source mip level
4624 resolveRegion.srcSubresource.mipLevel = image_create_info.mipLevels;
Mark Lobodzinski20310782020-02-28 14:25:17 -07004625 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdResolveImage-srcSubresource-01709");
unknown088160a2019-05-23 17:43:13 -06004626 m_commandBuffer->ResolveImage(srcImage.image(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, dstImage.image(),
4627 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &resolveRegion);
4628 m_errorMonitor->VerifyFound();
Jeff Leger465acf52020-10-12 18:07:16 -04004629
4630 // Equivalent test using KHR_copy_commands2
4631 if (copy_commands2 && vkCmdResolveImage2Function) {
4632 const VkImageResolve2KHR resolveRegion2 = {VK_STRUCTURE_TYPE_IMAGE_RESOLVE_2_KHR,
4633 NULL,
4634 resolveRegion.srcSubresource,
4635 resolveRegion.srcOffset,
4636 resolveRegion.dstSubresource,
4637 resolveRegion.dstOffset,
4638 resolveRegion.extent};
4639 const VkResolveImageInfo2KHR resolve_image_info2 = {VK_STRUCTURE_TYPE_RESOLVE_IMAGE_INFO_2_KHR,
4640 NULL,
4641 srcImage.image(),
4642 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
4643 dstImage.image(),
4644 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
4645 1,
4646 &resolveRegion2};
4647 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkResolveImageInfo2KHR-srcSubresource-01709");
4648 vkCmdResolveImage2Function(m_commandBuffer->handle(), &resolve_image_info2);
4649 m_errorMonitor->VerifyFound();
4650 }
4651
unknown088160a2019-05-23 17:43:13 -06004652 resolveRegion.srcSubresource.mipLevel = 0;
4653 // invalid dest mip level
4654 resolveRegion.dstSubresource.mipLevel = image_create_info.mipLevels;
Mark Lobodzinski20310782020-02-28 14:25:17 -07004655 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdResolveImage-dstSubresource-01710");
unknown088160a2019-05-23 17:43:13 -06004656 m_commandBuffer->ResolveImage(srcImage.image(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, dstImage.image(),
4657 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &resolveRegion);
4658 m_errorMonitor->VerifyFound();
Jeff Leger465acf52020-10-12 18:07:16 -04004659
4660 // Equivalent test using KHR_copy_commands2
4661 if (copy_commands2 && vkCmdResolveImage2Function) {
4662 const VkImageResolve2KHR resolveRegion2 = {VK_STRUCTURE_TYPE_IMAGE_RESOLVE_2_KHR,
4663 NULL,
4664 resolveRegion.srcSubresource,
4665 resolveRegion.srcOffset,
4666 resolveRegion.dstSubresource,
4667 resolveRegion.dstOffset,
4668 resolveRegion.extent};
4669 const VkResolveImageInfo2KHR resolve_image_info2 = {VK_STRUCTURE_TYPE_RESOLVE_IMAGE_INFO_2_KHR,
4670 NULL,
4671 srcImage.image(),
4672 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
4673 dstImage.image(),
4674 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
4675 1,
4676 &resolveRegion2};
4677 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkResolveImageInfo2KHR-dstSubresource-01710");
4678 vkCmdResolveImage2Function(m_commandBuffer->handle(), &resolve_image_info2);
4679 m_errorMonitor->VerifyFound();
4680 }
4681
unknown088160a2019-05-23 17:43:13 -06004682 resolveRegion.dstSubresource.mipLevel = 0;
4683 // invalid source array layer range
4684 resolveRegion.srcSubresource.baseArrayLayer = image_create_info.arrayLayers;
Mark Lobodzinski20310782020-02-28 14:25:17 -07004685 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdResolveImage-srcSubresource-01711");
unknown088160a2019-05-23 17:43:13 -06004686 m_commandBuffer->ResolveImage(srcImage.image(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, dstImage.image(),
4687 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &resolveRegion);
4688 m_errorMonitor->VerifyFound();
Jeff Leger465acf52020-10-12 18:07:16 -04004689
4690 // Equivalent test using KHR_copy_commands2
4691 if (copy_commands2 && vkCmdResolveImage2Function) {
4692 const VkImageResolve2KHR resolveRegion2 = {VK_STRUCTURE_TYPE_IMAGE_RESOLVE_2_KHR,
4693 NULL,
4694 resolveRegion.srcSubresource,
4695 resolveRegion.srcOffset,
4696 resolveRegion.dstSubresource,
4697 resolveRegion.dstOffset,
4698 resolveRegion.extent};
4699 const VkResolveImageInfo2KHR resolve_image_info2 = {VK_STRUCTURE_TYPE_RESOLVE_IMAGE_INFO_2_KHR,
4700 NULL,
4701 srcImage.image(),
4702 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
4703 dstImage.image(),
4704 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
4705 1,
4706 &resolveRegion2};
4707 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkResolveImageInfo2KHR-srcSubresource-01711");
4708 vkCmdResolveImage2Function(m_commandBuffer->handle(), &resolve_image_info2);
4709 m_errorMonitor->VerifyFound();
4710 }
4711
unknown088160a2019-05-23 17:43:13 -06004712 resolveRegion.srcSubresource.baseArrayLayer = 0;
4713 // invalid dest array layer range
4714 resolveRegion.dstSubresource.baseArrayLayer = image_create_info.arrayLayers;
Mark Lobodzinski20310782020-02-28 14:25:17 -07004715 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdResolveImage-dstSubresource-01712");
unknown088160a2019-05-23 17:43:13 -06004716 m_commandBuffer->ResolveImage(srcImage.image(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, dstImage.image(),
4717 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &resolveRegion);
4718 m_errorMonitor->VerifyFound();
Jeff Leger465acf52020-10-12 18:07:16 -04004719
4720 // Equivalent test using KHR_copy_commands2
4721 if (copy_commands2 && vkCmdResolveImage2Function) {
4722 const VkImageResolve2KHR resolveRegion2 = {VK_STRUCTURE_TYPE_IMAGE_RESOLVE_2_KHR,
4723 NULL,
4724 resolveRegion.srcSubresource,
4725 resolveRegion.srcOffset,
4726 resolveRegion.dstSubresource,
4727 resolveRegion.dstOffset,
4728 resolveRegion.extent};
4729 const VkResolveImageInfo2KHR resolve_image_info2 = {VK_STRUCTURE_TYPE_RESOLVE_IMAGE_INFO_2_KHR,
4730 NULL,
4731 srcImage.image(),
4732 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
4733 dstImage.image(),
4734 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
4735 1,
4736 &resolveRegion2};
4737 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkResolveImageInfo2KHR-dstSubresource-01712");
4738 vkCmdResolveImage2Function(m_commandBuffer->handle(), &resolve_image_info2);
4739 m_errorMonitor->VerifyFound();
4740 }
4741
unknown088160a2019-05-23 17:43:13 -06004742 resolveRegion.dstSubresource.baseArrayLayer = 0;
4743
4744 m_commandBuffer->end();
4745}
4746
sfricke-samsungf78d0592020-06-11 21:34:44 -07004747TEST_F(VkLayerTest, ResolveImageImageType) {
4748 ASSERT_NO_FATAL_FAILURE(Init());
4749 // Create images of different types and try to resolve between them
4750 VkImageObj srcImage2D(m_device);
4751 VkImageObj dstImage1D(m_device);
4752 VkImageObj dstImage3D(m_device);
4753
4754 VkImageCreateInfo image_create_info = {};
4755 image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
4756 image_create_info.pNext = NULL;
4757 image_create_info.format = VK_FORMAT_R8G8B8A8_UNORM;
4758 image_create_info.extent.width = 32;
4759 image_create_info.extent.height = 1;
4760 image_create_info.extent.depth = 1;
4761 image_create_info.mipLevels = 1;
4762 image_create_info.arrayLayers = 4; // more than 1 to not trip other validation
sfricke-samsungf46582f2021-03-31 02:02:37 -07004763 image_create_info.samples = VK_SAMPLE_COUNT_4_BIT; // guarantee support from sampledImageColorSampleCounts
sfricke-samsungf78d0592020-06-11 21:34:44 -07004764 image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL;
4765 image_create_info.usage =
4766 VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
4767 // Note: Some implementations expect color attachment usage for any
4768 // multisample surface
4769 image_create_info.flags = 0;
4770
4771 image_create_info.imageType = VK_IMAGE_TYPE_2D;
4772 srcImage2D.init(&image_create_info);
4773 ASSERT_TRUE(srcImage2D.initialized());
4774
4775 image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
4776 image_create_info.imageType = VK_IMAGE_TYPE_1D;
4777 dstImage1D.init(&image_create_info);
4778 ASSERT_TRUE(dstImage1D.initialized());
4779
4780 image_create_info.imageType = VK_IMAGE_TYPE_3D;
4781 image_create_info.extent.height = 16;
4782 image_create_info.extent.depth = 16;
4783 image_create_info.arrayLayers = 1;
4784 dstImage3D.init(&image_create_info);
4785 ASSERT_TRUE(dstImage3D.initialized());
4786
4787 m_commandBuffer->begin();
4788
4789 VkImageResolve resolveRegion;
4790 resolveRegion.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
4791 resolveRegion.srcSubresource.mipLevel = 0;
4792 resolveRegion.srcSubresource.baseArrayLayer = 0;
4793 resolveRegion.srcSubresource.layerCount = 1;
4794 resolveRegion.srcOffset.x = 0;
4795 resolveRegion.srcOffset.y = 0;
4796 resolveRegion.srcOffset.z = 0;
4797 resolveRegion.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
4798 resolveRegion.dstSubresource.mipLevel = 0;
4799 resolveRegion.dstSubresource.baseArrayLayer = 0;
4800 resolveRegion.dstSubresource.layerCount = 1;
4801 resolveRegion.dstOffset.x = 0;
4802 resolveRegion.dstOffset.y = 0;
4803 resolveRegion.dstOffset.z = 0;
4804 resolveRegion.extent.width = 1;
4805 resolveRegion.extent.height = 1;
4806 resolveRegion.extent.depth = 1;
4807
4808 // non-zero value baseArrayLayer
4809 resolveRegion.srcSubresource.baseArrayLayer = 2;
Shannon McPherson74b341c2020-09-08 15:43:05 -06004810 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdResolveImage-srcImage-04446");
sfricke-samsungf78d0592020-06-11 21:34:44 -07004811 m_commandBuffer->ResolveImage(srcImage2D.image(), VK_IMAGE_LAYOUT_GENERAL, dstImage3D.image(), VK_IMAGE_LAYOUT_GENERAL, 1,
4812 &resolveRegion);
4813 m_errorMonitor->VerifyFound();
4814 resolveRegion.srcSubresource.baseArrayLayer = 0;
4815
4816 // Set height with 1D dstImage
4817 resolveRegion.extent.height = 2;
Shannon McPherson2c793ba2020-08-28 12:13:24 -06004818 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdResolveImage-dstImage-00276");
sfricke-samsungdfeb3172020-07-25 21:17:07 -07004819 // Also exceed height of both images
Shannon McPherson2c793ba2020-08-28 12:13:24 -06004820 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdResolveImage-srcOffset-00270");
4821 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdResolveImage-dstOffset-00275");
sfricke-samsungf78d0592020-06-11 21:34:44 -07004822 m_commandBuffer->ResolveImage(srcImage2D.image(), VK_IMAGE_LAYOUT_GENERAL, dstImage1D.image(), VK_IMAGE_LAYOUT_GENERAL, 1,
4823 &resolveRegion);
4824 m_errorMonitor->VerifyFound();
4825 resolveRegion.extent.height = 1;
4826
4827 // Set depth with 1D dstImage and 2D srcImage
4828 resolveRegion.extent.depth = 2;
Shannon McPherson2c793ba2020-08-28 12:13:24 -06004829 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdResolveImage-dstImage-00278");
4830 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdResolveImage-srcImage-00273");
sfricke-samsungf78d0592020-06-11 21:34:44 -07004831 m_commandBuffer->ResolveImage(srcImage2D.image(), VK_IMAGE_LAYOUT_GENERAL, dstImage1D.image(), VK_IMAGE_LAYOUT_GENERAL, 1,
4832 &resolveRegion);
4833 m_errorMonitor->VerifyFound();
4834 resolveRegion.extent.depth = 1;
4835
4836 m_commandBuffer->end();
4837}
4838
sfricke-samsungc967a2d2020-07-25 21:17:16 -07004839TEST_F(VkLayerTest, ResolveImageSizeExceeded) {
4840 TEST_DESCRIPTION("Resolve Image with subresource region greater than size of src/dst image");
4841 ASSERT_NO_FATAL_FAILURE(Init());
4842
Tony-LunarG0f8f94b2021-06-01 13:23:09 -06004843 m_errorMonitor->ExpectSuccess();
sfricke-samsungc967a2d2020-07-25 21:17:16 -07004844 VkImageObj srcImage2D(m_device);
4845 VkImageObj dstImage2D(m_device);
4846
4847 VkImageCreateInfo image_create_info = {};
4848 image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
4849 image_create_info.pNext = NULL;
4850 image_create_info.format = VK_FORMAT_R8G8B8A8_UNORM;
4851 image_create_info.extent.width = 32;
4852 image_create_info.extent.height = 32;
4853 image_create_info.extent.depth = 1;
Tony-LunarG0f8f94b2021-06-01 13:23:09 -06004854 image_create_info.mipLevels = 1;
sfricke-samsungc967a2d2020-07-25 21:17:16 -07004855 image_create_info.arrayLayers = 1;
4856 image_create_info.samples = VK_SAMPLE_COUNT_4_BIT;
4857 image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL;
4858 image_create_info.usage =
4859 VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
4860 // Note: Some implementations expect color attachment usage for any
4861 // multisample surface
4862 image_create_info.flags = 0;
4863
4864 image_create_info.imageType = VK_IMAGE_TYPE_2D;
4865 srcImage2D.init(&image_create_info);
4866 ASSERT_TRUE(srcImage2D.initialized());
4867
4868 image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
4869 dstImage2D.init(&image_create_info);
4870 ASSERT_TRUE(dstImage2D.initialized());
4871
4872 m_commandBuffer->begin();
4873
4874 VkImageResolve resolveRegion = {};
4875 resolveRegion.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
4876 resolveRegion.srcSubresource.mipLevel = 0;
4877 resolveRegion.srcSubresource.baseArrayLayer = 0;
4878 resolveRegion.srcSubresource.layerCount = 1;
4879 resolveRegion.srcOffset.x = 0;
4880 resolveRegion.srcOffset.y = 0;
4881 resolveRegion.srcOffset.z = 0;
4882 resolveRegion.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
4883 resolveRegion.dstSubresource.mipLevel = 0;
4884 resolveRegion.dstSubresource.baseArrayLayer = 0;
4885 resolveRegion.dstSubresource.layerCount = 1;
4886 resolveRegion.dstOffset.x = 0;
4887 resolveRegion.dstOffset.y = 0;
4888 resolveRegion.dstOffset.z = 0;
4889 resolveRegion.extent.width = 32;
4890 resolveRegion.extent.height = 32;
4891 resolveRegion.extent.depth = 1;
4892
sfricke-samsungc967a2d2020-07-25 21:17:16 -07004893 m_commandBuffer->ResolveImage(srcImage2D.image(), VK_IMAGE_LAYOUT_GENERAL, dstImage2D.image(), VK_IMAGE_LAYOUT_GENERAL, 1,
4894 &resolveRegion);
4895 m_errorMonitor->VerifyNotFound();
4896
4897 // srcImage exceeded in x-dim
4898 resolveRegion.srcOffset.x = 4;
Shannon McPherson2c793ba2020-08-28 12:13:24 -06004899 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdResolveImage-srcOffset-00269");
sfricke-samsungc967a2d2020-07-25 21:17:16 -07004900 m_commandBuffer->ResolveImage(srcImage2D.image(), VK_IMAGE_LAYOUT_GENERAL, dstImage2D.image(), VK_IMAGE_LAYOUT_GENERAL, 1,
4901 &resolveRegion);
4902 m_errorMonitor->VerifyFound();
4903 resolveRegion.srcOffset.x = 0;
4904
4905 // dstImage exceeded in x-dim
4906 resolveRegion.dstOffset.x = 4;
Shannon McPherson2c793ba2020-08-28 12:13:24 -06004907 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdResolveImage-dstOffset-00274");
sfricke-samsungc967a2d2020-07-25 21:17:16 -07004908 m_commandBuffer->ResolveImage(srcImage2D.image(), VK_IMAGE_LAYOUT_GENERAL, dstImage2D.image(), VK_IMAGE_LAYOUT_GENERAL, 1,
4909 &resolveRegion);
4910 m_errorMonitor->VerifyFound();
4911 resolveRegion.dstOffset.x = 0;
4912
Tony-LunarG0f8f94b2021-06-01 13:23:09 -06004913 // both image exceeded in y-dim
4914 resolveRegion.srcOffset.y = 32;
Shannon McPherson2c793ba2020-08-28 12:13:24 -06004915 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdResolveImage-srcOffset-00270");
sfricke-samsungc967a2d2020-07-25 21:17:16 -07004916 m_commandBuffer->ResolveImage(srcImage2D.image(), VK_IMAGE_LAYOUT_GENERAL, dstImage2D.image(), VK_IMAGE_LAYOUT_GENERAL, 1,
4917 &resolveRegion);
4918 m_errorMonitor->VerifyFound();
Tony-LunarG0f8f94b2021-06-01 13:23:09 -06004919 resolveRegion.srcOffset.y = 0;
sfricke-samsungc967a2d2020-07-25 21:17:16 -07004920
Tony-LunarG0f8f94b2021-06-01 13:23:09 -06004921 resolveRegion.dstOffset.y = 32;
Shannon McPherson2c793ba2020-08-28 12:13:24 -06004922 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdResolveImage-dstOffset-00275");
sfricke-samsungc967a2d2020-07-25 21:17:16 -07004923 m_commandBuffer->ResolveImage(srcImage2D.image(), VK_IMAGE_LAYOUT_GENERAL, dstImage2D.image(), VK_IMAGE_LAYOUT_GENERAL, 1,
4924 &resolveRegion);
4925 m_errorMonitor->VerifyFound();
Tony-LunarG0f8f94b2021-06-01 13:23:09 -06004926 resolveRegion.dstOffset.y = 0;
sfricke-samsungc967a2d2020-07-25 21:17:16 -07004927
4928 // srcImage exceeded in z-dim
4929 resolveRegion.srcOffset.z = 1;
Shannon McPherson2c793ba2020-08-28 12:13:24 -06004930 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdResolveImage-srcOffset-00272");
4931 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdResolveImage-srcImage-00273"); // because it's a 2d image
sfricke-samsungc967a2d2020-07-25 21:17:16 -07004932 m_commandBuffer->ResolveImage(srcImage2D.image(), VK_IMAGE_LAYOUT_GENERAL, dstImage2D.image(), VK_IMAGE_LAYOUT_GENERAL, 1,
4933 &resolveRegion);
4934 m_errorMonitor->VerifyFound();
4935 resolveRegion.srcOffset.z = 0;
4936
4937 // dstImage exceeded in z-dim
4938 resolveRegion.dstOffset.z = 1;
Shannon McPherson2c793ba2020-08-28 12:13:24 -06004939 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdResolveImage-dstOffset-00277");
4940 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdResolveImage-dstImage-00278"); // because it's a 2d image
sfricke-samsungc967a2d2020-07-25 21:17:16 -07004941 m_commandBuffer->ResolveImage(srcImage2D.image(), VK_IMAGE_LAYOUT_GENERAL, dstImage2D.image(), VK_IMAGE_LAYOUT_GENERAL, 1,
4942 &resolveRegion);
4943 m_errorMonitor->VerifyFound();
4944 resolveRegion.dstOffset.z = 0;
4945
4946 m_commandBuffer->end();
4947}
4948
unknown088160a2019-05-23 17:43:13 -06004949TEST_F(VkLayerTest, ClearImageErrors) {
4950 TEST_DESCRIPTION("Call ClearColorImage w/ a depth|stencil image and ClearDepthStencilImage with a color image.");
4951
4952 ASSERT_NO_FATAL_FAILURE(Init());
4953 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
4954
4955 m_commandBuffer->begin();
4956
4957 // Color image
4958 VkClearColorValue clear_color;
4959 memset(clear_color.uint32, 0, sizeof(uint32_t) * 4);
4960 const VkFormat color_format = VK_FORMAT_B8G8R8A8_UNORM;
4961 const int32_t img_width = 32;
4962 const int32_t img_height = 32;
4963 VkImageCreateInfo image_create_info = {};
4964 image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
4965 image_create_info.pNext = NULL;
4966 image_create_info.imageType = VK_IMAGE_TYPE_2D;
4967 image_create_info.format = color_format;
4968 image_create_info.extent.width = img_width;
4969 image_create_info.extent.height = img_height;
4970 image_create_info.extent.depth = 1;
4971 image_create_info.mipLevels = 1;
4972 image_create_info.arrayLayers = 1;
4973 image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
4974 image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL;
4975
4976 image_create_info.usage = VK_IMAGE_USAGE_SAMPLED_BIT;
4977 vk_testing::Image color_image_no_transfer;
4978 color_image_no_transfer.init(*m_device, image_create_info);
4979
4980 image_create_info.usage = VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
4981 vk_testing::Image color_image;
4982 color_image.init(*m_device, image_create_info);
4983
4984 const VkImageSubresourceRange color_range = vk_testing::Image::subresource_range(image_create_info, VK_IMAGE_ASPECT_COLOR_BIT);
4985
4986 // Depth/Stencil image
4987 VkClearDepthStencilValue clear_value = {0};
4988 VkImageCreateInfo ds_image_create_info = vk_testing::Image::create_info();
4989 ds_image_create_info.imageType = VK_IMAGE_TYPE_2D;
4990 ds_image_create_info.format = VK_FORMAT_D16_UNORM;
4991 ds_image_create_info.extent.width = 64;
4992 ds_image_create_info.extent.height = 64;
4993 ds_image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL;
4994 ds_image_create_info.usage = VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
4995
4996 vk_testing::Image ds_image;
4997 ds_image.init(*m_device, ds_image_create_info);
4998
4999 const VkImageSubresourceRange ds_range = vk_testing::Image::subresource_range(ds_image_create_info, VK_IMAGE_ASPECT_DEPTH_BIT);
5000
sfricke-samsungcd924d92020-05-20 23:51:17 -07005001 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdClearColorImage-image-00007");
unknown088160a2019-05-23 17:43:13 -06005002
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06005003 vk::CmdClearColorImage(m_commandBuffer->handle(), ds_image.handle(), VK_IMAGE_LAYOUT_GENERAL, &clear_color, 1, &color_range);
unknown088160a2019-05-23 17:43:13 -06005004
5005 m_errorMonitor->VerifyFound();
5006
sfricke-samsungcd924d92020-05-20 23:51:17 -07005007 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdClearColorImage-image-00002");
unknown088160a2019-05-23 17:43:13 -06005008
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06005009 vk::CmdClearColorImage(m_commandBuffer->handle(), color_image_no_transfer.handle(), VK_IMAGE_LAYOUT_GENERAL, &clear_color, 1,
5010 &color_range);
unknown088160a2019-05-23 17:43:13 -06005011
5012 m_errorMonitor->VerifyFound();
5013
5014 // Call CmdClearDepthStencilImage with color image
sfricke-samsungcd924d92020-05-20 23:51:17 -07005015 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdClearDepthStencilImage-image-00014");
sfricke-samsung30e325a2020-07-25 12:56:13 -07005016 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdClearDepthStencilImage-image-02826");
unknown088160a2019-05-23 17:43:13 -06005017
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06005018 vk::CmdClearDepthStencilImage(m_commandBuffer->handle(), color_image.handle(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
5019 &clear_value, 1, &ds_range);
unknown088160a2019-05-23 17:43:13 -06005020
5021 m_errorMonitor->VerifyFound();
5022}
5023
5024TEST_F(VkLayerTest, CommandQueueFlags) {
5025 TEST_DESCRIPTION(
5026 "Allocate a command buffer on a queue that does not support graphics and try to issue a graphics-only command");
5027
5028 ASSERT_NO_FATAL_FAILURE(Init());
5029
5030 uint32_t queueFamilyIndex = m_device->QueueFamilyWithoutCapabilities(VK_QUEUE_GRAPHICS_BIT);
5031 if (queueFamilyIndex == UINT32_MAX) {
5032 printf("%s Non-graphics queue family not found; skipped.\n", kSkipPrefix);
5033 return;
5034 } else {
5035 // Create command pool on a non-graphics queue
5036 VkCommandPoolObj command_pool(m_device, queueFamilyIndex);
5037
5038 // Setup command buffer on pool
5039 VkCommandBufferObj command_buffer(m_device, &command_pool);
5040 command_buffer.begin();
5041
5042 // Issue a graphics only command
Mark Lobodzinski20310782020-02-28 14:25:17 -07005043 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdSetViewport-commandBuffer-cmdpool");
unknown088160a2019-05-23 17:43:13 -06005044 VkViewport viewport = {0, 0, 16, 16, 0, 1};
5045 command_buffer.SetViewport(0, 1, &viewport);
5046 m_errorMonitor->VerifyFound();
5047 }
5048}
5049
sfricke-samsung674ba102020-08-18 22:38:49 -07005050TEST_F(VkLayerTest, DepthStencilImageCopyNoGraphicsQueueFlags) {
5051 TEST_DESCRIPTION(
5052 "Allocate a command buffer on a queue that does not support graphics and try to issue a depth/stencil image copy to "
5053 "buffer");
5054
5055 ASSERT_NO_FATAL_FAILURE(Init());
5056
5057 uint32_t queueFamilyIndex = m_device->QueueFamilyWithoutCapabilities(VK_QUEUE_GRAPHICS_BIT);
5058 if (queueFamilyIndex == UINT32_MAX) {
5059 printf("%s Non-graphics queue family not found; skipped.\n", kSkipPrefix);
5060 return;
5061 } else {
5062 // Create Depth image
5063 const VkFormat ds_format = FindSupportedDepthOnlyFormat(gpu());
5064 if (ds_format == VK_FORMAT_UNDEFINED) {
5065 printf("%s No only Depth format found. Skipped.\n", kSkipPrefix);
5066 return;
5067 }
5068
5069 VkImageObj ds_image(m_device);
5070 ds_image.Init(64, 64, 1, ds_format, VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT,
5071 VK_IMAGE_TILING_OPTIMAL, 0);
5072 ASSERT_TRUE(ds_image.initialized());
5073
5074 // Allocate buffers
5075 VkBufferObj buffer;
5076 VkMemoryPropertyFlags reqs = 0;
5077 buffer.init_as_src_and_dst(*m_device, 262144, reqs); // 256k to have more then enough to copy
5078
5079 VkBufferImageCopy region = {};
5080 region.bufferRowLength = 0;
5081 region.bufferImageHeight = 0;
5082 region.imageSubresource.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT;
5083 region.imageSubresource.layerCount = 1;
5084 region.imageOffset = {0, 0, 0};
5085 region.imageExtent = {64, 64, 1};
5086 region.bufferOffset = 0;
5087
5088 // Create command pool on a non-graphics queue
5089 VkCommandPoolObj command_pool(m_device, queueFamilyIndex);
5090
5091 // Setup command buffer on pool
5092 VkCommandBufferObj command_buffer(m_device, &command_pool);
5093 command_buffer.begin();
5094
sfricke-samsungea4fd142020-10-17 23:51:59 -07005095 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdCopyBufferToImage-commandBuffer-04477");
sfricke-samsung674ba102020-08-18 22:38:49 -07005096 vk::CmdCopyBufferToImage(command_buffer.handle(), buffer.handle(), ds_image.handle(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
5097 1, &region);
5098 m_errorMonitor->VerifyFound();
5099 }
5100}
5101
sfricke-samsung5a019492021-01-25 10:32:08 -08005102TEST_F(VkLayerTest, ImageCopyTransferQueueFlags) {
5103 TEST_DESCRIPTION(
5104 "Allocate a command buffer on a queue that does not support graphics/compute and try to issue an invalid image copy to "
5105 "buffer");
5106
5107 ASSERT_NO_FATAL_FAILURE(Init());
5108
5109 // Should be left with a tranfser queue
5110 uint32_t queueFamilyIndex = m_device->QueueFamilyWithoutCapabilities(VK_QUEUE_GRAPHICS_BIT | VK_QUEUE_COMPUTE_BIT);
5111 if (queueFamilyIndex == UINT32_MAX) {
5112 printf("%s Non-graphics/compute queue family not found; skipped.\n", kSkipPrefix);
5113 return;
5114 }
5115
5116 VkImageObj image(m_device);
5117 image.Init(32, 32, 1, VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT,
5118 VK_IMAGE_TILING_OPTIMAL, 0);
5119 ASSERT_TRUE(image.initialized());
5120
5121 // Allocate buffers
5122 VkBufferObj buffer;
5123 VkMemoryPropertyFlags reqs = 0;
5124 buffer.init_as_src_and_dst(*m_device, 262144, reqs); // 256k to have more then enough to copy
5125
5126 VkBufferImageCopy region = {};
5127 region.bufferRowLength = 0;
5128 region.bufferImageHeight = 0;
5129 region.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
5130 region.imageSubresource.layerCount = 1;
5131 region.imageOffset = {0, 0, 0};
5132 region.imageExtent = {16, 16, 1};
5133 region.bufferOffset = 5;
5134
5135 // Create command pool on a non-graphics queue
5136 VkCommandPoolObj command_pool(m_device, queueFamilyIndex);
5137
5138 // Setup command buffer on pool
5139 VkCommandBufferObj command_buffer(m_device, &command_pool);
5140 command_buffer.begin();
5141
5142 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdCopyBufferToImage-bufferOffset-00193");
5143 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdCopyBufferToImage-commandBuffer-04052");
5144 vk::CmdCopyBufferToImage(command_buffer.handle(), buffer.handle(), image.handle(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1,
5145 &region);
5146 m_errorMonitor->VerifyFound();
5147}
5148
sfricke-samsungcb467672020-11-25 00:09:28 -08005149TEST_F(VkLayerTest, ExecuteDiffertQueueFlagsSecondaryCB) {
5150 TEST_DESCRIPTION("Allocate a command buffer from two different queues and try to use a secondary command buffer");
5151
5152 ASSERT_NO_FATAL_FAILURE(Init());
5153
5154 if (m_device->queue_props.size() < 2) {
5155 printf("%s Need 2 different queues for testing skipping.\n", kSkipPrefix);
5156 return;
5157 }
5158
5159 // First two queue families
5160 uint32_t queue_index_A = 0;
5161 uint32_t queue_index_B = 1;
5162
5163 VkCommandPoolCreateInfo pool_create_info = {};
5164 pool_create_info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
5165 pool_create_info.pNext = nullptr;
5166 pool_create_info.flags = 0;
5167
5168 VkCommandPool command_pool_A;
5169 pool_create_info.queueFamilyIndex = queue_index_A;
5170 vk::CreateCommandPool(m_device->device(), &pool_create_info, nullptr, &command_pool_A);
5171
5172 VkCommandPool command_pool_B;
5173 pool_create_info.queueFamilyIndex = queue_index_B;
5174 vk::CreateCommandPool(m_device->device(), &pool_create_info, nullptr, &command_pool_B);
5175
5176 VkCommandBuffer command_buffer[2]; // [0] primary and [1] secondary
5177 VkCommandBufferAllocateInfo command_buffer_allocate_info{};
5178 command_buffer_allocate_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
5179 command_buffer_allocate_info.commandBufferCount = 1;
5180 command_buffer_allocate_info.commandPool = command_pool_A;
5181 command_buffer_allocate_info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
5182 vk::AllocateCommandBuffers(m_device->device(), &command_buffer_allocate_info, &command_buffer[0]);
5183
5184 command_buffer_allocate_info.commandPool = command_pool_B;
5185 command_buffer_allocate_info.level = VK_COMMAND_BUFFER_LEVEL_SECONDARY;
5186 vk::AllocateCommandBuffers(m_device->device(), &command_buffer_allocate_info, &command_buffer[1]);
5187
5188 VkCommandBufferBeginInfo begin_info = {};
5189 begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
5190
5191 // secondary
5192 vk::BeginCommandBuffer(command_buffer[1], &begin_info);
5193 vk::EndCommandBuffer(command_buffer[1]);
5194
5195 // Try using different pool's command buffer as secondary
5196 vk::BeginCommandBuffer(command_buffer[0], &begin_info);
5197 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdExecuteCommands-pCommandBuffers-00094");
5198 vk::CmdExecuteCommands(command_buffer[0], 1, &command_buffer[1]);
5199 m_errorMonitor->VerifyFound();
5200 vk::EndCommandBuffer(command_buffer[0]);
5201
5202 vk::DestroyCommandPool(m_device->device(), command_pool_A, NULL);
5203 vk::DestroyCommandPool(m_device->device(), command_pool_B, NULL);
5204}
5205
unknown088160a2019-05-23 17:43:13 -06005206TEST_F(VkLayerTest, ExecuteUnrecordedSecondaryCB) {
5207 TEST_DESCRIPTION("Attempt vkCmdExecuteCommands with a CB in the initial state");
5208 ASSERT_NO_FATAL_FAILURE(Init());
5209 VkCommandBufferObj secondary(m_device, m_commandPool, VK_COMMAND_BUFFER_LEVEL_SECONDARY);
5210 // never record secondary
5211
Mark Lobodzinski20310782020-02-28 14:25:17 -07005212 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdExecuteCommands-pCommandBuffers-00089");
unknown088160a2019-05-23 17:43:13 -06005213 m_commandBuffer->begin();
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06005214 vk::CmdExecuteCommands(m_commandBuffer->handle(), 1, &secondary.handle());
unknown088160a2019-05-23 17:43:13 -06005215 m_errorMonitor->VerifyFound();
5216 m_commandBuffer->end();
5217}
5218
5219TEST_F(VkLayerTest, ExecuteSecondaryCBWithLayoutMismatch) {
5220 TEST_DESCRIPTION("Attempt vkCmdExecuteCommands with a CB with incorrect initial layout.");
5221
Mark Lobodzinski09ce9c42020-03-06 10:02:44 -07005222 ASSERT_NO_FATAL_FAILURE(InitFramework(m_errorMonitor));
unknown088160a2019-05-23 17:43:13 -06005223 ASSERT_NO_FATAL_FAILURE(InitState(nullptr, nullptr, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT));
5224
5225 VkImageCreateInfo image_create_info = {};
5226 image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
5227 image_create_info.pNext = NULL;
5228 image_create_info.imageType = VK_IMAGE_TYPE_2D;
5229 image_create_info.format = VK_FORMAT_B8G8R8A8_UNORM;
5230 image_create_info.extent.width = 32;
5231 image_create_info.extent.height = 1;
5232 image_create_info.extent.depth = 1;
5233 image_create_info.mipLevels = 1;
5234 image_create_info.arrayLayers = 1;
5235 image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
5236 image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL;
5237 image_create_info.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
5238 image_create_info.flags = 0;
5239
5240 VkImageSubresource image_sub = VkImageObj::subresource(VK_IMAGE_ASPECT_COLOR_BIT, 0, 0);
5241 VkImageSubresourceRange image_sub_range = VkImageObj::subresource_range(image_sub);
5242
5243 VkImageObj image(m_device);
5244 image.init(&image_create_info);
5245 ASSERT_TRUE(image.initialized());
5246 VkImageMemoryBarrier image_barrier =
5247 image.image_memory_barrier(0, 0, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_GENERAL, image_sub_range);
5248
5249 auto pipeline = [&image_barrier](const VkCommandBufferObj &cb, VkImageLayout old_layout, VkImageLayout new_layout) {
5250 image_barrier.oldLayout = old_layout;
5251 image_barrier.newLayout = new_layout;
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06005252 vk::CmdPipelineBarrier(cb.handle(), VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, 0, nullptr,
5253 0, nullptr, 1, &image_barrier);
unknown088160a2019-05-23 17:43:13 -06005254 };
5255
5256 // Validate that mismatched use of image layout in secondary command buffer is caught at record time
5257 VkCommandBufferObj secondary(m_device, m_commandPool, VK_COMMAND_BUFFER_LEVEL_SECONDARY);
5258 secondary.begin();
5259 pipeline(secondary, VK_IMAGE_LAYOUT_GENERAL, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
5260 secondary.end();
5261
Mark Lobodzinski20310782020-02-28 14:25:17 -07005262 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "UNASSIGNED-vkCmdExecuteCommands-commandBuffer-00001");
unknown088160a2019-05-23 17:43:13 -06005263 m_commandBuffer->begin();
5264 pipeline(*m_commandBuffer, VK_IMAGE_LAYOUT_GENERAL, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL);
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06005265 vk::CmdExecuteCommands(m_commandBuffer->handle(), 1, &secondary.handle());
unknown088160a2019-05-23 17:43:13 -06005266 m_errorMonitor->VerifyFound();
5267
unknown088160a2019-05-23 17:43:13 -06005268 m_commandBuffer->reset();
5269 secondary.reset();
5270
5271 // Validate that UNDEFINED doesn't false positive on us
5272 secondary.begin();
5273 pipeline(secondary, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
5274 secondary.end();
5275 m_commandBuffer->begin();
5276 pipeline(*m_commandBuffer, VK_IMAGE_LAYOUT_GENERAL, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
5277 m_errorMonitor->ExpectSuccess();
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06005278 vk::CmdExecuteCommands(m_commandBuffer->handle(), 1, &secondary.handle());
unknown088160a2019-05-23 17:43:13 -06005279 m_errorMonitor->VerifyNotFound();
5280 m_commandBuffer->end();
5281}
5282
5283TEST_F(VkLayerTest, SetDynViewportParamTests) {
5284 TEST_DESCRIPTION("Test parameters of vkCmdSetViewport without multiViewport feature");
5285
5286 SetTargetApiVersion(VK_API_VERSION_1_1);
5287 VkPhysicalDeviceFeatures features{};
5288 ASSERT_NO_FATAL_FAILURE(Init(&features));
5289
5290 const VkViewport vp = {0.0, 0.0, 64.0, 64.0, 0.0, 1.0};
5291 const VkViewport viewports[] = {vp, vp};
5292
5293 m_commandBuffer->begin();
5294
5295 // array tests
Mark Lobodzinski20310782020-02-28 14:25:17 -07005296 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdSetViewport-firstViewport-01224");
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06005297 vk::CmdSetViewport(m_commandBuffer->handle(), 1, 1, viewports);
unknown088160a2019-05-23 17:43:13 -06005298 m_errorMonitor->VerifyFound();
5299
Mark Lobodzinski20310782020-02-28 14:25:17 -07005300 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdSetViewport-viewportCount-arraylength");
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06005301 vk::CmdSetViewport(m_commandBuffer->handle(), 0, 0, nullptr);
unknown088160a2019-05-23 17:43:13 -06005302 m_errorMonitor->VerifyFound();
5303
Mark Lobodzinski20310782020-02-28 14:25:17 -07005304 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdSetViewport-viewportCount-01225");
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06005305 vk::CmdSetViewport(m_commandBuffer->handle(), 0, 2, viewports);
unknown088160a2019-05-23 17:43:13 -06005306 m_errorMonitor->VerifyFound();
5307
Mark Lobodzinski20310782020-02-28 14:25:17 -07005308 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdSetViewport-firstViewport-01224");
5309 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdSetViewport-viewportCount-01225");
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06005310 vk::CmdSetViewport(m_commandBuffer->handle(), 1, 2, viewports);
unknown088160a2019-05-23 17:43:13 -06005311 m_errorMonitor->VerifyFound();
5312
Mark Lobodzinski20310782020-02-28 14:25:17 -07005313 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdSetViewport-pViewports-parameter");
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06005314 vk::CmdSetViewport(m_commandBuffer->handle(), 0, 1, nullptr);
unknown088160a2019-05-23 17:43:13 -06005315 m_errorMonitor->VerifyFound();
5316
5317 // core viewport tests
5318 using std::vector;
5319 struct TestCase {
5320 VkViewport vp;
5321 std::string veid;
5322 };
5323
5324 // not necessarily boundary values (unspecified cast rounding), but guaranteed to be over limit
5325 const auto one_past_max_w = NearestGreater(static_cast<float>(m_device->props.limits.maxViewportDimensions[0]));
5326 const auto one_past_max_h = NearestGreater(static_cast<float>(m_device->props.limits.maxViewportDimensions[1]));
5327
5328 const auto min_bound = m_device->props.limits.viewportBoundsRange[0];
5329 const auto max_bound = m_device->props.limits.viewportBoundsRange[1];
5330 const auto one_before_min_bounds = NearestSmaller(min_bound);
5331 const auto one_past_max_bounds = NearestGreater(max_bound);
5332
5333 const auto below_zero = NearestSmaller(0.0f);
5334 const auto past_one = NearestGreater(1.0f);
5335
5336 vector<TestCase> test_cases = {
5337 {{0.0, 0.0, 0.0, 64.0, 0.0, 1.0}, "VUID-VkViewport-width-01770"},
5338 {{0.0, 0.0, one_past_max_w, 64.0, 0.0, 1.0}, "VUID-VkViewport-width-01771"},
5339 {{0.0, 0.0, NAN, 64.0, 0.0, 1.0}, "VUID-VkViewport-width-01770"},
5340 {{0.0, 0.0, 64.0, one_past_max_h, 0.0, 1.0}, "VUID-VkViewport-height-01773"},
5341 {{one_before_min_bounds, 0.0, 64.0, 64.0, 0.0, 1.0}, "VUID-VkViewport-x-01774"},
5342 {{one_past_max_bounds, 0.0, 64.0, 64.0, 0.0, 1.0}, "VUID-VkViewport-x-01232"},
5343 {{NAN, 0.0, 64.0, 64.0, 0.0, 1.0}, "VUID-VkViewport-x-01774"},
5344 {{0.0, one_before_min_bounds, 64.0, 64.0, 0.0, 1.0}, "VUID-VkViewport-y-01775"},
5345 {{0.0, NAN, 64.0, 64.0, 0.0, 1.0}, "VUID-VkViewport-y-01775"},
5346 {{max_bound, 0.0, 1.0, 64.0, 0.0, 1.0}, "VUID-VkViewport-x-01232"},
5347 {{0.0, max_bound, 64.0, 1.0, 0.0, 1.0}, "VUID-VkViewport-y-01233"},
5348 {{0.0, 0.0, 64.0, 64.0, below_zero, 1.0}, "VUID-VkViewport-minDepth-01234"},
5349 {{0.0, 0.0, 64.0, 64.0, past_one, 1.0}, "VUID-VkViewport-minDepth-01234"},
5350 {{0.0, 0.0, 64.0, 64.0, NAN, 1.0}, "VUID-VkViewport-minDepth-01234"},
5351 {{0.0, 0.0, 64.0, 64.0, 0.0, below_zero}, "VUID-VkViewport-maxDepth-01235"},
5352 {{0.0, 0.0, 64.0, 64.0, 0.0, past_one}, "VUID-VkViewport-maxDepth-01235"},
5353 {{0.0, 0.0, 64.0, 64.0, 0.0, NAN}, "VUID-VkViewport-maxDepth-01235"},
5354 };
5355
5356 if (DeviceValidationVersion() < VK_API_VERSION_1_1) {
5357 test_cases.push_back({{0.0, 0.0, 64.0, 0.0, 0.0, 1.0}, "VUID-VkViewport-height-01772"});
5358 test_cases.push_back({{0.0, 0.0, 64.0, NAN, 0.0, 1.0}, "VUID-VkViewport-height-01772"});
5359 } else {
5360 test_cases.push_back({{0.0, 0.0, 64.0, NAN, 0.0, 1.0}, "VUID-VkViewport-height-01773"});
5361 }
5362
5363 for (const auto &test_case : test_cases) {
Mark Lobodzinski20310782020-02-28 14:25:17 -07005364 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, test_case.veid);
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06005365 vk::CmdSetViewport(m_commandBuffer->handle(), 0, 1, &test_case.vp);
unknown088160a2019-05-23 17:43:13 -06005366 m_errorMonitor->VerifyFound();
5367 }
5368}
5369
5370TEST_F(VkLayerTest, SetDynViewportParamMaintenance1Tests) {
5371 TEST_DESCRIPTION("Verify errors are detected on misuse of SetViewport with a negative viewport extension enabled.");
5372
Mark Lobodzinski09ce9c42020-03-06 10:02:44 -07005373 ASSERT_NO_FATAL_FAILURE(InitFramework(m_errorMonitor));
unknown088160a2019-05-23 17:43:13 -06005374
5375 if (DeviceExtensionSupported(gpu(), nullptr, VK_KHR_MAINTENANCE1_EXTENSION_NAME)) {
5376 m_device_extension_names.push_back(VK_KHR_MAINTENANCE1_EXTENSION_NAME);
5377 } else {
5378 printf("%s VK_KHR_maintenance1 extension not supported -- skipping test\n", kSkipPrefix);
5379 return;
5380 }
5381 ASSERT_NO_FATAL_FAILURE(InitState());
5382
5383 NegHeightViewportTests(m_device, m_commandBuffer, m_errorMonitor);
5384}
5385
5386TEST_F(VkLayerTest, SetDynViewportParamMultiviewportTests) {
5387 TEST_DESCRIPTION("Test parameters of vkCmdSetViewport with multiViewport feature enabled");
5388
5389 ASSERT_NO_FATAL_FAILURE(Init());
5390
5391 if (!m_device->phy().features().multiViewport) {
5392 printf("%s VkPhysicalDeviceFeatures::multiViewport is not supported -- skipping test.\n", kSkipPrefix);
5393 return;
5394 }
5395
unknown088160a2019-05-23 17:43:13 -06005396 m_commandBuffer->begin();
5397
Mark Lobodzinski20310782020-02-28 14:25:17 -07005398 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdSetViewport-viewportCount-arraylength");
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06005399 vk::CmdSetViewport(m_commandBuffer->handle(), 0, 0, nullptr);
unknown088160a2019-05-23 17:43:13 -06005400 m_errorMonitor->VerifyFound();
5401
Petr Kraus14e49492019-09-09 20:13:29 +02005402 const auto max_viewports = m_device->props.limits.maxViewports;
5403
Mark Lobodzinski20310782020-02-28 14:25:17 -07005404 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdSetViewport-pViewports-parameter");
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06005405 vk::CmdSetViewport(m_commandBuffer->handle(), 0, max_viewports, nullptr);
unknown088160a2019-05-23 17:43:13 -06005406 m_errorMonitor->VerifyFound();
5407
Petr Kraus14e49492019-09-09 20:13:29 +02005408 const uint32_t too_big_max_viewports = 65536 + 1; // let's say this is too much to allocate
5409 if (max_viewports >= too_big_max_viewports) {
5410 printf("%s VkPhysicalDeviceLimits::maxViewports is too large to practically test against -- skipping part of test.\n",
5411 kSkipPrefix);
5412 } else {
5413 const VkViewport vp = {0.0, 0.0, 64.0, 64.0, 0.0, 1.0};
5414 const std::vector<VkViewport> viewports(max_viewports + 1, vp);
5415
Mark Lobodzinski20310782020-02-28 14:25:17 -07005416 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdSetViewport-firstViewport-01223");
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06005417 vk::CmdSetViewport(m_commandBuffer->handle(), 0, max_viewports + 1, viewports.data());
Petr Kraus14e49492019-09-09 20:13:29 +02005418 m_errorMonitor->VerifyFound();
5419
Mark Lobodzinski20310782020-02-28 14:25:17 -07005420 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdSetViewport-firstViewport-01223");
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06005421 vk::CmdSetViewport(m_commandBuffer->handle(), max_viewports, 1, viewports.data());
Petr Kraus14e49492019-09-09 20:13:29 +02005422 m_errorMonitor->VerifyFound();
5423
Mark Lobodzinski20310782020-02-28 14:25:17 -07005424 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdSetViewport-firstViewport-01223");
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06005425 vk::CmdSetViewport(m_commandBuffer->handle(), 1, max_viewports, viewports.data());
Petr Kraus14e49492019-09-09 20:13:29 +02005426 m_errorMonitor->VerifyFound();
5427
Mark Lobodzinski20310782020-02-28 14:25:17 -07005428 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdSetViewport-viewportCount-arraylength");
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06005429 vk::CmdSetViewport(m_commandBuffer->handle(), 1, 0, viewports.data());
Petr Kraus14e49492019-09-09 20:13:29 +02005430 m_errorMonitor->VerifyFound();
unknown088160a2019-05-23 17:43:13 -06005431 }
unknown088160a2019-05-23 17:43:13 -06005432}
5433
5434TEST_F(VkLayerTest, BadRenderPassScopeSecondaryCmdBuffer) {
5435 TEST_DESCRIPTION(
5436 "Test secondary buffers executed in wrong render pass scope wrt VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT");
5437
5438 ASSERT_NO_FATAL_FAILURE(Init());
5439 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
5440
5441 VkCommandBufferObj sec_cmdbuff_inside_rp(m_device, m_commandPool, VK_COMMAND_BUFFER_LEVEL_SECONDARY);
5442 VkCommandBufferObj sec_cmdbuff_outside_rp(m_device, m_commandPool, VK_COMMAND_BUFFER_LEVEL_SECONDARY);
5443
5444 const VkCommandBufferInheritanceInfo cmdbuff_ii = {
5445 VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO,
5446 nullptr, // pNext
5447 m_renderPass,
5448 0, // subpass
5449 m_framebuffer,
5450 };
5451 const VkCommandBufferBeginInfo cmdbuff_bi_tmpl = {VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,
5452 nullptr, // pNext
5453 VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT, &cmdbuff_ii};
5454
5455 VkCommandBufferBeginInfo cmdbuff_inside_rp_bi = cmdbuff_bi_tmpl;
5456 cmdbuff_inside_rp_bi.flags |= VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT;
5457 sec_cmdbuff_inside_rp.begin(&cmdbuff_inside_rp_bi);
5458 sec_cmdbuff_inside_rp.end();
5459
5460 VkCommandBufferBeginInfo cmdbuff_outside_rp_bi = cmdbuff_bi_tmpl;
5461 cmdbuff_outside_rp_bi.flags &= ~VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT;
5462 sec_cmdbuff_outside_rp.begin(&cmdbuff_outside_rp_bi);
5463 sec_cmdbuff_outside_rp.end();
5464
5465 m_commandBuffer->begin();
5466
Mark Lobodzinski20310782020-02-28 14:25:17 -07005467 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdExecuteCommands-pCommandBuffers-00100");
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06005468 vk::CmdExecuteCommands(m_commandBuffer->handle(), 1, &sec_cmdbuff_inside_rp.handle());
unknown088160a2019-05-23 17:43:13 -06005469 m_errorMonitor->VerifyFound();
5470
5471 const VkRenderPassBeginInfo rp_bi{VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,
5472 nullptr, // pNext
5473 m_renderPass,
5474 m_framebuffer,
5475 {{0, 0}, {32, 32}},
5476 static_cast<uint32_t>(m_renderPassClearValues.size()),
5477 m_renderPassClearValues.data()};
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06005478 vk::CmdBeginRenderPass(m_commandBuffer->handle(), &rp_bi, VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS);
unknown088160a2019-05-23 17:43:13 -06005479
Mark Lobodzinski20310782020-02-28 14:25:17 -07005480 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdExecuteCommands-pCommandBuffers-00096");
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06005481 vk::CmdExecuteCommands(m_commandBuffer->handle(), 1, &sec_cmdbuff_outside_rp.handle());
unknown088160a2019-05-23 17:43:13 -06005482 m_errorMonitor->VerifyFound();
5483}
5484
5485TEST_F(VkLayerTest, SecondaryCommandBufferClearColorAttachmentsRenderArea) {
5486 TEST_DESCRIPTION(
5487 "Create a secondary command buffer with CmdClearAttachments call that has a rect outside of renderPass renderArea");
5488 ASSERT_NO_FATAL_FAILURE(Init());
5489 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
5490
5491 VkCommandBufferAllocateInfo command_buffer_allocate_info = {};
5492 command_buffer_allocate_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
5493 command_buffer_allocate_info.commandPool = m_commandPool->handle();
5494 command_buffer_allocate_info.level = VK_COMMAND_BUFFER_LEVEL_SECONDARY;
5495 command_buffer_allocate_info.commandBufferCount = 1;
5496
5497 VkCommandBuffer secondary_command_buffer;
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06005498 ASSERT_VK_SUCCESS(vk::AllocateCommandBuffers(m_device->device(), &command_buffer_allocate_info, &secondary_command_buffer));
unknown088160a2019-05-23 17:43:13 -06005499 VkCommandBufferBeginInfo command_buffer_begin_info = {};
5500 VkCommandBufferInheritanceInfo command_buffer_inheritance_info = {};
5501 command_buffer_inheritance_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO;
5502 command_buffer_inheritance_info.renderPass = m_renderPass;
5503 command_buffer_inheritance_info.framebuffer = m_framebuffer;
5504
5505 command_buffer_begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
5506 command_buffer_begin_info.flags =
5507 VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT | VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT;
5508 command_buffer_begin_info.pInheritanceInfo = &command_buffer_inheritance_info;
5509
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06005510 vk::BeginCommandBuffer(secondary_command_buffer, &command_buffer_begin_info);
unknown088160a2019-05-23 17:43:13 -06005511 VkClearAttachment color_attachment;
5512 color_attachment.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
5513 color_attachment.clearValue.color.float32[0] = 0;
5514 color_attachment.clearValue.color.float32[1] = 0;
5515 color_attachment.clearValue.color.float32[2] = 0;
5516 color_attachment.clearValue.color.float32[3] = 0;
5517 color_attachment.colorAttachment = 0;
5518 // x extent of 257 exceeds render area of 256
Mark Lobodzinski62490892019-06-28 09:58:27 -06005519 VkClearRect clear_rect = {{{0, 0}, {257, 32}}, 0, 1};
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06005520 vk::CmdClearAttachments(secondary_command_buffer, 1, &color_attachment, 1, &clear_rect);
5521 vk::EndCommandBuffer(secondary_command_buffer);
unknown088160a2019-05-23 17:43:13 -06005522 m_commandBuffer->begin();
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06005523 vk::CmdBeginRenderPass(m_commandBuffer->handle(), &m_renderPassBeginInfo, VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS);
unknown088160a2019-05-23 17:43:13 -06005524
Mark Lobodzinski20310782020-02-28 14:25:17 -07005525 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdClearAttachments-pRects-00016");
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06005526 vk::CmdExecuteCommands(m_commandBuffer->handle(), 1, &secondary_command_buffer);
unknown088160a2019-05-23 17:43:13 -06005527 m_errorMonitor->VerifyFound();
5528
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06005529 vk::CmdEndRenderPass(m_commandBuffer->handle());
unknown088160a2019-05-23 17:43:13 -06005530 m_commandBuffer->end();
5531}
5532
5533TEST_F(VkLayerTest, PushDescriptorSetCmdPushBadArgs) {
5534 TEST_DESCRIPTION("Attempt to push a push descriptor set with incorrect arguments.");
5535 if (InstanceExtensionSupported(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME)) {
5536 m_instance_extension_names.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
5537 } else {
5538 printf("%s %s Extension not supported, skipping tests\n", kSkipPrefix,
5539 VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
5540 return;
5541 }
5542
Mark Lobodzinski09ce9c42020-03-06 10:02:44 -07005543 ASSERT_NO_FATAL_FAILURE(InitFramework(m_errorMonitor));
unknown088160a2019-05-23 17:43:13 -06005544 if (DeviceExtensionSupported(gpu(), nullptr, VK_KHR_PUSH_DESCRIPTOR_EXTENSION_NAME)) {
5545 m_device_extension_names.push_back(VK_KHR_PUSH_DESCRIPTOR_EXTENSION_NAME);
5546 } else {
5547 printf("%s %s Extension not supported, skipping tests\n", kSkipPrefix, VK_KHR_PUSH_DESCRIPTOR_EXTENSION_NAME);
5548 return;
5549 }
5550 ASSERT_NO_FATAL_FAILURE(InitState());
5551
5552 auto push_descriptor_prop = GetPushDescriptorProperties(instance(), gpu());
5553 if (push_descriptor_prop.maxPushDescriptors < 1) {
5554 // Some implementations report an invalid maxPushDescriptors of 0
5555 printf("%s maxPushDescriptors is zero, skipping tests\n", kSkipPrefix);
5556 return;
5557 }
5558
5559 // Create ordinary and push descriptor set layout
5560 VkDescriptorSetLayoutBinding binding = {0, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1, VK_SHADER_STAGE_FRAGMENT_BIT, nullptr};
5561 const VkDescriptorSetLayoutObj ds_layout(m_device, {binding});
5562 ASSERT_TRUE(ds_layout.initialized());
5563 const VkDescriptorSetLayoutObj push_ds_layout(m_device, {binding}, VK_DESCRIPTOR_SET_LAYOUT_CREATE_PUSH_DESCRIPTOR_BIT_KHR);
5564 ASSERT_TRUE(push_ds_layout.initialized());
5565
5566 // Now use the descriptor set layouts to create a pipeline layout
5567 const VkPipelineLayoutObj pipeline_layout(m_device, {&push_ds_layout, &ds_layout});
5568 ASSERT_TRUE(pipeline_layout.initialized());
5569
5570 // Create a descriptor to push
5571 const uint32_t buffer_data[4] = {4, 5, 6, 7};
5572 VkConstantBufferObj buffer_obj(m_device, sizeof(buffer_data), &buffer_data);
5573 ASSERT_TRUE(buffer_obj.initialized());
5574
5575 // Create a "write" struct, noting that the buffer_info cannot be a temporary arg (the return from write_descriptor_set
5576 // references its data), and the DescriptorSet() can be temporary, because the value is ignored
5577 VkDescriptorBufferInfo buffer_info = {buffer_obj.handle(), 0, VK_WHOLE_SIZE};
5578
5579 VkWriteDescriptorSet descriptor_write = vk_testing::Device::write_descriptor_set(
5580 vk_testing::DescriptorSet(), 0, 0, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1, &buffer_info);
5581
5582 // Find address of extension call and make the call
5583 PFN_vkCmdPushDescriptorSetKHR vkCmdPushDescriptorSetKHR =
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06005584 (PFN_vkCmdPushDescriptorSetKHR)vk::GetDeviceProcAddr(m_device->device(), "vkCmdPushDescriptorSetKHR");
unknown088160a2019-05-23 17:43:13 -06005585 ASSERT_TRUE(vkCmdPushDescriptorSetKHR != nullptr);
5586
5587 // Section 1: Queue family matching/capabilities.
5588 // Create command pool on a non-graphics queue
5589 const uint32_t no_gfx_qfi = m_device->QueueFamilyMatching(VK_QUEUE_COMPUTE_BIT, VK_QUEUE_GRAPHICS_BIT);
5590 const uint32_t transfer_only_qfi =
5591 m_device->QueueFamilyMatching(VK_QUEUE_TRANSFER_BIT, (VK_QUEUE_COMPUTE_BIT | VK_QUEUE_GRAPHICS_BIT));
5592 if ((UINT32_MAX == transfer_only_qfi) && (UINT32_MAX == no_gfx_qfi)) {
unknownc3033e52019-06-21 16:56:20 -06005593 printf("%s No compute or transfer only queue family, skipping bindpoint and queue tests.\n", kSkipPrefix);
unknown088160a2019-05-23 17:43:13 -06005594 } else {
5595 const uint32_t err_qfi = (UINT32_MAX == no_gfx_qfi) ? transfer_only_qfi : no_gfx_qfi;
5596
5597 VkCommandPoolObj command_pool(m_device, err_qfi);
5598 ASSERT_TRUE(command_pool.initialized());
5599 VkCommandBufferObj command_buffer(m_device, &command_pool);
5600 ASSERT_TRUE(command_buffer.initialized());
5601 command_buffer.begin();
5602
Mark Lobodzinski20310782020-02-28 14:25:17 -07005603 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdPushDescriptorSetKHR-pipelineBindPoint-00363");
5604 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkWriteDescriptorSet-descriptorType-00330");
unknown088160a2019-05-23 17:43:13 -06005605 if (err_qfi == transfer_only_qfi) {
5606 // This as this queue neither supports the gfx or compute bindpoints, we'll get two errors
Mark Lobodzinski20310782020-02-28 14:25:17 -07005607 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdPushDescriptorSetKHR-commandBuffer-cmdpool");
unknown088160a2019-05-23 17:43:13 -06005608 }
5609 vkCmdPushDescriptorSetKHR(command_buffer.handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_layout.handle(), 0, 1,
5610 &descriptor_write);
5611 m_errorMonitor->VerifyFound();
5612 command_buffer.end();
5613
5614 // If we succeed in testing only one condition above, we need to test the other below.
5615 if ((UINT32_MAX != transfer_only_qfi) && (err_qfi != transfer_only_qfi)) {
5616 // Need to test the neither compute/gfx supported case separately.
5617 VkCommandPoolObj tran_command_pool(m_device, transfer_only_qfi);
5618 ASSERT_TRUE(tran_command_pool.initialized());
5619 VkCommandBufferObj tran_command_buffer(m_device, &tran_command_pool);
5620 ASSERT_TRUE(tran_command_buffer.initialized());
5621 tran_command_buffer.begin();
5622
5623 // We can't avoid getting *both* errors in this case
Mark Lobodzinski20310782020-02-28 14:25:17 -07005624 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdPushDescriptorSetKHR-pipelineBindPoint-00363");
5625 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkWriteDescriptorSet-descriptorType-00330");
5626 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdPushDescriptorSetKHR-commandBuffer-cmdpool");
unknown088160a2019-05-23 17:43:13 -06005627 vkCmdPushDescriptorSetKHR(tran_command_buffer.handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_layout.handle(), 0, 1,
5628 &descriptor_write);
5629 m_errorMonitor->VerifyFound();
5630 tran_command_buffer.end();
5631 }
5632 }
5633
5634 // Push to the non-push binding
5635 m_commandBuffer->begin();
Mark Lobodzinski20310782020-02-28 14:25:17 -07005636 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdPushDescriptorSetKHR-set-00365");
unknown088160a2019-05-23 17:43:13 -06005637 vkCmdPushDescriptorSetKHR(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_layout.handle(), 1, 1,
5638 &descriptor_write);
5639 m_errorMonitor->VerifyFound();
5640
5641 // Specify set out of bounds
Mark Lobodzinski20310782020-02-28 14:25:17 -07005642 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdPushDescriptorSetKHR-set-00364");
unknown088160a2019-05-23 17:43:13 -06005643 vkCmdPushDescriptorSetKHR(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_layout.handle(), 2, 1,
5644 &descriptor_write);
5645 m_errorMonitor->VerifyFound();
5646 m_commandBuffer->end();
5647
5648 // This is a test for VUID-vkCmdPushDescriptorSetKHR-commandBuffer-recording
5649 // TODO: Add VALIDATION_ERROR_ code support to core_validation::ValidateCmd
Mark Lobodzinski20310782020-02-28 14:25:17 -07005650 m_errorMonitor->SetDesiredFailureMsg(kErrorBit,
unknown088160a2019-05-23 17:43:13 -06005651 "You must call vkBeginCommandBuffer() before this call to vkCmdPushDescriptorSetKHR()");
Mark Lobodzinski20310782020-02-28 14:25:17 -07005652 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkWriteDescriptorSet-descriptorType-00330");
unknown088160a2019-05-23 17:43:13 -06005653 vkCmdPushDescriptorSetKHR(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_layout.handle(), 0, 1,
5654 &descriptor_write);
5655 m_errorMonitor->VerifyFound();
5656}
5657
Jeremy Hayesf96a5162020-02-10 13:49:31 -07005658TEST_F(VkLayerTest, PushDescriptorSetCmdBufferOffsetUnaligned) {
5659 TEST_DESCRIPTION("Attempt to push a push descriptor set buffer with unaligned offset.");
5660 if (InstanceExtensionSupported(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME)) {
5661 m_instance_extension_names.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
5662 } else {
5663 printf("%s %s Extension not supported, skipping tests\n", kSkipPrefix,
5664 VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
5665 return;
5666 }
5667
Mark Lobodzinski09ce9c42020-03-06 10:02:44 -07005668 ASSERT_NO_FATAL_FAILURE(InitFramework(m_errorMonitor));
Jeremy Hayesf96a5162020-02-10 13:49:31 -07005669 if (DeviceExtensionSupported(gpu(), nullptr, VK_KHR_PUSH_DESCRIPTOR_EXTENSION_NAME)) {
5670 m_device_extension_names.push_back(VK_KHR_PUSH_DESCRIPTOR_EXTENSION_NAME);
5671 } else {
5672 printf("%s %s Extension not supported, skipping tests\n", kSkipPrefix, VK_KHR_PUSH_DESCRIPTOR_EXTENSION_NAME);
5673 return;
5674 }
5675 ASSERT_NO_FATAL_FAILURE(InitState());
5676
5677 auto const push_descriptor_prop = GetPushDescriptorProperties(instance(), gpu());
5678 if (push_descriptor_prop.maxPushDescriptors < 1) {
5679 // Some implementations report an invalid maxPushDescriptors of 0.
5680 printf("%s maxPushDescriptors is zero, skipping test\n", kSkipPrefix);
5681 return;
5682 }
5683
5684 auto const min_alignment = m_device->props.limits.minUniformBufferOffsetAlignment;
5685 if (min_alignment == 0) {
5686 printf("%s minUniformBufferOffsetAlignment is zero, skipping test\n", kSkipPrefix);
5687 return;
5688 }
5689
5690 VkDescriptorSetLayoutBinding binding = {0, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1, VK_SHADER_STAGE_FRAGMENT_BIT, nullptr};
5691 const VkDescriptorSetLayoutObj push_ds_layout(m_device, {binding}, VK_DESCRIPTOR_SET_LAYOUT_CREATE_PUSH_DESCRIPTOR_BIT_KHR);
5692 ASSERT_TRUE(push_ds_layout.initialized());
5693
5694 const VkPipelineLayoutObj pipeline_layout(m_device, {&push_ds_layout});
5695 ASSERT_TRUE(pipeline_layout.initialized());
5696
5697 const uint32_t buffer_data[4] = {4, 5, 6, 7};
5698 VkConstantBufferObj buffer_obj(m_device, sizeof(buffer_data), &buffer_data, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT);
5699 ASSERT_TRUE(buffer_obj.initialized());
5700
5701 // Use an invalid alignment.
5702 VkDescriptorBufferInfo buffer_info = {buffer_obj.handle(), min_alignment - 1, VK_WHOLE_SIZE};
5703 VkWriteDescriptorSet descriptor_write = vk_testing::Device::write_descriptor_set(
5704 vk_testing::DescriptorSet(), 0, 0, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1, &buffer_info);
5705
5706 PFN_vkCmdPushDescriptorSetKHR vkCmdPushDescriptorSetKHR =
5707 (PFN_vkCmdPushDescriptorSetKHR)vk::GetDeviceProcAddr(m_device->device(), "vkCmdPushDescriptorSetKHR");
5708 ASSERT_TRUE(vkCmdPushDescriptorSetKHR != nullptr);
5709
5710 m_commandBuffer->begin();
Mark Lobodzinski20310782020-02-28 14:25:17 -07005711 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkWriteDescriptorSet-descriptorType-00327");
Jeremy Hayesf96a5162020-02-10 13:49:31 -07005712 vkCmdPushDescriptorSetKHR(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_layout.handle(), 0, 1,
5713 &descriptor_write);
5714 m_errorMonitor->VerifyFound();
5715
5716 m_commandBuffer->end();
5717}
5718
unknown088160a2019-05-23 17:43:13 -06005719TEST_F(VkLayerTest, SetDynScissorParamTests) {
5720 TEST_DESCRIPTION("Test parameters of vkCmdSetScissor without multiViewport feature");
5721
5722 VkPhysicalDeviceFeatures features{};
5723 ASSERT_NO_FATAL_FAILURE(Init(&features));
5724
5725 const VkRect2D scissor = {{0, 0}, {16, 16}};
5726 const VkRect2D scissors[] = {scissor, scissor};
5727
5728 m_commandBuffer->begin();
5729
5730 // array tests
Mark Lobodzinski20310782020-02-28 14:25:17 -07005731 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdSetScissor-firstScissor-00593");
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06005732 vk::CmdSetScissor(m_commandBuffer->handle(), 1, 1, scissors);
unknown088160a2019-05-23 17:43:13 -06005733 m_errorMonitor->VerifyFound();
5734
Mark Lobodzinski20310782020-02-28 14:25:17 -07005735 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdSetScissor-scissorCount-arraylength");
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06005736 vk::CmdSetScissor(m_commandBuffer->handle(), 0, 0, nullptr);
unknown088160a2019-05-23 17:43:13 -06005737 m_errorMonitor->VerifyFound();
5738
Mark Lobodzinski20310782020-02-28 14:25:17 -07005739 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdSetScissor-scissorCount-00594");
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06005740 vk::CmdSetScissor(m_commandBuffer->handle(), 0, 2, scissors);
unknown088160a2019-05-23 17:43:13 -06005741 m_errorMonitor->VerifyFound();
5742
Mark Lobodzinski20310782020-02-28 14:25:17 -07005743 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdSetScissor-firstScissor-00593");
5744 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdSetScissor-scissorCount-00594");
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06005745 vk::CmdSetScissor(m_commandBuffer->handle(), 1, 2, scissors);
unknown088160a2019-05-23 17:43:13 -06005746 m_errorMonitor->VerifyFound();
5747
Mark Lobodzinski20310782020-02-28 14:25:17 -07005748 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdSetScissor-pScissors-parameter");
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06005749 vk::CmdSetScissor(m_commandBuffer->handle(), 0, 1, nullptr);
unknown088160a2019-05-23 17:43:13 -06005750 m_errorMonitor->VerifyFound();
5751
5752 struct TestCase {
5753 VkRect2D scissor;
5754 std::string vuid;
5755 };
5756
5757 std::vector<TestCase> test_cases = {{{{-1, 0}, {16, 16}}, "VUID-vkCmdSetScissor-x-00595"},
5758 {{{0, -1}, {16, 16}}, "VUID-vkCmdSetScissor-x-00595"},
5759 {{{1, 0}, {INT32_MAX, 16}}, "VUID-vkCmdSetScissor-offset-00596"},
5760 {{{INT32_MAX, 0}, {1, 16}}, "VUID-vkCmdSetScissor-offset-00596"},
5761 {{{0, 0}, {uint32_t{INT32_MAX} + 1, 16}}, "VUID-vkCmdSetScissor-offset-00596"},
5762 {{{0, 1}, {16, INT32_MAX}}, "VUID-vkCmdSetScissor-offset-00597"},
5763 {{{0, INT32_MAX}, {16, 1}}, "VUID-vkCmdSetScissor-offset-00597"},
5764 {{{0, 0}, {16, uint32_t{INT32_MAX} + 1}}, "VUID-vkCmdSetScissor-offset-00597"}};
5765
5766 for (const auto &test_case : test_cases) {
Mark Lobodzinski20310782020-02-28 14:25:17 -07005767 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, test_case.vuid);
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06005768 vk::CmdSetScissor(m_commandBuffer->handle(), 0, 1, &test_case.scissor);
unknown088160a2019-05-23 17:43:13 -06005769 m_errorMonitor->VerifyFound();
5770 }
5771
5772 m_commandBuffer->end();
5773}
5774
5775TEST_F(VkLayerTest, SetDynScissorParamMultiviewportTests) {
5776 TEST_DESCRIPTION("Test parameters of vkCmdSetScissor with multiViewport feature enabled");
5777
5778 ASSERT_NO_FATAL_FAILURE(Init());
5779
5780 if (!m_device->phy().features().multiViewport) {
5781 printf("%s VkPhysicalDeviceFeatures::multiViewport is not supported -- skipping test.\n", kSkipPrefix);
5782 return;
5783 }
5784
unknown088160a2019-05-23 17:43:13 -06005785 m_commandBuffer->begin();
5786
Mark Lobodzinski20310782020-02-28 14:25:17 -07005787 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdSetScissor-scissorCount-arraylength");
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06005788 vk::CmdSetScissor(m_commandBuffer->handle(), 0, 0, nullptr);
unknown088160a2019-05-23 17:43:13 -06005789 m_errorMonitor->VerifyFound();
5790
Petr Kraus14e49492019-09-09 20:13:29 +02005791 const auto max_scissors = m_device->props.limits.maxViewports;
5792
Mark Lobodzinski20310782020-02-28 14:25:17 -07005793 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdSetScissor-pScissors-parameter");
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06005794 vk::CmdSetScissor(m_commandBuffer->handle(), 0, max_scissors, nullptr);
unknown088160a2019-05-23 17:43:13 -06005795 m_errorMonitor->VerifyFound();
5796
Petr Kraus14e49492019-09-09 20:13:29 +02005797 const uint32_t too_big_max_scissors = 65536 + 1; // let's say this is too much to allocate
5798 if (max_scissors >= too_big_max_scissors) {
5799 printf("%s VkPhysicalDeviceLimits::maxViewports is too large to practically test against -- skipping part of test.\n",
5800 kSkipPrefix);
5801 } else {
5802 const VkRect2D scissor = {{0, 0}, {16, 16}};
5803 const std::vector<VkRect2D> scissors(max_scissors + 1, scissor);
5804
Mark Lobodzinski20310782020-02-28 14:25:17 -07005805 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdSetScissor-firstScissor-00592");
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06005806 vk::CmdSetScissor(m_commandBuffer->handle(), 0, max_scissors + 1, scissors.data());
Petr Kraus14e49492019-09-09 20:13:29 +02005807 m_errorMonitor->VerifyFound();
5808
Mark Lobodzinski20310782020-02-28 14:25:17 -07005809 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdSetScissor-firstScissor-00592");
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06005810 vk::CmdSetScissor(m_commandBuffer->handle(), max_scissors, 1, scissors.data());
Petr Kraus14e49492019-09-09 20:13:29 +02005811 m_errorMonitor->VerifyFound();
5812
Mark Lobodzinski20310782020-02-28 14:25:17 -07005813 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdSetScissor-firstScissor-00592");
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06005814 vk::CmdSetScissor(m_commandBuffer->handle(), 1, max_scissors, scissors.data());
Petr Kraus14e49492019-09-09 20:13:29 +02005815 m_errorMonitor->VerifyFound();
5816
Mark Lobodzinski20310782020-02-28 14:25:17 -07005817 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdSetScissor-scissorCount-arraylength");
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06005818 vk::CmdSetScissor(m_commandBuffer->handle(), 1, 0, scissors.data());
Petr Kraus14e49492019-09-09 20:13:29 +02005819 m_errorMonitor->VerifyFound();
unknown088160a2019-05-23 17:43:13 -06005820 }
unknown088160a2019-05-23 17:43:13 -06005821}
5822
Tony-LunarG667cc022021-06-25 10:11:17 -06005823TEST_F(VkLayerTest, MultiDrawTests) {
5824 TEST_DESCRIPTION("Test validation of multi_draw extension");
5825 SetTargetApiVersion(VK_API_VERSION_1_2);
5826 ASSERT_NO_FATAL_FAILURE(InitFramework(m_errorMonitor));
5827 if (DeviceValidationVersion() < VK_API_VERSION_1_2) {
5828 printf("%s Tests requires Vulkan 1.2+, skipping test\n", kSkipPrefix);
5829 return;
5830 }
5831
5832 auto multi_draw_features = LvlInitStruct<VkPhysicalDeviceMultiDrawFeaturesEXT>();
5833 auto features2 = LvlInitStruct<VkPhysicalDeviceFeatures2KHR>(&multi_draw_features);
5834 vk::GetPhysicalDeviceFeatures2(gpu(), &features2);
5835 if (!multi_draw_features.multiDraw) {
5836 printf("%s Test requires (unsupported) multiDraw, skipping\n", kSkipPrefix);
5837 return;
5838 }
5839 if (DeviceExtensionSupported(gpu(), nullptr, VK_EXT_MULTI_DRAW_EXTENSION_NAME)) {
5840 m_device_extension_names.push_back(VK_EXT_MULTI_DRAW_EXTENSION_NAME);
5841 } else {
5842 printf("%s VK_EXT_multi_draw extension not supported, skipping test\n", kSkipPrefix);
5843 return;
5844 }
5845 auto multi_draw_properties = LvlInitStruct<VkPhysicalDeviceMultiDrawPropertiesEXT>();
5846 auto properties2 = LvlInitStruct<VkPhysicalDeviceProperties2>(&multi_draw_properties);
5847 vk::GetPhysicalDeviceProperties2(gpu(), &properties2);
5848
5849 ASSERT_NO_FATAL_FAILURE(InitState(nullptr, &features2));
5850 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
5851
5852 auto vkCmdDrawMultiEXT = (PFN_vkCmdDrawMultiEXT)vk::GetDeviceProcAddr(m_device->device(), "vkCmdDrawMultiEXT");
5853 auto vkCmdDrawMultiIndexedEXT =
5854 (PFN_vkCmdDrawMultiIndexedEXT)vk::GetDeviceProcAddr(m_device->device(), "vkCmdDrawMultiIndexedEXT");
5855 assert(vkCmdDrawMultiEXT != nullptr && vkCmdDrawMultiIndexedEXT != nullptr);
5856
5857 VkMultiDrawInfoEXT multi_draws[3] = {};
5858 multi_draws[0].vertexCount = multi_draws[1].vertexCount = multi_draws[2].vertexCount = 3;
5859
5860 VkMultiDrawIndexedInfoEXT multi_draw_indices[3] = {};
5861 multi_draw_indices[0].indexCount = multi_draw_indices[1].indexCount = multi_draw_indices[2].indexCount = 1;
5862
5863 CreatePipelineHelper pipe(*this);
5864 pipe.InitInfo();
5865 pipe.InitState();
5866 pipe.CreateGraphicsPipeline();
5867
5868 // Try existing VUID checks
5869 m_commandBuffer->begin();
5870 m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
5871
5872 vk::CmdBindDescriptorSets(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.pipeline_layout_.handle(), 0, 1,
5873 &pipe.descriptor_set_->set_, 0, NULL);
5874 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdDrawMultiEXT-None-02700");
5875 vkCmdDrawMultiEXT(m_commandBuffer->handle(), 3, multi_draws, 1, 0, sizeof(VkMultiDrawInfoEXT));
5876 m_errorMonitor->VerifyFound();
5877 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdDrawMultiIndexedEXT-None-02700");
5878 vkCmdDrawMultiIndexedEXT(m_commandBuffer->handle(), 3, multi_draw_indices, 1, 0, sizeof(VkMultiDrawIndexedInfoEXT), 0);
5879 m_errorMonitor->VerifyFound();
5880
5881 vk::CmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.pipeline_);
5882
5883 // New VUIDs added with multi_draw (also see GPU-AV)
5884 VkBufferObj buffer;
5885 buffer.init(*m_device, 1024, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, VK_BUFFER_USAGE_INDEX_BUFFER_BIT);
5886 multi_draw_indices[2].indexCount = 513;
5887 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdDrawMultiIndexedEXT-firstIndex-04938");
5888 m_commandBuffer->BindIndexBuffer(&buffer, 0, VK_INDEX_TYPE_UINT16);
5889 vkCmdDrawMultiIndexedEXT(m_commandBuffer->handle(), 3, multi_draw_indices, 1, 0, sizeof(VkMultiDrawIndexedInfoEXT), 0);
5890 m_errorMonitor->VerifyFound();
5891 multi_draw_indices[2].indexCount = 1;
5892
5893 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdDrawMultiEXT-stride-04936");
5894 vkCmdDrawMultiEXT(m_commandBuffer->handle(), 3, multi_draws, 1, 0, sizeof(VkMultiDrawInfoEXT) + 1);
5895 m_errorMonitor->VerifyFound();
5896 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdDrawMultiIndexedEXT-stride-04941");
5897 vkCmdDrawMultiIndexedEXT(m_commandBuffer->handle(), 3, multi_draw_indices, 1, 0, sizeof(VkMultiDrawIndexedInfoEXT) + 1, 0);
5898 m_errorMonitor->VerifyFound();
5899
5900 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdDrawMultiEXT-drawCount-04935");
5901 vkCmdDrawMultiEXT(m_commandBuffer->handle(), 3, nullptr, 1, 0, sizeof(VkMultiDrawInfoEXT));
5902 m_errorMonitor->VerifyFound();
5903 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdDrawMultiIndexedEXT-drawCount-04940");
5904 vkCmdDrawMultiIndexedEXT(m_commandBuffer->handle(), 3, nullptr, 1, 0, sizeof(VkMultiDrawIndexedInfoEXT), 0);
5905 m_errorMonitor->VerifyFound();
5906
5907 if (multi_draw_properties.maxMultiDrawCount < UINT32_MAX) {
5908 uint32_t draw_count = multi_draw_properties.maxMultiDrawCount + 1;
5909 std::vector<VkMultiDrawInfoEXT> max_multi_draws(draw_count);
5910 std::vector<VkMultiDrawIndexedInfoEXT> max_multi_indexed_draws(draw_count);
5911 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdDrawMultiEXT-drawCount-04934");
5912 vkCmdDrawMultiEXT(m_commandBuffer->handle(), draw_count, max_multi_draws.data(), 1, 0, sizeof(VkMultiDrawInfoEXT));
5913 m_errorMonitor->VerifyFound();
5914 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdDrawMultiIndexedEXT-drawCount-04939");
5915 vkCmdDrawMultiIndexedEXT(m_commandBuffer->handle(), draw_count, max_multi_indexed_draws.data(), 1, 0,
5916 sizeof(VkMultiDrawIndexedInfoEXT), 0);
5917 m_errorMonitor->VerifyFound();
5918 }
5919}
5920
5921TEST_F(VkLayerTest, MultiDrawFeatures) {
5922 TEST_DESCRIPTION("Test validation of multi draw feature enabled");
5923 SetTargetApiVersion(VK_API_VERSION_1_2);
5924 ASSERT_NO_FATAL_FAILURE(InitFramework(m_errorMonitor));
5925 if (DeviceValidationVersion() < VK_API_VERSION_1_2) {
5926 printf("%s Tests requires Vulkan 1.2+, skipping test\n", kSkipPrefix);
5927 return;
5928 }
5929 if (DeviceExtensionSupported(gpu(), nullptr, VK_EXT_MULTI_DRAW_EXTENSION_NAME)) {
5930 m_device_extension_names.push_back(VK_EXT_MULTI_DRAW_EXTENSION_NAME);
5931 } else {
5932 printf("%s VK_EXT_multi_draw extension not supported, skipping test\n", kSkipPrefix);
5933 return;
5934 }
5935 ASSERT_NO_FATAL_FAILURE(InitState());
5936 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
5937
5938 auto vkCmdDrawMultiEXT = (PFN_vkCmdDrawMultiEXT)vk::GetDeviceProcAddr(m_device->device(), "vkCmdDrawMultiEXT");
5939 auto vkCmdDrawMultiIndexedEXT =
5940 (PFN_vkCmdDrawMultiIndexedEXT)vk::GetDeviceProcAddr(m_device->device(), "vkCmdDrawMultiIndexedEXT");
5941 assert(vkCmdDrawMultiEXT != nullptr && vkCmdDrawMultiIndexedEXT != nullptr);
5942
5943 VkMultiDrawInfoEXT multi_draws[3] = {};
5944 multi_draws[0].vertexCount = multi_draws[1].vertexCount = multi_draws[2].vertexCount = 3;
5945
5946 VkMultiDrawIndexedInfoEXT multi_draw_indices[3] = {};
5947 multi_draw_indices[0].indexCount = multi_draw_indices[1].indexCount = multi_draw_indices[2].indexCount = 1;
5948
5949 CreatePipelineHelper pipe(*this);
5950 pipe.InitInfo();
5951 pipe.InitState();
5952 pipe.CreateGraphicsPipeline();
5953
5954 m_commandBuffer->begin();
5955 vk::CmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.pipeline_);
5956 m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
5957 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdDrawMultiEXT-None-04933");
5958 vkCmdDrawMultiEXT(m_commandBuffer->handle(), 3, multi_draws, 1, 0, sizeof(VkMultiDrawInfoEXT));
5959 m_errorMonitor->VerifyFound();
5960 VkBufferObj buffer;
5961 buffer.init(*m_device, 1024, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, VK_BUFFER_USAGE_INDEX_BUFFER_BIT);
5962 m_commandBuffer->BindIndexBuffer(&buffer, 0, VK_INDEX_TYPE_UINT16);
5963 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdDrawMultiIndexedEXT-None-04937");
5964 vkCmdDrawMultiIndexedEXT(m_commandBuffer->handle(), 3, multi_draw_indices, 1, 0, sizeof(VkMultiDrawIndexedInfoEXT), 0);
5965 m_errorMonitor->VerifyFound();
5966}
5967
Mark Lobodzinski128608f2020-11-02 13:46:57 -07005968TEST_F(VkLayerTest, IndirectDrawTests) {
5969 TEST_DESCRIPTION("Test covered valid usage for vkCmdDrawIndirect and vkCmdDrawIndexedIndirect");
unknown088160a2019-05-23 17:43:13 -06005970
Mark Lobodzinski128608f2020-11-02 13:46:57 -07005971 if (InstanceExtensionSupported(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME)) {
5972 m_instance_extension_names.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
5973 } else {
5974 printf("%s Did not find required instance extension %s; skipped.\n", kSkipPrefix,
5975 VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
5976 return;
5977 }
5978 ASSERT_NO_FATAL_FAILURE(InitFramework(m_errorMonitor));
5979
5980 if (IsPlatform(kMockICD) || DeviceSimulation()) {
5981 printf("%sNot suppored by MockICD, skipping tests\n", kSkipPrefix);
5982 return;
5983 }
5984
5985 PFN_vkGetPhysicalDeviceFeatures2KHR vkGetPhysicalDeviceFeatures2KHR =
5986 (PFN_vkGetPhysicalDeviceFeatures2KHR)vk::GetInstanceProcAddr(instance(), "vkGetPhysicalDeviceFeatures2KHR");
5987 ASSERT_TRUE(vkGetPhysicalDeviceFeatures2KHR != nullptr);
5988
5989 // Create a device and ensure multiDrawIndirect is disabled
Mark Lobodzinski07d0a612020-12-30 15:42:31 -07005990 auto mesh_shader_features = LvlInitStruct<VkPhysicalDeviceMeshShaderFeaturesNV>();
5991 auto features2 = LvlInitStruct<VkPhysicalDeviceFeatures2KHR>(&mesh_shader_features);
Mark Lobodzinski128608f2020-11-02 13:46:57 -07005992 vkGetPhysicalDeviceFeatures2KHR(gpu(), &features2);
5993 features2.features.multiDrawIndirect = VK_FALSE;
5994
5995 ASSERT_NO_FATAL_FAILURE(InitState(nullptr, &features2));
unknown088160a2019-05-23 17:43:13 -06005996 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
5997
locke-lunarg8e2c91b2019-06-11 17:53:26 -06005998 CreatePipelineHelper pipe(*this);
5999 pipe.InitInfo();
6000 const VkDynamicState dyn_states[] = {VK_DYNAMIC_STATE_VIEWPORT, VK_DYNAMIC_STATE_SCISSOR};
6001 VkPipelineDynamicStateCreateInfo dyn_state_ci = {};
6002 dyn_state_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO;
6003 dyn_state_ci.dynamicStateCount = size(dyn_states);
6004 dyn_state_ci.pDynamicStates = dyn_states;
6005 pipe.dyn_state_ci_ = dyn_state_ci;
6006 pipe.InitState();
6007 pipe.CreateGraphicsPipeline();
unknown088160a2019-05-23 17:43:13 -06006008
6009 m_commandBuffer->begin();
6010 m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
6011
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06006012 vk::CmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.pipeline_);
6013 vk::CmdBindDescriptorSets(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.pipeline_layout_.handle(), 0, 1,
6014 &pipe.descriptor_set_->set_, 0, NULL);
unknown088160a2019-05-23 17:43:13 -06006015
6016 VkViewport viewport = {0, 0, 16, 16, 0, 1};
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06006017 vk::CmdSetViewport(m_commandBuffer->handle(), 0, 1, &viewport);
unknown088160a2019-05-23 17:43:13 -06006018 VkRect2D scissor = {{0, 0}, {16, 16}};
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06006019 vk::CmdSetScissor(m_commandBuffer->handle(), 0, 1, &scissor);
unknown088160a2019-05-23 17:43:13 -06006020
6021 VkBufferCreateInfo buffer_create_info = {VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO};
6022 buffer_create_info.usage = VK_BUFFER_USAGE_VERTEX_BUFFER_BIT;
6023 buffer_create_info.size = sizeof(VkDrawIndirectCommand);
locke-lunarg8e2c91b2019-06-11 17:53:26 -06006024 VkBufferObj draw_buffer;
6025 draw_buffer.init(*m_device, buffer_create_info);
unknown088160a2019-05-23 17:43:13 -06006026
6027 // VUID-vkCmdDrawIndirect-buffer-02709
Mark Lobodzinski20310782020-02-28 14:25:17 -07006028 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdDrawIndirect-buffer-02709");
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06006029 vk::CmdDrawIndirect(m_commandBuffer->handle(), draw_buffer.handle(), 0, 1, sizeof(VkDrawIndirectCommand));
unknown088160a2019-05-23 17:43:13 -06006030 m_errorMonitor->VerifyFound();
6031
Mark Lobodzinski128608f2020-11-02 13:46:57 -07006032 // VUID-vkCmdDrawIndirect-drawCount-02718
6033 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdDrawIndirect-drawCount-02718");
6034 vk::CmdDrawIndirect(m_commandBuffer->handle(), draw_buffer.handle(), 0, 2, sizeof(VkDrawIndirectCommand));
6035 m_errorMonitor->VerifyFound();
6036
6037 // VUID-vkCmdDrawIndexedIndirect-drawCount-02718
6038 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdDrawIndexedIndirect-drawCount-02718");
6039 vk::CmdDrawIndexedIndirect(m_commandBuffer->handle(), draw_buffer.handle(), 0, 2, sizeof(VkDrawIndexedIndirectCommand));
6040 m_errorMonitor->VerifyFound();
6041
unknown088160a2019-05-23 17:43:13 -06006042 m_commandBuffer->EndRenderPass();
6043 m_commandBuffer->end();
unknown088160a2019-05-23 17:43:13 -06006044}
6045
Mark Lobodzinski977f0342019-12-19 14:24:09 -07006046TEST_F(VkLayerTest, DrawIndirectByteCountEXT) {
6047 TEST_DESCRIPTION("Test covered valid usage for vkCmdDrawIndirectByteCountEXT");
6048
6049 if (InstanceExtensionSupported(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME)) {
6050 m_instance_extension_names.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
6051 } else {
6052 printf("%s Did not find required instance extension %s; skipped.\n", kSkipPrefix,
6053 VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
6054 return;
6055 }
Mark Lobodzinski09ce9c42020-03-06 10:02:44 -07006056 ASSERT_NO_FATAL_FAILURE(InitFramework(m_errorMonitor));
Mark Lobodzinski977f0342019-12-19 14:24:09 -07006057
6058 if (DeviceExtensionSupported(gpu(), nullptr, VK_EXT_TRANSFORM_FEEDBACK_EXTENSION_NAME)) {
6059 m_device_extension_names.push_back(VK_EXT_TRANSFORM_FEEDBACK_EXTENSION_NAME);
6060 } else {
6061 printf("%s VK_EXT_transform_feedback extension not supported, skipping test\n", kSkipPrefix);
Mark Lobodzinskid01b2bc2019-12-20 10:19:36 -07006062 return;
Mark Lobodzinski977f0342019-12-19 14:24:09 -07006063 }
6064
6065 ASSERT_NO_FATAL_FAILURE(InitState());
6066 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
6067
Mark Lobodzinski07d0a612020-12-30 15:42:31 -07006068 auto tf_properties = LvlInitStruct<VkPhysicalDeviceTransformFeedbackPropertiesEXT>();
6069 auto pd_properties = LvlInitStruct<VkPhysicalDeviceProperties2>(&tf_properties);
sfricke-samsungd5e9adb2020-10-26 03:59:29 -07006070 vk::GetPhysicalDeviceProperties2(gpu(), &pd_properties);
6071
Mark Lobodzinski977f0342019-12-19 14:24:09 -07006072 PFN_vkCmdDrawIndirectByteCountEXT fpvkCmdDrawIndirectByteCountEXT =
6073 (PFN_vkCmdDrawIndirectByteCountEXT)vk::GetDeviceProcAddr(device(), "vkCmdDrawIndirectByteCountEXT");
6074
6075 m_commandBuffer->begin();
6076 m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
6077 VkBufferCreateInfo buffer_create_info = {VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO};
6078 buffer_create_info.usage = VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT;
6079 buffer_create_info.size = 1024;
6080 VkBufferObj counter_buffer;
6081 counter_buffer.init(*m_device, buffer_create_info);
6082
sfricke-samsungd5e9adb2020-10-26 03:59:29 -07006083 // Greater stride than maxTransformFeedbackBufferDataStride
Mark Lobodzinski20310782020-02-28 14:25:17 -07006084 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdDrawIndirectByteCountEXT-vertexStride-02289");
sfricke-samsungd5e9adb2020-10-26 03:59:29 -07006085 fpvkCmdDrawIndirectByteCountEXT(m_commandBuffer->handle(), 1, 0, counter_buffer.handle(), 0, 0, 0xCADECADE);
Mark Lobodzinski977f0342019-12-19 14:24:09 -07006086 m_errorMonitor->VerifyFound();
6087
sfricke-samsungd5e9adb2020-10-26 03:59:29 -07006088 // some mock ICD json files are missing a valid stride value
6089 if (tf_properties.maxTransformFeedbackBufferDataStride > 0) {
6090 // non-4 multiple stride
sfricke-samsung6886c4b2021-01-16 08:37:35 -08006091 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdDrawIndirectByteCountEXT-counterBufferOffset-04568");
sfricke-samsungd5e9adb2020-10-26 03:59:29 -07006092 fpvkCmdDrawIndirectByteCountEXT(m_commandBuffer->handle(), 1, 0, counter_buffer.handle(), 0, 1, 4);
6093 m_errorMonitor->VerifyFound();
6094 }
6095
Mark Lobodzinski977f0342019-12-19 14:24:09 -07006096 m_commandBuffer->EndRenderPass();
6097 m_commandBuffer->end();
Tony-LunarG983bbc52020-11-06 11:04:59 -07006098
6099 if (!tf_properties.maxTransformFeedbackBufferDataStride) {
6100 printf("%s , maxTransformFeedbackBufferDataStride is zero, skipping subtests\n", kSkipPrefix);
6101 return;
6102 }
6103
6104 std::vector<const char *> device_extension_names;
6105 device_extension_names.push_back(VK_EXT_TRANSFORM_FEEDBACK_EXTENSION_NAME);
6106 VkDeviceObj test_device(0, gpu(), device_extension_names);
6107 VkCommandPoolObj commandPool(&test_device, 0);
6108 VkCommandBufferObj commandBuffer(&test_device, &commandPool);
6109 VkBufferObj counter_buffer2;
6110 counter_buffer2.init(test_device, buffer_create_info);
6111 VkPipelineLayoutObj pipelineLayout(&test_device);
6112 VkRenderPass renderpass;
6113 VkRenderPassCreateInfo rp_info = {};
6114 VkSubpassDescription subpass = {};
6115 rp_info.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO;
6116 rp_info.pSubpasses = &subpass;
6117 rp_info.subpassCount = 1;
6118 vk::CreateRenderPass(test_device.handle(), &rp_info, nullptr, &renderpass);
6119 VkPipelineObj pipeline(&test_device);
6120 VkShaderObj vs(&test_device, bindStateVertShaderText, VK_SHADER_STAGE_VERTEX_BIT, this);
6121 pipeline.AddShader(&vs);
6122 pipeline.CreateVKPipeline(pipelineLayout.handle(), renderpass);
6123 m_renderPassBeginInfo.renderPass = renderpass;
6124 VkFramebuffer fb;
6125 VkFramebufferCreateInfo fbci = {VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, nullptr, 0, renderpass, 0, nullptr, 256, 256, 1};
6126 vk::CreateFramebuffer(test_device.handle(), &fbci, nullptr, &fb);
6127 m_renderPassBeginInfo.framebuffer = fb;
6128 m_renderPassBeginInfo.renderPass = renderpass;
6129 commandBuffer.begin();
6130 VkViewport viewport = {0, 0, 16, 16, 0, 1};
6131 vk::CmdSetViewport(commandBuffer.handle(), 0, 1, &viewport);
6132 VkRect2D scissor = {{0, 0}, {16, 16}};
6133 vk::CmdSetScissor(commandBuffer.handle(), 0, 1, &scissor);
6134 vk::CmdBindPipeline(commandBuffer.handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline.handle());
6135 commandBuffer.BeginRenderPass(m_renderPassBeginInfo);
6136 if (!tf_properties.transformFeedbackDraw) {
sfricke-samsungba459bd2020-12-06 23:20:04 -08006137 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdDrawIndirectByteCountEXT-transformFeedbackDraw-02288");
Tony-LunarG983bbc52020-11-06 11:04:59 -07006138 }
6139 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdDrawIndirectByteCountEXT-transformFeedback-02287");
6140 fpvkCmdDrawIndirectByteCountEXT(commandBuffer.handle(), 1, 0, counter_buffer2.handle(), 0, 0, 1);
6141 m_errorMonitor->VerifyFound();
6142 vk::DestroyRenderPass(test_device.handle(), renderpass, nullptr);
6143 vk::DestroyFramebuffer(test_device.handle(), fb, nullptr);
Mark Lobodzinski977f0342019-12-19 14:24:09 -07006144}
6145
unknown088160a2019-05-23 17:43:13 -06006146TEST_F(VkLayerTest, DrawIndirectCountKHR) {
6147 TEST_DESCRIPTION("Test covered valid usage for vkCmdDrawIndirectCountKHR");
6148
Mark Lobodzinski09ce9c42020-03-06 10:02:44 -07006149 ASSERT_NO_FATAL_FAILURE(InitFramework(m_errorMonitor));
unknown088160a2019-05-23 17:43:13 -06006150 if (DeviceExtensionSupported(gpu(), nullptr, VK_KHR_DRAW_INDIRECT_COUNT_EXTENSION_NAME)) {
6151 m_device_extension_names.push_back(VK_KHR_DRAW_INDIRECT_COUNT_EXTENSION_NAME);
6152 } else {
6153 printf(" VK_KHR_draw_indirect_count Extension not supported, skipping test\n");
6154 return;
6155 }
6156 ASSERT_NO_FATAL_FAILURE(InitState());
6157 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
6158
6159 VkMemoryRequirements memory_requirements;
6160 VkMemoryAllocateInfo memory_allocate_info = {VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO};
6161
6162 auto vkCmdDrawIndirectCountKHR =
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06006163 (PFN_vkCmdDrawIndirectCountKHR)vk::GetDeviceProcAddr(m_device->device(), "vkCmdDrawIndirectCountKHR");
unknown088160a2019-05-23 17:43:13 -06006164
locke-lunarg8e2c91b2019-06-11 17:53:26 -06006165 CreatePipelineHelper pipe(*this);
6166 pipe.InitInfo();
6167 const VkDynamicState dyn_states[] = {VK_DYNAMIC_STATE_VIEWPORT, VK_DYNAMIC_STATE_SCISSOR};
6168 VkPipelineDynamicStateCreateInfo dyn_state_ci = {};
6169 dyn_state_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO;
6170 dyn_state_ci.dynamicStateCount = size(dyn_states);
6171 dyn_state_ci.pDynamicStates = dyn_states;
6172 pipe.dyn_state_ci_ = dyn_state_ci;
6173 pipe.InitState();
6174 pipe.CreateGraphicsPipeline();
unknown088160a2019-05-23 17:43:13 -06006175
6176 m_commandBuffer->begin();
6177 m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
6178
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06006179 vk::CmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.pipeline_);
6180 vk::CmdBindDescriptorSets(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.pipeline_layout_.handle(), 0, 1,
6181 &pipe.descriptor_set_->set_, 0, NULL);
unknown088160a2019-05-23 17:43:13 -06006182
6183 VkViewport viewport = {0, 0, 16, 16, 0, 1};
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06006184 vk::CmdSetViewport(m_commandBuffer->handle(), 0, 1, &viewport);
unknown088160a2019-05-23 17:43:13 -06006185 VkRect2D scissor = {{0, 0}, {16, 16}};
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06006186 vk::CmdSetScissor(m_commandBuffer->handle(), 0, 1, &scissor);
unknown088160a2019-05-23 17:43:13 -06006187
6188 VkBufferCreateInfo buffer_create_info = {VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO};
6189 buffer_create_info.size = sizeof(VkDrawIndirectCommand);
6190 buffer_create_info.usage = VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT;
6191 VkBuffer draw_buffer;
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06006192 vk::CreateBuffer(m_device->device(), &buffer_create_info, nullptr, &draw_buffer);
unknown088160a2019-05-23 17:43:13 -06006193
6194 VkBufferCreateInfo count_buffer_create_info = {VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO};
6195 count_buffer_create_info.size = sizeof(uint32_t);
6196 count_buffer_create_info.usage = VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT;
locke-lunarg8e2c91b2019-06-11 17:53:26 -06006197 VkBufferObj count_buffer;
6198 count_buffer.init(*m_device, count_buffer_create_info);
unknown088160a2019-05-23 17:43:13 -06006199
Mike Schuchardt65847d92019-12-20 13:50:47 -08006200 // VUID-vkCmdDrawIndirectCount-buffer-02708
Mark Lobodzinski20310782020-02-28 14:25:17 -07006201 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdDrawIndirectCount-buffer-02708");
locke-lunarg8e2c91b2019-06-11 17:53:26 -06006202 vkCmdDrawIndirectCountKHR(m_commandBuffer->handle(), draw_buffer, 0, count_buffer.handle(), 0, 1,
6203 sizeof(VkDrawIndirectCommand));
unknown088160a2019-05-23 17:43:13 -06006204 m_errorMonitor->VerifyFound();
6205
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06006206 vk::GetBufferMemoryRequirements(m_device->device(), draw_buffer, &memory_requirements);
unknown088160a2019-05-23 17:43:13 -06006207 memory_allocate_info.allocationSize = memory_requirements.size;
6208 m_device->phy().set_memory_type(memory_requirements.memoryTypeBits, &memory_allocate_info, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT);
6209 VkDeviceMemory draw_buffer_memory;
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06006210 vk::AllocateMemory(m_device->device(), &memory_allocate_info, NULL, &draw_buffer_memory);
6211 vk::BindBufferMemory(m_device->device(), draw_buffer, draw_buffer_memory, 0);
unknown088160a2019-05-23 17:43:13 -06006212
6213 VkBuffer count_buffer_unbound;
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06006214 vk::CreateBuffer(m_device->device(), &count_buffer_create_info, nullptr, &count_buffer_unbound);
unknown088160a2019-05-23 17:43:13 -06006215
Mike Schuchardt65847d92019-12-20 13:50:47 -08006216 // VUID-vkCmdDrawIndirectCount-countBuffer-02714
Mark Lobodzinski20310782020-02-28 14:25:17 -07006217 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdDrawIndirectCount-countBuffer-02714");
unknown088160a2019-05-23 17:43:13 -06006218 vkCmdDrawIndirectCountKHR(m_commandBuffer->handle(), draw_buffer, 0, count_buffer_unbound, 0, 1, sizeof(VkDrawIndirectCommand));
6219 m_errorMonitor->VerifyFound();
6220
Mike Schuchardt65847d92019-12-20 13:50:47 -08006221 // VUID-vkCmdDrawIndirectCount-offset-02710
Mark Lobodzinski20310782020-02-28 14:25:17 -07006222 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdDrawIndirectCount-offset-02710");
locke-lunarg8e2c91b2019-06-11 17:53:26 -06006223 vkCmdDrawIndirectCountKHR(m_commandBuffer->handle(), draw_buffer, 1, count_buffer.handle(), 0, 1,
6224 sizeof(VkDrawIndirectCommand));
unknown088160a2019-05-23 17:43:13 -06006225 m_errorMonitor->VerifyFound();
6226
Mike Schuchardt65847d92019-12-20 13:50:47 -08006227 // VUID-vkCmdDrawIndirectCount-countBufferOffset-02716
Mark Lobodzinski20310782020-02-28 14:25:17 -07006228 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdDrawIndirectCount-countBufferOffset-02716");
locke-lunarg8e2c91b2019-06-11 17:53:26 -06006229 vkCmdDrawIndirectCountKHR(m_commandBuffer->handle(), draw_buffer, 0, count_buffer.handle(), 1, 1,
6230 sizeof(VkDrawIndirectCommand));
unknown088160a2019-05-23 17:43:13 -06006231 m_errorMonitor->VerifyFound();
6232
Mike Schuchardt65847d92019-12-20 13:50:47 -08006233 // VUID-vkCmdDrawIndirectCount-stride-03110
Mark Lobodzinski20310782020-02-28 14:25:17 -07006234 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdDrawIndirectCount-stride-03110");
locke-lunarg8e2c91b2019-06-11 17:53:26 -06006235 vkCmdDrawIndirectCountKHR(m_commandBuffer->handle(), draw_buffer, 0, count_buffer.handle(), 0, 1, 1);
unknown088160a2019-05-23 17:43:13 -06006236 m_errorMonitor->VerifyFound();
6237
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06006238 // TODO: These covered VUIDs aren't tested. There is also no test coverage for the core Vulkan 1.0 vk::CmdDraw* equivalent of
unknown088160a2019-05-23 17:43:13 -06006239 // these:
Mike Schuchardt65847d92019-12-20 13:50:47 -08006240 // VUID-vkCmdDrawIndirectCount-renderPass-02684
6241 // VUID-vkCmdDrawIndirectCount-subpass-02685
6242 // VUID-vkCmdDrawIndirectCount-commandBuffer-02701
unknown088160a2019-05-23 17:43:13 -06006243
6244 m_commandBuffer->EndRenderPass();
6245 m_commandBuffer->end();
6246
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06006247 vk::DestroyBuffer(m_device->device(), draw_buffer, 0);
6248 vk::DestroyBuffer(m_device->device(), count_buffer_unbound, 0);
unknown088160a2019-05-23 17:43:13 -06006249
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06006250 vk::FreeMemory(m_device->device(), draw_buffer_memory, 0);
unknown088160a2019-05-23 17:43:13 -06006251}
6252
6253TEST_F(VkLayerTest, DrawIndexedIndirectCountKHR) {
6254 TEST_DESCRIPTION("Test covered valid usage for vkCmdDrawIndexedIndirectCountKHR");
6255
Mark Lobodzinski09ce9c42020-03-06 10:02:44 -07006256 ASSERT_NO_FATAL_FAILURE(InitFramework(m_errorMonitor));
unknown088160a2019-05-23 17:43:13 -06006257 if (DeviceExtensionSupported(gpu(), nullptr, VK_KHR_DRAW_INDIRECT_COUNT_EXTENSION_NAME)) {
6258 m_device_extension_names.push_back(VK_KHR_DRAW_INDIRECT_COUNT_EXTENSION_NAME);
6259 } else {
6260 printf(" VK_KHR_draw_indirect_count Extension not supported, skipping test\n");
6261 return;
6262 }
6263 ASSERT_NO_FATAL_FAILURE(InitState());
6264 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
6265
unknown088160a2019-05-23 17:43:13 -06006266 auto vkCmdDrawIndexedIndirectCountKHR =
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06006267 (PFN_vkCmdDrawIndexedIndirectCountKHR)vk::GetDeviceProcAddr(m_device->device(), "vkCmdDrawIndexedIndirectCountKHR");
unknown088160a2019-05-23 17:43:13 -06006268
locke-lunarg8e2c91b2019-06-11 17:53:26 -06006269 CreatePipelineHelper pipe(*this);
6270 pipe.InitInfo();
6271 const VkDynamicState dyn_states[] = {VK_DYNAMIC_STATE_VIEWPORT, VK_DYNAMIC_STATE_SCISSOR};
6272 VkPipelineDynamicStateCreateInfo dyn_state_ci = {};
6273 dyn_state_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO;
6274 dyn_state_ci.dynamicStateCount = size(dyn_states);
6275 dyn_state_ci.pDynamicStates = dyn_states;
6276 pipe.dyn_state_ci_ = dyn_state_ci;
6277 pipe.InitState();
6278 pipe.CreateGraphicsPipeline();
unknown088160a2019-05-23 17:43:13 -06006279
6280 m_commandBuffer->begin();
6281 m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
6282
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06006283 vk::CmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.pipeline_);
6284 vk::CmdBindDescriptorSets(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.pipeline_layout_.handle(), 0, 1,
6285 &pipe.descriptor_set_->set_, 0, NULL);
unknown088160a2019-05-23 17:43:13 -06006286
6287 VkViewport viewport = {0, 0, 16, 16, 0, 1};
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06006288 vk::CmdSetViewport(m_commandBuffer->handle(), 0, 1, &viewport);
unknown088160a2019-05-23 17:43:13 -06006289 VkRect2D scissor = {{0, 0}, {16, 16}};
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06006290 vk::CmdSetScissor(m_commandBuffer->handle(), 0, 1, &scissor);
unknown088160a2019-05-23 17:43:13 -06006291
6292 VkBufferCreateInfo buffer_create_info = {VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO};
6293 buffer_create_info.size = sizeof(VkDrawIndexedIndirectCommand);
6294 buffer_create_info.usage = VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT;
locke-lunarg8e2c91b2019-06-11 17:53:26 -06006295 VkBufferObj draw_buffer;
6296 draw_buffer.init(*m_device, buffer_create_info);
unknown088160a2019-05-23 17:43:13 -06006297
6298 VkBufferCreateInfo count_buffer_create_info = {VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO};
6299 count_buffer_create_info.size = sizeof(uint32_t);
6300 count_buffer_create_info.usage = VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT;
locke-lunarg8e2c91b2019-06-11 17:53:26 -06006301 VkBufferObj count_buffer;
6302 count_buffer.init(*m_device, count_buffer_create_info);
unknown088160a2019-05-23 17:43:13 -06006303
6304 VkBufferCreateInfo index_buffer_create_info = {VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO};
6305 index_buffer_create_info.size = sizeof(uint32_t);
6306 index_buffer_create_info.usage = VK_BUFFER_USAGE_INDEX_BUFFER_BIT;
locke-lunarg8e2c91b2019-06-11 17:53:26 -06006307 VkBufferObj index_buffer;
6308 index_buffer.init(*m_device, index_buffer_create_info);
unknown088160a2019-05-23 17:43:13 -06006309
Mike Schuchardt65847d92019-12-20 13:50:47 -08006310 // VUID-vkCmdDrawIndexedIndirectCount-commandBuffer-02701 (partial - only tests whether the index buffer is bound)
Mark Lobodzinski20310782020-02-28 14:25:17 -07006311 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdDrawIndexedIndirectCount-commandBuffer-02701");
locke-lunarg8e2c91b2019-06-11 17:53:26 -06006312 vkCmdDrawIndexedIndirectCountKHR(m_commandBuffer->handle(), draw_buffer.handle(), 0, count_buffer.handle(), 0, 1,
unknown088160a2019-05-23 17:43:13 -06006313 sizeof(VkDrawIndexedIndirectCommand));
6314 m_errorMonitor->VerifyFound();
6315
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06006316 vk::CmdBindIndexBuffer(m_commandBuffer->handle(), index_buffer.handle(), 0, VK_INDEX_TYPE_UINT32);
unknown088160a2019-05-23 17:43:13 -06006317
6318 VkBuffer draw_buffer_unbound;
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06006319 vk::CreateBuffer(m_device->device(), &count_buffer_create_info, nullptr, &draw_buffer_unbound);
unknown088160a2019-05-23 17:43:13 -06006320
Mike Schuchardt65847d92019-12-20 13:50:47 -08006321 // VUID-vkCmdDrawIndexedIndirectCount-buffer-02708
Mark Lobodzinski20310782020-02-28 14:25:17 -07006322 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdDrawIndexedIndirectCount-buffer-02708");
locke-lunarg8e2c91b2019-06-11 17:53:26 -06006323 vkCmdDrawIndexedIndirectCountKHR(m_commandBuffer->handle(), draw_buffer_unbound, 0, count_buffer.handle(), 0, 1,
unknown088160a2019-05-23 17:43:13 -06006324 sizeof(VkDrawIndexedIndirectCommand));
6325 m_errorMonitor->VerifyFound();
6326
6327 VkBuffer count_buffer_unbound;
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06006328 vk::CreateBuffer(m_device->device(), &count_buffer_create_info, nullptr, &count_buffer_unbound);
unknown088160a2019-05-23 17:43:13 -06006329
Mike Schuchardt65847d92019-12-20 13:50:47 -08006330 // VUID-vkCmdDrawIndexedIndirectCount-countBuffer-02714
Mark Lobodzinski20310782020-02-28 14:25:17 -07006331 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdDrawIndexedIndirectCount-countBuffer-02714");
locke-lunarg8e2c91b2019-06-11 17:53:26 -06006332 vkCmdDrawIndexedIndirectCountKHR(m_commandBuffer->handle(), draw_buffer.handle(), 0, count_buffer_unbound, 0, 1,
unknown088160a2019-05-23 17:43:13 -06006333 sizeof(VkDrawIndexedIndirectCommand));
6334 m_errorMonitor->VerifyFound();
6335
Mike Schuchardt65847d92019-12-20 13:50:47 -08006336 // VUID-vkCmdDrawIndexedIndirectCount-offset-02710
Mark Lobodzinski20310782020-02-28 14:25:17 -07006337 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdDrawIndexedIndirectCount-offset-02710");
locke-lunarg8e2c91b2019-06-11 17:53:26 -06006338 vkCmdDrawIndexedIndirectCountKHR(m_commandBuffer->handle(), draw_buffer.handle(), 1, count_buffer.handle(), 0, 1,
unknown088160a2019-05-23 17:43:13 -06006339 sizeof(VkDrawIndexedIndirectCommand));
6340 m_errorMonitor->VerifyFound();
6341
Mike Schuchardt65847d92019-12-20 13:50:47 -08006342 // VUID-vkCmdDrawIndexedIndirectCount-countBufferOffset-02716
Mark Lobodzinski20310782020-02-28 14:25:17 -07006343 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdDrawIndexedIndirectCount-countBufferOffset-02716");
locke-lunarg8e2c91b2019-06-11 17:53:26 -06006344 vkCmdDrawIndexedIndirectCountKHR(m_commandBuffer->handle(), draw_buffer.handle(), 0, count_buffer.handle(), 1, 1,
unknown088160a2019-05-23 17:43:13 -06006345 sizeof(VkDrawIndexedIndirectCommand));
6346 m_errorMonitor->VerifyFound();
6347
Mike Schuchardt65847d92019-12-20 13:50:47 -08006348 // VUID-vkCmdDrawIndexedIndirectCount-stride-03142
Mark Lobodzinski20310782020-02-28 14:25:17 -07006349 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdDrawIndexedIndirectCount-stride-03142");
locke-lunarg8e2c91b2019-06-11 17:53:26 -06006350 vkCmdDrawIndexedIndirectCountKHR(m_commandBuffer->handle(), draw_buffer.handle(), 0, count_buffer.handle(), 0, 1, 1);
unknown088160a2019-05-23 17:43:13 -06006351 m_errorMonitor->VerifyFound();
6352
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06006353 // TODO: These covered VUIDs aren't tested. There is also no test coverage for the core Vulkan 1.0 vk::CmdDraw* equivalent of
unknown088160a2019-05-23 17:43:13 -06006354 // these:
Mike Schuchardt65847d92019-12-20 13:50:47 -08006355 // VUID-vkCmdDrawIndexedIndirectCount-renderPass-02684
6356 // VUID-vkCmdDrawIndexedIndirectCount-subpass-02685
6357 // VUID-vkCmdDrawIndexedIndirectCount-commandBuffer-02701 (partial)
unknown088160a2019-05-23 17:43:13 -06006358
6359 m_commandBuffer->EndRenderPass();
6360 m_commandBuffer->end();
6361
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06006362 vk::DestroyBuffer(m_device->device(), draw_buffer_unbound, 0);
6363 vk::DestroyBuffer(m_device->device(), count_buffer_unbound, 0);
unknown088160a2019-05-23 17:43:13 -06006364}
6365
sfricke-samsung860d3b22020-05-04 21:08:29 -07006366TEST_F(VkLayerTest, DrawIndirectCountFeature) {
6367 TEST_DESCRIPTION("Test covered valid usage for the 1.2 drawIndirectCount feature");
6368
6369 SetTargetApiVersion(VK_API_VERSION_1_2);
6370 ASSERT_NO_FATAL_FAILURE(Init());
6371 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
6372 if (DeviceValidationVersion() < VK_API_VERSION_1_2) {
6373 printf("%s Tests requires Vulkan 1.2+, skipping test\n", kSkipPrefix);
6374 return;
6375 }
6376
6377 VkBufferObj indirect_buffer;
6378 indirect_buffer.init(*m_device, sizeof(VkDrawIndirectCommand), VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT,
6379 VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT);
6380
6381 VkBufferObj indexed_indirect_buffer;
6382 indexed_indirect_buffer.init(*m_device, sizeof(VkDrawIndexedIndirectCommand), VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT,
6383 VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT);
6384
6385 VkBufferObj count_buffer;
6386 count_buffer.init(*m_device, sizeof(uint32_t), VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT);
6387
6388 VkBufferObj index_buffer;
6389 index_buffer.init(*m_device, sizeof(uint32_t), VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, VK_BUFFER_USAGE_INDEX_BUFFER_BIT);
6390
6391 CreatePipelineHelper pipe(*this);
6392 pipe.InitInfo();
6393 pipe.InitState();
6394 pipe.CreateGraphicsPipeline();
6395
6396 // Make calls to valid commands but without the drawIndirectCount feature set
6397 m_commandBuffer->begin();
6398 m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
6399
6400 vk::CmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.pipeline_);
6401
Shannon McPherson2c793ba2020-08-28 12:13:24 -06006402 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdDrawIndirectCount-None-04445");
sfricke-samsung860d3b22020-05-04 21:08:29 -07006403 vk::CmdDrawIndirectCount(m_commandBuffer->handle(), indirect_buffer.handle(), 0, count_buffer.handle(), 0, 1,
6404 sizeof(VkDrawIndirectCommand));
6405 m_errorMonitor->VerifyFound();
6406
6407 vk::CmdBindIndexBuffer(m_commandBuffer->handle(), index_buffer.handle(), 0, VK_INDEX_TYPE_UINT32);
6408
Shannon McPherson2c793ba2020-08-28 12:13:24 -06006409 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdDrawIndexedIndirectCount-None-04445");
sfricke-samsung860d3b22020-05-04 21:08:29 -07006410 vk::CmdDrawIndexedIndirectCount(m_commandBuffer->handle(), indexed_indirect_buffer.handle(), 0, count_buffer.handle(), 0, 1,
6411 sizeof(VkDrawIndexedIndirectCommand));
6412 m_errorMonitor->VerifyFound();
6413
6414 m_commandBuffer->EndRenderPass();
6415 m_commandBuffer->end();
6416}
6417
unknown088160a2019-05-23 17:43:13 -06006418TEST_F(VkLayerTest, ExclusiveScissorNV) {
6419 TEST_DESCRIPTION("Test VK_NV_scissor_exclusive with multiViewport disabled.");
6420
6421 if (InstanceExtensionSupported(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME)) {
6422 m_instance_extension_names.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
6423 } else {
6424 printf("%s Did not find required instance extension %s; skipped.\n", kSkipPrefix,
6425 VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
6426 return;
6427 }
Mark Lobodzinski09ce9c42020-03-06 10:02:44 -07006428 ASSERT_NO_FATAL_FAILURE(InitFramework(m_errorMonitor));
unknown088160a2019-05-23 17:43:13 -06006429 std::array<const char *, 1> required_device_extensions = {{VK_NV_SCISSOR_EXCLUSIVE_EXTENSION_NAME}};
6430 for (auto device_extension : required_device_extensions) {
6431 if (DeviceExtensionSupported(gpu(), nullptr, device_extension)) {
6432 m_device_extension_names.push_back(device_extension);
6433 } else {
6434 printf("%s %s Extension not supported, skipping tests\n", kSkipPrefix, device_extension);
6435 return;
6436 }
6437 }
6438
6439 PFN_vkGetPhysicalDeviceFeatures2KHR vkGetPhysicalDeviceFeatures2KHR =
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06006440 (PFN_vkGetPhysicalDeviceFeatures2KHR)vk::GetInstanceProcAddr(instance(), "vkGetPhysicalDeviceFeatures2KHR");
unknown088160a2019-05-23 17:43:13 -06006441 ASSERT_TRUE(vkGetPhysicalDeviceFeatures2KHR != nullptr);
6442
6443 // Create a device that enables exclusive scissor but disables multiViewport
Mark Lobodzinski07d0a612020-12-30 15:42:31 -07006444 auto exclusive_scissor_features = LvlInitStruct<VkPhysicalDeviceExclusiveScissorFeaturesNV>();
6445 auto features2 = LvlInitStruct<VkPhysicalDeviceFeatures2KHR>(&exclusive_scissor_features);
unknown088160a2019-05-23 17:43:13 -06006446 vkGetPhysicalDeviceFeatures2KHR(gpu(), &features2);
6447
6448 features2.features.multiViewport = VK_FALSE;
6449
6450 ASSERT_NO_FATAL_FAILURE(InitState(nullptr, &features2));
6451 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
6452
6453 if (m_device->phy().properties().limits.maxViewports) {
6454 printf("%s Device doesn't support the necessary number of viewports, skipping test.\n", kSkipPrefix);
6455 return;
6456 }
6457
6458 // Based on PSOViewportStateTests
6459 {
6460 VkViewport viewport = {0.0f, 0.0f, 64.0f, 64.0f, 0.0f, 1.0f};
6461 VkViewport viewports[] = {viewport, viewport};
6462 VkRect2D scissor = {{0, 0}, {64, 64}};
6463 VkRect2D scissors[100] = {scissor, scissor};
6464
6465 using std::vector;
6466 struct TestCase {
6467 uint32_t viewport_count;
6468 VkViewport *viewports;
6469 uint32_t scissor_count;
6470 VkRect2D *scissors;
6471 uint32_t exclusive_scissor_count;
6472 VkRect2D *exclusive_scissors;
6473
6474 vector<std::string> vuids;
6475 };
6476
6477 vector<TestCase> test_cases = {
6478 {1,
6479 viewports,
6480 1,
6481 scissors,
6482 2,
6483 scissors,
6484 {"VUID-VkPipelineViewportExclusiveScissorStateCreateInfoNV-exclusiveScissorCount-02027",
6485 "VUID-VkPipelineViewportExclusiveScissorStateCreateInfoNV-exclusiveScissorCount-02029"}},
6486 {1,
6487 viewports,
6488 1,
6489 scissors,
6490 100,
6491 scissors,
6492 {"VUID-VkPipelineViewportExclusiveScissorStateCreateInfoNV-exclusiveScissorCount-02027",
6493 "VUID-VkPipelineViewportExclusiveScissorStateCreateInfoNV-exclusiveScissorCount-02028",
6494 "VUID-VkPipelineViewportExclusiveScissorStateCreateInfoNV-exclusiveScissorCount-02029"}},
Shannon McPherson24c13d12020-06-18 15:51:41 -06006495 {1, viewports, 1, scissors, 1, nullptr, {"VUID-VkGraphicsPipelineCreateInfo-pDynamicStates-04056"}},
unknown088160a2019-05-23 17:43:13 -06006496 };
6497
6498 for (const auto &test_case : test_cases) {
6499 VkPipelineViewportExclusiveScissorStateCreateInfoNV exc = {
6500 VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_EXCLUSIVE_SCISSOR_STATE_CREATE_INFO_NV};
6501
6502 const auto break_vp = [&test_case, &exc](CreatePipelineHelper &helper) {
6503 helper.vp_state_ci_.viewportCount = test_case.viewport_count;
6504 helper.vp_state_ci_.pViewports = test_case.viewports;
6505 helper.vp_state_ci_.scissorCount = test_case.scissor_count;
6506 helper.vp_state_ci_.pScissors = test_case.scissors;
6507 helper.vp_state_ci_.pNext = &exc;
6508
6509 exc.exclusiveScissorCount = test_case.exclusive_scissor_count;
6510 exc.pExclusiveScissors = test_case.exclusive_scissors;
6511 };
Mark Lobodzinski20310782020-02-28 14:25:17 -07006512 CreatePipelineHelper::OneshotTest(*this, break_vp, kErrorBit, test_case.vuids);
unknown088160a2019-05-23 17:43:13 -06006513 }
6514 }
6515
6516 // Based on SetDynScissorParamTests
6517 {
6518 auto vkCmdSetExclusiveScissorNV =
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06006519 (PFN_vkCmdSetExclusiveScissorNV)vk::GetDeviceProcAddr(m_device->device(), "vkCmdSetExclusiveScissorNV");
unknown088160a2019-05-23 17:43:13 -06006520
6521 const VkRect2D scissor = {{0, 0}, {16, 16}};
6522 const VkRect2D scissors[] = {scissor, scissor};
6523
6524 m_commandBuffer->begin();
6525
Mark Lobodzinski20310782020-02-28 14:25:17 -07006526 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdSetExclusiveScissorNV-firstExclusiveScissor-02035");
unknown088160a2019-05-23 17:43:13 -06006527 vkCmdSetExclusiveScissorNV(m_commandBuffer->handle(), 1, 1, scissors);
6528 m_errorMonitor->VerifyFound();
6529
Mark Lobodzinski20310782020-02-28 14:25:17 -07006530 m_errorMonitor->SetDesiredFailureMsg(kErrorBit,
unknown088160a2019-05-23 17:43:13 -06006531 "vkCmdSetExclusiveScissorNV: parameter exclusiveScissorCount must be greater than 0");
6532 vkCmdSetExclusiveScissorNV(m_commandBuffer->handle(), 0, 0, nullptr);
6533 m_errorMonitor->VerifyFound();
6534
Mark Lobodzinski20310782020-02-28 14:25:17 -07006535 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdSetExclusiveScissorNV-exclusiveScissorCount-02036");
unknown088160a2019-05-23 17:43:13 -06006536 vkCmdSetExclusiveScissorNV(m_commandBuffer->handle(), 0, 2, scissors);
6537 m_errorMonitor->VerifyFound();
6538
Mark Lobodzinski20310782020-02-28 14:25:17 -07006539 m_errorMonitor->SetDesiredFailureMsg(kErrorBit,
unknown088160a2019-05-23 17:43:13 -06006540 "vkCmdSetExclusiveScissorNV: parameter exclusiveScissorCount must be greater than 0");
Mark Lobodzinski20310782020-02-28 14:25:17 -07006541 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdSetExclusiveScissorNV-firstExclusiveScissor-02035");
unknown088160a2019-05-23 17:43:13 -06006542 vkCmdSetExclusiveScissorNV(m_commandBuffer->handle(), 1, 0, scissors);
6543 m_errorMonitor->VerifyFound();
6544
Mark Lobodzinski20310782020-02-28 14:25:17 -07006545 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdSetExclusiveScissorNV-firstExclusiveScissor-02035");
6546 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdSetExclusiveScissorNV-exclusiveScissorCount-02036");
unknown088160a2019-05-23 17:43:13 -06006547 vkCmdSetExclusiveScissorNV(m_commandBuffer->handle(), 1, 2, scissors);
6548 m_errorMonitor->VerifyFound();
6549
Mark Lobodzinski20310782020-02-28 14:25:17 -07006550 m_errorMonitor->SetDesiredFailureMsg(kErrorBit,
unknown088160a2019-05-23 17:43:13 -06006551 "vkCmdSetExclusiveScissorNV: required parameter pExclusiveScissors specified as NULL");
6552 vkCmdSetExclusiveScissorNV(m_commandBuffer->handle(), 0, 1, nullptr);
6553 m_errorMonitor->VerifyFound();
6554
6555 struct TestCase {
6556 VkRect2D scissor;
6557 std::string vuid;
6558 };
6559
6560 std::vector<TestCase> test_cases = {
6561 {{{-1, 0}, {16, 16}}, "VUID-vkCmdSetExclusiveScissorNV-x-02037"},
6562 {{{0, -1}, {16, 16}}, "VUID-vkCmdSetExclusiveScissorNV-x-02037"},
6563 {{{1, 0}, {INT32_MAX, 16}}, "VUID-vkCmdSetExclusiveScissorNV-offset-02038"},
6564 {{{INT32_MAX, 0}, {1, 16}}, "VUID-vkCmdSetExclusiveScissorNV-offset-02038"},
6565 {{{0, 0}, {uint32_t{INT32_MAX} + 1, 16}}, "VUID-vkCmdSetExclusiveScissorNV-offset-02038"},
6566 {{{0, 1}, {16, INT32_MAX}}, "VUID-vkCmdSetExclusiveScissorNV-offset-02039"},
6567 {{{0, INT32_MAX}, {16, 1}}, "VUID-vkCmdSetExclusiveScissorNV-offset-02039"},
6568 {{{0, 0}, {16, uint32_t{INT32_MAX} + 1}}, "VUID-vkCmdSetExclusiveScissorNV-offset-02039"}};
6569
6570 for (const auto &test_case : test_cases) {
Mark Lobodzinski20310782020-02-28 14:25:17 -07006571 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, test_case.vuid);
unknown088160a2019-05-23 17:43:13 -06006572 vkCmdSetExclusiveScissorNV(m_commandBuffer->handle(), 0, 1, &test_case.scissor);
6573 m_errorMonitor->VerifyFound();
6574 }
6575
6576 m_commandBuffer->end();
6577 }
6578}
6579
6580TEST_F(VkLayerTest, MeshShaderNV) {
6581 TEST_DESCRIPTION("Test VK_NV_mesh_shader.");
6582
6583 if (InstanceExtensionSupported(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME)) {
6584 m_instance_extension_names.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
6585 } else {
6586 printf("%s Did not find required instance extension %s; skipped.\n", kSkipPrefix,
6587 VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
6588 return;
6589 }
Mark Lobodzinski09ce9c42020-03-06 10:02:44 -07006590 ASSERT_NO_FATAL_FAILURE(InitFramework(m_errorMonitor));
unknown088160a2019-05-23 17:43:13 -06006591 std::array<const char *, 1> required_device_extensions = {{VK_NV_MESH_SHADER_EXTENSION_NAME}};
6592 for (auto device_extension : required_device_extensions) {
6593 if (DeviceExtensionSupported(gpu(), nullptr, device_extension)) {
6594 m_device_extension_names.push_back(device_extension);
6595 } else {
6596 printf("%s %s Extension not supported, skipping tests\n", kSkipPrefix, device_extension);
6597 return;
6598 }
6599 }
6600
Tony-LunarG048f5012020-04-29 16:55:11 -06006601 if (IsPlatform(kMockICD) || DeviceSimulation()) {
unknown088160a2019-05-23 17:43:13 -06006602 printf("%sNot suppored by MockICD, skipping tests\n", kSkipPrefix);
6603 return;
6604 }
6605
6606 PFN_vkGetPhysicalDeviceFeatures2KHR vkGetPhysicalDeviceFeatures2KHR =
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06006607 (PFN_vkGetPhysicalDeviceFeatures2KHR)vk::GetInstanceProcAddr(instance(), "vkGetPhysicalDeviceFeatures2KHR");
unknown088160a2019-05-23 17:43:13 -06006608 ASSERT_TRUE(vkGetPhysicalDeviceFeatures2KHR != nullptr);
6609
6610 // Create a device that enables mesh_shader
Mark Lobodzinski07d0a612020-12-30 15:42:31 -07006611 auto mesh_shader_features = LvlInitStruct<VkPhysicalDeviceMeshShaderFeaturesNV>();
6612 auto features2 = LvlInitStruct<VkPhysicalDeviceFeatures2KHR>(&mesh_shader_features);
unknown088160a2019-05-23 17:43:13 -06006613 vkGetPhysicalDeviceFeatures2KHR(gpu(), &features2);
6614 features2.features.multiDrawIndirect = VK_FALSE;
6615
6616 ASSERT_NO_FATAL_FAILURE(InitState(nullptr, &features2));
6617 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
6618
6619 static const char vertShaderText[] =
6620 "#version 450\n"
6621 "vec2 vertices[3];\n"
6622 "void main() {\n"
6623 " vertices[0] = vec2(-1.0, -1.0);\n"
6624 " vertices[1] = vec2( 1.0, -1.0);\n"
6625 " vertices[2] = vec2( 0.0, 1.0);\n"
6626 " gl_Position = vec4(vertices[gl_VertexIndex % 3], 0.0, 1.0);\n"
6627 " gl_PointSize = 1.0f;\n"
6628 "}\n";
6629
6630 static const char meshShaderText[] =
6631 "#version 450\n"
6632 "#extension GL_NV_mesh_shader : require\n"
6633 "layout(local_size_x = 1) in;\n"
6634 "layout(max_vertices = 3) out;\n"
6635 "layout(max_primitives = 1) out;\n"
6636 "layout(triangles) out;\n"
6637 "void main() {\n"
6638 " gl_MeshVerticesNV[0].gl_Position = vec4(-1.0, -1.0, 0, 1);\n"
6639 " gl_MeshVerticesNV[1].gl_Position = vec4( 1.0, -1.0, 0, 1);\n"
6640 " gl_MeshVerticesNV[2].gl_Position = vec4( 0.0, 1.0, 0, 1);\n"
6641 " gl_PrimitiveIndicesNV[0] = 0;\n"
6642 " gl_PrimitiveIndicesNV[1] = 1;\n"
6643 " gl_PrimitiveIndicesNV[2] = 2;\n"
6644 " gl_PrimitiveCountNV = 1;\n"
6645 "}\n";
6646
6647 VkShaderObj vs(m_device, vertShaderText, VK_SHADER_STAGE_VERTEX_BIT, this);
6648 VkShaderObj ms(m_device, meshShaderText, VK_SHADER_STAGE_MESH_BIT_NV, this);
6649 VkShaderObj fs(m_device, bindStateFragShaderText, VK_SHADER_STAGE_FRAGMENT_BIT, this);
6650
6651 // Test pipeline creation
6652 {
6653 // can't mix mesh with vertex
6654 const auto break_vp = [&](CreatePipelineHelper &helper) {
6655 helper.shader_stages_ = {vs.GetStageCreateInfo(), fs.GetStageCreateInfo(), ms.GetStageCreateInfo()};
6656 };
Mark Lobodzinski20310782020-02-28 14:25:17 -07006657 CreatePipelineHelper::OneshotTest(*this, break_vp, kErrorBit,
unknown088160a2019-05-23 17:43:13 -06006658 vector<std::string>({"VUID-VkGraphicsPipelineCreateInfo-pStages-02095"}));
6659
6660 // vertex or mesh must be present
6661 const auto break_vp2 = [&](CreatePipelineHelper &helper) { helper.shader_stages_ = {fs.GetStageCreateInfo()}; };
Mark Lobodzinski20310782020-02-28 14:25:17 -07006662 CreatePipelineHelper::OneshotTest(*this, break_vp2, kErrorBit,
unknown088160a2019-05-23 17:43:13 -06006663 vector<std::string>({"VUID-VkGraphicsPipelineCreateInfo-stage-02096"}));
6664
6665 // vertexinput and inputassembly must be valid when vertex stage is present
6666 const auto break_vp3 = [&](CreatePipelineHelper &helper) {
6667 helper.shader_stages_ = {vs.GetStageCreateInfo(), fs.GetStageCreateInfo()};
6668 helper.gp_ci_.pVertexInputState = nullptr;
6669 helper.gp_ci_.pInputAssemblyState = nullptr;
6670 };
Mark Lobodzinski20310782020-02-28 14:25:17 -07006671 CreatePipelineHelper::OneshotTest(*this, break_vp3, kErrorBit,
unknown088160a2019-05-23 17:43:13 -06006672 vector<std::string>({"VUID-VkGraphicsPipelineCreateInfo-pStages-02097",
6673 "VUID-VkGraphicsPipelineCreateInfo-pStages-02098"}));
6674 }
6675
6676 PFN_vkCmdDrawMeshTasksIndirectNV vkCmdDrawMeshTasksIndirectNV =
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06006677 (PFN_vkCmdDrawMeshTasksIndirectNV)vk::GetInstanceProcAddr(instance(), "vkCmdDrawMeshTasksIndirectNV");
unknown088160a2019-05-23 17:43:13 -06006678
6679 VkBufferCreateInfo buffer_create_info = {VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO};
6680 buffer_create_info.size = sizeof(uint32_t);
6681 buffer_create_info.usage = VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT;
6682 VkBuffer buffer;
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06006683 VkResult result = vk::CreateBuffer(m_device->device(), &buffer_create_info, nullptr, &buffer);
unknown088160a2019-05-23 17:43:13 -06006684 ASSERT_VK_SUCCESS(result);
6685
6686 m_commandBuffer->begin();
6687
Mark Lobodzinski20310782020-02-28 14:25:17 -07006688 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdDrawMeshTasksIndirectNV-drawCount-02146");
6689 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdDrawMeshTasksIndirectNV-drawCount-02718");
unknown088160a2019-05-23 17:43:13 -06006690 vkCmdDrawMeshTasksIndirectNV(m_commandBuffer->handle(), buffer, 0, 2, 0);
6691 m_errorMonitor->VerifyFound();
6692
6693 m_commandBuffer->end();
6694
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06006695 vk::DestroyBuffer(m_device->device(), buffer, 0);
unknown088160a2019-05-23 17:43:13 -06006696}
6697
6698TEST_F(VkLayerTest, MeshShaderDisabledNV) {
6699 TEST_DESCRIPTION("Test VK_NV_mesh_shader VUs with NV_mesh_shader disabled.");
6700 ASSERT_NO_FATAL_FAILURE(Init());
6701 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
6702
6703 VkEvent event;
6704 VkEventCreateInfo event_create_info{};
6705 event_create_info.sType = VK_STRUCTURE_TYPE_EVENT_CREATE_INFO;
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06006706 vk::CreateEvent(m_device->device(), &event_create_info, nullptr, &event);
unknown088160a2019-05-23 17:43:13 -06006707
6708 m_commandBuffer->begin();
6709
Shannon McPherson93970b12020-06-12 14:34:35 -06006710 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdSetEvent-stageMask-04095");
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06006711 vk::CmdSetEvent(m_commandBuffer->handle(), event, VK_PIPELINE_STAGE_MESH_SHADER_BIT_NV);
unknown088160a2019-05-23 17:43:13 -06006712 m_errorMonitor->VerifyFound();
6713
Shannon McPherson93970b12020-06-12 14:34:35 -06006714 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdSetEvent-stageMask-04096");
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06006715 vk::CmdSetEvent(m_commandBuffer->handle(), event, VK_PIPELINE_STAGE_TASK_SHADER_BIT_NV);
unknown088160a2019-05-23 17:43:13 -06006716 m_errorMonitor->VerifyFound();
6717
Shannon McPherson93970b12020-06-12 14:34:35 -06006718 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdResetEvent-stageMask-04095");
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06006719 vk::CmdResetEvent(m_commandBuffer->handle(), event, VK_PIPELINE_STAGE_MESH_SHADER_BIT_NV);
unknown088160a2019-05-23 17:43:13 -06006720 m_errorMonitor->VerifyFound();
6721
Shannon McPherson93970b12020-06-12 14:34:35 -06006722 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdResetEvent-stageMask-04096");
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06006723 vk::CmdResetEvent(m_commandBuffer->handle(), event, VK_PIPELINE_STAGE_TASK_SHADER_BIT_NV);
unknown088160a2019-05-23 17:43:13 -06006724 m_errorMonitor->VerifyFound();
6725
Shannon McPherson93970b12020-06-12 14:34:35 -06006726 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdWaitEvents-srcStageMask-04095");
6727 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdWaitEvents-dstStageMask-04095");
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06006728 vk::CmdWaitEvents(m_commandBuffer->handle(), 1, &event, VK_PIPELINE_STAGE_MESH_SHADER_BIT_NV,
6729 VK_PIPELINE_STAGE_MESH_SHADER_BIT_NV, 0, nullptr, 0, nullptr, 0, nullptr);
unknown088160a2019-05-23 17:43:13 -06006730 m_errorMonitor->VerifyFound();
6731
Shannon McPherson93970b12020-06-12 14:34:35 -06006732 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdWaitEvents-srcStageMask-04096");
6733 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdWaitEvents-dstStageMask-04096");
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06006734 vk::CmdWaitEvents(m_commandBuffer->handle(), 1, &event, VK_PIPELINE_STAGE_TASK_SHADER_BIT_NV,
6735 VK_PIPELINE_STAGE_TASK_SHADER_BIT_NV, 0, nullptr, 0, nullptr, 0, nullptr);
unknown088160a2019-05-23 17:43:13 -06006736 m_errorMonitor->VerifyFound();
6737
Shannon McPherson93970b12020-06-12 14:34:35 -06006738 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdPipelineBarrier-srcStageMask-04095");
6739 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdPipelineBarrier-dstStageMask-04095");
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06006740 vk::CmdPipelineBarrier(m_commandBuffer->handle(), VK_PIPELINE_STAGE_MESH_SHADER_BIT_NV, VK_PIPELINE_STAGE_MESH_SHADER_BIT_NV, 0,
6741 0, nullptr, 0, nullptr, 0, nullptr);
unknown088160a2019-05-23 17:43:13 -06006742 m_errorMonitor->VerifyFound();
6743
Shannon McPherson93970b12020-06-12 14:34:35 -06006744 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdPipelineBarrier-srcStageMask-04096");
6745 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdPipelineBarrier-dstStageMask-04096");
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06006746 vk::CmdPipelineBarrier(m_commandBuffer->handle(), VK_PIPELINE_STAGE_TASK_SHADER_BIT_NV, VK_PIPELINE_STAGE_TASK_SHADER_BIT_NV, 0,
6747 0, nullptr, 0, nullptr, 0, nullptr);
unknown088160a2019-05-23 17:43:13 -06006748 m_errorMonitor->VerifyFound();
6749
6750 m_commandBuffer->end();
6751
6752 VkSemaphoreCreateInfo semaphore_create_info = {};
6753 semaphore_create_info.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO;
6754 VkSemaphore semaphore;
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06006755 ASSERT_VK_SUCCESS(vk::CreateSemaphore(m_device->device(), &semaphore_create_info, nullptr, &semaphore));
unknown088160a2019-05-23 17:43:13 -06006756
6757 VkPipelineStageFlags stage_flags = VK_PIPELINE_STAGE_MESH_SHADER_BIT_NV | VK_PIPELINE_STAGE_TASK_SHADER_BIT_NV;
6758 VkSubmitInfo submit_info = {};
6759
6760 // Signal the semaphore so the next test can wait on it.
6761 submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
6762 submit_info.signalSemaphoreCount = 1;
6763 submit_info.pSignalSemaphores = &semaphore;
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06006764 vk::QueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
unknown088160a2019-05-23 17:43:13 -06006765 m_errorMonitor->VerifyNotFound();
6766
6767 submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
6768 submit_info.signalSemaphoreCount = 0;
6769 submit_info.pSignalSemaphores = nullptr;
6770 submit_info.waitSemaphoreCount = 1;
6771 submit_info.pWaitSemaphores = &semaphore;
6772 submit_info.pWaitDstStageMask = &stage_flags;
6773
Mark Lobodzinski20310782020-02-28 14:25:17 -07006774 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkSubmitInfo-pWaitDstStageMask-02089");
6775 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkSubmitInfo-pWaitDstStageMask-02090");
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06006776 vk::QueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
unknown088160a2019-05-23 17:43:13 -06006777 m_errorMonitor->VerifyFound();
6778
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06006779 vk::QueueWaitIdle(m_device->m_queue);
unknown088160a2019-05-23 17:43:13 -06006780
6781 VkShaderObj vs(m_device, bindStateVertShaderText, VK_SHADER_STAGE_VERTEX_BIT, this);
6782 VkPipelineShaderStageCreateInfo meshStage = {VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO};
6783 meshStage = vs.GetStageCreateInfo();
6784 meshStage.stage = VK_SHADER_STAGE_MESH_BIT_NV;
6785 VkPipelineShaderStageCreateInfo taskStage = {VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO};
6786 taskStage = vs.GetStageCreateInfo();
6787 taskStage.stage = VK_SHADER_STAGE_TASK_BIT_NV;
6788
6789 // mesh and task shaders not supported
6790 const auto break_vp = [&](CreatePipelineHelper &helper) {
6791 helper.shader_stages_ = {meshStage, taskStage, vs.GetStageCreateInfo()};
6792 };
6793 CreatePipelineHelper::OneshotTest(
Mark Lobodzinski20310782020-02-28 14:25:17 -07006794 *this, break_vp, kErrorBit,
unknown088160a2019-05-23 17:43:13 -06006795 vector<std::string>({"VUID-VkPipelineShaderStageCreateInfo-pName-00707", "VUID-VkPipelineShaderStageCreateInfo-pName-00707",
6796 "VUID-VkPipelineShaderStageCreateInfo-stage-02091",
6797 "VUID-VkPipelineShaderStageCreateInfo-stage-02092"}));
6798
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06006799 vk::DestroyEvent(m_device->device(), event, nullptr);
6800 vk::DestroySemaphore(m_device->device(), semaphore, nullptr);
unknown088160a2019-05-23 17:43:13 -06006801}
Chris Mayerc93536f2019-09-19 16:34:49 +02006802
6803TEST_F(VkLayerTest, ViewportWScalingNV) {
6804 TEST_DESCRIPTION("Verify VK_NV_clip_space_w_scaling");
6805
Mark Lobodzinski09ce9c42020-03-06 10:02:44 -07006806 ASSERT_NO_FATAL_FAILURE(InitFramework(m_errorMonitor));
Chris Mayerc93536f2019-09-19 16:34:49 +02006807
6808 VkPhysicalDeviceFeatures device_features = {};
6809 ASSERT_NO_FATAL_FAILURE(GetPhysicalDeviceFeatures(&device_features));
6810
6811 if (!device_features.multiViewport) {
6812 printf("%s VkPhysicalDeviceFeatures::multiViewport is not supported, skipping tests\n", kSkipPrefix);
6813 return;
6814 }
6815
6816 if (DeviceExtensionSupported(gpu(), nullptr, VK_NV_CLIP_SPACE_W_SCALING_EXTENSION_NAME)) {
6817 m_device_extension_names.push_back(VK_NV_CLIP_SPACE_W_SCALING_EXTENSION_NAME);
6818 } else {
6819 printf("%s %s Extension not supported, skipping tests\n", kSkipPrefix, VK_NV_CLIP_SPACE_W_SCALING_EXTENSION_NAME);
6820 return;
6821 }
6822
6823 ASSERT_NO_FATAL_FAILURE(InitState(&device_features));
6824 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
6825
6826 auto vkCmdSetViewportWScalingNV =
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06006827 reinterpret_cast<PFN_vkCmdSetViewportWScalingNV>(vk::GetDeviceProcAddr(m_device->device(), "vkCmdSetViewportWScalingNV"));
Chris Mayerc93536f2019-09-19 16:34:49 +02006828
6829 const char vs_src[] = R"(
6830 #version 450
6831 const vec2 positions[] = { vec2(-1.0f, 1.0f),
6832 vec2( 1.0f, 1.0f),
6833 vec2(-1.0f, -1.0f),
6834 vec2( 1.0f, -1.0f) };
6835 out gl_PerVertex {
6836 vec4 gl_Position;
6837 };
6838
6839 void main() {
6840 gl_Position = vec4(positions[gl_VertexIndex % 4], 0.0f, 1.0f);
6841 })";
6842
6843 const char fs_src[] = R"(
6844 #version 450
6845 layout(location = 0) out vec4 outColor;
6846
6847 void main() {
6848 outColor = vec4(0.0f, 1.0f, 0.0f, 1.0f);
6849 })";
6850
6851 const std::vector<VkViewport> vp = {
6852 {0.0f, 0.0f, 64.0f, 64.0f}, {0.0f, 0.0f, 64.0f, 64.0f}, {0.0f, 0.0f, 64.0f, 64.0f}, {0.0f, 0.0f, 64.0f, 64.0f}};
6853 const std::vector<VkRect2D> sc = {{{0, 0}, {32, 32}}, {{32, 0}, {32, 32}}, {{0, 32}, {32, 32}}, {{32, 32}, {32, 32}}};
6854 const std::vector<VkViewportWScalingNV> scale = {{-0.2f, -0.2f}, {0.2f, -0.2f}, {-0.2f, 0.2f}, {0.2f, 0.2f}};
6855
6856 const uint32_t vp_count = static_cast<uint32_t>(vp.size());
6857
6858 VkPipelineViewportWScalingStateCreateInfoNV vpsi = {VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_W_SCALING_STATE_CREATE_INFO_NV};
6859 vpsi.viewportWScalingEnable = VK_TRUE;
6860 vpsi.viewportCount = vp_count;
6861 vpsi.pViewportWScalings = scale.data();
6862
6863 VkPipelineViewportStateCreateInfo vpci = {VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO};
6864 vpci.viewportCount = vp_count;
6865 vpci.pViewports = vp.data();
6866 vpci.scissorCount = vp_count;
6867 vpci.pScissors = sc.data();
6868 vpci.pNext = &vpsi;
6869
6870 const auto set_vpci = [&vpci](CreatePipelineHelper &helper) { helper.vp_state_ci_ = vpci; };
6871
6872 // Make sure no errors show up when creating the pipeline with w-scaling enabled
Mark Lobodzinski20310782020-02-28 14:25:17 -07006873 CreatePipelineHelper::OneshotTest(*this, set_vpci, kErrorBit, vector<std::string>(), true);
Chris Mayerc93536f2019-09-19 16:34:49 +02006874
6875 // Create pipeline with w-scaling enabled but without a valid scaling array
6876 vpsi.pViewportWScalings = nullptr;
Mark Lobodzinski20310782020-02-28 14:25:17 -07006877 CreatePipelineHelper::OneshotTest(*this, set_vpci, kErrorBit,
Chris Mayerc93536f2019-09-19 16:34:49 +02006878 vector<std::string>({"VUID-VkGraphicsPipelineCreateInfo-pDynamicStates-01715"}));
6879
6880 vpsi.pViewportWScalings = scale.data();
6881
6882 // Create pipeline with w-scaling enabled but without matching viewport counts
6883 vpsi.viewportCount = 1;
Mark Lobodzinski20310782020-02-28 14:25:17 -07006884 CreatePipelineHelper::OneshotTest(*this, set_vpci, kErrorBit,
Chris Mayerc93536f2019-09-19 16:34:49 +02006885 vector<std::string>({"VUID-VkPipelineViewportStateCreateInfo-viewportWScalingEnable-01726"}));
6886
6887 const VkPipelineLayoutObj pl(m_device);
6888
6889 VkShaderObj vs(m_device, vs_src, VK_SHADER_STAGE_VERTEX_BIT, this);
6890 VkShaderObj fs(m_device, fs_src, VK_SHADER_STAGE_FRAGMENT_BIT, this);
6891
6892 VkPipelineObj pipe(m_device);
6893 pipe.AddDefaultColorAttachment();
6894 pipe.AddShader(&vs);
6895 pipe.AddShader(&fs);
6896 pipe.SetViewport(vp);
6897 pipe.SetScissor(sc);
6898 pipe.CreateVKPipeline(pl.handle(), renderPass());
6899
6900 VkPipelineObj pipeDynWScale(m_device);
6901 pipeDynWScale.AddDefaultColorAttachment();
6902 pipeDynWScale.AddShader(&vs);
6903 pipeDynWScale.AddShader(&fs);
6904 pipeDynWScale.SetViewport(vp);
6905 pipeDynWScale.SetScissor(sc);
6906 pipeDynWScale.MakeDynamic(VK_DYNAMIC_STATE_VIEWPORT_W_SCALING_NV);
6907 pipeDynWScale.CreateVKPipeline(pl.handle(), renderPass());
6908
6909 m_commandBuffer->begin();
6910
6911 // Bind pipeline without dynamic w scaling enabled
6912 m_errorMonitor->ExpectSuccess();
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06006913 vk::CmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.handle());
Chris Mayerc93536f2019-09-19 16:34:49 +02006914 m_errorMonitor->VerifyNotFound();
6915
Chris Mayerc93536f2019-09-19 16:34:49 +02006916 // Bind pipeline that has dynamic w-scaling enabled
6917 m_errorMonitor->ExpectSuccess();
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06006918 vk::CmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeDynWScale.handle());
Chris Mayerc93536f2019-09-19 16:34:49 +02006919 m_errorMonitor->VerifyNotFound();
6920
6921 const auto max_vps = m_device->props.limits.maxViewports;
6922
Mark Lobodzinski20310782020-02-28 14:25:17 -07006923 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdSetViewportWScalingNV-firstViewport-01324");
Chris Mayerc93536f2019-09-19 16:34:49 +02006924 vkCmdSetViewportWScalingNV(m_commandBuffer->handle(), 1, max_vps, scale.data());
6925 m_errorMonitor->VerifyFound();
6926
6927 m_errorMonitor->ExpectSuccess();
6928 vkCmdSetViewportWScalingNV(m_commandBuffer->handle(), 0, vp_count, scale.data());
6929 m_errorMonitor->VerifyNotFound();
6930
6931 m_commandBuffer->end();
6932}
sfricke-samsung914e8002020-01-07 22:26:18 -08006933
6934TEST_F(VkLayerTest, CreateSamplerYcbcrConversionEnable) {
6935 TEST_DESCRIPTION("Checks samplerYcbcrConversion is enabled before calling vkCreateSamplerYcbcrConversion");
6936
6937 // Enable Sampler YCbCr Conversion req'd extensions
6938 // Only need revision 1 of vkGetPhysicalDeviceProperties2 and this allows more device capable for testing
6939 bool mp_extensions = InstanceExtensionSupported(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME, 1);
6940 if (mp_extensions) {
6941 m_instance_extension_names.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
6942 }
6943 SetTargetApiVersion(VK_API_VERSION_1_1);
Mark Lobodzinski09ce9c42020-03-06 10:02:44 -07006944 ASSERT_NO_FATAL_FAILURE(InitFramework(m_errorMonitor));
sfricke-samsung914e8002020-01-07 22:26:18 -08006945 mp_extensions = mp_extensions && DeviceExtensionSupported(gpu(), nullptr, VK_KHR_MAINTENANCE1_EXTENSION_NAME);
6946 mp_extensions = mp_extensions && DeviceExtensionSupported(gpu(), nullptr, VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME);
6947 mp_extensions = mp_extensions && DeviceExtensionSupported(gpu(), nullptr, VK_KHR_BIND_MEMORY_2_EXTENSION_NAME);
6948 mp_extensions = mp_extensions && DeviceExtensionSupported(gpu(), nullptr, VK_KHR_SAMPLER_YCBCR_CONVERSION_EXTENSION_NAME);
6949 if (mp_extensions) {
6950 m_device_extension_names.push_back(VK_KHR_MAINTENANCE1_EXTENSION_NAME);
6951 m_device_extension_names.push_back(VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME);
6952 m_device_extension_names.push_back(VK_KHR_BIND_MEMORY_2_EXTENSION_NAME);
6953 m_device_extension_names.push_back(VK_KHR_SAMPLER_YCBCR_CONVERSION_EXTENSION_NAME);
6954 } else {
6955 printf("%s test requires Sampler YCbCr Conversion extensions, not available. Skipping.\n", kSkipPrefix);
6956 return;
6957 }
6958
6959 // Explictly not enable Ycbcr Conversion Features
6960 VkPhysicalDeviceSamplerYcbcrConversionFeatures ycbcr_features = {};
6961 ycbcr_features.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SAMPLER_YCBCR_CONVERSION_FEATURES;
6962 ycbcr_features.samplerYcbcrConversion = VK_FALSE;
6963 ASSERT_NO_FATAL_FAILURE(InitState(nullptr, &ycbcr_features));
6964
6965 PFN_vkCreateSamplerYcbcrConversionKHR vkCreateSamplerYcbcrConversionFunction =
6966 (PFN_vkCreateSamplerYcbcrConversionKHR)vk::GetDeviceProcAddr(m_device->handle(), "vkCreateSamplerYcbcrConversionKHR");
6967 if (vkCreateSamplerYcbcrConversionFunction == nullptr) {
6968 printf("%s did not find vkCreateSamplerYcbcrConversionKHR function pointer; Skipping.\n", kSkipPrefix);
6969 return;
6970 }
6971
6972 // Create Ycbcr conversion
6973 VkSamplerYcbcrConversion conversions;
6974 VkSamplerYcbcrConversionCreateInfo ycbcr_create_info = {VK_STRUCTURE_TYPE_SAMPLER_YCBCR_CONVERSION_CREATE_INFO,
6975 NULL,
6976 VK_FORMAT_G8_B8R8_2PLANE_420_UNORM_KHR,
6977 VK_SAMPLER_YCBCR_MODEL_CONVERSION_RGB_IDENTITY,
6978 VK_SAMPLER_YCBCR_RANGE_ITU_FULL,
6979 {VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY,
6980 VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY},
6981 VK_CHROMA_LOCATION_COSITED_EVEN,
6982 VK_CHROMA_LOCATION_COSITED_EVEN,
6983 VK_FILTER_NEAREST,
6984 false};
6985
Mark Lobodzinski20310782020-02-28 14:25:17 -07006986 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCreateSamplerYcbcrConversion-None-01648");
sfricke-samsung914e8002020-01-07 22:26:18 -08006987 vkCreateSamplerYcbcrConversionFunction(m_device->handle(), &ycbcr_create_info, nullptr, &conversions);
6988 m_errorMonitor->VerifyFound();
Shannon McPherson50421602020-01-28 15:18:46 -07006989}
Jeremy Hayescd7df2c2020-05-21 16:36:47 -06006990
6991TEST_F(VkLayerTest, TransformFeedbackFeatureEnabled) {
6992 TEST_DESCRIPTION("VkPhysicalDeviceTransformFeedbackFeaturesEXT::transformFeedback must be enabled");
6993
6994 if (!InstanceExtensionSupported(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME)) {
6995 printf("%s Did not find required instance extension %s; skipped.\n", kSkipPrefix,
6996 VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
6997 return;
6998 }
6999 m_instance_extension_names.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
7000
7001 ASSERT_NO_FATAL_FAILURE(InitFramework(m_errorMonitor));
7002
7003 if (!DeviceExtensionSupported(gpu(), nullptr, VK_EXT_TRANSFORM_FEEDBACK_EXTENSION_NAME)) {
7004 printf("%s %s Extension not supported, skipping tests\n", kSkipPrefix, VK_EXT_TRANSFORM_FEEDBACK_EXTENSION_NAME);
7005 return;
7006 }
7007 m_device_extension_names.push_back(VK_EXT_TRANSFORM_FEEDBACK_EXTENSION_NAME);
7008
7009 {
7010 PFN_vkGetPhysicalDeviceFeatures2KHR vkGetPhysicalDeviceFeatures2KHR =
7011 (PFN_vkGetPhysicalDeviceFeatures2KHR)vk::GetInstanceProcAddr(instance(), "vkGetPhysicalDeviceFeatures2KHR");
7012 ASSERT_TRUE(vkGetPhysicalDeviceFeatures2KHR != nullptr);
7013
Mark Lobodzinski07d0a612020-12-30 15:42:31 -07007014 auto tf_features = LvlInitStruct<VkPhysicalDeviceTransformFeedbackFeaturesEXT>();
7015 auto pd_features = LvlInitStruct<VkPhysicalDeviceFeatures2>(&tf_features);
Jeremy Hayescd7df2c2020-05-21 16:36:47 -06007016 vkGetPhysicalDeviceFeatures2KHR(gpu(), &pd_features);
7017
7018 if (!tf_features.transformFeedback) {
7019 printf("%s transformFeedback not supported; skipped.\n", kSkipPrefix);
7020 return;
7021 }
7022 }
7023
7024 ASSERT_NO_FATAL_FAILURE(InitState());
7025 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
7026
7027 {
7028 auto vkCmdBindTransformFeedbackBuffersEXT = (PFN_vkCmdBindTransformFeedbackBuffersEXT)vk::GetDeviceProcAddr(
7029 m_device->device(), "vkCmdBindTransformFeedbackBuffersEXT");
7030 ASSERT_TRUE(vkCmdBindTransformFeedbackBuffersEXT != nullptr);
7031
Mark Lobodzinski07d0a612020-12-30 15:42:31 -07007032 auto info = LvlInitStruct<VkBufferCreateInfo>();
Jeremy Hayescd7df2c2020-05-21 16:36:47 -06007033 info.usage = VK_BUFFER_USAGE_TRANSFORM_FEEDBACK_BUFFER_BIT_EXT;
7034 info.size = 4;
7035 VkBufferObj buffer;
7036 buffer.init(*m_device, info);
7037 VkDeviceSize offsets[1]{};
7038
7039 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdBindTransformFeedbackBuffersEXT-transformFeedback-02355");
7040 vkCmdBindTransformFeedbackBuffersEXT(m_commandBuffer->handle(), 0, 1, &buffer.handle(), offsets, nullptr);
7041 m_errorMonitor->VerifyFound();
7042 }
7043
7044 {
7045 auto vkCmdBeginTransformFeedbackEXT =
7046 (PFN_vkCmdBeginTransformFeedbackEXT)vk::GetDeviceProcAddr(m_device->device(), "vkCmdBeginTransformFeedbackEXT");
7047 ASSERT_TRUE(vkCmdBeginTransformFeedbackEXT != nullptr);
7048
7049 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdBeginTransformFeedbackEXT-transformFeedback-02366");
7050 vkCmdBeginTransformFeedbackEXT(m_commandBuffer->handle(), 0, 1, nullptr, nullptr);
7051 m_errorMonitor->VerifyFound();
7052 }
7053
7054 {
7055 auto vkCmdEndTransformFeedbackEXT =
7056 (PFN_vkCmdEndTransformFeedbackEXT)vk::GetDeviceProcAddr(m_device->device(), "vkCmdEndTransformFeedbackEXT");
7057 ASSERT_TRUE(vkCmdEndTransformFeedbackEXT != nullptr);
7058
7059 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdEndTransformFeedbackEXT-transformFeedback-02374");
7060 m_errorMonitor->SetUnexpectedError("VUID-vkCmdEndTransformFeedbackEXT-None-02375");
7061 vkCmdEndTransformFeedbackEXT(m_commandBuffer->handle(), 0, 1, nullptr, nullptr);
7062 m_errorMonitor->VerifyFound();
7063 }
7064}
7065
7066TEST_F(VkLayerTest, TransformFeedbackCmdBindTransformFeedbackBuffersEXT) {
7067 TEST_DESCRIPTION("Submit invalid arguments to vkCmdBindTransformFeedbackBuffersEXT");
7068
7069 if (!InstanceExtensionSupported(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME)) {
7070 printf("%s Did not find required instance extension %s; skipped.\n", kSkipPrefix,
7071 VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
7072 return;
7073 }
7074 m_instance_extension_names.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
7075
7076 ASSERT_NO_FATAL_FAILURE(InitFramework(m_errorMonitor));
7077
7078 if (!DeviceExtensionSupported(gpu(), nullptr, VK_EXT_TRANSFORM_FEEDBACK_EXTENSION_NAME)) {
7079 printf("%s %s Extension not supported, skipping tests\n", kSkipPrefix, VK_EXT_TRANSFORM_FEEDBACK_EXTENSION_NAME);
7080 return;
7081 }
7082 m_device_extension_names.push_back(VK_EXT_TRANSFORM_FEEDBACK_EXTENSION_NAME);
7083
7084 {
7085 PFN_vkGetPhysicalDeviceFeatures2KHR vkGetPhysicalDeviceFeatures2KHR =
7086 (PFN_vkGetPhysicalDeviceFeatures2KHR)vk::GetInstanceProcAddr(instance(), "vkGetPhysicalDeviceFeatures2KHR");
7087 ASSERT_TRUE(vkGetPhysicalDeviceFeatures2KHR != nullptr);
7088
Mark Lobodzinski07d0a612020-12-30 15:42:31 -07007089 auto tf_features = LvlInitStruct<VkPhysicalDeviceTransformFeedbackFeaturesEXT>();
7090 auto pd_features = LvlInitStruct<VkPhysicalDeviceFeatures2>(&tf_features);
Jeremy Hayescd7df2c2020-05-21 16:36:47 -06007091 vkGetPhysicalDeviceFeatures2KHR(gpu(), &pd_features);
7092
7093 if (!tf_features.transformFeedback) {
7094 printf("%s transformFeedback not supported; skipped.\n", kSkipPrefix);
7095 return;
7096 }
7097
7098 ASSERT_NO_FATAL_FAILURE(InitState(nullptr, &pd_features));
7099 }
7100
7101 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
7102
7103 auto vkCmdBindTransformFeedbackBuffersEXT =
7104 (PFN_vkCmdBindTransformFeedbackBuffersEXT)vk::GetDeviceProcAddr(m_device->device(), "vkCmdBindTransformFeedbackBuffersEXT");
7105 ASSERT_TRUE(vkCmdBindTransformFeedbackBuffersEXT != nullptr);
7106
7107 {
Mark Lobodzinski07d0a612020-12-30 15:42:31 -07007108 auto tf_properties = LvlInitStruct<VkPhysicalDeviceTransformFeedbackPropertiesEXT>();
7109 auto pd_properties = LvlInitStruct<VkPhysicalDeviceProperties2>(&tf_properties);
Jeremy Hayescd7df2c2020-05-21 16:36:47 -06007110 vk::GetPhysicalDeviceProperties2(gpu(), &pd_properties);
7111
Mark Lobodzinski07d0a612020-12-30 15:42:31 -07007112 auto info = LvlInitStruct<VkBufferCreateInfo>();
Jeremy Hayescd7df2c2020-05-21 16:36:47 -06007113 info.usage = VK_BUFFER_USAGE_TRANSFORM_FEEDBACK_BUFFER_BIT_EXT;
7114 info.size = 8;
7115 VkBufferObj const buffer_obj(*m_device, info);
7116
7117 // Request a firstBinding that is too large.
7118 {
7119 auto const firstBinding = tf_properties.maxTransformFeedbackBuffers;
7120 VkDeviceSize const offsets[1]{};
7121
7122 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdBindTransformFeedbackBuffersEXT-firstBinding-02356");
7123 m_errorMonitor->SetUnexpectedError("VUID-vkCmdBindTransformFeedbackBuffersEXT-firstBinding-02357");
7124 vkCmdBindTransformFeedbackBuffersEXT(m_commandBuffer->handle(), firstBinding, 1, &buffer_obj.handle(), offsets,
7125 nullptr);
7126 m_errorMonitor->VerifyFound();
7127 }
7128
7129 // Request too many bindings.
7130 if (tf_properties.maxTransformFeedbackBuffers < std::numeric_limits<uint32_t>::max()) {
7131 auto const bindingCount = tf_properties.maxTransformFeedbackBuffers + 1;
7132 std::vector<VkBuffer> buffers(bindingCount, buffer_obj.handle());
7133
7134 std::vector<VkDeviceSize> offsets(bindingCount);
7135
7136 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdBindTransformFeedbackBuffersEXT-firstBinding-02357");
7137 vkCmdBindTransformFeedbackBuffersEXT(m_commandBuffer->handle(), 0, bindingCount, buffers.data(), offsets.data(),
7138 nullptr);
7139 m_errorMonitor->VerifyFound();
7140 }
7141
7142 // Request a size that is larger than the maximum size.
7143 if (tf_properties.maxTransformFeedbackBufferSize < std::numeric_limits<VkDeviceSize>::max()) {
7144 VkDeviceSize const offsets[1]{};
7145 VkDeviceSize const sizes[1]{tf_properties.maxTransformFeedbackBufferSize + 1};
7146
7147 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdBindTransformFeedbackBuffersEXT-pSize-02361");
7148 vkCmdBindTransformFeedbackBuffersEXT(m_commandBuffer->handle(), 0, 1, &buffer_obj.handle(), offsets, sizes);
7149 m_errorMonitor->VerifyFound();
7150 }
7151 }
7152
7153 {
Mark Lobodzinski07d0a612020-12-30 15:42:31 -07007154 auto info = LvlInitStruct<VkBufferCreateInfo>();
Jeremy Hayescd7df2c2020-05-21 16:36:47 -06007155 info.usage = VK_BUFFER_USAGE_TRANSFORM_FEEDBACK_BUFFER_BIT_EXT;
7156 info.size = 8;
7157 VkBufferObj const buffer_obj(*m_device, info);
7158
7159 // Request an offset that is too large.
7160 {
7161 VkDeviceSize const offsets[1]{info.size + 4};
7162
7163 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdBindTransformFeedbackBuffersEXT-pOffsets-02358");
7164 vkCmdBindTransformFeedbackBuffersEXT(m_commandBuffer->handle(), 0, 1, &buffer_obj.handle(), offsets, nullptr);
7165 m_errorMonitor->VerifyFound();
7166 }
7167
7168 // Request an offset that is not a multiple of 4.
7169 {
7170 VkDeviceSize const offsets[1]{1};
7171
7172 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdBindTransformFeedbackBuffersEXT-pOffsets-02359");
7173 vkCmdBindTransformFeedbackBuffersEXT(m_commandBuffer->handle(), 0, 1, &buffer_obj.handle(), offsets, nullptr);
7174 m_errorMonitor->VerifyFound();
7175 }
7176
7177 // Request a size that is larger than the buffer's size.
7178 {
7179 VkDeviceSize const offsets[1]{};
7180 VkDeviceSize const sizes[1]{info.size + 1};
7181
7182 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdBindTransformFeedbackBuffersEXT-pSizes-02362");
Jeremy Hayescd7df2c2020-05-21 16:36:47 -06007183 vkCmdBindTransformFeedbackBuffersEXT(m_commandBuffer->handle(), 0, 1, &buffer_obj.handle(), offsets, sizes);
7184 m_errorMonitor->VerifyFound();
7185 }
7186
7187 // Request an offset and size whose sum is larger than the buffer's size.
7188 {
7189 VkDeviceSize const offsets[1]{4};
7190 VkDeviceSize const sizes[1]{info.size - 3};
7191
7192 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdBindTransformFeedbackBuffersEXT-pOffsets-02363");
7193 vkCmdBindTransformFeedbackBuffersEXT(m_commandBuffer->handle(), 0, 1, &buffer_obj.handle(), offsets, sizes);
7194 m_errorMonitor->VerifyFound();
7195 }
7196
7197 // Bind while transform feedback is active.
7198 {
7199 auto vkCmdBeginTransformFeedbackEXT =
7200 (PFN_vkCmdBeginTransformFeedbackEXT)vk::GetDeviceProcAddr(m_device->device(), "vkCmdBeginTransformFeedbackEXT");
7201 ASSERT_TRUE(vkCmdBeginTransformFeedbackEXT != nullptr);
7202 vkCmdBeginTransformFeedbackEXT(m_commandBuffer->handle(), 0, 1, nullptr, nullptr);
7203
7204 VkDeviceSize const offsets[1]{};
7205
7206 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdBindTransformFeedbackBuffersEXT-None-02365");
7207 vkCmdBindTransformFeedbackBuffersEXT(m_commandBuffer->handle(), 0, 1, &buffer_obj.handle(), offsets, nullptr);
7208 m_errorMonitor->VerifyFound();
7209
7210 auto vkCmdEndTransformFeedbackEXT =
7211 (PFN_vkCmdEndTransformFeedbackEXT)vk::GetDeviceProcAddr(m_device->device(), "vkCmdEndTransformFeedbackEXT");
7212 ASSERT_TRUE(vkCmdEndTransformFeedbackEXT != nullptr);
7213 vkCmdEndTransformFeedbackEXT(m_commandBuffer->handle(), 0, 1, nullptr, nullptr);
7214 }
7215 }
7216
7217 // Don't set VK_BUFFER_USAGE_TRANSFORM_FEEDBACK_BUFFER_BIT_EXT.
7218 {
Mark Lobodzinski07d0a612020-12-30 15:42:31 -07007219 auto info = LvlInitStruct<VkBufferCreateInfo>();
Jeremy Hayescd7df2c2020-05-21 16:36:47 -06007220 // info.usage = VK_BUFFER_USAGE_TRANSFORM_FEEDBACK_BUFFER_BIT_EXT;
7221 info.size = 4;
7222 VkBufferObj const buffer_obj(*m_device, info);
7223
7224 VkDeviceSize const offsets[1]{};
7225
7226 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdBindTransformFeedbackBuffersEXT-pBuffers-02360");
7227 vkCmdBindTransformFeedbackBuffersEXT(m_commandBuffer->handle(), 0, 1, &buffer_obj.handle(), offsets, nullptr);
7228 m_errorMonitor->VerifyFound();
7229 }
7230
7231 // Don't bind memory.
7232 {
7233 VkBuffer buffer{};
7234 {
7235 auto vkCreateBuffer = (PFN_vkCreateBuffer)vk::GetDeviceProcAddr(m_device->device(), "vkCreateBuffer");
7236 ASSERT_TRUE(vkCreateBuffer != nullptr);
7237
Mark Lobodzinski07d0a612020-12-30 15:42:31 -07007238 auto info = LvlInitStruct<VkBufferCreateInfo>();
Jeremy Hayescd7df2c2020-05-21 16:36:47 -06007239 info.usage = VK_BUFFER_USAGE_TRANSFORM_FEEDBACK_BUFFER_BIT_EXT;
7240 info.size = 4;
7241 vkCreateBuffer(m_device->device(), &info, nullptr, &buffer);
7242 }
7243
7244 VkDeviceSize const offsets[1]{};
7245
7246 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdBindTransformFeedbackBuffersEXT-pBuffers-02364");
7247 vkCmdBindTransformFeedbackBuffersEXT(m_commandBuffer->handle(), 0, 1, &buffer, offsets, nullptr);
7248 m_errorMonitor->VerifyFound();
7249 }
7250}
7251
7252TEST_F(VkLayerTest, TransformFeedbackCmdBeginTransformFeedbackEXT) {
7253 TEST_DESCRIPTION("Submit invalid arguments to vkCmdBeginTransformFeedbackEXT");
7254
7255 if (!InstanceExtensionSupported(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME)) {
7256 printf("%s Did not find required instance extension %s; skipped.\n", kSkipPrefix,
7257 VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
7258 return;
7259 }
7260 m_instance_extension_names.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
7261
7262 ASSERT_NO_FATAL_FAILURE(InitFramework(m_errorMonitor));
7263
7264 if (!DeviceExtensionSupported(gpu(), nullptr, VK_EXT_TRANSFORM_FEEDBACK_EXTENSION_NAME)) {
7265 printf("%s %s Extension not supported, skipping tests\n", kSkipPrefix, VK_EXT_TRANSFORM_FEEDBACK_EXTENSION_NAME);
7266 return;
7267 }
7268 m_device_extension_names.push_back(VK_EXT_TRANSFORM_FEEDBACK_EXTENSION_NAME);
7269
7270 {
7271 PFN_vkGetPhysicalDeviceFeatures2KHR vkGetPhysicalDeviceFeatures2KHR =
7272 (PFN_vkGetPhysicalDeviceFeatures2KHR)vk::GetInstanceProcAddr(instance(), "vkGetPhysicalDeviceFeatures2KHR");
7273 ASSERT_TRUE(vkGetPhysicalDeviceFeatures2KHR != nullptr);
7274
Mark Lobodzinski07d0a612020-12-30 15:42:31 -07007275 auto tf_features = LvlInitStruct<VkPhysicalDeviceTransformFeedbackFeaturesEXT>();
7276 auto pd_features = LvlInitStruct<VkPhysicalDeviceFeatures2>(&tf_features);
Jeremy Hayescd7df2c2020-05-21 16:36:47 -06007277 vkGetPhysicalDeviceFeatures2KHR(gpu(), &pd_features);
7278
7279 if (!tf_features.transformFeedback) {
7280 printf("%s transformFeedback not supported; skipped.\n", kSkipPrefix);
7281 return;
7282 }
7283
7284 ASSERT_NO_FATAL_FAILURE(InitState(nullptr, &pd_features));
7285 }
7286
7287 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
7288
7289 auto vkCmdBeginTransformFeedbackEXT =
7290 (PFN_vkCmdBeginTransformFeedbackEXT)vk::GetDeviceProcAddr(m_device->device(), "vkCmdBeginTransformFeedbackEXT");
7291 ASSERT_TRUE(vkCmdBeginTransformFeedbackEXT != nullptr);
7292
7293 {
Mark Lobodzinski07d0a612020-12-30 15:42:31 -07007294 auto tf_properties = LvlInitStruct<VkPhysicalDeviceTransformFeedbackPropertiesEXT>();
7295 auto pd_properties = LvlInitStruct<VkPhysicalDeviceProperties2>(&tf_properties);
Jeremy Hayescd7df2c2020-05-21 16:36:47 -06007296 vk::GetPhysicalDeviceProperties2(gpu(), &pd_properties);
7297
7298 // Request a firstCounterBuffer that is too large.
7299 {
7300 auto const firstCounterBuffer = tf_properties.maxTransformFeedbackBuffers;
7301
7302 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdBeginTransformFeedbackEXT-firstCounterBuffer-02368");
7303 m_errorMonitor->SetUnexpectedError("VUID-vkCmdBeginTransformFeedbackEXT-firstCounterBuffer-02369");
7304 vkCmdBeginTransformFeedbackEXT(m_commandBuffer->handle(), firstCounterBuffer, 1, nullptr, nullptr);
7305 m_errorMonitor->VerifyFound();
7306 }
7307
7308 // Request too many buffers.
7309 if (tf_properties.maxTransformFeedbackBuffers < std::numeric_limits<uint32_t>::max()) {
7310 auto const counterBufferCount = tf_properties.maxTransformFeedbackBuffers + 1;
7311
7312 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdBeginTransformFeedbackEXT-firstCounterBuffer-02369");
7313 vkCmdBeginTransformFeedbackEXT(m_commandBuffer->handle(), 0, counterBufferCount, nullptr, nullptr);
7314 m_errorMonitor->VerifyFound();
7315 }
7316 }
7317
7318 // Request an out-of-bounds location.
7319 {
Mark Lobodzinski07d0a612020-12-30 15:42:31 -07007320 auto info = LvlInitStruct<VkBufferCreateInfo>();
Jeremy Hayescd7df2c2020-05-21 16:36:47 -06007321 info.usage = VK_BUFFER_USAGE_TRANSFORM_FEEDBACK_COUNTER_BUFFER_BIT_EXT;
7322 info.size = 4;
7323 VkBufferObj const buffer_obj(*m_device, info);
7324
7325 VkDeviceSize const offsets[1]{1};
7326
7327 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdBeginTransformFeedbackEXT-pCounterBufferOffsets-02370");
7328 vkCmdBeginTransformFeedbackEXT(m_commandBuffer->handle(), 0, 1, &buffer_obj.handle(), offsets);
7329 m_errorMonitor->VerifyFound();
7330 }
7331
7332 // Request specific offsets without specifying buffers.
7333 {
7334 VkDeviceSize const offsets[1]{};
7335
7336 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdBeginTransformFeedbackEXT-pCounterBuffer-02371");
7337 vkCmdBeginTransformFeedbackEXT(m_commandBuffer->handle(), 0, 1, nullptr, offsets);
7338 m_errorMonitor->VerifyFound();
7339 }
7340
7341 // Don't set VK_BUFFER_USAGE_TRANSFORM_FEEDBACK_COUNTER_BUFFER_BIT_EXT.
7342 {
Mark Lobodzinski07d0a612020-12-30 15:42:31 -07007343 auto info = LvlInitStruct<VkBufferCreateInfo>();
Jeremy Hayescd7df2c2020-05-21 16:36:47 -06007344 // info.usage = VK_BUFFER_USAGE_TRANSFORM_FEEDBACK_COUNTER_BUFFER_BIT_EXT;
7345 info.size = 4;
7346 VkBufferObj const buffer_obj(*m_device, info);
7347
7348 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdBeginTransformFeedbackEXT-pCounterBuffers-02372");
7349 vkCmdBeginTransformFeedbackEXT(m_commandBuffer->handle(), 0, 1, &buffer_obj.handle(), nullptr);
7350 m_errorMonitor->VerifyFound();
7351 }
7352
7353 // Begin while transform feedback is active.
7354 {
7355 vkCmdBeginTransformFeedbackEXT(m_commandBuffer->handle(), 0, 1, nullptr, nullptr);
7356
7357 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdBeginTransformFeedbackEXT-None-02367");
7358 vkCmdBeginTransformFeedbackEXT(m_commandBuffer->handle(), 0, 1, nullptr, nullptr);
7359 m_errorMonitor->VerifyFound();
7360
7361 auto vkCmdEndTransformFeedbackEXT =
7362 (PFN_vkCmdEndTransformFeedbackEXT)vk::GetDeviceProcAddr(m_device->device(), "vkCmdEndTransformFeedbackEXT");
7363 ASSERT_TRUE(vkCmdEndTransformFeedbackEXT != nullptr);
7364
7365 vkCmdEndTransformFeedbackEXT(m_commandBuffer->handle(), 0, 1, nullptr, nullptr);
7366 }
7367}
7368
7369TEST_F(VkLayerTest, TransformFeedbackCmdEndTransformFeedbackEXT) {
7370 TEST_DESCRIPTION("Submit invalid arguments to vkCmdEndTransformFeedbackEXT");
7371
7372 if (!InstanceExtensionSupported(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME)) {
7373 printf("%s Did not find required instance extension %s; skipped.\n", kSkipPrefix,
7374 VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
7375 return;
7376 }
7377 m_instance_extension_names.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
7378
7379 ASSERT_NO_FATAL_FAILURE(InitFramework(m_errorMonitor));
7380
7381 if (!DeviceExtensionSupported(gpu(), nullptr, VK_EXT_TRANSFORM_FEEDBACK_EXTENSION_NAME)) {
7382 printf("%s %s Extension not supported, skipping tests\n", kSkipPrefix, VK_EXT_TRANSFORM_FEEDBACK_EXTENSION_NAME);
7383 return;
7384 }
7385 m_device_extension_names.push_back(VK_EXT_TRANSFORM_FEEDBACK_EXTENSION_NAME);
7386
7387 {
7388 PFN_vkGetPhysicalDeviceFeatures2KHR vkGetPhysicalDeviceFeatures2KHR =
7389 (PFN_vkGetPhysicalDeviceFeatures2KHR)vk::GetInstanceProcAddr(instance(), "vkGetPhysicalDeviceFeatures2KHR");
7390 ASSERT_TRUE(vkGetPhysicalDeviceFeatures2KHR != nullptr);
7391
Mark Lobodzinski07d0a612020-12-30 15:42:31 -07007392 auto tf_features = LvlInitStruct<VkPhysicalDeviceTransformFeedbackFeaturesEXT>();
7393 auto pd_features = LvlInitStruct<VkPhysicalDeviceFeatures2>(&tf_features);
Jeremy Hayescd7df2c2020-05-21 16:36:47 -06007394 vkGetPhysicalDeviceFeatures2KHR(gpu(), &pd_features);
7395
7396 if (!tf_features.transformFeedback) {
7397 printf("%s transformFeedback not supported; skipped.\n", kSkipPrefix);
7398 return;
7399 }
7400
7401 ASSERT_NO_FATAL_FAILURE(InitState(nullptr, &pd_features));
7402 }
7403
7404 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
7405
7406 auto vkCmdEndTransformFeedbackEXT =
7407 (PFN_vkCmdEndTransformFeedbackEXT)vk::GetDeviceProcAddr(m_device->device(), "vkCmdEndTransformFeedbackEXT");
7408 ASSERT_TRUE(vkCmdEndTransformFeedbackEXT != nullptr);
7409
7410 {
7411 // Activate transform feedback.
7412 auto vkCmdBeginTransformFeedbackEXT =
7413 (PFN_vkCmdBeginTransformFeedbackEXT)vk::GetDeviceProcAddr(m_device->device(), "vkCmdBeginTransformFeedbackEXT");
7414 ASSERT_TRUE(vkCmdBeginTransformFeedbackEXT != nullptr);
7415 vkCmdBeginTransformFeedbackEXT(m_commandBuffer->handle(), 0, 1, nullptr, nullptr);
7416
7417 {
Mark Lobodzinski07d0a612020-12-30 15:42:31 -07007418 auto tf_properties = LvlInitStruct<VkPhysicalDeviceTransformFeedbackPropertiesEXT>();
7419 auto pd_properties = LvlInitStruct<VkPhysicalDeviceProperties2>(&tf_properties);
Jeremy Hayescd7df2c2020-05-21 16:36:47 -06007420 vk::GetPhysicalDeviceProperties2(gpu(), &pd_properties);
7421
7422 // Request a firstCounterBuffer that is too large.
7423 {
7424 auto const firstCounterBuffer = tf_properties.maxTransformFeedbackBuffers;
7425
7426 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdEndTransformFeedbackEXT-firstCounterBuffer-02376");
7427 m_errorMonitor->SetUnexpectedError("VUID-vkCmdEndTransformFeedbackEXT-firstCounterBuffer-02377");
7428 vkCmdEndTransformFeedbackEXT(m_commandBuffer->handle(), firstCounterBuffer, 1, nullptr, nullptr);
7429 m_errorMonitor->VerifyFound();
7430 }
7431
7432 // Request too many buffers.
7433 if (tf_properties.maxTransformFeedbackBuffers < std::numeric_limits<uint32_t>::max()) {
7434 auto const counterBufferCount = tf_properties.maxTransformFeedbackBuffers + 1;
7435
7436 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdEndTransformFeedbackEXT-firstCounterBuffer-02377");
7437 vkCmdEndTransformFeedbackEXT(m_commandBuffer->handle(), 0, counterBufferCount, nullptr, nullptr);
7438 m_errorMonitor->VerifyFound();
7439 }
7440 }
7441
7442 // Request an out-of-bounds location.
7443 {
Mark Lobodzinski07d0a612020-12-30 15:42:31 -07007444 auto info = LvlInitStruct<VkBufferCreateInfo>();
Jeremy Hayescd7df2c2020-05-21 16:36:47 -06007445 info.usage = VK_BUFFER_USAGE_TRANSFORM_FEEDBACK_COUNTER_BUFFER_BIT_EXT;
7446 info.size = 4;
7447 VkBufferObj const buffer_obj(*m_device, info);
7448
7449 VkDeviceSize const offsets[1]{1};
7450
7451 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdEndTransformFeedbackEXT-pCounterBufferOffsets-02378");
7452 vkCmdEndTransformFeedbackEXT(m_commandBuffer->handle(), 0, 1, &buffer_obj.handle(), offsets);
7453 m_errorMonitor->VerifyFound();
7454 }
7455
7456 // Request specific offsets without specifying buffers.
7457 {
7458 VkDeviceSize const offsets[1]{};
7459
7460 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdEndTransformFeedbackEXT-pCounterBuffer-02379");
7461 vkCmdEndTransformFeedbackEXT(m_commandBuffer->handle(), 0, 1, nullptr, offsets);
7462 m_errorMonitor->VerifyFound();
7463 }
7464
7465 // Don't set VK_BUFFER_USAGE_TRANSFORM_FEEDBACK_COUNTER_BUFFER_BIT_EXT.
7466 {
Mark Lobodzinski07d0a612020-12-30 15:42:31 -07007467 auto info = LvlInitStruct<VkBufferCreateInfo>();
Jeremy Hayescd7df2c2020-05-21 16:36:47 -06007468 // info.usage = VK_BUFFER_USAGE_TRANSFORM_FEEDBACK_COUNTER_BUFFER_BIT_EXT;
7469 info.size = 4;
7470 VkBufferObj const buffer_obj(*m_device, info);
7471
7472 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdEndTransformFeedbackEXT-pCounterBuffers-02380");
7473 vkCmdEndTransformFeedbackEXT(m_commandBuffer->handle(), 0, 1, &buffer_obj.handle(), nullptr);
7474 m_errorMonitor->VerifyFound();
7475 }
7476 }
7477
7478 // End while transform feedback is inactive.
7479 {
7480 vkCmdEndTransformFeedbackEXT(m_commandBuffer->handle(), 0, 1, nullptr, nullptr);
7481
7482 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdEndTransformFeedbackEXT-None-02375");
7483 vkCmdEndTransformFeedbackEXT(m_commandBuffer->handle(), 0, 1, nullptr, nullptr);
7484 m_errorMonitor->VerifyFound();
7485 }
7486}
sfricke-samsung071af2d2020-07-02 10:37:22 -07007487
sfricke-samsung39ee2442020-07-22 21:21:15 -07007488TEST_F(VkLayerTest, InvalidUnprotectedCommands) {
7489 TEST_DESCRIPTION("Test making commands in unprotected command buffers that can't be used");
sfricke-samsung071af2d2020-07-02 10:37:22 -07007490
7491 // protect memory added in VK 1.1
7492 SetTargetApiVersion(VK_API_VERSION_1_1);
7493
7494 if (InstanceExtensionSupported(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME)) {
7495 m_instance_extension_names.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
7496 } else {
7497 printf("%s Did not find required instance extension %s; skipped.\n", kSkipPrefix,
7498 VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
7499 return;
7500 }
7501 ASSERT_NO_FATAL_FAILURE(InitFramework(m_errorMonitor));
7502
7503 PFN_vkGetPhysicalDeviceFeatures2KHR vkGetPhysicalDeviceFeatures2KHR =
7504 (PFN_vkGetPhysicalDeviceFeatures2KHR)vk::GetInstanceProcAddr(instance(), "vkGetPhysicalDeviceFeatures2KHR");
7505 ASSERT_TRUE(vkGetPhysicalDeviceFeatures2KHR != nullptr);
7506
Mark Lobodzinski07d0a612020-12-30 15:42:31 -07007507 auto protected_memory_features = LvlInitStruct<VkPhysicalDeviceProtectedMemoryFeatures>();
7508 auto features2 = LvlInitStruct<VkPhysicalDeviceFeatures2KHR>(&protected_memory_features);
sfricke-samsung071af2d2020-07-02 10:37:22 -07007509 vkGetPhysicalDeviceFeatures2KHR(gpu(), &features2);
7510
7511 if (protected_memory_features.protectedMemory == VK_FALSE) {
7512 printf("%s protectedMemory feature not supported, skipped.\n", kSkipPrefix);
7513 return;
7514 };
7515
7516 // Turns m_commandBuffer into a protected command buffer
7517 ASSERT_NO_FATAL_FAILURE(InitState(nullptr, &features2, VK_COMMAND_POOL_CREATE_PROTECTED_BIT));
7518
7519 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
7520 if (DeviceValidationVersion() < VK_API_VERSION_1_1) {
7521 printf("%s Tests requires Vulkan 1.1+, skipping test\n", kSkipPrefix);
7522 return;
7523 }
7524
7525 VkBufferObj indirect_buffer;
7526 indirect_buffer.init(*m_device, sizeof(VkDrawIndirectCommand), VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT,
7527 VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT);
7528
7529 VkBufferObj indexed_indirect_buffer;
7530 indexed_indirect_buffer.init(*m_device, sizeof(VkDrawIndexedIndirectCommand), VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT,
7531 VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT);
7532
7533 VkBufferObj index_buffer;
7534 index_buffer.init(*m_device, sizeof(uint32_t), VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, VK_BUFFER_USAGE_INDEX_BUFFER_BIT);
7535
7536 CreatePipelineHelper pipe(*this);
7537 pipe.InitInfo();
7538 pipe.InitState();
7539 pipe.CreateGraphicsPipeline();
7540
sfricke-samsung39ee2442020-07-22 21:21:15 -07007541 VkQueryPool query_pool;
7542 VkQueryPoolCreateInfo query_pool_create_info{};
7543 query_pool_create_info.sType = VK_STRUCTURE_TYPE_QUERY_POOL_CREATE_INFO;
7544 query_pool_create_info.queryType = VK_QUERY_TYPE_OCCLUSION;
7545 query_pool_create_info.queryCount = 1;
7546 vk::CreateQueryPool(m_device->device(), &query_pool_create_info, nullptr, &query_pool);
7547
sfricke-samsung071af2d2020-07-02 10:37:22 -07007548 m_commandBuffer->begin();
7549 m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
7550
7551 vk::CmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.pipeline_);
7552
7553 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdDrawIndirect-commandBuffer-02711");
7554 vk::CmdDrawIndirect(m_commandBuffer->handle(), indirect_buffer.handle(), 0, 1, sizeof(VkDrawIndirectCommand));
7555 m_errorMonitor->VerifyFound();
7556
7557 vk::CmdBindIndexBuffer(m_commandBuffer->handle(), index_buffer.handle(), 0, VK_INDEX_TYPE_UINT32);
7558
7559 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdDrawIndexedIndirect-commandBuffer-02711");
7560 vk::CmdDrawIndexedIndirect(m_commandBuffer->handle(), indexed_indirect_buffer.handle(), 0, 1,
7561 sizeof(VkDrawIndexedIndirectCommand));
7562 m_errorMonitor->VerifyFound();
7563
7564 m_commandBuffer->EndRenderPass();
sfricke-samsung39ee2442020-07-22 21:21:15 -07007565
7566 // Query should be outside renderpass
7567 vk::CmdResetQueryPool(m_commandBuffer->handle(), query_pool, 0, 1);
7568
7569 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdBeginQuery-commandBuffer-01885");
7570 vk::CmdBeginQuery(m_commandBuffer->handle(), query_pool, 0, 0);
7571 m_errorMonitor->VerifyFound();
7572
7573 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdEndQuery-commandBuffer-01886");
7574 m_errorMonitor->SetUnexpectedError("VUID-vkCmdEndQuery-None-01923");
7575 vk::CmdEndQuery(m_commandBuffer->handle(), query_pool, 0);
7576 m_errorMonitor->VerifyFound();
7577
sfricke-samsung071af2d2020-07-02 10:37:22 -07007578 m_commandBuffer->end();
sfricke-samsung39ee2442020-07-22 21:21:15 -07007579
7580 vk::DestroyQueryPool(m_device->device(), query_pool, nullptr);
sfricke-samsung071af2d2020-07-02 10:37:22 -07007581}
sfricke-samsung2aaf66f2020-07-24 03:26:22 -07007582
7583TEST_F(VkLayerTest, InvalidMixingProtectedResources) {
7584 TEST_DESCRIPTION("Test where there is mixing of protectedMemory backed resource in command buffers");
7585
7586 SetTargetApiVersion(VK_API_VERSION_1_1);
7587
7588 if (InstanceExtensionSupported(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME)) {
7589 m_instance_extension_names.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
7590 } else {
7591 printf("%s Did not find required instance extension %s; skipped.\n", kSkipPrefix,
7592 VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
7593 return;
7594 }
7595 ASSERT_NO_FATAL_FAILURE(InitFramework(m_errorMonitor));
7596
Mark Lobodzinskic2312742020-08-05 13:57:11 -06007597 if (IsPlatform(kShieldTV) || IsPlatform(kShieldTVb)) {
7598 printf("%s CreateImageView calls crash ShieldTV, skipped for this platform.\n", kSkipPrefix);
7599 return;
7600 }
7601
sfricke-samsung2aaf66f2020-07-24 03:26:22 -07007602 PFN_vkGetPhysicalDeviceFeatures2KHR vkGetPhysicalDeviceFeatures2KHR =
7603 (PFN_vkGetPhysicalDeviceFeatures2KHR)vk::GetInstanceProcAddr(instance(), "vkGetPhysicalDeviceFeatures2KHR");
7604 ASSERT_TRUE(vkGetPhysicalDeviceFeatures2KHR != nullptr);
7605
Mark Lobodzinski07d0a612020-12-30 15:42:31 -07007606 auto protected_memory_features = LvlInitStruct<VkPhysicalDeviceProtectedMemoryFeatures>();
7607 auto features2 = LvlInitStruct<VkPhysicalDeviceFeatures2KHR>(&protected_memory_features);
sfricke-samsung2aaf66f2020-07-24 03:26:22 -07007608 vkGetPhysicalDeviceFeatures2KHR(gpu(), &features2);
7609
7610 if (protected_memory_features.protectedMemory == VK_FALSE) {
7611 printf("%s protectedMemory feature not supported, skipped.\n", kSkipPrefix);
7612 return;
7613 };
7614
7615 // Turns m_commandBuffer into a unprotected command buffer
7616 ASSERT_NO_FATAL_FAILURE(InitState(nullptr, &features2));
7617
7618 VkCommandPoolObj protectedCommandPool(m_device, m_device->graphics_queue_node_index_, VK_COMMAND_POOL_CREATE_PROTECTED_BIT);
7619 VkCommandBufferObj protectedCommandBuffer(m_device, &protectedCommandPool);
7620
7621 if (DeviceValidationVersion() < VK_API_VERSION_1_1) {
7622 printf("%s Tests requires Vulkan 1.1+, skipping test\n", kSkipPrefix);
7623 return;
7624 }
7625
7626 // Create actual protected and unprotected buffers
7627 VkBuffer buffer_protected = VK_NULL_HANDLE;
7628 VkBuffer buffer_unprotected = VK_NULL_HANDLE;
7629 VkBufferCreateInfo buffer_create_info = {};
7630 buffer_create_info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
7631 buffer_create_info.pNext = nullptr;
7632 buffer_create_info.size = 1 << 20; // 1 MB
locke-lunarg0de02522020-10-27 22:55:17 -06007633 buffer_create_info.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT |
7634 VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT | VK_BUFFER_USAGE_INDEX_BUFFER_BIT |
7635 VK_BUFFER_USAGE_VERTEX_BUFFER_BIT;
sfricke-samsung2aaf66f2020-07-24 03:26:22 -07007636 buffer_create_info.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
7637
7638 buffer_create_info.flags = VK_BUFFER_CREATE_PROTECTED_BIT;
7639 vk::CreateBuffer(device(), &buffer_create_info, nullptr, &buffer_protected);
7640 buffer_create_info.flags = 0;
7641 vk::CreateBuffer(device(), &buffer_create_info, nullptr, &buffer_unprotected);
7642
7643 // Create actual protected and unprotected images
7644 VkImageObj image_protected(m_device);
7645 VkImageObj image_unprotected(m_device);
locke-lunarg0de02522020-10-27 22:55:17 -06007646 VkImageObj image_protected_descriptor(m_device);
7647 VkImageObj image_unprotected_descriptor(m_device);
sfricke-samsungc1c43b02020-08-04 00:21:48 -07007648 VkImageView image_views[2];
locke-lunarg0de02522020-10-27 22:55:17 -06007649 VkImageView image_views_descriptor[2];
sfricke-samsung2aaf66f2020-07-24 03:26:22 -07007650 VkImageCreateInfo image_create_info = {};
7651 image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
7652 image_create_info.pNext = nullptr;
7653 image_create_info.extent = {64, 64, 1};
7654 image_create_info.format = VK_FORMAT_R8G8B8A8_UNORM;
7655 image_create_info.imageType = VK_IMAGE_TYPE_2D;
7656 image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL;
locke-lunarg0de02522020-10-27 22:55:17 -06007657 image_create_info.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT |
7658 VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_STORAGE_BIT;
sfricke-samsung2aaf66f2020-07-24 03:26:22 -07007659 image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
7660 image_create_info.arrayLayers = 1;
7661 image_create_info.mipLevels = 1;
7662
7663 image_create_info.flags = VK_IMAGE_CREATE_PROTECTED_BIT;
7664 image_protected.init_no_mem(*m_device, image_create_info);
7665 image_protected.SetLayout(VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_GENERAL);
sfricke-samsungc1c43b02020-08-04 00:21:48 -07007666 image_views[0] = image_protected.targetView(VK_FORMAT_R8G8B8A8_UNORM);
sfricke-samsung2aaf66f2020-07-24 03:26:22 -07007667
locke-lunarg0de02522020-10-27 22:55:17 -06007668 image_protected_descriptor.init_no_mem(*m_device, image_create_info);
7669 image_protected_descriptor.SetLayout(VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_GENERAL);
7670 image_views_descriptor[0] = image_protected_descriptor.targetView(VK_FORMAT_R8G8B8A8_UNORM);
7671
sfricke-samsung2aaf66f2020-07-24 03:26:22 -07007672 image_create_info.flags = 0;
7673 image_unprotected.init_no_mem(*m_device, image_create_info);
7674 image_unprotected.SetLayout(VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_GENERAL);
sfricke-samsungc1c43b02020-08-04 00:21:48 -07007675 image_views[1] = image_unprotected.targetView(VK_FORMAT_R8G8B8A8_UNORM);
sfricke-samsung2aaf66f2020-07-24 03:26:22 -07007676
locke-lunarg0de02522020-10-27 22:55:17 -06007677 image_unprotected_descriptor.init_no_mem(*m_device, image_create_info);
7678 image_unprotected_descriptor.SetLayout(VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_GENERAL);
7679 image_views_descriptor[1] = image_unprotected_descriptor.targetView(VK_FORMAT_R8G8B8A8_UNORM);
7680
sfricke-samsung2aaf66f2020-07-24 03:26:22 -07007681 // Create protected and unproteced memory
7682 VkDeviceMemory memory_protected = VK_NULL_HANDLE;
7683 VkDeviceMemory memory_unprotected = VK_NULL_HANDLE;
7684
7685 VkMemoryAllocateInfo alloc_info = {};
7686 alloc_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
7687 alloc_info.pNext = nullptr;
7688 alloc_info.allocationSize = 0;
7689
7690 // set allocationSize to buffer as it will be larger than the image, but query image to avoid BP warning
7691 VkMemoryRequirements mem_reqs_protected;
7692 vk::GetImageMemoryRequirements(device(), image_protected.handle(), &mem_reqs_protected);
7693 vk::GetBufferMemoryRequirements(device(), buffer_protected, &mem_reqs_protected);
7694 VkMemoryRequirements mem_reqs_unprotected;
7695 vk::GetImageMemoryRequirements(device(), image_unprotected.handle(), &mem_reqs_unprotected);
7696 vk::GetBufferMemoryRequirements(device(), buffer_unprotected, &mem_reqs_unprotected);
7697
7698 // Get memory index for a protected and unprotected memory
7699 VkPhysicalDeviceMemoryProperties phys_mem_props;
7700 vk::GetPhysicalDeviceMemoryProperties(gpu(), &phys_mem_props);
7701 uint32_t memory_type_protected = phys_mem_props.memoryTypeCount + 1;
7702 uint32_t memory_type_unprotected = phys_mem_props.memoryTypeCount + 1;
7703 for (uint32_t i = 0; i < phys_mem_props.memoryTypeCount; i++) {
7704 if ((mem_reqs_unprotected.memoryTypeBits & (1 << i)) &&
7705 ((phys_mem_props.memoryTypes[i].propertyFlags & VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT) ==
7706 VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT)) {
7707 memory_type_unprotected = i;
7708 }
7709 // Check just protected bit is in type at all
7710 if ((mem_reqs_protected.memoryTypeBits & (1 << i)) &&
7711 ((phys_mem_props.memoryTypes[i].propertyFlags & VK_MEMORY_PROPERTY_PROTECTED_BIT) != 0)) {
7712 memory_type_protected = i;
7713 }
7714 }
7715 if ((memory_type_protected >= phys_mem_props.memoryTypeCount) || (memory_type_unprotected >= phys_mem_props.memoryTypeCount)) {
7716 printf("%s No valid memory type index could be found; skipped.\n", kSkipPrefix);
7717 vk::DestroyBuffer(device(), buffer_protected, nullptr);
7718 vk::DestroyBuffer(device(), buffer_unprotected, nullptr);
7719 return;
7720 }
7721
7722 alloc_info.memoryTypeIndex = memory_type_protected;
7723 alloc_info.allocationSize = mem_reqs_protected.size;
7724 vk::AllocateMemory(device(), &alloc_info, NULL, &memory_protected);
7725
7726 alloc_info.allocationSize = mem_reqs_unprotected.size;
7727 alloc_info.memoryTypeIndex = memory_type_unprotected;
7728 vk::AllocateMemory(device(), &alloc_info, NULL, &memory_unprotected);
7729
7730 vk::BindBufferMemory(device(), buffer_protected, memory_protected, 0);
7731 vk::BindBufferMemory(device(), buffer_unprotected, memory_unprotected, 0);
7732 vk::BindImageMemory(device(), image_protected.handle(), memory_protected, 0);
7733 vk::BindImageMemory(device(), image_unprotected.handle(), memory_unprotected, 0);
7734
sfricke-samsungc1c43b02020-08-04 00:21:48 -07007735 // A renderpass and framebuffer that contains a protected and unprotected image view
7736 VkAttachmentDescription attachments[2] = {
7737 {0, VK_FORMAT_R8G8B8A8_UNORM, VK_SAMPLE_COUNT_1_BIT, VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE,
7738 VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE, VK_IMAGE_LAYOUT_UNDEFINED,
7739 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL},
7740 {0, VK_FORMAT_R8G8B8A8_UNORM, VK_SAMPLE_COUNT_1_BIT, VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE,
7741 VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE, VK_IMAGE_LAYOUT_UNDEFINED,
7742 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL},
7743 };
7744 VkAttachmentReference references[2] = {{0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL},
7745 {1, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL}};
7746 VkSubpassDescription subpass = {0, VK_PIPELINE_BIND_POINT_GRAPHICS, 0, nullptr, 2, references, nullptr, nullptr, 0, nullptr};
7747 VkSubpassDependency dependency = {0,
7748 0,
7749 VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
7750 VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
7751 VK_ACCESS_SHADER_WRITE_BIT,
7752 VK_ACCESS_SHADER_WRITE_BIT,
7753 VK_DEPENDENCY_BY_REGION_BIT};
7754 VkRenderPassCreateInfo render_pass_create_info = {
7755 VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, nullptr, 0, 2, attachments, 1, &subpass, 1, &dependency};
7756 VkRenderPass render_pass;
7757 ASSERT_VK_SUCCESS(vk::CreateRenderPass(device(), &render_pass_create_info, nullptr, &render_pass));
7758 VkFramebufferCreateInfo framebuffer_create_info = {
7759 VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, nullptr, 0, render_pass, 2, image_views, 8, 8, 1};
7760 VkFramebuffer framebuffer;
7761 ASSERT_VK_SUCCESS(vk::CreateFramebuffer(device(), &framebuffer_create_info, nullptr, &framebuffer));
7762
sfricke-samsung2aaf66f2020-07-24 03:26:22 -07007763 // Various structs used for commands
7764 VkImageSubresourceLayers image_subresource = {VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 1};
7765 VkImageBlit blit_region = {};
7766 blit_region.srcSubresource = image_subresource;
7767 blit_region.dstSubresource = image_subresource;
7768 blit_region.srcOffsets[0] = {0, 0, 0};
7769 blit_region.srcOffsets[1] = {8, 8, 1};
7770 blit_region.dstOffsets[0] = {0, 8, 0};
7771 blit_region.dstOffsets[1] = {8, 8, 1};
7772 VkClearColorValue clear_color = {{0, 0, 0, 0}};
7773 VkImageSubresourceRange subresource_range = {VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1};
7774 VkBufferCopy buffer_copy = {0, 0, 64};
7775 VkBufferImageCopy buffer_image_copy = {};
7776 buffer_image_copy.bufferRowLength = 0;
7777 buffer_image_copy.bufferImageHeight = 0;
7778 buffer_image_copy.imageSubresource = image_subresource;
7779 buffer_image_copy.imageOffset = {0, 0, 0};
7780 buffer_image_copy.imageExtent = {1, 1, 1};
7781 buffer_image_copy.bufferOffset = 0;
7782 VkImageCopy image_copy = {};
7783 image_copy.srcSubresource = image_subresource;
7784 image_copy.srcOffset = {0, 0, 0};
7785 image_copy.dstSubresource = image_subresource;
7786 image_copy.dstOffset = {0, 0, 0};
7787 image_copy.extent = {1, 1, 1};
7788 uint32_t update_data[4] = {0, 0, 0, 0};
sfricke-samsungc1c43b02020-08-04 00:21:48 -07007789 VkRect2D render_area = {{0, 0}, {8, 8}};
7790 VkRenderPassBeginInfo render_pass_begin = {
7791 VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, nullptr, render_pass, framebuffer, render_area, 0, nullptr};
7792 VkClearAttachment clear_attachments[2] = {{VK_IMAGE_ASPECT_COLOR_BIT, 0, {m_clear_color}},
7793 {VK_IMAGE_ASPECT_COLOR_BIT, 1, {m_clear_color}}};
7794 VkClearRect clear_rect[2] = {{render_area, 0, 1}, {render_area, 0, 1}};
sfricke-samsung2aaf66f2020-07-24 03:26:22 -07007795
locke-lunarg0de02522020-10-27 22:55:17 -06007796 const char fsSource[] =
7797 "#version 450\n"
7798 "layout(set=0, binding=0) uniform foo { int x; int y; } bar;\n"
7799 "layout(set=0, binding=1, rgba8) uniform image2D si1;\n"
7800 "layout(location=0) out vec4 x;\n"
7801 "void main(){\n"
7802 " x = vec4(bar.y);\n"
7803 " imageStore(si1, ivec2(0), vec4(0));\n"
7804 "}\n";
7805 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
7806
7807 CreatePipelineHelper g_pipe(*this);
7808 g_pipe.InitInfo();
7809 g_pipe.gp_ci_.renderPass = render_pass;
7810 g_pipe.shader_stages_ = {g_pipe.vs_->GetStageCreateInfo(), fs.GetStageCreateInfo()};
7811 g_pipe.dsl_bindings_ = {{0, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1, VK_SHADER_STAGE_FRAGMENT_BIT, nullptr},
7812 {1, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, 1, VK_SHADER_STAGE_FRAGMENT_BIT, nullptr}};
7813 std::array<VkPipelineColorBlendAttachmentState, 2> color_blend_attachments;
7814 color_blend_attachments[0] = g_pipe.cb_attachments_;
7815 color_blend_attachments[1] = g_pipe.cb_attachments_;
7816 g_pipe.cb_ci_.attachmentCount = color_blend_attachments.size();
7817 g_pipe.cb_ci_.pAttachments = color_blend_attachments.data();
7818 g_pipe.InitState();
7819 ASSERT_VK_SUCCESS(g_pipe.CreateGraphicsPipeline());
7820
7821 VkSampler sampler;
7822 VkSamplerCreateInfo sampler_ci = SafeSaneSamplerCreateInfo();
7823 VkResult err = vk::CreateSampler(m_device->device(), &sampler_ci, nullptr, &sampler);
7824 ASSERT_VK_SUCCESS(err);
7825
sfricke-samsung2aaf66f2020-07-24 03:26:22 -07007826 // Use protected resources in unprotected command buffer
sfricke-samsung36428462021-02-10 01:23:34 -08007827 g_pipe.descriptor_set_->WriteDescriptorBufferInfo(0, buffer_protected, 0, 1024);
locke-lunarg0de02522020-10-27 22:55:17 -06007828 g_pipe.descriptor_set_->WriteDescriptorImageInfo(1, image_views_descriptor[0], sampler, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE,
7829 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
7830 g_pipe.descriptor_set_->UpdateDescriptorSets();
7831
sfricke-samsung2aaf66f2020-07-24 03:26:22 -07007832 m_commandBuffer->begin();
7833
7834 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdBlitImage-commandBuffer-01834");
7835 vk::CmdBlitImage(m_commandBuffer->handle(), image_protected.handle(), VK_IMAGE_LAYOUT_GENERAL, image_unprotected.handle(),
7836 VK_IMAGE_LAYOUT_GENERAL, 1, &blit_region, VK_FILTER_NEAREST);
7837 m_errorMonitor->VerifyFound();
7838
7839 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdBlitImage-commandBuffer-01835");
7840 vk::CmdBlitImage(m_commandBuffer->handle(), image_unprotected.handle(), VK_IMAGE_LAYOUT_GENERAL, image_protected.handle(),
7841 VK_IMAGE_LAYOUT_GENERAL, 1, &blit_region, VK_FILTER_NEAREST);
7842 m_errorMonitor->VerifyFound();
7843
7844 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdClearColorImage-commandBuffer-01805");
7845 vk::CmdClearColorImage(m_commandBuffer->handle(), image_protected.handle(), VK_IMAGE_LAYOUT_GENERAL, &clear_color, 1,
7846 &subresource_range);
7847 m_errorMonitor->VerifyFound();
7848
7849 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdCopyBuffer-commandBuffer-01822");
7850 vk::CmdCopyBuffer(m_commandBuffer->handle(), buffer_protected, buffer_unprotected, 1, &buffer_copy);
7851 m_errorMonitor->VerifyFound();
7852
7853 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdCopyBuffer-commandBuffer-01823");
7854 vk::CmdCopyBuffer(m_commandBuffer->handle(), buffer_unprotected, buffer_protected, 1, &buffer_copy);
7855 m_errorMonitor->VerifyFound();
7856
7857 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdCopyBufferToImage-commandBuffer-01828");
7858 vk::CmdCopyBufferToImage(m_commandBuffer->handle(), buffer_protected, image_unprotected.handle(), VK_IMAGE_LAYOUT_GENERAL, 1,
7859 &buffer_image_copy);
7860 m_errorMonitor->VerifyFound();
7861
7862 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdCopyBufferToImage-commandBuffer-01829");
7863 vk::CmdCopyBufferToImage(m_commandBuffer->handle(), buffer_unprotected, image_protected.handle(), VK_IMAGE_LAYOUT_GENERAL, 1,
7864 &buffer_image_copy);
7865 m_errorMonitor->VerifyFound();
7866
7867 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdCopyImage-commandBuffer-01825");
7868 vk::CmdCopyImage(m_commandBuffer->handle(), image_protected.handle(), VK_IMAGE_LAYOUT_GENERAL, image_unprotected.handle(),
7869 VK_IMAGE_LAYOUT_GENERAL, 1, &image_copy);
7870 m_errorMonitor->VerifyFound();
7871
7872 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdCopyImage-commandBuffer-01826");
7873 vk::CmdCopyImage(m_commandBuffer->handle(), image_unprotected.handle(), VK_IMAGE_LAYOUT_GENERAL, image_protected.handle(),
7874 VK_IMAGE_LAYOUT_GENERAL, 1, &image_copy);
7875 m_errorMonitor->VerifyFound();
7876
7877 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdCopyImageToBuffer-commandBuffer-01831");
7878 vk::CmdCopyImageToBuffer(m_commandBuffer->handle(), image_protected.handle(), VK_IMAGE_LAYOUT_GENERAL, buffer_unprotected, 1,
7879 &buffer_image_copy);
7880 m_errorMonitor->VerifyFound();
7881
7882 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdCopyImageToBuffer-commandBuffer-01832");
7883 vk::CmdCopyImageToBuffer(m_commandBuffer->handle(), image_unprotected.handle(), VK_IMAGE_LAYOUT_GENERAL, buffer_protected, 1,
7884 &buffer_image_copy);
7885 m_errorMonitor->VerifyFound();
7886
7887 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdFillBuffer-commandBuffer-01811");
7888 vk::CmdFillBuffer(m_commandBuffer->handle(), buffer_protected, 0, 4, 0);
7889 m_errorMonitor->VerifyFound();
7890
7891 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdUpdateBuffer-commandBuffer-01813");
7892 vk::CmdUpdateBuffer(m_commandBuffer->handle(), buffer_protected, 0, 4, (void *)update_data);
7893 m_errorMonitor->VerifyFound();
7894
sfricke-samsungc1c43b02020-08-04 00:21:48 -07007895 vk::CmdBeginRenderPass(m_commandBuffer->handle(), &render_pass_begin, VK_SUBPASS_CONTENTS_INLINE);
7896
7897 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdClearAttachments-commandBuffer-02504");
7898 vk::CmdClearAttachments(m_commandBuffer->handle(), 2, clear_attachments, 2, clear_rect);
7899 m_errorMonitor->VerifyFound();
7900
locke-lunarg0de02522020-10-27 22:55:17 -06007901 vk::CmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipe.pipeline_);
7902 vk::CmdBindDescriptorSets(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipe.pipeline_layout_.handle(), 0, 1,
7903 &g_pipe.descriptor_set_->set_, 0, nullptr);
7904 VkDeviceSize offset = 0;
7905 vk::CmdBindVertexBuffers(m_commandBuffer->handle(), 0, 1, &buffer_protected, &offset);
7906 vk::CmdBindIndexBuffer(m_commandBuffer->handle(), buffer_protected, 0, VK_INDEX_TYPE_UINT16);
7907
7908 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdDrawIndexed-commandBuffer-02707"); // color attachment
7909 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdDrawIndexed-commandBuffer-02707"); // buffer descriptorSet
7910 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdDrawIndexed-commandBuffer-02707"); // image descriptorSet
7911 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdDrawIndexed-commandBuffer-02707"); // vertex
7912 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdDrawIndexed-commandBuffer-02707"); // index
7913
7914 vk::CmdDrawIndexed(m_commandBuffer->handle(), 1, 0, 0, 0, 0);
7915 m_errorMonitor->VerifyFound();
7916
sfricke-samsungc1c43b02020-08-04 00:21:48 -07007917 vk::CmdEndRenderPass(m_commandBuffer->handle());
sfricke-samsung2aaf66f2020-07-24 03:26:22 -07007918 m_commandBuffer->end();
7919
7920 // Use unprotected resources in protected command buffer
sfricke-samsung36428462021-02-10 01:23:34 -08007921 g_pipe.descriptor_set_->WriteDescriptorBufferInfo(0, buffer_unprotected, 0, 1024);
locke-lunarg5ec8ddf2020-11-25 01:05:55 -07007922 g_pipe.descriptor_set_->WriteDescriptorImageInfo(1, image_views_descriptor[1], sampler, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE,
7923 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
locke-lunarg0de02522020-10-27 22:55:17 -06007924 g_pipe.descriptor_set_->UpdateDescriptorSets();
7925
sfricke-samsung2aaf66f2020-07-24 03:26:22 -07007926 protectedCommandBuffer.begin();
7927
7928 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdBlitImage-commandBuffer-01836");
7929 vk::CmdBlitImage(protectedCommandBuffer.handle(), image_protected.handle(), VK_IMAGE_LAYOUT_GENERAL, image_unprotected.handle(),
7930 VK_IMAGE_LAYOUT_GENERAL, 1, &blit_region, VK_FILTER_NEAREST);
7931 m_errorMonitor->VerifyFound();
7932
7933 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdClearColorImage-commandBuffer-01806");
7934 vk::CmdClearColorImage(protectedCommandBuffer.handle(), image_unprotected.handle(), VK_IMAGE_LAYOUT_GENERAL, &clear_color, 1,
7935 &subresource_range);
7936 m_errorMonitor->VerifyFound();
7937
7938 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdCopyBuffer-commandBuffer-01824");
7939 vk::CmdCopyBuffer(protectedCommandBuffer.handle(), buffer_protected, buffer_unprotected, 1, &buffer_copy);
7940 m_errorMonitor->VerifyFound();
7941
7942 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdCopyBufferToImage-commandBuffer-01830");
7943 vk::CmdCopyBufferToImage(protectedCommandBuffer.handle(), buffer_protected, image_unprotected.handle(), VK_IMAGE_LAYOUT_GENERAL,
7944 1, &buffer_image_copy);
7945 m_errorMonitor->VerifyFound();
7946
7947 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdCopyImage-commandBuffer-01827");
7948 vk::CmdCopyImage(protectedCommandBuffer.handle(), image_protected.handle(), VK_IMAGE_LAYOUT_GENERAL, image_unprotected.handle(),
7949 VK_IMAGE_LAYOUT_GENERAL, 1, &image_copy);
7950 m_errorMonitor->VerifyFound();
7951
7952 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdCopyImageToBuffer-commandBuffer-01833");
7953 vk::CmdCopyImageToBuffer(protectedCommandBuffer.handle(), image_protected.handle(), VK_IMAGE_LAYOUT_GENERAL, buffer_unprotected,
7954 1, &buffer_image_copy);
7955 m_errorMonitor->VerifyFound();
7956
7957 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdFillBuffer-commandBuffer-01812");
7958 vk::CmdFillBuffer(protectedCommandBuffer.handle(), buffer_unprotected, 0, 4, 0);
7959 m_errorMonitor->VerifyFound();
7960
7961 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdUpdateBuffer-commandBuffer-01814");
7962 vk::CmdUpdateBuffer(protectedCommandBuffer.handle(), buffer_unprotected, 0, 4, (void *)update_data);
7963 m_errorMonitor->VerifyFound();
7964
sfricke-samsungc1c43b02020-08-04 00:21:48 -07007965 vk::CmdBeginRenderPass(protectedCommandBuffer.handle(), &render_pass_begin, VK_SUBPASS_CONTENTS_INLINE);
7966
7967 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdClearAttachments-commandBuffer-02505");
7968 vk::CmdClearAttachments(protectedCommandBuffer.handle(), 2, clear_attachments, 2, clear_rect);
7969 m_errorMonitor->VerifyFound();
7970
locke-lunarg0de02522020-10-27 22:55:17 -06007971 vk::CmdBindPipeline(protectedCommandBuffer.handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipe.pipeline_);
7972 vk::CmdBindDescriptorSets(protectedCommandBuffer.handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipe.pipeline_layout_.handle(), 0,
7973 1, &g_pipe.descriptor_set_->set_, 0, nullptr);
7974 vk::CmdBindVertexBuffers(protectedCommandBuffer.handle(), 0, 1, &buffer_unprotected, &offset);
7975 vk::CmdBindIndexBuffer(protectedCommandBuffer.handle(), buffer_unprotected, 0, VK_INDEX_TYPE_UINT16);
7976
7977 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdDrawIndexed-commandBuffer-02712"); // color attachment
7978 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdDrawIndexed-commandBuffer-02712"); // descriptorSet
7979 vk::CmdDrawIndexed(protectedCommandBuffer.handle(), 1, 0, 0, 0, 0);
7980 m_errorMonitor->VerifyFound();
7981
sfricke-samsungc1c43b02020-08-04 00:21:48 -07007982 vk::CmdEndRenderPass(protectedCommandBuffer.handle());
sfricke-samsung2aaf66f2020-07-24 03:26:22 -07007983 protectedCommandBuffer.end();
7984
sfricke-samsung96cd9932020-08-23 20:57:11 -07007985 // Try submitting together to test only 1 error occurs for the corresponding command buffer
7986 VkCommandBuffer comman_buffers[2] = {m_commandBuffer->handle(), protectedCommandBuffer.handle()};
7987
7988 VkProtectedSubmitInfo protected_submit_info = {};
7989 protected_submit_info.sType = VK_STRUCTURE_TYPE_PROTECTED_SUBMIT_INFO;
7990 protected_submit_info.pNext = nullptr;
7991
7992 VkSubmitInfo submit_info = {};
7993 submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
7994 submit_info.pNext = &protected_submit_info;
7995 submit_info.commandBufferCount = 2;
7996 submit_info.pCommandBuffers = comman_buffers;
7997
7998 protected_submit_info.protectedSubmit = VK_TRUE;
Shannon McPherson2c793ba2020-08-28 12:13:24 -06007999 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkSubmitInfo-pNext-04148");
sfricke-samsung96cd9932020-08-23 20:57:11 -07008000 vk::QueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
8001 m_errorMonitor->VerifyFound();
8002
8003 protected_submit_info.protectedSubmit = VK_FALSE;
8004 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkSubmitInfo-pNext-04120");
8005 vk::QueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
8006 m_errorMonitor->VerifyFound();
8007
sfricke-samsung2aaf66f2020-07-24 03:26:22 -07008008 vk::DestroyBuffer(device(), buffer_protected, nullptr);
8009 vk::DestroyBuffer(device(), buffer_unprotected, nullptr);
8010 vk::FreeMemory(device(), memory_protected, nullptr);
8011 vk::FreeMemory(device(), memory_unprotected, nullptr);
sfricke-samsungc1c43b02020-08-04 00:21:48 -07008012 vk::DestroyFramebuffer(device(), framebuffer, nullptr);
8013 vk::DestroyRenderPass(device(), render_pass, nullptr);
Mark Lobodzinskic2312742020-08-05 13:57:11 -06008014}
locke-lunarg6b0de702020-08-07 17:42:13 -06008015
Tony-LunarG1ed322e2021-06-04 12:59:27 -06008016TEST_F(VkLayerTest, InvalidStorageAtomicOperation) {
locke-lunarg6b0de702020-08-07 17:42:13 -06008017 TEST_DESCRIPTION(
8018 "If storage view use atomic operation, the view's format MUST support VK_FORMAT_FEATURE_STORAGE_IMAGE_ATOMIC_BIT or "
8019 "VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_ATOMIC_BIT ");
8020
8021 ASSERT_NO_FATAL_FAILURE(Init());
8022
Tony-LunarG1ed322e2021-06-04 12:59:27 -06008023 m_errorMonitor->ExpectSuccess();
locke-lunarg6b0de702020-08-07 17:42:13 -06008024 VkImageUsageFlags usage = VK_IMAGE_USAGE_STORAGE_BIT;
8025 VkFormat image_format = VK_FORMAT_R8G8B8A8_UNORM; // The format doesn't support VK_FORMAT_FEATURE_STORAGE_IMAGE_ATOMIC_BIT to
8026 // cause DesiredFailure. VK_FORMAT_R32_UINT is right format.
8027 auto image_ci = VkImageObj::ImageCreateInfo2D(64, 64, 1, 1, image_format, usage, VK_IMAGE_TILING_OPTIMAL);
8028
8029 if (ImageFormatAndFeaturesSupported(instance(), gpu(), image_ci, VK_FORMAT_FEATURE_STORAGE_IMAGE_ATOMIC_BIT)) {
8030 printf("%s Cannot make VK_FORMAT_FEATURE_STORAGE_IMAGE_ATOMIC_BIT not supported. Skipping test.\n", kSkipPrefix);
8031 return;
8032 }
8033
8034 VkFormat buffer_view_format =
8035 VK_FORMAT_R8_UNORM; // The format doesn't support VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_ATOMIC_BIT to
8036 // cause DesiredFailure. VK_FORMAT_R32_UINT is right format.
8037 if (BufferFormatAndFeaturesSupported(gpu(), buffer_view_format, VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_ATOMIC_BIT)) {
8038 printf("%s Cannot make VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_ATOMIC_BIT not supported. Skipping test.\n", kSkipPrefix);
8039 return;
8040 }
8041 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
8042
8043 VkPhysicalDeviceFeatures device_features = {};
8044 ASSERT_NO_FATAL_FAILURE(GetPhysicalDeviceFeatures(&device_features));
8045 if (!device_features.vertexPipelineStoresAndAtomics || !device_features.fragmentStoresAndAtomics) {
8046 printf("%s vertexPipelineStoresAndAtomics & fragmentStoresAndAtomics NOT supported. skipped.\n", kSkipPrefix);
8047 return;
8048 }
8049
8050 VkImageObj image(m_device);
8051 image.Init(image_ci);
8052 VkImageView image_view = image.targetView(image_format);
8053
8054 VkSampler sampler = VK_NULL_HANDLE;
8055 VkSamplerCreateInfo sampler_info = SafeSaneSamplerCreateInfo();
8056 vk::CreateSampler(m_device->device(), &sampler_info, NULL, &sampler);
8057
8058 VkBufferObj buffer;
8059 buffer.init(*m_device, 64, 0, VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT);
8060
8061 VkBufferViewCreateInfo bvci = {};
8062 bvci.sType = VK_STRUCTURE_TYPE_BUFFER_VIEW_CREATE_INFO;
8063 bvci.buffer = buffer.handle();
8064 bvci.format = buffer_view_format;
8065 bvci.range = VK_WHOLE_SIZE;
8066 VkBufferView buffer_view;
8067 vk::CreateBufferView(m_device->device(), &bvci, NULL, &buffer_view);
8068
8069 char const *fsSource =
8070 "#version 450\n"
Tony-LunarG1ed322e2021-06-04 12:59:27 -06008071 "layout(set=0, binding=3, r32f) uniform image2D si0;\n "
8072 "layout(set=0, binding=2, r32f) uniform image2D si1[2];\n "
8073 "layout(set = 0, binding = 1, r32f) uniform imageBuffer stb2;\n"
8074 "layout(set = 0, binding = 0, r32f) uniform imageBuffer stb3[2];\n"
locke-lunarg6b0de702020-08-07 17:42:13 -06008075 "void main() {\n"
8076 " imageAtomicExchange(si0, ivec2(0), 1);\n"
8077 " imageAtomicExchange(si1[0], ivec2(0), 1);\n "
locke-lunarg76e8dee2020-08-21 13:20:02 -06008078 " imageAtomicExchange(si1[1], ivec2(0), 1);\n "
locke-lunarg6b0de702020-08-07 17:42:13 -06008079 " imageAtomicExchange(stb2, 0, 1);\n"
8080 " imageAtomicExchange(stb3[0], 0, 1);\n "
locke-lunarg76e8dee2020-08-21 13:20:02 -06008081 " imageAtomicExchange(stb3[1], 0, 1);\n "
locke-lunarg6b0de702020-08-07 17:42:13 -06008082 "}\n";
8083
8084 VkShaderObj vs(m_device, bindStateVertShaderText, VK_SHADER_STAGE_VERTEX_BIT, this);
8085 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
8086
8087 CreatePipelineHelper g_pipe(*this);
8088 g_pipe.InitInfo();
8089 g_pipe.shader_stages_ = {vs.GetStageCreateInfo(), fs.GetStageCreateInfo()};
locke-lunarg76e8dee2020-08-21 13:20:02 -06008090 g_pipe.dsl_bindings_ = {{3, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, 1, VK_SHADER_STAGE_FRAGMENT_BIT, nullptr},
8091 {2, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, 2, VK_SHADER_STAGE_FRAGMENT_BIT, nullptr},
8092 {1, VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER, 1, VK_SHADER_STAGE_FRAGMENT_BIT, nullptr},
8093 {0, VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER, 2, VK_SHADER_STAGE_FRAGMENT_BIT, nullptr}};
locke-lunarg6b0de702020-08-07 17:42:13 -06008094 g_pipe.InitState();
8095 ASSERT_VK_SUCCESS(g_pipe.CreateGraphicsPipeline());
8096
locke-lunarg76e8dee2020-08-21 13:20:02 -06008097 g_pipe.descriptor_set_->WriteDescriptorImageInfo(3, image_view, sampler, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE,
locke-lunarg6b0de702020-08-07 17:42:13 -06008098 VK_IMAGE_LAYOUT_GENERAL);
locke-lunarg76e8dee2020-08-21 13:20:02 -06008099 g_pipe.descriptor_set_->WriteDescriptorImageInfo(2, image_view, sampler, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE,
sfricke-samsung392ba9f2021-03-05 02:23:21 -08008100 VK_IMAGE_LAYOUT_GENERAL, 0, 2);
locke-lunarg76e8dee2020-08-21 13:20:02 -06008101 g_pipe.descriptor_set_->WriteDescriptorBufferView(1, buffer_view);
sfricke-samsung392ba9f2021-03-05 02:23:21 -08008102 g_pipe.descriptor_set_->WriteDescriptorBufferView(0, buffer_view, VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER, 0, 2);
locke-lunarg6b0de702020-08-07 17:42:13 -06008103 g_pipe.descriptor_set_->UpdateDescriptorSets();
8104
8105 m_commandBuffer->begin();
8106 m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
8107 vk::CmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipe.pipeline_);
8108 vk::CmdBindDescriptorSets(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipe.pipeline_layout_.handle(), 0, 1,
8109 &g_pipe.descriptor_set_->set_, 0, nullptr);
8110
Tony-LunarG1ed322e2021-06-04 12:59:27 -06008111 m_errorMonitor->VerifyNotFound();
locke-lunarg6b0de702020-08-07 17:42:13 -06008112 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdDraw-None-02691");
8113 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdDraw-None-02691");
8114 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "UNASSIGNED-None-MismatchAtomicBufferFeature");
8115 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "UNASSIGNED-None-MismatchAtomicBufferFeature");
8116 vk::CmdDraw(m_commandBuffer->handle(), 1, 0, 0, 0);
8117 m_errorMonitor->VerifyFound();
8118
8119 m_commandBuffer->EndRenderPass();
8120 m_commandBuffer->end();
Tony-LunarG1ed322e2021-06-04 12:59:27 -06008121 vk::DestroyBufferView(m_device->handle(), buffer_view, nullptr);
8122 vk::DestroySampler(m_device->handle(), sampler, nullptr);
locke-lunarg6b0de702020-08-07 17:42:13 -06008123}
locke-lunargae1bbab2020-09-10 11:55:56 -06008124
8125TEST_F(VkLayerTest, DrawWithoutUpdatePushConstants) {
8126 TEST_DESCRIPTION("Not every bytes in used push constant ranges has been set before Draw ");
8127
8128 ASSERT_NO_FATAL_FAILURE(Init());
8129 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
8130
8131 // push constant range: 0-99
8132 char const *const vsSource =
8133 "#version 450\n"
8134 "\n"
8135 "layout(push_constant, std430) uniform foo {\n"
8136 " bool b;\n"
8137 " float f2[3];\n"
8138 " vec3 v;\n"
8139 " vec4 v2[2];\n"
8140 " mat3 m;\n"
8141 "} constants;\n"
8142 "void func1( float f ){\n"
8143 // use the whole v2[1]. byte: 48-63.
8144 " vec2 v2 = constants.v2[1].yz;\n"
8145 "}\n"
8146 "void main(){\n"
8147 // use only v2[0].z. byte: 40-43.
8148 " func1( constants.v2[0].z);\n"
8149 // index of m is variable. The all m is used. byte: 64-99.
8150 " for(int i=1;i<2;++i) {\n"
8151 " vec3 v3 = constants.m[i]; \n"
8152 " }\n"
8153 "}\n";
8154
8155 // push constant range: 0 - 95
8156 char const *const fsSource =
8157 "#version 450\n"
8158 "\n"
8159 "struct foo1{\n"
8160 " int i[4];"
8161 "}f;\n"
8162 "layout(push_constant, std430) uniform foo {\n"
8163 " float x[2][2][2];\n"
8164 " foo1 s;\n"
8165 " foo1 ss[3];\n"
8166 "} constants;\n"
8167 "void main(){\n"
8168 // use s. byte: 32-47.
8169 " f = constants.s;\n"
8170 // use every i[3] in ss. byte: 60-63, 76-79, 92-95.
8171 " for(int i=1;i<2;++i) {\n"
8172 " int ii = constants.ss[i].i[3]; \n"
8173 " }\n"
8174 "}\n";
8175
8176 VkShaderObj const vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
8177 VkShaderObj const fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
8178
8179 VkPushConstantRange push_constant_range = {VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT, 0, 128};
8180 VkPushConstantRange push_constant_range_small = {VK_SHADER_STAGE_VERTEX_BIT, 4, 4};
8181
8182 VkPipelineLayoutCreateInfo pipeline_layout_info{
8183 VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, nullptr, 0, 0, nullptr, 1, &push_constant_range};
8184
8185 VkPipelineLayout pipeline_layout;
8186 vk::CreatePipelineLayout(m_device->device(), &pipeline_layout_info, NULL, &pipeline_layout);
8187
8188 CreatePipelineHelper g_pipe(*this);
8189 g_pipe.InitInfo();
8190 g_pipe.shader_stages_ = {vs.GetStageCreateInfo(), fs.GetStageCreateInfo()};
8191 g_pipe.pipeline_layout_ci_ = pipeline_layout_info;
8192 g_pipe.InitState();
8193 ASSERT_VK_SUCCESS(g_pipe.CreateGraphicsPipeline());
8194
8195 pipeline_layout_info.pPushConstantRanges = &push_constant_range_small;
8196 VkPipelineLayout pipeline_layout_small;
8197 vk::CreatePipelineLayout(m_device->device(), &pipeline_layout_info, NULL, &pipeline_layout_small);
8198
8199 CreatePipelineHelper g_pipe_small_range(*this);
8200 g_pipe_small_range.InitInfo();
8201 g_pipe_small_range.shader_stages_ = {vs.GetStageCreateInfo(), fs.GetStageCreateInfo()};
8202 g_pipe_small_range.pipeline_layout_ci_ = pipeline_layout_info;
8203 g_pipe_small_range.InitState();
8204
sfricke-samsung7699b912021-04-12 23:01:51 -07008205 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkGraphicsPipelineCreateInfo-layout-00756");
8206 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkGraphicsPipelineCreateInfo-layout-00756");
locke-lunargae1bbab2020-09-10 11:55:56 -06008207 g_pipe_small_range.CreateGraphicsPipeline();
8208 m_errorMonitor->VerifyFound();
8209
8210 m_commandBuffer->begin();
8211 m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
8212
8213 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdDraw-None-02698");
8214 vk::CmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipe.pipeline_);
8215 vk::CmdBindDescriptorSets(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipe.pipeline_layout_.handle(), 0, 1,
8216 &g_pipe.descriptor_set_->set_, 0, nullptr);
8217 vk::CmdDraw(m_commandBuffer->handle(), 1, 0, 0, 0);
8218 m_errorMonitor->VerifyFound();
8219
locke-lunargae1bbab2020-09-10 11:55:56 -06008220 const float dummy_values[128] = {};
locke-lunargae1bbab2020-09-10 11:55:56 -06008221
Nathaniel Cesarioee42bab2021-04-14 20:02:16 -06008222 // NOTE: these are commented out due to ambiguity around VUID 02698 and push constant lifetimes
8223 // See https://gitlab.khronos.org/vulkan/vulkan/-/issues/2602 and
8224 // https://github.com/KhronosGroup/Vulkan-ValidationLayers/issues/2689
8225 // for more details.
8226 // m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdDraw-None-02698");
8227 // vk::CmdPushConstants(m_commandBuffer->handle(), g_pipe.pipeline_layout_.handle(),
8228 // VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT, 0, 96, dummy_values);
8229 // vk::CmdDraw(m_commandBuffer->handle(), 1, 0, 0, 0);
8230 // m_errorMonitor->VerifyFound();
8231
8232 // m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdDraw-None-02698");
8233 // vk::CmdPushConstants(m_commandBuffer->handle(), pipeline_layout_small, VK_SHADER_STAGE_VERTEX_BIT, 4, 4, dummy_values);
8234 // vk::CmdDraw(m_commandBuffer->handle(), 1, 0, 0, 0);
8235 // m_errorMonitor->VerifyFound();
locke-lunargae1bbab2020-09-10 11:55:56 -06008236
8237 m_errorMonitor->ExpectSuccess();
8238 vk::CmdPushConstants(m_commandBuffer->handle(), pipeline_layout, VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT, 32,
8239 68, dummy_values);
8240 vk::CmdDraw(m_commandBuffer->handle(), 1, 0, 0, 0);
8241 m_errorMonitor->VerifyNotFound();
locke-lunarg41b8c362020-10-16 23:30:12 -06008242}
8243
8244TEST_F(VkLayerTest, VerifyVertextBinding) {
8245 TEST_DESCRIPTION("Verify if VkPipelineVertexInputStateCreateInfo matches vkCmdBindVertexBuffers");
8246
8247 ASSERT_NO_FATAL_FAILURE(Init());
8248 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
8249
8250 VkBufferObj vtx_buf;
8251 auto info = vtx_buf.create_info(32, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT);
8252 vtx_buf.init(*m_device, info);
8253
8254 CreatePipelineHelper pipe(*this);
8255 pipe.InitInfo();
8256 // CmdBindVertexBuffers only has binding:1. It causes 04007 & 04008 desired fail.
8257 VkVertexInputBindingDescription vtx_binding_des[3] = {
8258 {0, 64, VK_VERTEX_INPUT_RATE_VERTEX}, {1, 64, VK_VERTEX_INPUT_RATE_VERTEX}, {2, 64, VK_VERTEX_INPUT_RATE_VERTEX}};
8259
8260 // CmdBindVertexBuffers only has binding:1. It causes twice 02721 desired fail.
8261 // Plus, binding:1's offset is wrong. It causes 02721 desired fail, again.
8262 VkVertexInputAttributeDescription vtx_attri_des[3] = {{0, 0, VK_FORMAT_R32G32B32A32_SFLOAT, 10},
8263 {1, 1, VK_FORMAT_R32G32B32A32_SFLOAT, 10},
8264 {2, 2, VK_FORMAT_R32G32B32A32_SFLOAT, 10}};
8265 pipe.vi_ci_.vertexBindingDescriptionCount = 3;
8266 pipe.vi_ci_.pVertexBindingDescriptions = vtx_binding_des;
8267 pipe.vi_ci_.vertexAttributeDescriptionCount = 3;
8268 pipe.vi_ci_.pVertexAttributeDescriptions = vtx_attri_des;
8269 pipe.InitState();
8270 pipe.CreateGraphicsPipeline();
8271
8272 m_commandBuffer->begin();
8273 m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
8274 vk::CmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.pipeline_);
8275 VkDeviceSize offset = 0;
8276 vk::CmdBindVertexBuffers(m_commandBuffer->handle(), 1, 1, &vtx_buf.handle(), &offset);
8277
8278 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdDraw-None-04008");
8279 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdDraw-None-04007");
8280 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdDraw-None-02721");
8281 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdDraw-None-02721");
8282 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdDraw-None-02721");
8283 vk::CmdDraw(m_commandBuffer->handle(), 1, 0, 0, 0);
8284 m_errorMonitor->VerifyFound();
locke-lunargae1bbab2020-09-10 11:55:56 -06008285
8286 m_commandBuffer->EndRenderPass();
8287 m_commandBuffer->end();
8288}
locke-lunargd7a08e92020-10-21 00:24:00 -06008289
8290TEST_F(VkLayerTest, VerifyDynamicStateSettingCommands) {
8291 TEST_DESCRIPTION("Verify if pipeline doesn't setup dynamic state, but set dynamic commands");
8292 ASSERT_NO_FATAL_FAILURE(Init());
8293 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
8294
8295 CreatePipelineHelper pipe(*this);
8296 pipe.InitInfo();
8297
8298 std::vector<VkDynamicState> dyn_states = {VK_DYNAMIC_STATE_VIEWPORT};
8299
Mark Lobodzinski07d0a612020-12-30 15:42:31 -07008300 auto dyn_state_ci = LvlInitStruct<VkPipelineDynamicStateCreateInfo>();
locke-lunargd7a08e92020-10-21 00:24:00 -06008301 dyn_state_ci.dynamicStateCount = static_cast<uint32_t>(dyn_states.size());
8302 dyn_state_ci.pDynamicStates = dyn_states.data();
8303 pipe.dyn_state_ci_ = dyn_state_ci;
8304 pipe.InitState();
8305 pipe.CreateGraphicsPipeline();
8306
8307 m_commandBuffer->begin();
8308 m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
8309 vk::CmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.pipeline_);
8310
8311 VkViewport viewport = {0, 0, 16, 16, 0, 1};
8312 vk::CmdSetViewport(m_commandBuffer->handle(), 0, 1, &viewport);
8313 VkRect2D scissor = {{0, 0}, {16, 16}};
8314 vk::CmdSetScissor(m_commandBuffer->handle(), 0, 1, &scissor);
8315 vk::CmdSetLineWidth(m_commandBuffer->handle(), 1);
8316
8317 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdDraw-None-02859");
8318 vk::CmdDraw(m_commandBuffer->handle(), 1, 0, 0, 0);
8319 m_errorMonitor->VerifyFound();
8320
8321 m_commandBuffer->EndRenderPass();
8322 m_commandBuffer->end();
8323}
locke-lunarg0de02522020-10-27 22:55:17 -06008324
8325TEST_F(VkLayerTest, VerifyFilterCubicSamplerInCmdDraw) {
8326 TEST_DESCRIPTION("Verify if sampler is filter cubic, image view needs to support it.");
8327 uint32_t version = SetTargetApiVersion(VK_API_VERSION_1_1);
8328 if (version < VK_API_VERSION_1_1) {
8329 printf("%s At least Vulkan version 1.1 is required, skipping test.\n", kSkipPrefix);
8330 return;
8331 }
8332 ASSERT_NO_FATAL_FAILURE(InitFramework(m_errorMonitor));
8333
8334 if (DeviceExtensionSupported(gpu(), nullptr, VK_EXT_FILTER_CUBIC_EXTENSION_NAME)) {
8335 m_device_extension_names.push_back(VK_EXT_FILTER_CUBIC_EXTENSION_NAME);
8336 } else {
8337 printf("%s %s Extension not supported, skipping tests\n", kSkipPrefix, VK_EXT_FILTER_CUBIC_EXTENSION_NAME);
8338 return;
8339 }
8340
8341 ASSERT_NO_FATAL_FAILURE(InitState(nullptr, nullptr, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT));
8342 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
8343
8344 VkImageUsageFlags usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT;
8345 VkFormat format = VK_FORMAT_R8G8B8A8_UNORM;
sfricke-samsung715e3d12020-12-01 22:45:49 -08008346
8347 VkFormatProperties format_props;
8348 vk::GetPhysicalDeviceFormatProperties(m_device->phy().handle(), format, &format_props);
8349 if ((format_props.optimalTilingFeatures & VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_CUBIC_BIT_EXT) == 0) {
8350 printf("%s SAMPLED_IMAGE_FILTER_CUBIC_BIT for format is not supported.\n", kSkipPrefix);
8351 return;
8352 }
8353
locke-lunarg0de02522020-10-27 22:55:17 -06008354 auto image_ci = VkImageObj::ImageCreateInfo2D(128, 128, 1, 1, format, usage, VK_IMAGE_TILING_OPTIMAL);
8355 VkImageViewType imageViewType = VK_IMAGE_VIEW_TYPE_2D;
8356
Mark Lobodzinski07d0a612020-12-30 15:42:31 -07008357 auto imageview_format_info = LvlInitStruct<VkPhysicalDeviceImageViewImageFormatInfoEXT>();
locke-lunarg0de02522020-10-27 22:55:17 -06008358 imageview_format_info.imageViewType = imageViewType;
Mark Lobodzinski07d0a612020-12-30 15:42:31 -07008359 auto image_format_info = LvlInitStruct<VkPhysicalDeviceImageFormatInfo2>(&imageview_format_info);
locke-lunarg0de02522020-10-27 22:55:17 -06008360 image_format_info.type = image_ci.imageType;
8361 image_format_info.format = image_ci.format;
8362 image_format_info.tiling = image_ci.tiling;
8363 image_format_info.usage = image_ci.usage;
8364 image_format_info.flags = image_ci.flags;
8365
Mark Lobodzinski07d0a612020-12-30 15:42:31 -07008366 auto filter_cubic_props = LvlInitStruct<VkFilterCubicImageViewImageFormatPropertiesEXT>();
8367 auto image_format_properties = LvlInitStruct<VkImageFormatProperties2>(&filter_cubic_props);
locke-lunarg0de02522020-10-27 22:55:17 -06008368
8369 vk::GetPhysicalDeviceImageFormatProperties2(gpu(), &image_format_info, &image_format_properties);
8370
8371 if (filter_cubic_props.filterCubic || filter_cubic_props.filterCubicMinmax) {
8372 printf("%s Image and ImageView supports filter cubic ; skipped.\n", kSkipPrefix);
8373 return;
8374 }
8375
8376 VkImageObj image(m_device);
8377 image.Init(image_ci);
8378 VkImageView imageView = image.targetView(format, imageViewType);
8379
Mark Lobodzinski07d0a612020-12-30 15:42:31 -07008380 auto sampler_ci = LvlInitStruct<VkSamplerCreateInfo>();
locke-lunarg0de02522020-10-27 22:55:17 -06008381 sampler_ci.minFilter = VK_FILTER_CUBIC_EXT;
8382 sampler_ci.magFilter = VK_FILTER_CUBIC_EXT;
8383 VkSampler sampler;
8384 vk::CreateSampler(m_device->device(), &sampler_ci, NULL, &sampler);
8385
Mark Lobodzinski07d0a612020-12-30 15:42:31 -07008386 auto reduction_mode_ci = LvlInitStruct<VkSamplerReductionModeCreateInfo>();
locke-lunarg0de02522020-10-27 22:55:17 -06008387 reduction_mode_ci.reductionMode = VK_SAMPLER_REDUCTION_MODE_MIN;
8388 sampler_ci.pNext = &reduction_mode_ci;
8389 VkSampler sampler_rediction;
8390 vk::CreateSampler(m_device->device(), &sampler_ci, NULL, &sampler_rediction);
8391
8392 VkShaderObj fs(m_device, bindStateFragSamplerShaderText, VK_SHADER_STAGE_FRAGMENT_BIT, this);
8393
8394 CreatePipelineHelper g_pipe(*this);
8395 g_pipe.InitInfo();
8396 g_pipe.shader_stages_ = {g_pipe.vs_->GetStageCreateInfo(), fs.GetStageCreateInfo()};
8397 g_pipe.dsl_bindings_ = {{0, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_FRAGMENT_BIT, nullptr}};
8398 g_pipe.InitState();
8399 ASSERT_VK_SUCCESS(g_pipe.CreateGraphicsPipeline());
8400
8401 g_pipe.descriptor_set_->WriteDescriptorImageInfo(0, imageView, sampler_rediction);
8402 g_pipe.descriptor_set_->UpdateDescriptorSets();
8403
8404 m_commandBuffer->begin();
8405 m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
8406 vk::CmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipe.pipeline_);
8407 vk::CmdBindDescriptorSets(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipe.pipeline_layout_.handle(), 0, 1,
8408 &g_pipe.descriptor_set_->set_, 0, nullptr);
8409
8410 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdDraw-filterCubicMinmax-02695");
8411 m_commandBuffer->Draw(1, 0, 0, 0);
8412 m_errorMonitor->VerifyFound();
8413
8414 m_commandBuffer->EndRenderPass();
8415 m_commandBuffer->end();
8416 m_commandBuffer->reset();
8417
8418 g_pipe.descriptor_set_->WriteDescriptorImageInfo(0, imageView, sampler);
8419 g_pipe.descriptor_set_->UpdateDescriptorSets();
8420
8421 m_commandBuffer->begin();
8422 m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
8423 vk::CmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipe.pipeline_);
8424 vk::CmdBindDescriptorSets(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipe.pipeline_layout_.handle(), 0, 1,
8425 &g_pipe.descriptor_set_->set_, 0, nullptr);
8426
8427 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdDraw-filterCubic-02694");
8428 m_commandBuffer->Draw(1, 0, 0, 0);
8429 m_errorMonitor->VerifyFound();
8430
8431 m_commandBuffer->EndRenderPass();
8432 m_commandBuffer->end();
8433}
8434
Mark Lobodzinski28168c52020-12-01 14:25:05 -07008435TEST_F(VkLayerTest, VerifyImgFilterCubicSamplerInCmdDraw) {
Mark Lobodzinski07d0a612020-12-30 15:42:31 -07008436 TEST_DESCRIPTION("Verify if sampler is filter cubic with the VK_IMG_filter cubic extension that it's a valid ImageViewType.");
Mark Lobodzinski28168c52020-12-01 14:25:05 -07008437 ASSERT_NO_FATAL_FAILURE(InitFramework(m_errorMonitor));
8438
8439 if (DeviceExtensionSupported(gpu(), nullptr, VK_IMG_FILTER_CUBIC_EXTENSION_NAME)) {
8440 m_device_extension_names.push_back(VK_IMG_FILTER_CUBIC_EXTENSION_NAME);
8441 } else {
8442 printf("%s %s Extension not supported, skipping tests\n", kSkipPrefix, VK_IMG_FILTER_CUBIC_EXTENSION_NAME);
8443 return;
8444 }
8445
8446 ASSERT_NO_FATAL_FAILURE(InitState(nullptr, nullptr, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT));
8447 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
8448
8449 VkImageUsageFlags usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT;
8450 VkFormat format = VK_FORMAT_R8G8B8A8_UNORM;
8451 auto image_ci = VkImageObj::ImageCreateInfo2D(128, 128, 1, 1, format, usage, VK_IMAGE_TILING_OPTIMAL);
8452 VkImageViewType imageViewType = VK_IMAGE_VIEW_TYPE_2D;
8453
8454 VkImageObj image(m_device);
8455 image.Init(image_ci);
8456 VkImageView imageView = image.targetView(format, VK_IMAGE_ASPECT_COLOR_BIT, 0, VK_REMAINING_MIP_LEVELS, 0,
8457 VK_REMAINING_ARRAY_LAYERS, imageViewType);
8458
Mark Lobodzinski07d0a612020-12-30 15:42:31 -07008459 auto sampler_ci = LvlInitStruct<VkSamplerCreateInfo>();
Mark Lobodzinski28168c52020-12-01 14:25:05 -07008460 sampler_ci.minFilter = VK_FILTER_CUBIC_EXT;
8461 sampler_ci.magFilter = VK_FILTER_CUBIC_EXT;
8462 VkSampler sampler;
8463 vk::CreateSampler(m_device->device(), &sampler_ci, NULL, &sampler);
8464
8465 VkShaderObj fs(m_device, bindStateFragSamplerShaderText, VK_SHADER_STAGE_FRAGMENT_BIT, this);
8466
8467 CreatePipelineHelper g_pipe(*this);
8468 g_pipe.InitInfo();
8469 g_pipe.shader_stages_ = {g_pipe.vs_->GetStageCreateInfo(), fs.GetStageCreateInfo()};
8470 g_pipe.dsl_bindings_ = {{0, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_FRAGMENT_BIT, nullptr}};
8471 g_pipe.InitState();
8472 ASSERT_VK_SUCCESS(g_pipe.CreateGraphicsPipeline());
8473
8474 g_pipe.descriptor_set_->WriteDescriptorImageInfo(0, imageView, sampler);
8475 g_pipe.descriptor_set_->UpdateDescriptorSets();
8476
8477 m_commandBuffer->begin();
8478 m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
8479 vk::CmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipe.pipeline_);
8480 vk::CmdBindDescriptorSets(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, g_pipe.pipeline_layout_.handle(), 0, 1,
8481 &g_pipe.descriptor_set_->set_, 0, nullptr);
8482
8483 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdDraw-None-02693");
8484 m_commandBuffer->Draw(1, 0, 0, 0);
8485 m_errorMonitor->VerifyFound();
8486
8487 m_commandBuffer->EndRenderPass();
8488 m_commandBuffer->end();
8489}
8490
locke-lunarg0de02522020-10-27 22:55:17 -06008491TEST_F(VkLayerTest, VerifyMaxMultiviewInstanceIndex) {
8492 TEST_DESCRIPTION("Verify if instance index in CmdDraw is greater than maxMultiviewInstanceIndex.");
8493 uint32_t version = SetTargetApiVersion(VK_API_VERSION_1_1);
8494 if (version < VK_API_VERSION_1_1) {
8495 printf("%s At least Vulkan version 1.1 is required, skipping test.\n", kSkipPrefix);
8496 return;
8497 }
8498 if (InstanceExtensionSupported(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME)) {
8499 m_instance_extension_names.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
8500 } else {
8501 printf("%s Did not find required instance extension %s; skipped.\n", kSkipPrefix,
8502 VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
8503 return;
8504 }
8505 ASSERT_NO_FATAL_FAILURE(InitFramework(m_errorMonitor));
8506
8507 if (DeviceExtensionSupported(gpu(), nullptr, VK_KHR_MULTIVIEW_EXTENSION_NAME)) {
8508 m_device_extension_names.push_back(VK_KHR_MULTIVIEW_EXTENSION_NAME);
8509 } else {
8510 printf("%s %s Extension not supported, skipping tests\n", kSkipPrefix, VK_KHR_MULTIVIEW_EXTENSION_NAME);
8511 return;
8512 }
8513
Mark Lobodzinski07d0a612020-12-30 15:42:31 -07008514 auto multiview_features = LvlInitStruct<VkPhysicalDeviceMultiviewFeatures>();
locke-lunarg0de02522020-10-27 22:55:17 -06008515 multiview_features.multiview = VK_TRUE;
8516 VkPhysicalDeviceFeatures2 pd_features2 = {};
8517 pd_features2.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2;
8518 pd_features2.pNext = &multiview_features;
8519
8520 ASSERT_NO_FATAL_FAILURE(InitState(nullptr, &pd_features2));
8521 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
8522
8523 PFN_vkGetPhysicalDeviceProperties2KHR vkGetPhysicalDeviceProperties2KHR =
8524 (PFN_vkGetPhysicalDeviceProperties2KHR)vk::GetInstanceProcAddr(instance(), "vkGetPhysicalDeviceProperties2KHR");
8525 ASSERT_TRUE(vkGetPhysicalDeviceProperties2KHR != nullptr);
Mark Lobodzinski07d0a612020-12-30 15:42:31 -07008526 auto multiview_props = LvlInitStruct<VkPhysicalDeviceMultiviewProperties>();
8527 VkPhysicalDeviceProperties2KHR properties2 = LvlInitStruct<VkPhysicalDeviceProperties2KHR>(&multiview_props);
locke-lunarg0de02522020-10-27 22:55:17 -06008528 vkGetPhysicalDeviceProperties2KHR(gpu(), &properties2);
8529 if (multiview_props.maxMultiviewInstanceIndex == std::numeric_limits<uint32_t>::max()) {
8530 printf("%s maxMultiviewInstanceIndex is uint32_t max, skipping tests\n", kSkipPrefix);
8531 return;
8532 }
8533 CreatePipelineHelper pipe(*this);
8534 pipe.InitInfo();
8535 pipe.InitState();
8536 pipe.CreateGraphicsPipeline();
8537
8538 m_commandBuffer->begin();
8539 m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
8540 vk::CmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.pipeline_);
8541
8542 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdDraw-maxMultiviewInstanceIndex-02688");
8543 m_commandBuffer->Draw(1, multiview_props.maxMultiviewInstanceIndex + 1, 0, 0);
8544 m_errorMonitor->VerifyFound();
8545
8546 m_commandBuffer->EndRenderPass();
8547 m_commandBuffer->end();
8548}
Tobias Hector04f2ab22020-12-01 10:59:33 +00008549
8550TEST_F(VkLayerTest, InvalidSetFragmentShadingRateValues) {
8551 TEST_DESCRIPTION("Specify invalid fragment shading rate values");
8552
8553 // Enable KHR_fragment_shading_rate and all of its required extensions
8554 bool fsr_extensions = InstanceExtensionSupported(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
8555 if (fsr_extensions) {
8556 m_instance_extension_names.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
8557 }
8558 ASSERT_NO_FATAL_FAILURE(InitFramework(m_errorMonitor));
8559
8560 fsr_extensions = fsr_extensions && DeviceExtensionSupported(gpu(), nullptr, VK_KHR_MAINTENANCE1_EXTENSION_NAME);
8561 fsr_extensions = fsr_extensions && DeviceExtensionSupported(gpu(), nullptr, VK_KHR_MAINTENANCE2_EXTENSION_NAME);
8562 fsr_extensions = fsr_extensions && DeviceExtensionSupported(gpu(), nullptr, VK_KHR_MULTIVIEW_EXTENSION_NAME);
8563 fsr_extensions = fsr_extensions && DeviceExtensionSupported(gpu(), nullptr, VK_KHR_CREATE_RENDERPASS_2_EXTENSION_NAME);
8564 fsr_extensions = fsr_extensions && DeviceExtensionSupported(gpu(), nullptr, VK_KHR_FRAGMENT_SHADING_RATE_EXTENSION_NAME);
8565 if (fsr_extensions) {
8566 m_device_extension_names.push_back(VK_KHR_MAINTENANCE1_EXTENSION_NAME);
8567 m_device_extension_names.push_back(VK_KHR_MAINTENANCE2_EXTENSION_NAME);
8568 m_device_extension_names.push_back(VK_KHR_MULTIVIEW_EXTENSION_NAME);
8569 m_device_extension_names.push_back(VK_KHR_CREATE_RENDERPASS_2_EXTENSION_NAME);
8570 m_device_extension_names.push_back(VK_KHR_FRAGMENT_SHADING_RATE_EXTENSION_NAME);
8571 } else {
8572 printf("%s requires VK_KHR_fragment_shading_rate.\n", kSkipPrefix);
8573 return;
8574 }
8575
8576 VkPhysicalDeviceFragmentShadingRateFeaturesKHR fsr_features = {};
8577 fsr_features.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_SHADING_RATE_FEATURES_KHR;
8578 fsr_features.pipelineFragmentShadingRate = true;
8579
8580 VkPhysicalDeviceFeatures2 device_features = {};
8581 device_features.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2;
8582 device_features.pNext = &fsr_features;
8583
8584 ASSERT_NO_FATAL_FAILURE(InitState(nullptr, &device_features));
8585
8586 // Find address of extension call and make the call
8587 PFN_vkCmdSetFragmentShadingRateKHR vkCmdSetFragmentShadingRateKHR =
8588 (PFN_vkCmdSetFragmentShadingRateKHR)vk::GetDeviceProcAddr(m_device->device(), "vkCmdSetFragmentShadingRateKHR");
8589 ASSERT_TRUE(vkCmdSetFragmentShadingRateKHR != nullptr);
8590
8591 VkExtent2D fragmentSize = {1, 1};
8592 VkFragmentShadingRateCombinerOpKHR combinerOps[2] = {VK_FRAGMENT_SHADING_RATE_COMBINER_OP_KEEP_KHR,
8593 VK_FRAGMENT_SHADING_RATE_COMBINER_OP_KEEP_KHR};
8594
8595 m_commandBuffer->begin();
8596 fragmentSize.width = 0;
8597 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdSetFragmentShadingRateKHR-pFragmentSize-04513");
8598 vkCmdSetFragmentShadingRateKHR(m_commandBuffer->handle(), &fragmentSize, combinerOps);
8599 m_errorMonitor->VerifyFound();
8600 fragmentSize.width = 1;
8601
8602 fragmentSize.height = 0;
8603 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdSetFragmentShadingRateKHR-pFragmentSize-04514");
8604 vkCmdSetFragmentShadingRateKHR(m_commandBuffer->handle(), &fragmentSize, combinerOps);
8605 m_errorMonitor->VerifyFound();
8606 fragmentSize.height = 1;
8607
8608 fragmentSize.width = 3;
8609 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdSetFragmentShadingRateKHR-pFragmentSize-04515");
8610 vkCmdSetFragmentShadingRateKHR(m_commandBuffer->handle(), &fragmentSize, combinerOps);
8611 m_errorMonitor->VerifyFound();
8612 fragmentSize.width = 1;
8613
8614 fragmentSize.height = 3;
8615 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdSetFragmentShadingRateKHR-pFragmentSize-04516");
8616 vkCmdSetFragmentShadingRateKHR(m_commandBuffer->handle(), &fragmentSize, combinerOps);
8617 m_errorMonitor->VerifyFound();
8618 fragmentSize.height = 1;
8619
8620 fragmentSize.width = 8;
8621 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdSetFragmentShadingRateKHR-pFragmentSize-04517");
8622 vkCmdSetFragmentShadingRateKHR(m_commandBuffer->handle(), &fragmentSize, combinerOps);
8623 m_errorMonitor->VerifyFound();
8624 fragmentSize.width = 1;
8625
8626 fragmentSize.height = 8;
8627 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdSetFragmentShadingRateKHR-pFragmentSize-04518");
8628 vkCmdSetFragmentShadingRateKHR(m_commandBuffer->handle(), &fragmentSize, combinerOps);
8629 m_errorMonitor->VerifyFound();
8630 fragmentSize.height = 1;
8631 m_commandBuffer->end();
8632}
8633
8634TEST_F(VkLayerTest, InvalidSetFragmentShadingRateValuesNoFeatures) {
8635 TEST_DESCRIPTION("Specify invalid fsr pipeline settings for the enabled features");
8636
8637 // Enable KHR_fragment_shading_rate and all of its required extensions
8638 bool fsr_extensions = InstanceExtensionSupported(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
8639 if (fsr_extensions) {
8640 m_instance_extension_names.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
8641 }
8642 ASSERT_NO_FATAL_FAILURE(InitFramework(m_errorMonitor));
8643
8644 fsr_extensions = fsr_extensions && DeviceExtensionSupported(gpu(), nullptr, VK_KHR_MAINTENANCE1_EXTENSION_NAME);
8645 fsr_extensions = fsr_extensions && DeviceExtensionSupported(gpu(), nullptr, VK_KHR_MAINTENANCE2_EXTENSION_NAME);
8646 fsr_extensions = fsr_extensions && DeviceExtensionSupported(gpu(), nullptr, VK_KHR_MULTIVIEW_EXTENSION_NAME);
8647 fsr_extensions = fsr_extensions && DeviceExtensionSupported(gpu(), nullptr, VK_KHR_CREATE_RENDERPASS_2_EXTENSION_NAME);
8648 fsr_extensions = fsr_extensions && DeviceExtensionSupported(gpu(), nullptr, VK_KHR_FRAGMENT_SHADING_RATE_EXTENSION_NAME);
8649 if (fsr_extensions) {
8650 m_device_extension_names.push_back(VK_KHR_MAINTENANCE1_EXTENSION_NAME);
8651 m_device_extension_names.push_back(VK_KHR_MAINTENANCE2_EXTENSION_NAME);
8652 m_device_extension_names.push_back(VK_KHR_MULTIVIEW_EXTENSION_NAME);
8653 m_device_extension_names.push_back(VK_KHR_CREATE_RENDERPASS_2_EXTENSION_NAME);
8654 m_device_extension_names.push_back(VK_KHR_FRAGMENT_SHADING_RATE_EXTENSION_NAME);
8655 } else {
8656 printf("%s requires VK_KHR_fragment_shading_rate.\n", kSkipPrefix);
8657 return;
8658 }
8659
8660 ASSERT_NO_FATAL_FAILURE(InitState());
8661 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
8662
8663 // Find address of extension call and make the call
8664 PFN_vkCmdSetFragmentShadingRateKHR vkCmdSetFragmentShadingRateKHR =
8665 (PFN_vkCmdSetFragmentShadingRateKHR)vk::GetDeviceProcAddr(m_device->device(), "vkCmdSetFragmentShadingRateKHR");
8666 ASSERT_TRUE(vkCmdSetFragmentShadingRateKHR != nullptr);
8667
8668 VkExtent2D fragmentSize = {1, 1};
8669 VkFragmentShadingRateCombinerOpKHR combinerOps[2] = {VK_FRAGMENT_SHADING_RATE_COMBINER_OP_KEEP_KHR,
8670 VK_FRAGMENT_SHADING_RATE_COMBINER_OP_KEEP_KHR};
8671
8672 m_commandBuffer->begin();
8673 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
8674 "VUID-vkCmdSetFragmentShadingRateKHR-pipelineFragmentShadingRate-04509");
8675 vkCmdSetFragmentShadingRateKHR(m_commandBuffer->handle(), &fragmentSize, combinerOps);
8676 m_errorMonitor->VerifyFound();
8677 m_commandBuffer->end();
8678}
8679
8680TEST_F(VkLayerTest, InvalidSetFragmentShadingRateCombinerOpsNoFeatures) {
8681 TEST_DESCRIPTION("Specify combiner operations when only pipeline rate is supported");
8682
8683 // Enable KHR_fragment_shading_rate and all of its required extensions
8684 bool fsr_extensions = InstanceExtensionSupported(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
8685 if (fsr_extensions) {
8686 m_instance_extension_names.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
8687 }
8688 ASSERT_NO_FATAL_FAILURE(InitFramework(m_errorMonitor));
8689
8690 fsr_extensions = fsr_extensions && DeviceExtensionSupported(gpu(), nullptr, VK_KHR_MAINTENANCE1_EXTENSION_NAME);
8691 fsr_extensions = fsr_extensions && DeviceExtensionSupported(gpu(), nullptr, VK_KHR_MAINTENANCE2_EXTENSION_NAME);
8692 fsr_extensions = fsr_extensions && DeviceExtensionSupported(gpu(), nullptr, VK_KHR_MULTIVIEW_EXTENSION_NAME);
8693 fsr_extensions = fsr_extensions && DeviceExtensionSupported(gpu(), nullptr, VK_KHR_CREATE_RENDERPASS_2_EXTENSION_NAME);
8694 fsr_extensions = fsr_extensions && DeviceExtensionSupported(gpu(), nullptr, VK_KHR_FRAGMENT_SHADING_RATE_EXTENSION_NAME);
8695 if (fsr_extensions) {
8696 m_device_extension_names.push_back(VK_KHR_MAINTENANCE1_EXTENSION_NAME);
8697 m_device_extension_names.push_back(VK_KHR_MAINTENANCE2_EXTENSION_NAME);
8698 m_device_extension_names.push_back(VK_KHR_MULTIVIEW_EXTENSION_NAME);
8699 m_device_extension_names.push_back(VK_KHR_CREATE_RENDERPASS_2_EXTENSION_NAME);
8700 m_device_extension_names.push_back(VK_KHR_FRAGMENT_SHADING_RATE_EXTENSION_NAME);
8701 } else {
8702 printf("%s requires VK_KHR_fragment_shading_rate.\n", kSkipPrefix);
8703 return;
8704 }
8705
Mark Lobodzinski07d0a612020-12-30 15:42:31 -07008706 VkPhysicalDeviceFragmentShadingRateFeaturesKHR fsr_features = LvlInitStruct<VkPhysicalDeviceFragmentShadingRateFeaturesKHR>();
8707 VkPhysicalDeviceFeatures2KHR features2 = LvlInitStruct<VkPhysicalDeviceFeatures2KHR>(&fsr_features);
Tobias Hector04f2ab22020-12-01 10:59:33 +00008708
8709 fsr_features.pipelineFragmentShadingRate = VK_TRUE;
8710 fsr_features.primitiveFragmentShadingRate = VK_FALSE;
8711 fsr_features.attachmentFragmentShadingRate = VK_FALSE;
8712
8713 ASSERT_NO_FATAL_FAILURE(InitState(nullptr, &features2));
8714 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
8715
8716 // Find address of extension call and make the call
8717 PFN_vkCmdSetFragmentShadingRateKHR vkCmdSetFragmentShadingRateKHR =
8718 (PFN_vkCmdSetFragmentShadingRateKHR)vk::GetDeviceProcAddr(m_device->device(), "vkCmdSetFragmentShadingRateKHR");
8719 ASSERT_TRUE(vkCmdSetFragmentShadingRateKHR != nullptr);
8720
8721 VkExtent2D fragmentSize = {1, 1};
8722 VkFragmentShadingRateCombinerOpKHR combinerOps[2] = {VK_FRAGMENT_SHADING_RATE_COMBINER_OP_KEEP_KHR,
8723 VK_FRAGMENT_SHADING_RATE_COMBINER_OP_KEEP_KHR};
8724
8725 m_commandBuffer->begin();
8726
8727 combinerOps[0] = VK_FRAGMENT_SHADING_RATE_COMBINER_OP_REPLACE_KHR;
8728 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
8729 "VUID-vkCmdSetFragmentShadingRateKHR-primitiveFragmentShadingRate-04510");
8730 vkCmdSetFragmentShadingRateKHR(m_commandBuffer->handle(), &fragmentSize, combinerOps);
8731 m_errorMonitor->VerifyFound();
8732 combinerOps[0] = VK_FRAGMENT_SHADING_RATE_COMBINER_OP_KEEP_KHR;
8733
8734 combinerOps[1] = VK_FRAGMENT_SHADING_RATE_COMBINER_OP_REPLACE_KHR;
8735 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
8736 "VUID-vkCmdSetFragmentShadingRateKHR-attachmentFragmentShadingRate-04511");
8737 vkCmdSetFragmentShadingRateKHR(m_commandBuffer->handle(), &fragmentSize, combinerOps);
8738 m_errorMonitor->VerifyFound();
8739 combinerOps[1] = VK_FRAGMENT_SHADING_RATE_COMBINER_OP_KEEP_KHR;
8740
8741 m_commandBuffer->end();
8742}
8743
8744TEST_F(VkLayerTest, InvalidSetFragmentShadingRateCombinerOpsNoPipelineRate) {
8745 TEST_DESCRIPTION("Specify pipeline rate when only attachment or primitive rate are supported");
8746
8747 // Enable KHR_fragment_shading_rate and all of its required extensions
8748 bool fsr_extensions = InstanceExtensionSupported(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
8749 if (fsr_extensions) {
8750 m_instance_extension_names.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
8751 }
8752 ASSERT_NO_FATAL_FAILURE(InitFramework(m_errorMonitor));
8753
8754 fsr_extensions = fsr_extensions && DeviceExtensionSupported(gpu(), nullptr, VK_KHR_MAINTENANCE1_EXTENSION_NAME);
8755 fsr_extensions = fsr_extensions && DeviceExtensionSupported(gpu(), nullptr, VK_KHR_MAINTENANCE2_EXTENSION_NAME);
8756 fsr_extensions = fsr_extensions && DeviceExtensionSupported(gpu(), nullptr, VK_KHR_MULTIVIEW_EXTENSION_NAME);
8757 fsr_extensions = fsr_extensions && DeviceExtensionSupported(gpu(), nullptr, VK_KHR_CREATE_RENDERPASS_2_EXTENSION_NAME);
8758 fsr_extensions = fsr_extensions && DeviceExtensionSupported(gpu(), nullptr, VK_KHR_FRAGMENT_SHADING_RATE_EXTENSION_NAME);
8759 if (fsr_extensions) {
8760 m_device_extension_names.push_back(VK_KHR_MAINTENANCE1_EXTENSION_NAME);
8761 m_device_extension_names.push_back(VK_KHR_MAINTENANCE2_EXTENSION_NAME);
8762 m_device_extension_names.push_back(VK_KHR_MULTIVIEW_EXTENSION_NAME);
8763 m_device_extension_names.push_back(VK_KHR_CREATE_RENDERPASS_2_EXTENSION_NAME);
8764 m_device_extension_names.push_back(VK_KHR_FRAGMENT_SHADING_RATE_EXTENSION_NAME);
8765 } else {
8766 printf("%s requires VK_KHR_fragment_shading_rate.\n", kSkipPrefix);
8767 return;
8768 }
8769
8770 PFN_vkGetPhysicalDeviceFeatures2KHR vkGetPhysicalDeviceFeatures2KHR =
8771 (PFN_vkGetPhysicalDeviceFeatures2KHR)vk::GetInstanceProcAddr(instance(), "vkGetPhysicalDeviceFeatures2KHR");
8772 ASSERT_TRUE(vkGetPhysicalDeviceFeatures2KHR != nullptr);
Mark Lobodzinski07d0a612020-12-30 15:42:31 -07008773 VkPhysicalDeviceFragmentShadingRateFeaturesKHR fsr_features = LvlInitStruct<VkPhysicalDeviceFragmentShadingRateFeaturesKHR>();
8774 VkPhysicalDeviceFeatures2KHR features2 = LvlInitStruct<VkPhysicalDeviceFeatures2KHR>(&fsr_features);
Tobias Hector04f2ab22020-12-01 10:59:33 +00008775 vkGetPhysicalDeviceFeatures2KHR(gpu(), &features2);
8776
8777 if (fsr_features.attachmentFragmentShadingRate == VK_FALSE && fsr_features.primitiveFragmentShadingRate == VK_FALSE) {
8778 printf("%s requires attachmentFragmentShadingRate or primitiveFragmentShadingRate.\n", kSkipPrefix);
8779 return;
8780 }
8781
8782 fsr_features.pipelineFragmentShadingRate = VK_FALSE;
8783
8784 ASSERT_NO_FATAL_FAILURE(InitState(nullptr, &features2));
8785 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
8786
8787 // Find address of extension call and make the call
8788 PFN_vkCmdSetFragmentShadingRateKHR vkCmdSetFragmentShadingRateKHR =
8789 (PFN_vkCmdSetFragmentShadingRateKHR)vk::GetDeviceProcAddr(m_device->device(), "vkCmdSetFragmentShadingRateKHR");
8790 ASSERT_TRUE(vkCmdSetFragmentShadingRateKHR != nullptr);
8791
8792 VkExtent2D fragmentSize = {1, 1};
8793 VkFragmentShadingRateCombinerOpKHR combinerOps[2] = {VK_FRAGMENT_SHADING_RATE_COMBINER_OP_KEEP_KHR,
8794 VK_FRAGMENT_SHADING_RATE_COMBINER_OP_KEEP_KHR};
8795
8796 m_commandBuffer->begin();
8797 fragmentSize.width = 2;
8798 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
8799 "VUID-vkCmdSetFragmentShadingRateKHR-pipelineFragmentShadingRate-04507");
8800 vkCmdSetFragmentShadingRateKHR(m_commandBuffer->handle(), &fragmentSize, combinerOps);
8801 m_errorMonitor->VerifyFound();
8802 fragmentSize.width = 1;
8803
8804 fragmentSize.height = 2;
8805 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
8806 "VUID-vkCmdSetFragmentShadingRateKHR-pipelineFragmentShadingRate-04508");
8807 vkCmdSetFragmentShadingRateKHR(m_commandBuffer->handle(), &fragmentSize, combinerOps);
8808 m_errorMonitor->VerifyFound();
8809 fragmentSize.height = 1;
8810}
8811
8812TEST_F(VkLayerTest, InvalidSetFragmentShadingRateCombinerOpsLimit) {
8813 TEST_DESCRIPTION("Specify invalid fsr pipeline settings for the enabled features");
8814
8815 // Enable KHR_fragment_shading_rate and all of its required extensions
8816 bool fsr_extensions = InstanceExtensionSupported(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
8817 if (fsr_extensions) {
8818 m_instance_extension_names.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
8819 }
8820 ASSERT_NO_FATAL_FAILURE(InitFramework(m_errorMonitor));
8821
8822 fsr_extensions = fsr_extensions && DeviceExtensionSupported(gpu(), nullptr, VK_KHR_MAINTENANCE1_EXTENSION_NAME);
8823 fsr_extensions = fsr_extensions && DeviceExtensionSupported(gpu(), nullptr, VK_KHR_MAINTENANCE2_EXTENSION_NAME);
8824 fsr_extensions = fsr_extensions && DeviceExtensionSupported(gpu(), nullptr, VK_KHR_MULTIVIEW_EXTENSION_NAME);
8825 fsr_extensions = fsr_extensions && DeviceExtensionSupported(gpu(), nullptr, VK_KHR_CREATE_RENDERPASS_2_EXTENSION_NAME);
8826 fsr_extensions = fsr_extensions && DeviceExtensionSupported(gpu(), nullptr, VK_KHR_FRAGMENT_SHADING_RATE_EXTENSION_NAME);
8827 if (fsr_extensions) {
8828 m_device_extension_names.push_back(VK_KHR_MAINTENANCE1_EXTENSION_NAME);
8829 m_device_extension_names.push_back(VK_KHR_MAINTENANCE2_EXTENSION_NAME);
8830 m_device_extension_names.push_back(VK_KHR_MULTIVIEW_EXTENSION_NAME);
8831 m_device_extension_names.push_back(VK_KHR_CREATE_RENDERPASS_2_EXTENSION_NAME);
8832 m_device_extension_names.push_back(VK_KHR_FRAGMENT_SHADING_RATE_EXTENSION_NAME);
8833 } else {
8834 printf("%s requires VK_KHR_fragment_shading_rate.\n", kSkipPrefix);
8835 return;
8836 }
8837
8838 PFN_vkGetPhysicalDeviceProperties2KHR vkGetPhysicalDeviceProperties2KHR =
8839 (PFN_vkGetPhysicalDeviceProperties2KHR)vk::GetInstanceProcAddr(instance(), "vkGetPhysicalDeviceProperties2KHR");
8840 ASSERT_TRUE(vkGetPhysicalDeviceProperties2KHR != nullptr);
8841 VkPhysicalDeviceFragmentShadingRatePropertiesKHR fsr_properties =
Mark Lobodzinski07d0a612020-12-30 15:42:31 -07008842 LvlInitStruct<VkPhysicalDeviceFragmentShadingRatePropertiesKHR>();
8843 VkPhysicalDeviceProperties2KHR properties2 = LvlInitStruct<VkPhysicalDeviceProperties2KHR>(&fsr_properties);
Tobias Hector04f2ab22020-12-01 10:59:33 +00008844 vkGetPhysicalDeviceProperties2KHR(gpu(), &properties2);
8845
8846 if (fsr_properties.fragmentShadingRateNonTrivialCombinerOps) {
8847 printf("%s requires fragmentShadingRateNonTrivialCombinerOps to be unsupported.\n", kSkipPrefix);
8848 return;
8849 }
8850
8851 PFN_vkGetPhysicalDeviceFeatures2KHR vkGetPhysicalDeviceFeatures2KHR =
8852 (PFN_vkGetPhysicalDeviceFeatures2KHR)vk::GetInstanceProcAddr(instance(), "vkGetPhysicalDeviceFeatures2KHR");
8853 ASSERT_TRUE(vkGetPhysicalDeviceFeatures2KHR != nullptr);
Mark Lobodzinski07d0a612020-12-30 15:42:31 -07008854 VkPhysicalDeviceFragmentShadingRateFeaturesKHR fsr_features = LvlInitStruct<VkPhysicalDeviceFragmentShadingRateFeaturesKHR>();
8855 VkPhysicalDeviceFeatures2KHR features2 = LvlInitStruct<VkPhysicalDeviceFeatures2KHR>(&fsr_features);
Tobias Hector04f2ab22020-12-01 10:59:33 +00008856 vkGetPhysicalDeviceFeatures2KHR(gpu(), &features2);
8857
8858 if (!fsr_features.primitiveFragmentShadingRate && !fsr_features.attachmentFragmentShadingRate) {
8859 printf("%s requires primitiveFragmentShadingRate or attachmentFragmentShadingRate to be supported.\n", kSkipPrefix);
8860 return;
8861 }
8862
8863 ASSERT_NO_FATAL_FAILURE(InitState(nullptr, &features2));
8864 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
8865
8866 // Find address of extension call and make the call
8867 PFN_vkCmdSetFragmentShadingRateKHR vkCmdSetFragmentShadingRateKHR =
8868 (PFN_vkCmdSetFragmentShadingRateKHR)vk::GetDeviceProcAddr(m_device->device(), "vkCmdSetFragmentShadingRateKHR");
8869 ASSERT_TRUE(vkCmdSetFragmentShadingRateKHR != nullptr);
8870
8871 VkExtent2D fragmentSize = {1, 1};
8872 VkFragmentShadingRateCombinerOpKHR combinerOps[2] = {VK_FRAGMENT_SHADING_RATE_COMBINER_OP_KEEP_KHR,
8873 VK_FRAGMENT_SHADING_RATE_COMBINER_OP_KEEP_KHR};
8874
8875 m_commandBuffer->begin();
8876 if (fsr_features.primitiveFragmentShadingRate) {
8877 combinerOps[0] = VK_FRAGMENT_SHADING_RATE_COMBINER_OP_MUL_KHR;
8878 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
8879 "VUID-vkCmdSetFragmentShadingRateKHR-fragmentSizeNonTrivialCombinerOps-04512");
8880 vkCmdSetFragmentShadingRateKHR(m_commandBuffer->handle(), &fragmentSize, combinerOps);
8881 m_errorMonitor->VerifyFound();
8882 combinerOps[0] = VK_FRAGMENT_SHADING_RATE_COMBINER_OP_KEEP_KHR;
8883 }
8884
8885 if (fsr_features.attachmentFragmentShadingRate) {
8886 combinerOps[1] = VK_FRAGMENT_SHADING_RATE_COMBINER_OP_MUL_KHR;
8887 m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
8888 "VUID-vkCmdSetFragmentShadingRateKHR-fragmentSizeNonTrivialCombinerOps-04512");
8889 vkCmdSetFragmentShadingRateKHR(m_commandBuffer->handle(), &fragmentSize, combinerOps);
8890 m_errorMonitor->VerifyFound();
8891 combinerOps[1] = VK_FRAGMENT_SHADING_RATE_COMBINER_OP_KEEP_KHR;
8892 }
8893 m_commandBuffer->end();
8894}
8895
8896TEST_F(VkLayerTest, InvalidPrimitiveFragmentShadingRateWriteMultiViewportLimitDynamic) {
8897 TEST_DESCRIPTION("Test dynamic validation of the primitiveFragmentShadingRateWithMultipleViewports limit");
8898
8899 // Enable KHR_fragment_shading_rate and all of its required extensions
8900 bool fsr_extensions = InstanceExtensionSupported(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
8901 if (fsr_extensions) {
8902 m_instance_extension_names.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
8903 }
8904 ASSERT_NO_FATAL_FAILURE(InitFramework(m_errorMonitor));
8905
8906 fsr_extensions = fsr_extensions && DeviceExtensionSupported(gpu(), nullptr, VK_KHR_MAINTENANCE1_EXTENSION_NAME);
8907 fsr_extensions = fsr_extensions && DeviceExtensionSupported(gpu(), nullptr, VK_KHR_MAINTENANCE2_EXTENSION_NAME);
8908 fsr_extensions = fsr_extensions && DeviceExtensionSupported(gpu(), nullptr, VK_KHR_MULTIVIEW_EXTENSION_NAME);
8909 fsr_extensions = fsr_extensions && DeviceExtensionSupported(gpu(), nullptr, VK_KHR_CREATE_RENDERPASS_2_EXTENSION_NAME);
8910 fsr_extensions = fsr_extensions && DeviceExtensionSupported(gpu(), nullptr, VK_KHR_FRAGMENT_SHADING_RATE_EXTENSION_NAME);
8911 if (fsr_extensions) {
8912 m_device_extension_names.push_back(VK_KHR_MAINTENANCE1_EXTENSION_NAME);
8913 m_device_extension_names.push_back(VK_KHR_MAINTENANCE2_EXTENSION_NAME);
8914 m_device_extension_names.push_back(VK_KHR_MULTIVIEW_EXTENSION_NAME);
8915 m_device_extension_names.push_back(VK_KHR_CREATE_RENDERPASS_2_EXTENSION_NAME);
8916 m_device_extension_names.push_back(VK_KHR_FRAGMENT_SHADING_RATE_EXTENSION_NAME);
8917 } else {
8918 printf("%s requires VK_KHR_fragment_shading_rate.\n", kSkipPrefix);
8919 return;
8920 }
8921
8922 bool eds_extension = DeviceExtensionSupported(gpu(), nullptr, VK_EXT_EXTENDED_DYNAMIC_STATE_EXTENSION_NAME);
8923 if (eds_extension) {
8924 m_device_extension_names.push_back(VK_EXT_EXTENDED_DYNAMIC_STATE_EXTENSION_NAME);
8925 } else {
8926 printf("%s requires VK_EXT_extended_dynamic_state.\n", kSkipPrefix);
8927 return;
8928 }
8929
8930 PFN_vkGetPhysicalDeviceProperties2KHR vkGetPhysicalDeviceProperties2KHR =
8931 (PFN_vkGetPhysicalDeviceProperties2KHR)vk::GetInstanceProcAddr(instance(), "vkGetPhysicalDeviceProperties2KHR");
8932 ASSERT_TRUE(vkGetPhysicalDeviceProperties2KHR != nullptr);
8933 VkPhysicalDeviceFragmentShadingRatePropertiesKHR fsr_properties =
Mark Lobodzinski07d0a612020-12-30 15:42:31 -07008934 LvlInitStruct<VkPhysicalDeviceFragmentShadingRatePropertiesKHR>();
8935 VkPhysicalDeviceProperties2KHR properties2 = LvlInitStruct<VkPhysicalDeviceProperties2KHR>(&fsr_properties);
Tobias Hector04f2ab22020-12-01 10:59:33 +00008936 vkGetPhysicalDeviceProperties2KHR(gpu(), &properties2);
8937
8938 if (fsr_properties.primitiveFragmentShadingRateWithMultipleViewports) {
8939 printf("%s requires primitiveFragmentShadingRateWithMultipleViewports to be unsupported.\n", kSkipPrefix);
8940 return;
8941 }
8942
8943 PFN_vkGetPhysicalDeviceFeatures2KHR vkGetPhysicalDeviceFeatures2KHR =
8944 (PFN_vkGetPhysicalDeviceFeatures2KHR)vk::GetInstanceProcAddr(instance(), "vkGetPhysicalDeviceFeatures2KHR");
8945 ASSERT_TRUE(vkGetPhysicalDeviceFeatures2KHR != nullptr);
Mark Lobodzinski07d0a612020-12-30 15:42:31 -07008946 VkPhysicalDeviceExtendedDynamicStateFeaturesEXT eds_features = LvlInitStruct<VkPhysicalDeviceExtendedDynamicStateFeaturesEXT>();
Tobias Hector04f2ab22020-12-01 10:59:33 +00008947 VkPhysicalDeviceFragmentShadingRateFeaturesKHR fsr_features =
Mark Lobodzinski07d0a612020-12-30 15:42:31 -07008948 LvlInitStruct<VkPhysicalDeviceFragmentShadingRateFeaturesKHR>(&eds_features);
8949 VkPhysicalDeviceFeatures2KHR features2 = LvlInitStruct<VkPhysicalDeviceFeatures2KHR>(&fsr_features);
Tobias Hector04f2ab22020-12-01 10:59:33 +00008950 vkGetPhysicalDeviceFeatures2KHR(gpu(), &features2);
8951
8952 if (!fsr_features.primitiveFragmentShadingRate) {
8953 printf("%s requires primitiveFragmentShadingRate to be supported.\n", kSkipPrefix);
8954 return;
8955 }
8956
8957 if (!features2.features.multiViewport) {
8958 printf("%s requires multiViewport to be supported.\n", kSkipPrefix);
8959 return;
8960 }
8961
8962 ASSERT_NO_FATAL_FAILURE(InitState(nullptr, &features2));
8963 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
8964
8965 char const *vsSource =
8966 "#version 450\n"
8967 "#extension GL_EXT_fragment_shading_rate : enable\n"
8968 "void main() {\n"
8969 " gl_PrimitiveShadingRateEXT = gl_ShadingRateFlag4VerticalPixelsEXT | gl_ShadingRateFlag4HorizontalPixelsEXT;\n"
8970 "}\n";
8971
Tobias Hector04f2ab22020-12-01 10:59:33 +00008972 VkShaderObj fs(m_device, bindStateFragShaderText, VK_SHADER_STAGE_FRAGMENT_BIT, this);
8973
8974 VkPipelineObj pipe(m_device);
Tony-LunarG6ee10062021-02-03 13:56:52 -07008975 std::vector<VkRect2D> scissors = {{{0, 0}, {16, 16}}, {{1, 1}, {16, 16}}};
8976 pipe.SetScissor(scissors);
Tobias Hector04f2ab22020-12-01 10:59:33 +00008977 pipe.AddShader(&fs);
8978 pipe.AddDefaultColorAttachment();
8979 pipe.MakeDynamic(VK_DYNAMIC_STATE_VIEWPORT_WITH_COUNT_EXT);
Tobias Hector04f2ab22020-12-01 10:59:33 +00008980 const VkPipelineLayoutObj pl(m_device);
Tony-LunarG6ee10062021-02-03 13:56:52 -07008981 {
8982 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
8983 pipe.AddShader(&vs);
8984 VkResult err = pipe.CreateVKPipeline(pl.handle(), renderPass());
8985 ASSERT_VK_SUCCESS(err);
8986 }
Tobias Hector04f2ab22020-12-01 10:59:33 +00008987 m_commandBuffer->begin();
8988 m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
8989
8990 vk::CmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.handle());
8991
8992 VkViewport viewports[] = {{0, 0, 16, 16, 0, 1}, {1, 1, 16, 16, 0, 1}};
8993 PFN_vkCmdSetViewportWithCountEXT vkCmdSetViewportWithCountEXT =
8994 (PFN_vkCmdSetViewportWithCountEXT)vk::GetDeviceProcAddr(device(), "vkCmdSetViewportWithCountEXT");
8995 vkCmdSetViewportWithCountEXT(m_commandBuffer->handle(), 2, viewports);
8996
8997 // error produced here.
8998 vk::CmdDraw(m_commandBuffer->handle(), 3, 1, 0, 0);
8999
9000 m_errorMonitor->VerifyFound();
9001
9002 m_commandBuffer->EndRenderPass();
9003 m_commandBuffer->end();
Mark Lobodzinski07d0a612020-12-30 15:42:31 -07009004}