xref: /aosp_15_r20/external/vulkan-validation-layers/tests/vklayertests_command.cpp (revision b7893ccf7851cd6a48cc5a1e965257d8a5cdcc70)
1 /*
2  * Copyright (c) 2015-2019 The Khronos Group Inc.
3  * Copyright (c) 2015-2019 Valve Corporation
4  * Copyright (c) 2015-2019 LunarG, Inc.
5  * Copyright (c) 2015-2019 Google, Inc.
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  *     http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Author: Chia-I Wu <[email protected]>
14  * Author: Chris Forbes <[email protected]>
15  * Author: Courtney Goeltzenleuchter <[email protected]>
16  * Author: Mark Lobodzinski <[email protected]>
17  * Author: Mike Stroyan <[email protected]>
18  * Author: Tobin Ehlis <[email protected]>
19  * Author: Tony Barbour <[email protected]>
20  * Author: Cody Northrop <[email protected]>
21  * Author: Dave Houlton <[email protected]>
22  * Author: Jeremy Kniager <[email protected]>
23  * Author: Shannon McPherson <[email protected]>
24  * Author: John Zulauf <[email protected]>
25  */
26 
27 #include "cast_utils.h"
28 #include "layer_validation_tests.h"
29 
TEST_F(VkLayerTest,InvalidCommandPoolConsistency)30 TEST_F(VkLayerTest, InvalidCommandPoolConsistency) {
31     TEST_DESCRIPTION("Allocate command buffers from one command pool and attempt to delete them from another.");
32 
33     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkFreeCommandBuffers-pCommandBuffers-parent");
34 
35     ASSERT_NO_FATAL_FAILURE(Init());
36     VkCommandPool command_pool_one;
37     VkCommandPool command_pool_two;
38 
39     VkCommandPoolCreateInfo pool_create_info{};
40     pool_create_info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
41     pool_create_info.queueFamilyIndex = m_device->graphics_queue_node_index_;
42     pool_create_info.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT;
43 
44     vkCreateCommandPool(m_device->device(), &pool_create_info, nullptr, &command_pool_one);
45 
46     vkCreateCommandPool(m_device->device(), &pool_create_info, nullptr, &command_pool_two);
47 
48     VkCommandBuffer cb;
49     VkCommandBufferAllocateInfo command_buffer_allocate_info{};
50     command_buffer_allocate_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
51     command_buffer_allocate_info.commandPool = command_pool_one;
52     command_buffer_allocate_info.commandBufferCount = 1;
53     command_buffer_allocate_info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
54     vkAllocateCommandBuffers(m_device->device(), &command_buffer_allocate_info, &cb);
55 
56     vkFreeCommandBuffers(m_device->device(), command_pool_two, 1, &cb);
57 
58     m_errorMonitor->VerifyFound();
59 
60     vkDestroyCommandPool(m_device->device(), command_pool_one, NULL);
61     vkDestroyCommandPool(m_device->device(), command_pool_two, NULL);
62 }
63 
TEST_F(VkLayerTest,InvalidSecondaryCommandBufferBarrier)64 TEST_F(VkLayerTest, InvalidSecondaryCommandBufferBarrier) {
65     TEST_DESCRIPTION("Add an invalid image barrier in a secondary command buffer");
66     ASSERT_NO_FATAL_FAILURE(Init());
67 
68     // A renderpass with a single subpass that declared a self-dependency
69     VkAttachmentDescription attach[] = {
70         {0, VK_FORMAT_R8G8B8A8_UNORM, VK_SAMPLE_COUNT_1_BIT, VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE,
71          VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE, VK_IMAGE_LAYOUT_UNDEFINED,
72          VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL},
73     };
74     VkAttachmentReference ref = {0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL};
75     VkSubpassDescription subpasses[] = {
76         {0, VK_PIPELINE_BIND_POINT_GRAPHICS, 0, nullptr, 1, &ref, nullptr, nullptr, 0, nullptr},
77     };
78     VkSubpassDependency dep = {0,
79                                0,
80                                VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
81                                VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
82                                VK_ACCESS_SHADER_WRITE_BIT,
83                                VK_ACCESS_SHADER_WRITE_BIT,
84                                VK_DEPENDENCY_BY_REGION_BIT};
85     VkRenderPassCreateInfo rpci = {VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, nullptr, 0, 1, attach, 1, subpasses, 1, &dep};
86     VkRenderPass rp;
87 
88     VkResult err = vkCreateRenderPass(m_device->device(), &rpci, nullptr, &rp);
89     ASSERT_VK_SUCCESS(err);
90 
91     VkImageObj image(m_device);
92     image.Init(32, 32, 1, VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, VK_IMAGE_TILING_OPTIMAL, 0);
93     VkImageView imageView = image.targetView(VK_FORMAT_R8G8B8A8_UNORM);
94     // Second image that img_barrier will incorrectly use
95     VkImageObj image2(m_device);
96     image2.Init(32, 32, 1, VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, VK_IMAGE_TILING_OPTIMAL, 0);
97 
98     VkFramebufferCreateInfo fbci = {VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, nullptr, 0, rp, 1, &imageView, 32, 32, 1};
99     VkFramebuffer fb;
100     err = vkCreateFramebuffer(m_device->device(), &fbci, nullptr, &fb);
101     ASSERT_VK_SUCCESS(err);
102 
103     m_commandBuffer->begin();
104 
105     VkRenderPassBeginInfo rpbi = {VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,
106                                   nullptr,
107                                   rp,
108                                   fb,
109                                   {{
110                                        0,
111                                        0,
112                                    },
113                                    {32, 32}},
114                                   0,
115                                   nullptr};
116 
117     vkCmdBeginRenderPass(m_commandBuffer->handle(), &rpbi, VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS);
118 
119     VkCommandPoolObj pool(m_device, m_device->graphics_queue_node_index_, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT);
120     VkCommandBufferObj secondary(m_device, &pool, VK_COMMAND_BUFFER_LEVEL_SECONDARY);
121 
122     VkCommandBufferInheritanceInfo cbii = {VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO,
123                                            nullptr,
124                                            rp,
125                                            0,
126                                            VK_NULL_HANDLE,  // Set to NULL FB handle intentionally to flesh out any errors
127                                            VK_FALSE,
128                                            0,
129                                            0};
130     VkCommandBufferBeginInfo cbbi = {VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, nullptr,
131                                      VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT | VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT,
132                                      &cbii};
133     vkBeginCommandBuffer(secondary.handle(), &cbbi);
134     VkImageMemoryBarrier img_barrier = {};
135     img_barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
136     img_barrier.srcAccessMask = VK_ACCESS_SHADER_WRITE_BIT;
137     img_barrier.dstAccessMask = VK_ACCESS_SHADER_WRITE_BIT;
138     img_barrier.oldLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
139     img_barrier.newLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
140     img_barrier.image = image2.handle();  // Image mis-matches with FB image
141     img_barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
142     img_barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
143     img_barrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
144     img_barrier.subresourceRange.baseArrayLayer = 0;
145     img_barrier.subresourceRange.baseMipLevel = 0;
146     img_barrier.subresourceRange.layerCount = 1;
147     img_barrier.subresourceRange.levelCount = 1;
148     vkCmdPipelineBarrier(secondary.handle(), VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
149                          VK_DEPENDENCY_BY_REGION_BIT, 0, nullptr, 0, nullptr, 1, &img_barrier);
150     secondary.end();
151 
152     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdPipelineBarrier-image-02635");
153     vkCmdExecuteCommands(m_commandBuffer->handle(), 1, &secondary.handle());
154     m_errorMonitor->VerifyFound();
155 
156     vkDestroyFramebuffer(m_device->device(), fb, nullptr);
157     vkDestroyRenderPass(m_device->device(), rp, nullptr);
158 }
159 
TEST_F(VkLayerTest,DynamicDepthBiasNotBound)160 TEST_F(VkLayerTest, DynamicDepthBiasNotBound) {
161     TEST_DESCRIPTION(
162         "Run a simple draw calls to validate failure when Depth Bias dynamic state is required but not correctly bound.");
163 
164     ASSERT_NO_FATAL_FAILURE(Init());
165     // Dynamic depth bias
166     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Dynamic depth bias state not set for this command buffer");
167     VKTriangleTest(BsoFailDepthBias);
168     m_errorMonitor->VerifyFound();
169 }
170 
TEST_F(VkLayerTest,DynamicLineWidthNotBound)171 TEST_F(VkLayerTest, DynamicLineWidthNotBound) {
172     TEST_DESCRIPTION(
173         "Run a simple draw calls to validate failure when Line Width dynamic state is required but not correctly bound.");
174 
175     ASSERT_NO_FATAL_FAILURE(Init());
176     // Dynamic line width
177     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Dynamic line width state not set for this command buffer");
178     VKTriangleTest(BsoFailLineWidth);
179     m_errorMonitor->VerifyFound();
180 }
181 
TEST_F(VkLayerTest,DynamicLineStippleNotBound)182 TEST_F(VkLayerTest, DynamicLineStippleNotBound) {
183     TEST_DESCRIPTION(
184         "Run a simple draw calls to validate failure when Line Stipple dynamic state is required but not correctly bound.");
185 
186     if (InstanceExtensionSupported(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME)) {
187         m_instance_extension_names.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
188     } else {
189         printf("%s Did not find required instance extension %s; skipped.\n", kSkipPrefix,
190                VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
191         return;
192     }
193     ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor));
194     std::array<const char *, 1> required_device_extensions = {{VK_EXT_LINE_RASTERIZATION_EXTENSION_NAME}};
195     for (auto device_extension : required_device_extensions) {
196         if (DeviceExtensionSupported(gpu(), nullptr, device_extension)) {
197             m_device_extension_names.push_back(device_extension);
198         } else {
199             printf("%s %s Extension not supported, skipping tests\n", kSkipPrefix, device_extension);
200             return;
201         }
202     }
203 
204     PFN_vkGetPhysicalDeviceFeatures2KHR vkGetPhysicalDeviceFeatures2KHR =
205         (PFN_vkGetPhysicalDeviceFeatures2KHR)vkGetInstanceProcAddr(instance(), "vkGetPhysicalDeviceFeatures2KHR");
206     ASSERT_TRUE(vkGetPhysicalDeviceFeatures2KHR != nullptr);
207 
208     auto line_rasterization_features = lvl_init_struct<VkPhysicalDeviceLineRasterizationFeaturesEXT>();
209     auto features2 = lvl_init_struct<VkPhysicalDeviceFeatures2KHR>(&line_rasterization_features);
210     vkGetPhysicalDeviceFeatures2KHR(gpu(), &features2);
211 
212     if (!line_rasterization_features.stippledBresenhamLines || !line_rasterization_features.bresenhamLines) {
213         printf("%sStipple Bresenham lines not supported; skipped.\n", kSkipPrefix);
214         return;
215     }
216 
217     ASSERT_NO_FATAL_FAILURE(InitState(nullptr, &features2, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT));
218 
219     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
220                                          "Dynamic line stipple state not set for this command buffer");
221     VKTriangleTest(BsoFailLineStipple);
222     m_errorMonitor->VerifyFound();
223 }
224 
TEST_F(VkLayerTest,DynamicViewportNotBound)225 TEST_F(VkLayerTest, DynamicViewportNotBound) {
226     TEST_DESCRIPTION(
227         "Run a simple draw calls to validate failure when Viewport dynamic state is required but not correctly bound.");
228 
229     ASSERT_NO_FATAL_FAILURE(Init());
230     // Dynamic viewport state
231     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
232                                          "Dynamic viewport(s) 0 are used by pipeline state object, but were not provided");
233     VKTriangleTest(BsoFailViewport);
234     m_errorMonitor->VerifyFound();
235 }
236 
TEST_F(VkLayerTest,DynamicScissorNotBound)237 TEST_F(VkLayerTest, DynamicScissorNotBound) {
238     TEST_DESCRIPTION("Run a simple draw calls to validate failure when Scissor dynamic state is required but not correctly bound.");
239 
240     ASSERT_NO_FATAL_FAILURE(Init());
241     // Dynamic scissor state
242     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
243                                          "Dynamic scissor(s) 0 are used by pipeline state object, but were not provided");
244     VKTriangleTest(BsoFailScissor);
245     m_errorMonitor->VerifyFound();
246 }
247 
TEST_F(VkLayerTest,DynamicBlendConstantsNotBound)248 TEST_F(VkLayerTest, DynamicBlendConstantsNotBound) {
249     TEST_DESCRIPTION(
250         "Run a simple draw calls to validate failure when Blend Constants dynamic state is required but not correctly bound.");
251 
252     ASSERT_NO_FATAL_FAILURE(Init());
253     // Dynamic blend constant state
254     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
255                                          "Dynamic blend constants state not set for this command buffer");
256     VKTriangleTest(BsoFailBlend);
257     m_errorMonitor->VerifyFound();
258 }
259 
TEST_F(VkLayerTest,DynamicDepthBoundsNotBound)260 TEST_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
270     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
271                                          "Dynamic depth bounds state not set for this command buffer");
272     VKTriangleTest(BsoFailDepthBounds);
273     m_errorMonitor->VerifyFound();
274 }
275 
TEST_F(VkLayerTest,DynamicStencilReadNotBound)276 TEST_F(VkLayerTest, DynamicStencilReadNotBound) {
277     TEST_DESCRIPTION(
278         "Run a simple draw calls to validate failure when Stencil Read dynamic state is required but not correctly bound.");
279 
280     ASSERT_NO_FATAL_FAILURE(Init());
281     // Dynamic stencil read mask
282     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
283                                          "Dynamic stencil read mask state not set for this command buffer");
284     VKTriangleTest(BsoFailStencilReadMask);
285     m_errorMonitor->VerifyFound();
286 }
287 
TEST_F(VkLayerTest,DynamicStencilWriteNotBound)288 TEST_F(VkLayerTest, DynamicStencilWriteNotBound) {
289     TEST_DESCRIPTION(
290         "Run a simple draw calls to validate failure when Stencil Write dynamic state is required but not correctly bound.");
291 
292     ASSERT_NO_FATAL_FAILURE(Init());
293     // Dynamic stencil write mask
294     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
295                                          "Dynamic stencil write mask state not set for this command buffer");
296     VKTriangleTest(BsoFailStencilWriteMask);
297     m_errorMonitor->VerifyFound();
298 }
299 
TEST_F(VkLayerTest,DynamicStencilRefNotBound)300 TEST_F(VkLayerTest, DynamicStencilRefNotBound) {
301     TEST_DESCRIPTION(
302         "Run a simple draw calls to validate failure when Stencil Ref dynamic state is required but not correctly bound.");
303 
304     ASSERT_NO_FATAL_FAILURE(Init());
305     // Dynamic stencil reference
306     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
307                                          "Dynamic stencil reference state not set for this command buffer");
308     VKTriangleTest(BsoFailStencilReference);
309     m_errorMonitor->VerifyFound();
310 }
311 
TEST_F(VkLayerTest,IndexBufferNotBound)312 TEST_F(VkLayerTest, IndexBufferNotBound) {
313     TEST_DESCRIPTION("Run an indexed draw call without an index buffer bound.");
314 
315     ASSERT_NO_FATAL_FAILURE(Init());
316     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
317                                          "Index buffer object not bound to this command buffer when Indexed ");
318     VKTriangleTest(BsoFailIndexBuffer);
319     m_errorMonitor->VerifyFound();
320 }
321 
TEST_F(VkLayerTest,IndexBufferBadSize)322 TEST_F(VkLayerTest, IndexBufferBadSize) {
323     TEST_DESCRIPTION("Run indexed draw call with bad index buffer size.");
324 
325     ASSERT_NO_FATAL_FAILURE(Init(nullptr, nullptr, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT));
326     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "vkCmdDrawIndexed() index size ");
327     VKTriangleTest(BsoFailIndexBufferBadSize);
328     m_errorMonitor->VerifyFound();
329 }
330 
TEST_F(VkLayerTest,IndexBufferBadOffset)331 TEST_F(VkLayerTest, IndexBufferBadOffset) {
332     TEST_DESCRIPTION("Run indexed draw call with bad index buffer offset.");
333 
334     ASSERT_NO_FATAL_FAILURE(Init(nullptr, nullptr, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT));
335     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "vkCmdDrawIndexed() index size ");
336     VKTriangleTest(BsoFailIndexBufferBadOffset);
337     m_errorMonitor->VerifyFound();
338 }
339 
TEST_F(VkLayerTest,IndexBufferBadBindSize)340 TEST_F(VkLayerTest, IndexBufferBadBindSize) {
341     TEST_DESCRIPTION("Run bind index buffer with a size greater than the index buffer.");
342 
343     ASSERT_NO_FATAL_FAILURE(Init(nullptr, nullptr, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT));
344     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "vkCmdDrawIndexed() index size ");
345     VKTriangleTest(BsoFailIndexBufferBadMapSize);
346     m_errorMonitor->VerifyFound();
347 }
348 
TEST_F(VkLayerTest,IndexBufferBadBindOffset)349 TEST_F(VkLayerTest, IndexBufferBadBindOffset) {
350     TEST_DESCRIPTION("Run bind index buffer with an offset greater than the size of the index buffer.");
351 
352     ASSERT_NO_FATAL_FAILURE(Init(nullptr, nullptr, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT));
353     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "vkCmdDrawIndexed() index size ");
354     VKTriangleTest(BsoFailIndexBufferBadMapOffset);
355     m_errorMonitor->VerifyFound();
356 }
357 
TEST_F(VkLayerTest,MissingClearAttachment)358 TEST_F(VkLayerTest, MissingClearAttachment) {
359     TEST_DESCRIPTION("Points to a wrong colorAttachment index in a VkClearAttachment structure passed to vkCmdClearAttachments");
360     ASSERT_NO_FATAL_FAILURE(Init());
361     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdClearAttachments-aspectMask-02501");
362 
363     VKTriangleTest(BsoFailCmdClearAttachments);
364     m_errorMonitor->VerifyFound();
365 }
366 
TEST_F(VkLayerTest,CommandBufferTwoSubmits)367 TEST_F(VkLayerTest, CommandBufferTwoSubmits) {
368     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
369                                          "was begun w/ VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT set, but has been submitted");
370 
371     ASSERT_NO_FATAL_FAILURE(Init());
372     ASSERT_NO_FATAL_FAILURE(InitViewport());
373     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
374 
375     // We luck out b/c by default the framework creates CB w/ the
376     // VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT set
377     m_commandBuffer->begin();
378     m_commandBuffer->ClearAllBuffers(m_renderTargets, m_clear_color, nullptr, m_depth_clear_color, m_stencil_clear_color);
379     m_commandBuffer->end();
380 
381     // Bypass framework since it does the waits automatically
382     VkResult err = VK_SUCCESS;
383     VkSubmitInfo submit_info;
384     submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
385     submit_info.pNext = NULL;
386     submit_info.waitSemaphoreCount = 0;
387     submit_info.pWaitSemaphores = NULL;
388     submit_info.pWaitDstStageMask = NULL;
389     submit_info.commandBufferCount = 1;
390     submit_info.pCommandBuffers = &m_commandBuffer->handle();
391     submit_info.signalSemaphoreCount = 0;
392     submit_info.pSignalSemaphores = NULL;
393 
394     err = vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
395     ASSERT_VK_SUCCESS(err);
396     vkQueueWaitIdle(m_device->m_queue);
397 
398     // Cause validation error by re-submitting cmd buffer that should only be
399     // submitted once
400     err = vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
401     vkQueueWaitIdle(m_device->m_queue);
402 
403     m_errorMonitor->VerifyFound();
404 }
405 
TEST_F(VkLayerTest,InvalidPushConstants)406 TEST_F(VkLayerTest, InvalidPushConstants) {
407     ASSERT_NO_FATAL_FAILURE(Init());
408     ASSERT_NO_FATAL_FAILURE(InitViewport());
409     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
410 
411     VkPipelineLayout pipeline_layout;
412     VkPushConstantRange pc_range = {};
413     VkPipelineLayoutCreateInfo pipeline_layout_ci = {};
414     pipeline_layout_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
415     pipeline_layout_ci.pushConstantRangeCount = 1;
416     pipeline_layout_ci.pPushConstantRanges = &pc_range;
417 
418     //
419     // Check for invalid push constant ranges in pipeline layouts.
420     //
421     struct PipelineLayoutTestCase {
422         VkPushConstantRange const range;
423         char const *msg;
424     };
425 
426     const uint32_t too_big = m_device->props.limits.maxPushConstantsSize + 0x4;
427     const std::array<PipelineLayoutTestCase, 10> range_tests = {{
428         {{VK_SHADER_STAGE_VERTEX_BIT, 0, 0}, "vkCreatePipelineLayout() call has push constants index 0 with size 0."},
429         {{VK_SHADER_STAGE_VERTEX_BIT, 0, 1}, "vkCreatePipelineLayout() call has push constants index 0 with size 1."},
430         {{VK_SHADER_STAGE_VERTEX_BIT, 4, 1}, "vkCreatePipelineLayout() call has push constants index 0 with size 1."},
431         {{VK_SHADER_STAGE_VERTEX_BIT, 4, 0}, "vkCreatePipelineLayout() call has push constants index 0 with size 0."},
432         {{VK_SHADER_STAGE_VERTEX_BIT, 1, 4}, "vkCreatePipelineLayout() call has push constants index 0 with offset 1. Offset must"},
433         {{VK_SHADER_STAGE_VERTEX_BIT, 0, too_big}, "vkCreatePipelineLayout() call has push constants index 0 with offset "},
434         {{VK_SHADER_STAGE_VERTEX_BIT, too_big, too_big}, "vkCreatePipelineLayout() call has push constants index 0 with offset "},
435         {{VK_SHADER_STAGE_VERTEX_BIT, too_big, 4}, "vkCreatePipelineLayout() call has push constants index 0 with offset "},
436         {{VK_SHADER_STAGE_VERTEX_BIT, 0xFFFFFFF0, 0x00000020},
437          "vkCreatePipelineLayout() call has push constants index 0 with offset "},
438         {{VK_SHADER_STAGE_VERTEX_BIT, 0x00000020, 0xFFFFFFF0},
439          "vkCreatePipelineLayout() call has push constants index 0 with offset "},
440     }};
441 
442     // Check for invalid offset and size
443     for (const auto &iter : range_tests) {
444         pc_range = iter.range;
445         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, iter.msg);
446         vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipeline_layout);
447         m_errorMonitor->VerifyFound();
448     }
449 
450     // Check for invalid stage flag
451     pc_range.offset = 0;
452     pc_range.size = 16;
453     pc_range.stageFlags = 0;
454     m_errorMonitor->SetDesiredFailureMsg(
455         VK_DEBUG_REPORT_ERROR_BIT_EXT,
456         "vkCreatePipelineLayout: value of pCreateInfo->pPushConstantRanges[0].stageFlags must not be 0");
457     vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipeline_layout);
458     m_errorMonitor->VerifyFound();
459 
460     // Check for duplicate stage flags in a list of push constant ranges.
461     // A shader can only have one push constant block and that block is mapped
462     // to the push constant range that has that shader's stage flag set.
463     // The shader's stage flag can only appear once in all the ranges, so the
464     // implementation can find the one and only range to map it to.
465     const uint32_t ranges_per_test = 5;
466     struct DuplicateStageFlagsTestCase {
467         VkPushConstantRange const ranges[ranges_per_test];
468         std::vector<char const *> const msg;
469     };
470     // Overlapping ranges are OK, but a stage flag can appear only once.
471     const std::array<DuplicateStageFlagsTestCase, 3> duplicate_stageFlags_tests = {
472         {
473             {{{VK_SHADER_STAGE_VERTEX_BIT, 0, 4},
474               {VK_SHADER_STAGE_VERTEX_BIT, 0, 4},
475               {VK_SHADER_STAGE_VERTEX_BIT, 0, 4},
476               {VK_SHADER_STAGE_VERTEX_BIT, 0, 4},
477               {VK_SHADER_STAGE_VERTEX_BIT, 0, 4}},
478              {
479                  "vkCreatePipelineLayout() Duplicate stage flags found in ranges 0 and 1.",
480                  "vkCreatePipelineLayout() Duplicate stage flags found in ranges 0 and 2.",
481                  "vkCreatePipelineLayout() Duplicate stage flags found in ranges 0 and 3.",
482                  "vkCreatePipelineLayout() Duplicate stage flags found in ranges 0 and 4.",
483                  "vkCreatePipelineLayout() Duplicate stage flags found in ranges 1 and 2.",
484                  "vkCreatePipelineLayout() Duplicate stage flags found in ranges 1 and 3.",
485                  "vkCreatePipelineLayout() Duplicate stage flags found in ranges 1 and 4.",
486                  "vkCreatePipelineLayout() Duplicate stage flags found in ranges 2 and 3.",
487                  "vkCreatePipelineLayout() Duplicate stage flags found in ranges 2 and 4.",
488                  "vkCreatePipelineLayout() Duplicate stage flags found in ranges 3 and 4.",
489              }},
490             {{{VK_SHADER_STAGE_VERTEX_BIT, 0, 4},
491               {VK_SHADER_STAGE_GEOMETRY_BIT, 0, 4},
492               {VK_SHADER_STAGE_FRAGMENT_BIT, 0, 4},
493               {VK_SHADER_STAGE_VERTEX_BIT, 0, 4},
494               {VK_SHADER_STAGE_GEOMETRY_BIT, 0, 4}},
495              {
496                  "vkCreatePipelineLayout() Duplicate stage flags found in ranges 0 and 3.",
497                  "vkCreatePipelineLayout() Duplicate stage flags found in ranges 1 and 4.",
498              }},
499             {{{VK_SHADER_STAGE_FRAGMENT_BIT, 0, 4},
500               {VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT, 0, 4},
501               {VK_SHADER_STAGE_VERTEX_BIT, 0, 4},
502               {VK_SHADER_STAGE_VERTEX_BIT, 0, 4},
503               {VK_SHADER_STAGE_GEOMETRY_BIT, 0, 4}},
504              {
505                  "vkCreatePipelineLayout() Duplicate stage flags found in ranges 2 and 3.",
506              }},
507         },
508     };
509 
510     for (const auto &iter : duplicate_stageFlags_tests) {
511         pipeline_layout_ci.pPushConstantRanges = iter.ranges;
512         pipeline_layout_ci.pushConstantRangeCount = ranges_per_test;
513         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, iter.msg.begin(), iter.msg.end());
514         vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipeline_layout);
515         m_errorMonitor->VerifyFound();
516     }
517 
518     //
519     // CmdPushConstants tests
520     //
521 
522     // Setup a pipeline layout with ranges: [0,32) [16,80)
523     const std::vector<VkPushConstantRange> pc_range2 = {{VK_SHADER_STAGE_VERTEX_BIT, 16, 64},
524                                                         {VK_SHADER_STAGE_FRAGMENT_BIT, 0, 32}};
525     const VkPipelineLayoutObj pipeline_layout_obj(m_device, {}, pc_range2);
526 
527     const uint8_t dummy_values[100] = {};
528 
529     m_commandBuffer->begin();
530     m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
531 
532     // Check for invalid stage flag
533     // Note that VU 00996 isn't reached due to parameter validation
534     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "vkCmdPushConstants: value of stageFlags must not be 0");
535     vkCmdPushConstants(m_commandBuffer->handle(), pipeline_layout_obj.handle(), 0, 0, 16, dummy_values);
536     m_errorMonitor->VerifyFound();
537 
538     // Positive tests for the overlapping ranges
539     m_errorMonitor->ExpectSuccess();
540     vkCmdPushConstants(m_commandBuffer->handle(), pipeline_layout_obj.handle(), VK_SHADER_STAGE_FRAGMENT_BIT, 0, 16, dummy_values);
541     m_errorMonitor->VerifyNotFound();
542     m_errorMonitor->ExpectSuccess();
543     vkCmdPushConstants(m_commandBuffer->handle(), pipeline_layout_obj.handle(), VK_SHADER_STAGE_VERTEX_BIT, 32, 48, dummy_values);
544     m_errorMonitor->VerifyNotFound();
545     m_errorMonitor->ExpectSuccess();
546     vkCmdPushConstants(m_commandBuffer->handle(), pipeline_layout_obj.handle(),
547                        VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT, 16, 16, dummy_values);
548     m_errorMonitor->VerifyNotFound();
549 
550     // Wrong cmd stages for extant range
551     // No range for all cmd stages -- "VUID-vkCmdPushConstants-offset-01795" VUID-vkCmdPushConstants-offset-01795
552     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdPushConstants-offset-01795");
553     // Missing cmd stages for found overlapping range -- "VUID-vkCmdPushConstants-offset-01796" VUID-vkCmdPushConstants-offset-01796
554     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdPushConstants-offset-01796");
555     vkCmdPushConstants(m_commandBuffer->handle(), pipeline_layout_obj.handle(), VK_SHADER_STAGE_GEOMETRY_BIT, 0, 16, dummy_values);
556     m_errorMonitor->VerifyFound();
557 
558     // Wrong no extant range
559     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdPushConstants-offset-01795");
560     vkCmdPushConstants(m_commandBuffer->handle(), pipeline_layout_obj.handle(), VK_SHADER_STAGE_FRAGMENT_BIT, 80, 4, dummy_values);
561     m_errorMonitor->VerifyFound();
562 
563     // Wrong overlapping extent
564     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdPushConstants-offset-01795");
565     vkCmdPushConstants(m_commandBuffer->handle(), pipeline_layout_obj.handle(),
566                        VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT, 0, 20, dummy_values);
567     m_errorMonitor->VerifyFound();
568 
569     // Wrong stage flags for valid overlapping range
570     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdPushConstants-offset-01796");
571     vkCmdPushConstants(m_commandBuffer->handle(), pipeline_layout_obj.handle(), VK_SHADER_STAGE_VERTEX_BIT, 16, 16, dummy_values);
572     m_errorMonitor->VerifyFound();
573 
574     m_commandBuffer->EndRenderPass();
575     m_commandBuffer->end();
576 }
577 
TEST_F(VkLayerTest,NoBeginCommandBuffer)578 TEST_F(VkLayerTest, NoBeginCommandBuffer) {
579     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
580                                          "You must call vkBeginCommandBuffer() before this call to ");
581 
582     ASSERT_NO_FATAL_FAILURE(Init());
583     VkCommandBufferObj commandBuffer(m_device, m_commandPool);
584     // Call EndCommandBuffer() w/o calling BeginCommandBuffer()
585     vkEndCommandBuffer(commandBuffer.handle());
586 
587     m_errorMonitor->VerifyFound();
588 }
589 
TEST_F(VkLayerTest,SecondaryCommandBufferNullRenderpass)590 TEST_F(VkLayerTest, SecondaryCommandBufferNullRenderpass) {
591     ASSERT_NO_FATAL_FAILURE(Init());
592 
593     VkCommandBufferObj cb(m_device, m_commandPool, VK_COMMAND_BUFFER_LEVEL_SECONDARY);
594 
595     // Force the failure by not setting the Renderpass and Framebuffer fields
596     VkCommandBufferInheritanceInfo cmd_buf_hinfo = {};
597     cmd_buf_hinfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO;
598 
599     VkCommandBufferBeginInfo cmd_buf_info = {};
600     cmd_buf_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
601     cmd_buf_info.pNext = NULL;
602     cmd_buf_info.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT | VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT;
603     cmd_buf_info.pInheritanceInfo = &cmd_buf_hinfo;
604 
605     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkCommandBufferBeginInfo-flags-00053");
606     vkBeginCommandBuffer(cb.handle(), &cmd_buf_info);
607     m_errorMonitor->VerifyFound();
608 }
609 
TEST_F(VkLayerTest,SecondaryCommandBufferRerecordedExplicitReset)610 TEST_F(VkLayerTest, SecondaryCommandBufferRerecordedExplicitReset) {
611     ASSERT_NO_FATAL_FAILURE(Init());
612 
613     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "was destroyed or rerecorded");
614 
615     // A pool we can reset in.
616     VkCommandPoolObj pool(m_device, m_device->graphics_queue_node_index_, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT);
617     VkCommandBufferObj secondary(m_device, &pool, VK_COMMAND_BUFFER_LEVEL_SECONDARY);
618 
619     secondary.begin();
620     secondary.end();
621 
622     m_commandBuffer->begin();
623     vkCmdExecuteCommands(m_commandBuffer->handle(), 1, &secondary.handle());
624 
625     // rerecording of secondary
626     secondary.reset();  // explicit reset here.
627     secondary.begin();
628     secondary.end();
629 
630     vkCmdExecuteCommands(m_commandBuffer->handle(), 1, &secondary.handle());
631     m_errorMonitor->VerifyFound();
632 }
633 
TEST_F(VkLayerTest,SecondaryCommandBufferRerecordedNoReset)634 TEST_F(VkLayerTest, SecondaryCommandBufferRerecordedNoReset) {
635     ASSERT_NO_FATAL_FAILURE(Init());
636 
637     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "was destroyed or rerecorded");
638 
639     // A pool we can reset in.
640     VkCommandPoolObj pool(m_device, m_device->graphics_queue_node_index_, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT);
641     VkCommandBufferObj secondary(m_device, &pool, VK_COMMAND_BUFFER_LEVEL_SECONDARY);
642 
643     secondary.begin();
644     secondary.end();
645 
646     m_commandBuffer->begin();
647     vkCmdExecuteCommands(m_commandBuffer->handle(), 1, &secondary.handle());
648 
649     // rerecording of secondary
650     secondary.begin();  // implicit reset in begin
651     secondary.end();
652 
653     vkCmdExecuteCommands(m_commandBuffer->handle(), 1, &secondary.handle());
654     m_errorMonitor->VerifyFound();
655 }
656 
TEST_F(VkLayerTest,CascadedInvalidation)657 TEST_F(VkLayerTest, CascadedInvalidation) {
658     ASSERT_NO_FATAL_FAILURE(Init());
659 
660     VkEventCreateInfo eci = {VK_STRUCTURE_TYPE_EVENT_CREATE_INFO, nullptr, 0};
661     VkEvent event;
662     vkCreateEvent(m_device->device(), &eci, nullptr, &event);
663 
664     VkCommandBufferObj secondary(m_device, m_commandPool, VK_COMMAND_BUFFER_LEVEL_SECONDARY);
665     secondary.begin();
666     vkCmdSetEvent(secondary.handle(), event, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT);
667     secondary.end();
668 
669     m_commandBuffer->begin();
670     vkCmdExecuteCommands(m_commandBuffer->handle(), 1, &secondary.handle());
671     m_commandBuffer->end();
672 
673     // destroying the event should invalidate both primary and secondary CB
674     vkDestroyEvent(m_device->device(), event, nullptr);
675 
676     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
677                                          "UNASSIGNED-CoreValidation-DrawState-InvalidCommandBuffer-VkEvent");
678     m_commandBuffer->QueueCommandBuffer(false);
679     m_errorMonitor->VerifyFound();
680 }
681 
TEST_F(VkLayerTest,CommandBufferResetErrors)682 TEST_F(VkLayerTest, CommandBufferResetErrors) {
683     // Cause error due to Begin while recording CB
684     // Then cause 2 errors for attempting to reset CB w/o having
685     // VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT set for the pool from
686     // which CBs were allocated. Note that this bit is off by default.
687     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkBeginCommandBuffer-commandBuffer-00049");
688 
689     ASSERT_NO_FATAL_FAILURE(Init());
690 
691     // Calls AllocateCommandBuffers
692     VkCommandBufferObj commandBuffer(m_device, m_commandPool);
693 
694     // Force the failure by setting the Renderpass and Framebuffer fields with (fake) data
695     VkCommandBufferInheritanceInfo cmd_buf_hinfo = {};
696     cmd_buf_hinfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO;
697     VkCommandBufferBeginInfo cmd_buf_info = {};
698     cmd_buf_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
699     cmd_buf_info.pNext = NULL;
700     cmd_buf_info.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT;
701     cmd_buf_info.pInheritanceInfo = &cmd_buf_hinfo;
702 
703     // Begin CB to transition to recording state
704     vkBeginCommandBuffer(commandBuffer.handle(), &cmd_buf_info);
705     // Can't re-begin. This should trigger error
706     vkBeginCommandBuffer(commandBuffer.handle(), &cmd_buf_info);
707     m_errorMonitor->VerifyFound();
708 
709     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkResetCommandBuffer-commandBuffer-00046");
710     VkCommandBufferResetFlags flags = 0;  // Don't care about flags for this test
711     // Reset attempt will trigger error due to incorrect CommandPool state
712     vkResetCommandBuffer(commandBuffer.handle(), flags);
713     m_errorMonitor->VerifyFound();
714 
715     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkBeginCommandBuffer-commandBuffer-00050");
716     // Transition CB to RECORDED state
717     vkEndCommandBuffer(commandBuffer.handle());
718     // Now attempting to Begin will implicitly reset, which triggers error
719     vkBeginCommandBuffer(commandBuffer.handle(), &cmd_buf_info);
720     m_errorMonitor->VerifyFound();
721 }
722 
TEST_F(VkLayerTest,ClearColorAttachmentsOutsideRenderPass)723 TEST_F(VkLayerTest, ClearColorAttachmentsOutsideRenderPass) {
724     // Call CmdClearAttachmentss outside of an active RenderPass
725 
726     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
727                                          "vkCmdClearAttachments(): This call must be issued inside an active render pass");
728 
729     ASSERT_NO_FATAL_FAILURE(Init());
730     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
731 
732     // Start no RenderPass
733     m_commandBuffer->begin();
734 
735     VkClearAttachment color_attachment;
736     color_attachment.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
737     color_attachment.clearValue.color.float32[0] = 0;
738     color_attachment.clearValue.color.float32[1] = 0;
739     color_attachment.clearValue.color.float32[2] = 0;
740     color_attachment.clearValue.color.float32[3] = 0;
741     color_attachment.colorAttachment = 0;
742     VkClearRect clear_rect = {{{0, 0}, {32, 32}}, 0, 1};
743     vkCmdClearAttachments(m_commandBuffer->handle(), 1, &color_attachment, 1, &clear_rect);
744 
745     m_errorMonitor->VerifyFound();
746 }
747 
TEST_F(VkLayerTest,ClearColorAttachmentsZeroLayercount)748 TEST_F(VkLayerTest, ClearColorAttachmentsZeroLayercount) {
749     TEST_DESCRIPTION("Call CmdClearAttachments with a pRect having a layerCount of zero.");
750 
751     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdClearAttachments-layerCount-01934");
752 
753     ASSERT_NO_FATAL_FAILURE(Init());
754     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
755 
756     m_commandBuffer->begin();
757     vkCmdBeginRenderPass(m_commandBuffer->handle(), &renderPassBeginInfo(), VK_SUBPASS_CONTENTS_INLINE);
758 
759     VkClearAttachment color_attachment;
760     color_attachment.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
761     color_attachment.clearValue.color.float32[0] = 0;
762     color_attachment.clearValue.color.float32[1] = 0;
763     color_attachment.clearValue.color.float32[2] = 0;
764     color_attachment.clearValue.color.float32[3] = 0;
765     color_attachment.colorAttachment = 0;
766     VkClearRect clear_rect = {{{0, 0}, {32, 32}}};
767     vkCmdClearAttachments(m_commandBuffer->handle(), 1, &color_attachment, 1, &clear_rect);
768 
769     m_errorMonitor->VerifyFound();
770 }
771 
TEST_F(VkLayerTest,ExecuteCommandsPrimaryCB)772 TEST_F(VkLayerTest, ExecuteCommandsPrimaryCB) {
773     TEST_DESCRIPTION("Attempt vkCmdExecuteCommands with a primary command buffer (should only be secondary)");
774 
775     ASSERT_NO_FATAL_FAILURE(Init());
776     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
777 
778     // An empty primary command buffer
779     VkCommandBufferObj cb(m_device, m_commandPool);
780     cb.begin();
781     cb.end();
782 
783     m_commandBuffer->begin();
784     vkCmdBeginRenderPass(m_commandBuffer->handle(), &renderPassBeginInfo(), VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS);
785     VkCommandBuffer handle = cb.handle();
786 
787     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdExecuteCommands-pCommandBuffers-00088");
788     vkCmdExecuteCommands(m_commandBuffer->handle(), 1, &handle);
789     m_errorMonitor->VerifyFound();
790 
791     m_errorMonitor->SetUnexpectedError("All elements of pCommandBuffers must not be in the pending state");
792 
793     m_commandBuffer->EndRenderPass();
794     m_commandBuffer->end();
795 }
796 
TEST_F(VkLayerTest,InvalidVertexAttributeAlignment)797 TEST_F(VkLayerTest, InvalidVertexAttributeAlignment) {
798     TEST_DESCRIPTION("Check for proper aligment of attribAddress which depends on a bound pipeline and on a bound vertex buffer");
799 
800     ASSERT_NO_FATAL_FAILURE(Init());
801     ASSERT_NO_FATAL_FAILURE(InitViewport());
802     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
803 
804     const VkPipelineLayoutObj pipeline_layout(m_device);
805 
806     struct VboEntry {
807         uint16_t input0[2];
808         uint32_t input1;
809         float input2[4];
810     };
811 
812     const unsigned vbo_entry_count = 3;
813     const VboEntry vbo_data[vbo_entry_count] = {};
814 
815     VkConstantBufferObj vbo(m_device, static_cast<int>(sizeof(VboEntry) * vbo_entry_count),
816                             reinterpret_cast<const void *>(vbo_data), VK_BUFFER_USAGE_VERTEX_BUFFER_BIT);
817 
818     VkVertexInputBindingDescription input_binding;
819     input_binding.binding = 0;
820     input_binding.stride = sizeof(VboEntry);
821     input_binding.inputRate = VK_VERTEX_INPUT_RATE_VERTEX;
822 
823     VkVertexInputAttributeDescription input_attribs[3];
824 
825     input_attribs[0].binding = 0;
826     // Location switch between attrib[0] and attrib[1] is intentional
827     input_attribs[0].location = 1;
828     input_attribs[0].format = VK_FORMAT_A8B8G8R8_UNORM_PACK32;
829     input_attribs[0].offset = offsetof(VboEntry, input1);
830 
831     input_attribs[1].binding = 0;
832     input_attribs[1].location = 0;
833     input_attribs[1].format = VK_FORMAT_R16G16_UNORM;
834     input_attribs[1].offset = offsetof(VboEntry, input0);
835 
836     input_attribs[2].binding = 0;
837     input_attribs[2].location = 2;
838     input_attribs[2].format = VK_FORMAT_R32G32B32A32_SFLOAT;
839     input_attribs[2].offset = offsetof(VboEntry, input2);
840 
841     char const *vsSource =
842         "#version 450\n"
843         "\n"
844         "layout(location = 0) in vec2 input0;"
845         "layout(location = 1) in vec4 input1;"
846         "layout(location = 2) in vec4 input2;"
847         "\n"
848         "void main(){\n"
849         "   gl_Position = input1 + input2;\n"
850         "   gl_Position.xy += input0;\n"
851         "}\n";
852 
853     VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
854     VkShaderObj fs(m_device, bindStateFragShaderText, VK_SHADER_STAGE_FRAGMENT_BIT, this);
855 
856     VkPipelineObj pipe1(m_device);
857     pipe1.AddDefaultColorAttachment();
858     pipe1.AddShader(&vs);
859     pipe1.AddShader(&fs);
860     pipe1.AddVertexInputBindings(&input_binding, 1);
861     pipe1.AddVertexInputAttribs(&input_attribs[0], 3);
862     pipe1.SetViewport(m_viewports);
863     pipe1.SetScissor(m_scissors);
864     pipe1.CreateVKPipeline(pipeline_layout.handle(), renderPass());
865 
866     input_binding.stride = 6;
867 
868     VkPipelineObj pipe2(m_device);
869     pipe2.AddDefaultColorAttachment();
870     pipe2.AddShader(&vs);
871     pipe2.AddShader(&fs);
872     pipe2.AddVertexInputBindings(&input_binding, 1);
873     pipe2.AddVertexInputAttribs(&input_attribs[0], 3);
874     pipe2.SetViewport(m_viewports);
875     pipe2.SetScissor(m_scissors);
876     pipe2.CreateVKPipeline(pipeline_layout.handle(), renderPass());
877 
878     m_commandBuffer->begin();
879     m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
880 
881     // Test with invalid buffer offset
882     VkDeviceSize offset = 1;
883     vkCmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe1.handle());
884     vkCmdBindVertexBuffers(m_commandBuffer->handle(), 0, 1, &vbo.handle(), &offset);
885     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Invalid attribAddress alignment for vertex attribute 0");
886     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Invalid attribAddress alignment for vertex attribute 1");
887     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Invalid attribAddress alignment for vertex attribute 2");
888     m_commandBuffer->Draw(1, 0, 0, 0);
889     m_errorMonitor->VerifyFound();
890 
891     // Test with invalid buffer stride
892     offset = 0;
893     vkCmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe2.handle());
894     vkCmdBindVertexBuffers(m_commandBuffer->handle(), 0, 1, &vbo.handle(), &offset);
895     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Invalid attribAddress alignment for vertex attribute 0");
896     // Attribute[1] is aligned properly even with a wrong stride
897     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Invalid attribAddress alignment for vertex attribute 2");
898     m_commandBuffer->Draw(1, 0, 0, 0);
899     m_errorMonitor->VerifyFound();
900 
901     m_commandBuffer->EndRenderPass();
902     m_commandBuffer->end();
903 }
904 
TEST_F(VkLayerTest,NonSimultaneousSecondaryMarksPrimary)905 TEST_F(VkLayerTest, NonSimultaneousSecondaryMarksPrimary) {
906     ASSERT_NO_FATAL_FAILURE(Init());
907     const char *simultaneous_use_message = "UNASSIGNED-CoreValidation-DrawState-InvalidCommandBufferSimultaneousUse";
908 
909     VkCommandBufferObj secondary(m_device, m_commandPool, VK_COMMAND_BUFFER_LEVEL_SECONDARY);
910 
911     secondary.begin();
912     secondary.end();
913 
914     VkCommandBufferBeginInfo cbbi = {
915         VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,
916         nullptr,
917         VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT,
918         nullptr,
919     };
920 
921     m_commandBuffer->begin(&cbbi);
922     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_WARNING_BIT_EXT, simultaneous_use_message);
923     vkCmdExecuteCommands(m_commandBuffer->handle(), 1, &secondary.handle());
924     m_errorMonitor->VerifyFound();
925     m_commandBuffer->end();
926 }
927 
TEST_F(VkLayerTest,SimultaneousUseSecondaryTwoExecutes)928 TEST_F(VkLayerTest, SimultaneousUseSecondaryTwoExecutes) {
929     ASSERT_NO_FATAL_FAILURE(Init());
930 
931     const char *simultaneous_use_message = "VUID-vkCmdExecuteCommands-pCommandBuffers-00092";
932 
933     VkCommandBufferObj secondary(m_device, m_commandPool, VK_COMMAND_BUFFER_LEVEL_SECONDARY);
934 
935     VkCommandBufferInheritanceInfo inh = {
936         VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO,
937         nullptr,
938     };
939     VkCommandBufferBeginInfo cbbi = {VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, nullptr, 0, &inh};
940 
941     secondary.begin(&cbbi);
942     secondary.end();
943 
944     m_commandBuffer->begin();
945     vkCmdExecuteCommands(m_commandBuffer->handle(), 1, &secondary.handle());
946     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, simultaneous_use_message);
947     vkCmdExecuteCommands(m_commandBuffer->handle(), 1, &secondary.handle());
948     m_errorMonitor->VerifyFound();
949     m_commandBuffer->end();
950 }
951 
TEST_F(VkLayerTest,SimultaneousUseSecondarySingleExecute)952 TEST_F(VkLayerTest, SimultaneousUseSecondarySingleExecute) {
953     ASSERT_NO_FATAL_FAILURE(Init());
954 
955     // variation on previous test executing the same CB twice in the same
956     // CmdExecuteCommands call
957 
958     const char *simultaneous_use_message = "VUID-vkCmdExecuteCommands-pCommandBuffers-00093";
959 
960     VkCommandBufferObj secondary(m_device, m_commandPool, VK_COMMAND_BUFFER_LEVEL_SECONDARY);
961 
962     VkCommandBufferInheritanceInfo inh = {
963         VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO,
964         nullptr,
965     };
966     VkCommandBufferBeginInfo cbbi = {VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, nullptr, 0, &inh};
967 
968     secondary.begin(&cbbi);
969     secondary.end();
970 
971     m_commandBuffer->begin();
972     VkCommandBuffer cbs[] = {secondary.handle(), secondary.handle()};
973     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, simultaneous_use_message);
974     vkCmdExecuteCommands(m_commandBuffer->handle(), 2, cbs);
975     m_errorMonitor->VerifyFound();
976     m_commandBuffer->end();
977 }
978 
TEST_F(VkLayerTest,SimultaneousUseOneShot)979 TEST_F(VkLayerTest, SimultaneousUseOneShot) {
980     TEST_DESCRIPTION("Submit the same command buffer twice in one submit looking for simultaneous use and one time submit errors");
981     const char *simultaneous_use_message = "is already in use and is not marked for simultaneous use";
982     const char *one_shot_message = "VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT set, but has been submitted";
983     ASSERT_NO_FATAL_FAILURE(Init());
984 
985     VkCommandBuffer cmd_bufs[2];
986     VkCommandBufferAllocateInfo alloc_info;
987     alloc_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
988     alloc_info.pNext = NULL;
989     alloc_info.commandBufferCount = 2;
990     alloc_info.commandPool = m_commandPool->handle();
991     alloc_info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
992     vkAllocateCommandBuffers(m_device->device(), &alloc_info, cmd_bufs);
993 
994     VkCommandBufferBeginInfo cb_binfo;
995     cb_binfo.pNext = NULL;
996     cb_binfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
997     cb_binfo.pInheritanceInfo = VK_NULL_HANDLE;
998     cb_binfo.flags = 0;
999     vkBeginCommandBuffer(cmd_bufs[0], &cb_binfo);
1000     VkViewport viewport = {0, 0, 16, 16, 0, 1};
1001     vkCmdSetViewport(cmd_bufs[0], 0, 1, &viewport);
1002     vkEndCommandBuffer(cmd_bufs[0]);
1003     VkCommandBuffer duplicates[2] = {cmd_bufs[0], cmd_bufs[0]};
1004 
1005     VkSubmitInfo submit_info = {};
1006     submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
1007     submit_info.commandBufferCount = 2;
1008     submit_info.pCommandBuffers = duplicates;
1009     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, simultaneous_use_message);
1010     vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
1011     m_errorMonitor->VerifyFound();
1012     vkQueueWaitIdle(m_device->m_queue);
1013 
1014     // Set one time use and now look for one time submit
1015     duplicates[0] = duplicates[1] = cmd_bufs[1];
1016     cb_binfo.flags = VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT | VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT;
1017     vkBeginCommandBuffer(cmd_bufs[1], &cb_binfo);
1018     vkCmdSetViewport(cmd_bufs[1], 0, 1, &viewport);
1019     vkEndCommandBuffer(cmd_bufs[1]);
1020     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, one_shot_message);
1021     vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
1022     m_errorMonitor->VerifyFound();
1023     vkQueueWaitIdle(m_device->m_queue);
1024 }
1025 
TEST_F(VkLayerTest,DrawTimeImageViewTypeMismatchWithPipeline)1026 TEST_F(VkLayerTest, DrawTimeImageViewTypeMismatchWithPipeline) {
1027     TEST_DESCRIPTION(
1028         "Test that an error is produced when an image view type does not match the dimensionality declared in the shader");
1029 
1030     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "requires an image view of type VK_IMAGE_VIEW_TYPE_3D");
1031 
1032     ASSERT_NO_FATAL_FAILURE(Init());
1033     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
1034 
1035     char const *fsSource =
1036         "#version 450\n"
1037         "\n"
1038         "layout(set=0, binding=0) uniform sampler3D s;\n"
1039         "layout(location=0) out vec4 color;\n"
1040         "void main() {\n"
1041         "   color = texture(s, vec3(0));\n"
1042         "}\n";
1043     VkShaderObj vs(m_device, bindStateVertShaderText, VK_SHADER_STAGE_VERTEX_BIT, this);
1044     VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
1045 
1046     VkPipelineObj pipe(m_device);
1047     pipe.AddShader(&vs);
1048     pipe.AddShader(&fs);
1049     pipe.AddDefaultColorAttachment();
1050 
1051     VkTextureObj texture(m_device, nullptr);
1052     VkSamplerObj sampler(m_device);
1053 
1054     VkDescriptorSetObj descriptorSet(m_device);
1055     descriptorSet.AppendSamplerTexture(&sampler, &texture);
1056     descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
1057 
1058     VkResult err = pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass());
1059     ASSERT_VK_SUCCESS(err);
1060 
1061     m_commandBuffer->begin();
1062     m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
1063 
1064     vkCmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.handle());
1065     m_commandBuffer->BindDescriptorSet(descriptorSet);
1066 
1067     VkViewport viewport = {0, 0, 16, 16, 0, 1};
1068     vkCmdSetViewport(m_commandBuffer->handle(), 0, 1, &viewport);
1069     VkRect2D scissor = {{0, 0}, {16, 16}};
1070     vkCmdSetScissor(m_commandBuffer->handle(), 0, 1, &scissor);
1071 
1072     // error produced here.
1073     vkCmdDraw(m_commandBuffer->handle(), 3, 1, 0, 0);
1074 
1075     m_errorMonitor->VerifyFound();
1076 
1077     m_commandBuffer->EndRenderPass();
1078     m_commandBuffer->end();
1079 }
1080 
TEST_F(VkLayerTest,DrawTimeImageMultisampleMismatchWithPipeline)1081 TEST_F(VkLayerTest, DrawTimeImageMultisampleMismatchWithPipeline) {
1082     TEST_DESCRIPTION(
1083         "Test that an error is produced when a multisampled images are consumed via singlesample images types in the shader, or "
1084         "vice versa.");
1085 
1086     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "requires bound image to have multiple samples");
1087 
1088     ASSERT_NO_FATAL_FAILURE(Init());
1089     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
1090 
1091     char const *fsSource =
1092         "#version 450\n"
1093         "\n"
1094         "layout(set=0, binding=0) uniform sampler2DMS s;\n"
1095         "layout(location=0) out vec4 color;\n"
1096         "void main() {\n"
1097         "   color = texelFetch(s, ivec2(0), 0);\n"
1098         "}\n";
1099     VkShaderObj vs(m_device, bindStateVertShaderText, VK_SHADER_STAGE_VERTEX_BIT, this);
1100     VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
1101 
1102     VkPipelineObj pipe(m_device);
1103     pipe.AddShader(&vs);
1104     pipe.AddShader(&fs);
1105     pipe.AddDefaultColorAttachment();
1106 
1107     VkTextureObj texture(m_device, nullptr);  // THIS LINE CAUSES CRASH ON MALI
1108     VkSamplerObj sampler(m_device);
1109 
1110     VkDescriptorSetObj descriptorSet(m_device);
1111     descriptorSet.AppendSamplerTexture(&sampler, &texture);
1112     descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
1113 
1114     VkResult err = pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass());
1115     ASSERT_VK_SUCCESS(err);
1116 
1117     m_commandBuffer->begin();
1118     m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
1119 
1120     vkCmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.handle());
1121     m_commandBuffer->BindDescriptorSet(descriptorSet);
1122 
1123     VkViewport viewport = {0, 0, 16, 16, 0, 1};
1124     vkCmdSetViewport(m_commandBuffer->handle(), 0, 1, &viewport);
1125     VkRect2D scissor = {{0, 0}, {16, 16}};
1126     vkCmdSetScissor(m_commandBuffer->handle(), 0, 1, &scissor);
1127 
1128     // error produced here.
1129     vkCmdDraw(m_commandBuffer->handle(), 3, 1, 0, 0);
1130 
1131     m_errorMonitor->VerifyFound();
1132 
1133     m_commandBuffer->EndRenderPass();
1134     m_commandBuffer->end();
1135 }
1136 
TEST_F(VkLayerTest,DrawTimeImageComponentTypeMismatchWithPipeline)1137 TEST_F(VkLayerTest, DrawTimeImageComponentTypeMismatchWithPipeline) {
1138     TEST_DESCRIPTION(
1139         "Test that an error is produced when the component type of an imageview disagrees with the type in the shader.");
1140 
1141     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "SINT component type, but bound descriptor");
1142 
1143     ASSERT_NO_FATAL_FAILURE(Init());
1144     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
1145 
1146     char const *fsSource =
1147         "#version 450\n"
1148         "\n"
1149         "layout(set=0, binding=0) uniform isampler2D s;\n"
1150         "layout(location=0) out vec4 color;\n"
1151         "void main() {\n"
1152         "   color = texelFetch(s, ivec2(0), 0);\n"
1153         "}\n";
1154     VkShaderObj vs(m_device, bindStateVertShaderText, VK_SHADER_STAGE_VERTEX_BIT, this);
1155     VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
1156 
1157     VkPipelineObj pipe(m_device);
1158     pipe.AddShader(&vs);
1159     pipe.AddShader(&fs);
1160     pipe.AddDefaultColorAttachment();
1161 
1162     VkTextureObj texture(m_device, nullptr);  // UNORM texture by default, incompatible with isampler2D
1163     VkSamplerObj sampler(m_device);
1164 
1165     VkDescriptorSetObj descriptorSet(m_device);
1166     descriptorSet.AppendSamplerTexture(&sampler, &texture);
1167     descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
1168 
1169     VkResult err = pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass());
1170     ASSERT_VK_SUCCESS(err);
1171 
1172     m_commandBuffer->begin();
1173     m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
1174 
1175     vkCmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.handle());
1176     m_commandBuffer->BindDescriptorSet(descriptorSet);
1177 
1178     VkViewport viewport = {0, 0, 16, 16, 0, 1};
1179     vkCmdSetViewport(m_commandBuffer->handle(), 0, 1, &viewport);
1180     VkRect2D scissor = {{0, 0}, {16, 16}};
1181     vkCmdSetScissor(m_commandBuffer->handle(), 0, 1, &scissor);
1182 
1183     // error produced here.
1184     vkCmdDraw(m_commandBuffer->handle(), 3, 1, 0, 0);
1185 
1186     m_errorMonitor->VerifyFound();
1187 
1188     m_commandBuffer->EndRenderPass();
1189     m_commandBuffer->end();
1190 }
1191 
TEST_F(VkLayerTest,CopyImageLayerCountMismatch)1192 TEST_F(VkLayerTest, CopyImageLayerCountMismatch) {
1193     TEST_DESCRIPTION(
1194         "Try to copy between images with the source subresource having a different layerCount than the destination subresource");
1195     ASSERT_NO_FATAL_FAILURE(Init());
1196 
1197     // Create two images to copy between
1198     VkImageObj src_image_obj(m_device);
1199     VkImageObj dst_image_obj(m_device);
1200 
1201     VkImageCreateInfo image_create_info = {};
1202     image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
1203     image_create_info.pNext = NULL;
1204     image_create_info.imageType = VK_IMAGE_TYPE_2D;
1205     image_create_info.format = VK_FORMAT_B8G8R8A8_UNORM;
1206     image_create_info.extent.width = 32;
1207     image_create_info.extent.height = 32;
1208     image_create_info.extent.depth = 1;
1209     image_create_info.mipLevels = 1;
1210     image_create_info.arrayLayers = 4;
1211     image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
1212     image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL;
1213     image_create_info.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
1214     image_create_info.flags = 0;
1215 
1216     src_image_obj.init(&image_create_info);
1217     ASSERT_TRUE(src_image_obj.initialized());
1218 
1219     image_create_info.usage = VK_IMAGE_USAGE_TRANSFER_DST_BIT;
1220     dst_image_obj.init(&image_create_info);
1221     ASSERT_TRUE(dst_image_obj.initialized());
1222 
1223     m_commandBuffer->begin();
1224     VkImageCopy copyRegion;
1225     copyRegion.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
1226     copyRegion.srcSubresource.mipLevel = 0;
1227     copyRegion.srcSubresource.baseArrayLayer = 0;
1228     copyRegion.srcSubresource.layerCount = 1;
1229     copyRegion.srcOffset.x = 0;
1230     copyRegion.srcOffset.y = 0;
1231     copyRegion.srcOffset.z = 0;
1232     copyRegion.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
1233     copyRegion.dstSubresource.mipLevel = 0;
1234     copyRegion.dstSubresource.baseArrayLayer = 0;
1235     // Introduce failure by forcing the dst layerCount to differ from src
1236     copyRegion.dstSubresource.layerCount = 3;
1237     copyRegion.dstOffset.x = 0;
1238     copyRegion.dstOffset.y = 0;
1239     copyRegion.dstOffset.z = 0;
1240     copyRegion.extent.width = 1;
1241     copyRegion.extent.height = 1;
1242     copyRegion.extent.depth = 1;
1243 
1244     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkImageCopy-extent-00140");
1245     m_commandBuffer->CopyImage(src_image_obj.image(), VK_IMAGE_LAYOUT_GENERAL, dst_image_obj.image(), VK_IMAGE_LAYOUT_GENERAL, 1,
1246                                &copyRegion);
1247     m_errorMonitor->VerifyFound();
1248 }
1249 
TEST_F(VkLayerTest,CompressedImageMipCopyTests)1250 TEST_F(VkLayerTest, CompressedImageMipCopyTests) {
1251     TEST_DESCRIPTION("Image/Buffer copies for higher mip levels");
1252 
1253     ASSERT_NO_FATAL_FAILURE(Init());
1254 
1255     VkPhysicalDeviceFeatures device_features = {};
1256     ASSERT_NO_FATAL_FAILURE(GetPhysicalDeviceFeatures(&device_features));
1257     VkFormat compressed_format = VK_FORMAT_UNDEFINED;
1258     if (device_features.textureCompressionBC) {
1259         compressed_format = VK_FORMAT_BC3_SRGB_BLOCK;
1260     } else if (device_features.textureCompressionETC2) {
1261         compressed_format = VK_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK;
1262     } else if (device_features.textureCompressionASTC_LDR) {
1263         compressed_format = VK_FORMAT_ASTC_4x4_UNORM_BLOCK;
1264     } else {
1265         printf("%s No compressed formats supported - CompressedImageMipCopyTests skipped.\n", kSkipPrefix);
1266         return;
1267     }
1268 
1269     VkImageCreateInfo ci;
1270     ci.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
1271     ci.pNext = NULL;
1272     ci.flags = 0;
1273     ci.imageType = VK_IMAGE_TYPE_2D;
1274     ci.format = compressed_format;
1275     ci.extent = {32, 32, 1};
1276     ci.mipLevels = 6;
1277     ci.arrayLayers = 1;
1278     ci.samples = VK_SAMPLE_COUNT_1_BIT;
1279     ci.tiling = VK_IMAGE_TILING_OPTIMAL;
1280     ci.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
1281     ci.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
1282     ci.queueFamilyIndexCount = 0;
1283     ci.pQueueFamilyIndices = NULL;
1284     ci.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
1285 
1286     VkImageObj image(m_device);
1287     image.init(&ci);
1288     ASSERT_TRUE(image.initialized());
1289 
1290     VkImageObj odd_image(m_device);
1291     ci.extent = {31, 32, 1};  // Mips are [31,32] [15,16] [7,8] [3,4], [1,2] [1,1]
1292     odd_image.init(&ci);
1293     ASSERT_TRUE(odd_image.initialized());
1294 
1295     // Allocate buffers
1296     VkMemoryPropertyFlags reqs = 0;
1297     VkBufferObj buffer_1024, buffer_64, buffer_16, buffer_8;
1298     buffer_1024.init_as_src_and_dst(*m_device, 1024, reqs);
1299     buffer_64.init_as_src_and_dst(*m_device, 64, reqs);
1300     buffer_16.init_as_src_and_dst(*m_device, 16, reqs);
1301     buffer_8.init_as_src_and_dst(*m_device, 8, reqs);
1302 
1303     VkBufferImageCopy region = {};
1304     region.bufferRowLength = 0;
1305     region.bufferImageHeight = 0;
1306     region.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
1307     region.imageSubresource.layerCount = 1;
1308     region.imageOffset = {0, 0, 0};
1309     region.bufferOffset = 0;
1310 
1311     // start recording
1312     m_commandBuffer->begin();
1313 
1314     // Mip level copies that work - 5 levels
1315     m_errorMonitor->ExpectSuccess();
1316 
1317     // Mip 0 should fit in 1k buffer - 1k texels @ 1b each
1318     region.imageExtent = {32, 32, 1};
1319     region.imageSubresource.mipLevel = 0;
1320     vkCmdCopyImageToBuffer(m_commandBuffer->handle(), image.handle(), VK_IMAGE_LAYOUT_GENERAL, buffer_1024.handle(), 1, &region);
1321     vkCmdCopyBufferToImage(m_commandBuffer->handle(), buffer_1024.handle(), image.handle(), VK_IMAGE_LAYOUT_GENERAL, 1, &region);
1322 
1323     // Mip 2 should fit in 64b buffer - 64 texels @ 1b each
1324     region.imageExtent = {8, 8, 1};
1325     region.imageSubresource.mipLevel = 2;
1326     vkCmdCopyImageToBuffer(m_commandBuffer->handle(), image.handle(), VK_IMAGE_LAYOUT_GENERAL, buffer_64.handle(), 1, &region);
1327     vkCmdCopyBufferToImage(m_commandBuffer->handle(), buffer_64.handle(), image.handle(), VK_IMAGE_LAYOUT_GENERAL, 1, &region);
1328 
1329     // Mip 3 should fit in 16b buffer - 16 texels @ 1b each
1330     region.imageExtent = {4, 4, 1};
1331     region.imageSubresource.mipLevel = 3;
1332     vkCmdCopyImageToBuffer(m_commandBuffer->handle(), image.handle(), VK_IMAGE_LAYOUT_GENERAL, buffer_16.handle(), 1, &region);
1333     vkCmdCopyBufferToImage(m_commandBuffer->handle(), buffer_16.handle(), image.handle(), VK_IMAGE_LAYOUT_GENERAL, 1, &region);
1334 
1335     // Mip 4&5 should fit in 16b buffer with no complaint - 4 & 1 texels @ 1b each
1336     region.imageExtent = {2, 2, 1};
1337     region.imageSubresource.mipLevel = 4;
1338     vkCmdCopyImageToBuffer(m_commandBuffer->handle(), image.handle(), VK_IMAGE_LAYOUT_GENERAL, buffer_16.handle(), 1, &region);
1339     vkCmdCopyBufferToImage(m_commandBuffer->handle(), buffer_16.handle(), image.handle(), VK_IMAGE_LAYOUT_GENERAL, 1, &region);
1340 
1341     region.imageExtent = {1, 1, 1};
1342     region.imageSubresource.mipLevel = 5;
1343     vkCmdCopyImageToBuffer(m_commandBuffer->handle(), image.handle(), VK_IMAGE_LAYOUT_GENERAL, buffer_16.handle(), 1, &region);
1344     vkCmdCopyBufferToImage(m_commandBuffer->handle(), buffer_16.handle(), image.handle(), VK_IMAGE_LAYOUT_GENERAL, 1, &region);
1345     m_errorMonitor->VerifyNotFound();
1346 
1347     // Buffer must accommodate a full compressed block, regardless of texel count
1348     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdCopyImageToBuffer-pRegions-00183");
1349     vkCmdCopyImageToBuffer(m_commandBuffer->handle(), image.handle(), VK_IMAGE_LAYOUT_GENERAL, buffer_8.handle(), 1, &region);
1350     m_errorMonitor->VerifyFound();
1351     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdCopyBufferToImage-pRegions-00171");
1352     vkCmdCopyBufferToImage(m_commandBuffer->handle(), buffer_8.handle(), image.handle(), VK_IMAGE_LAYOUT_GENERAL, 1, &region);
1353     m_errorMonitor->VerifyFound();
1354 
1355     // Copy width < compressed block size, but not the full mip width
1356     region.imageExtent = {1, 2, 1};
1357     region.imageSubresource.mipLevel = 4;
1358     m_errorMonitor->SetDesiredFailureMsg(
1359         VK_DEBUG_REPORT_ERROR_BIT_EXT,
1360         "VUID-VkBufferImageCopy-imageExtent-00207");  // width not a multiple of compressed block width
1361     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
1362                                          "VUID-vkCmdCopyImageToBuffer-imageOffset-01794");  // image transfer granularity
1363     vkCmdCopyImageToBuffer(m_commandBuffer->handle(), image.handle(), VK_IMAGE_LAYOUT_GENERAL, buffer_16.handle(), 1, &region);
1364     m_errorMonitor->VerifyFound();
1365     m_errorMonitor->SetDesiredFailureMsg(
1366         VK_DEBUG_REPORT_ERROR_BIT_EXT,
1367         "VUID-VkBufferImageCopy-imageExtent-00207");  // width not a multiple of compressed block width
1368     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
1369                                          "VUID-vkCmdCopyBufferToImage-imageOffset-01793");  // image transfer granularity
1370     vkCmdCopyBufferToImage(m_commandBuffer->handle(), buffer_16.handle(), image.handle(), VK_IMAGE_LAYOUT_GENERAL, 1, &region);
1371     m_errorMonitor->VerifyFound();
1372 
1373     // Copy height < compressed block size but not the full mip height
1374     region.imageExtent = {2, 1, 1};
1375     m_errorMonitor->SetDesiredFailureMsg(
1376         VK_DEBUG_REPORT_ERROR_BIT_EXT,
1377         "VUID-VkBufferImageCopy-imageExtent-00208");  // height not a multiple of compressed block width
1378     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
1379                                          "VUID-vkCmdCopyImageToBuffer-imageOffset-01794");  // image transfer granularity
1380     vkCmdCopyImageToBuffer(m_commandBuffer->handle(), image.handle(), VK_IMAGE_LAYOUT_GENERAL, buffer_16.handle(), 1, &region);
1381     m_errorMonitor->VerifyFound();
1382     m_errorMonitor->SetDesiredFailureMsg(
1383         VK_DEBUG_REPORT_ERROR_BIT_EXT,
1384         "VUID-VkBufferImageCopy-imageExtent-00208");  // height not a multiple of compressed block width
1385     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
1386                                          "VUID-vkCmdCopyBufferToImage-imageOffset-01793");  // image transfer granularity
1387     vkCmdCopyBufferToImage(m_commandBuffer->handle(), buffer_16.handle(), image.handle(), VK_IMAGE_LAYOUT_GENERAL, 1, &region);
1388     m_errorMonitor->VerifyFound();
1389 
1390     // Offsets must be multiple of compressed block size
1391     region.imageOffset = {1, 1, 0};
1392     region.imageExtent = {1, 1, 1};
1393     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
1394                                          "VUID-VkBufferImageCopy-imageOffset-00205");  // imageOffset not a multiple of block size
1395     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
1396                                          "VUID-vkCmdCopyImageToBuffer-imageOffset-01794");  // image transfer granularity
1397     vkCmdCopyImageToBuffer(m_commandBuffer->handle(), image.handle(), VK_IMAGE_LAYOUT_GENERAL, buffer_16.handle(), 1, &region);
1398     m_errorMonitor->VerifyFound();
1399     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
1400                                          "VUID-VkBufferImageCopy-imageOffset-00205");  // imageOffset not a multiple of block size
1401     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
1402                                          "VUID-vkCmdCopyBufferToImage-imageOffset-01793");  // image transfer granularity
1403     vkCmdCopyBufferToImage(m_commandBuffer->handle(), buffer_16.handle(), image.handle(), VK_IMAGE_LAYOUT_GENERAL, 1, &region);
1404     m_errorMonitor->VerifyFound();
1405 
1406     // Offset + extent width = mip width - should succeed
1407     region.imageOffset = {4, 4, 0};
1408     region.imageExtent = {3, 4, 1};
1409     region.imageSubresource.mipLevel = 2;
1410     m_errorMonitor->ExpectSuccess();
1411     vkCmdCopyImageToBuffer(m_commandBuffer->handle(), odd_image.handle(), VK_IMAGE_LAYOUT_GENERAL, buffer_16.handle(), 1, &region);
1412     vkCmdCopyBufferToImage(m_commandBuffer->handle(), buffer_16.handle(), odd_image.handle(), VK_IMAGE_LAYOUT_GENERAL, 1, &region);
1413     m_errorMonitor->VerifyNotFound();
1414 
1415     // Offset + extent width < mip width and not a multiple of block width - should fail
1416     region.imageExtent = {3, 3, 1};
1417     m_errorMonitor->SetDesiredFailureMsg(
1418         VK_DEBUG_REPORT_ERROR_BIT_EXT,
1419         "VUID-VkBufferImageCopy-imageExtent-00208");  // offset+extent not a multiple of block width
1420     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
1421                                          "VUID-vkCmdCopyImageToBuffer-imageOffset-01794");  // image transfer granularity
1422     vkCmdCopyImageToBuffer(m_commandBuffer->handle(), odd_image.handle(), VK_IMAGE_LAYOUT_GENERAL, buffer_16.handle(), 1, &region);
1423     m_errorMonitor->VerifyFound();
1424     m_errorMonitor->SetDesiredFailureMsg(
1425         VK_DEBUG_REPORT_ERROR_BIT_EXT,
1426         "VUID-VkBufferImageCopy-imageExtent-00208");  // offset+extent not a multiple of block width
1427     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
1428                                          "VUID-vkCmdCopyBufferToImage-imageOffset-01793");  // image transfer granularity
1429     vkCmdCopyBufferToImage(m_commandBuffer->handle(), buffer_16.handle(), odd_image.handle(), VK_IMAGE_LAYOUT_GENERAL, 1, &region);
1430     m_errorMonitor->VerifyFound();
1431 }
1432 
TEST_F(VkLayerTest,ImageBufferCopyTests)1433 TEST_F(VkLayerTest, ImageBufferCopyTests) {
1434     TEST_DESCRIPTION("Image to buffer and buffer to image tests");
1435     ASSERT_NO_FATAL_FAILURE(Init());
1436 
1437     // Bail if any dimension of transfer granularity is 0.
1438     auto index = m_device->graphics_queue_node_index_;
1439     auto queue_family_properties = m_device->phy().queue_properties();
1440     if ((queue_family_properties[index].minImageTransferGranularity.depth == 0) ||
1441         (queue_family_properties[index].minImageTransferGranularity.width == 0) ||
1442         (queue_family_properties[index].minImageTransferGranularity.height == 0)) {
1443         printf("%s Subresource copies are disallowed when xfer granularity (x|y|z) is 0. Skipped.\n", kSkipPrefix);
1444         return;
1445     }
1446 
1447     VkImageObj image_64k(m_device);        // 128^2 texels, 64k
1448     VkImageObj image_16k(m_device);        // 64^2 texels, 16k
1449     VkImageObj image_16k_depth(m_device);  // 64^2 texels, depth, 16k
1450     VkImageObj ds_image_4D_1S(m_device);   // 256^2 texels, 512kb (256k depth, 64k stencil, 192k pack)
1451     VkImageObj ds_image_3D_1S(m_device);   // 256^2 texels, 256kb (192k depth, 64k stencil)
1452     VkImageObj ds_image_2D(m_device);      // 256^2 texels, 128k (128k depth)
1453     VkImageObj ds_image_1S(m_device);      // 256^2 texels, 64k (64k stencil)
1454 
1455     image_64k.Init(128, 128, 1, VK_FORMAT_R8G8B8A8_UINT,
1456                    VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT,
1457                    VK_IMAGE_TILING_OPTIMAL, 0);
1458     image_16k.Init(64, 64, 1, VK_FORMAT_R8G8B8A8_UINT,
1459                    VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT,
1460                    VK_IMAGE_TILING_OPTIMAL, 0);
1461     ASSERT_TRUE(image_64k.initialized());
1462     ASSERT_TRUE(image_16k.initialized());
1463 
1464     // Verify all needed Depth/Stencil formats are supported
1465     bool missing_ds_support = false;
1466     VkFormatProperties props = {0, 0, 0};
1467     vkGetPhysicalDeviceFormatProperties(m_device->phy().handle(), VK_FORMAT_D32_SFLOAT_S8_UINT, &props);
1468     missing_ds_support |= (props.bufferFeatures == 0 && props.linearTilingFeatures == 0 && props.optimalTilingFeatures == 0);
1469     missing_ds_support |= (props.optimalTilingFeatures & VK_FORMAT_FEATURE_TRANSFER_SRC_BIT) == 0;
1470     missing_ds_support |= (props.optimalTilingFeatures & VK_FORMAT_FEATURE_TRANSFER_DST_BIT) == 0;
1471     vkGetPhysicalDeviceFormatProperties(m_device->phy().handle(), VK_FORMAT_D24_UNORM_S8_UINT, &props);
1472     missing_ds_support |= (props.bufferFeatures == 0 && props.linearTilingFeatures == 0 && props.optimalTilingFeatures == 0);
1473     missing_ds_support |= (props.optimalTilingFeatures & VK_FORMAT_FEATURE_TRANSFER_SRC_BIT) == 0;
1474     missing_ds_support |= (props.optimalTilingFeatures & VK_FORMAT_FEATURE_TRANSFER_DST_BIT) == 0;
1475     vkGetPhysicalDeviceFormatProperties(m_device->phy().handle(), VK_FORMAT_D16_UNORM, &props);
1476     missing_ds_support |= (props.bufferFeatures == 0 && props.linearTilingFeatures == 0 && props.optimalTilingFeatures == 0);
1477     missing_ds_support |= (props.optimalTilingFeatures & VK_FORMAT_FEATURE_TRANSFER_SRC_BIT) == 0;
1478     missing_ds_support |= (props.optimalTilingFeatures & VK_FORMAT_FEATURE_TRANSFER_DST_BIT) == 0;
1479     vkGetPhysicalDeviceFormatProperties(m_device->phy().handle(), VK_FORMAT_S8_UINT, &props);
1480     missing_ds_support |= (props.bufferFeatures == 0 && props.linearTilingFeatures == 0 && props.optimalTilingFeatures == 0);
1481     missing_ds_support |= (props.optimalTilingFeatures & VK_FORMAT_FEATURE_TRANSFER_SRC_BIT) == 0;
1482     missing_ds_support |= (props.optimalTilingFeatures & VK_FORMAT_FEATURE_TRANSFER_DST_BIT) == 0;
1483 
1484     if (!missing_ds_support) {
1485         image_16k_depth.Init(64, 64, 1, VK_FORMAT_D24_UNORM_S8_UINT,
1486                              VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT, VK_IMAGE_TILING_OPTIMAL, 0);
1487         ASSERT_TRUE(image_16k_depth.initialized());
1488 
1489         ds_image_4D_1S.Init(
1490             256, 256, 1, VK_FORMAT_D32_SFLOAT_S8_UINT,
1491             VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT,
1492             VK_IMAGE_TILING_OPTIMAL, 0);
1493         ASSERT_TRUE(ds_image_4D_1S.initialized());
1494 
1495         ds_image_3D_1S.Init(
1496             256, 256, 1, VK_FORMAT_D24_UNORM_S8_UINT,
1497             VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT,
1498             VK_IMAGE_TILING_OPTIMAL, 0);
1499         ASSERT_TRUE(ds_image_3D_1S.initialized());
1500 
1501         ds_image_2D.Init(
1502             256, 256, 1, VK_FORMAT_D16_UNORM,
1503             VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT,
1504             VK_IMAGE_TILING_OPTIMAL, 0);
1505         ASSERT_TRUE(ds_image_2D.initialized());
1506 
1507         ds_image_1S.Init(
1508             256, 256, 1, VK_FORMAT_S8_UINT,
1509             VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT,
1510             VK_IMAGE_TILING_OPTIMAL, 0);
1511         ASSERT_TRUE(ds_image_1S.initialized());
1512     }
1513 
1514     // Allocate buffers
1515     VkBufferObj buffer_256k, buffer_128k, buffer_64k, buffer_16k;
1516     VkMemoryPropertyFlags reqs = 0;
1517     buffer_256k.init_as_src_and_dst(*m_device, 262144, reqs);  // 256k
1518     buffer_128k.init_as_src_and_dst(*m_device, 131072, reqs);  // 128k
1519     buffer_64k.init_as_src_and_dst(*m_device, 65536, reqs);    // 64k
1520     buffer_16k.init_as_src_and_dst(*m_device, 16384, reqs);    // 16k
1521 
1522     VkBufferImageCopy region = {};
1523     region.bufferRowLength = 0;
1524     region.bufferImageHeight = 0;
1525     region.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
1526     region.imageSubresource.layerCount = 1;
1527     region.imageOffset = {0, 0, 0};
1528     region.imageExtent = {64, 64, 1};
1529     region.bufferOffset = 0;
1530 
1531     // attempt copies before putting command buffer in recording state
1532     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdCopyBufferToImage-commandBuffer-recording");
1533     vkCmdCopyBufferToImage(m_commandBuffer->handle(), buffer_64k.handle(), image_64k.handle(), VK_IMAGE_LAYOUT_GENERAL, 1, &region);
1534     m_errorMonitor->VerifyFound();
1535 
1536     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdCopyImageToBuffer-commandBuffer-recording");
1537     vkCmdCopyImageToBuffer(m_commandBuffer->handle(), image_64k.handle(), VK_IMAGE_LAYOUT_GENERAL, buffer_64k.handle(), 1, &region);
1538     m_errorMonitor->VerifyFound();
1539 
1540     // start recording
1541     m_commandBuffer->begin();
1542 
1543     // successful copies
1544     m_errorMonitor->ExpectSuccess();
1545     vkCmdCopyImageToBuffer(m_commandBuffer->handle(), image_16k.handle(), VK_IMAGE_LAYOUT_GENERAL, buffer_16k.handle(), 1, &region);
1546     vkCmdCopyBufferToImage(m_commandBuffer->handle(), buffer_16k.handle(), image_16k.handle(), VK_IMAGE_LAYOUT_GENERAL, 1, &region);
1547     region.imageOffset.x = 16;  // 16k copy, offset requires larger image
1548     vkCmdCopyImageToBuffer(m_commandBuffer->handle(), image_64k.handle(), VK_IMAGE_LAYOUT_GENERAL, buffer_16k.handle(), 1, &region);
1549     region.imageExtent.height = 78;  // > 16k copy requires larger buffer & image
1550     vkCmdCopyBufferToImage(m_commandBuffer->handle(), buffer_64k.handle(), image_64k.handle(), VK_IMAGE_LAYOUT_GENERAL, 1, &region);
1551     region.imageOffset.x = 0;
1552     region.imageExtent.height = 64;
1553     region.bufferOffset = 256;  // 16k copy with buffer offset, requires larger buffer
1554     vkCmdCopyImageToBuffer(m_commandBuffer->handle(), image_16k.handle(), VK_IMAGE_LAYOUT_GENERAL, buffer_64k.handle(), 1, &region);
1555     m_errorMonitor->VerifyNotFound();
1556 
1557     // image/buffer too small (extent too large) on copy to image
1558     region.imageExtent = {65, 64, 1};
1559     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
1560                                          "VUID-vkCmdCopyBufferToImage-pRegions-00171");  // buffer too small
1561     vkCmdCopyBufferToImage(m_commandBuffer->handle(), buffer_16k.handle(), image_64k.handle(), VK_IMAGE_LAYOUT_GENERAL, 1, &region);
1562     m_errorMonitor->VerifyFound();
1563 
1564     m_errorMonitor->SetUnexpectedError("VUID-VkBufferImageCopy-imageOffset-00197");
1565     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
1566                                          "VUID-vkCmdCopyBufferToImage-pRegions-00172");  // image too small
1567     vkCmdCopyBufferToImage(m_commandBuffer->handle(), buffer_64k.handle(), image_16k.handle(), VK_IMAGE_LAYOUT_GENERAL, 1, &region);
1568     m_errorMonitor->VerifyFound();
1569 
1570     // image/buffer too small (offset) on copy to image
1571     region.imageExtent = {64, 64, 1};
1572     region.imageOffset = {0, 4, 0};
1573     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
1574                                          "VUID-vkCmdCopyBufferToImage-pRegions-00171");  // buffer too small
1575     vkCmdCopyBufferToImage(m_commandBuffer->handle(), buffer_16k.handle(), image_64k.handle(), VK_IMAGE_LAYOUT_GENERAL, 1, &region);
1576     m_errorMonitor->VerifyFound();
1577 
1578     m_errorMonitor->SetUnexpectedError("VUID-VkBufferImageCopy-imageOffset-00197");
1579     m_errorMonitor->SetUnexpectedError("VUID-VkBufferImageCopy-imageOffset-00198");
1580     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
1581                                          "VUID-vkCmdCopyBufferToImage-pRegions-00172");  // image too small
1582     vkCmdCopyBufferToImage(m_commandBuffer->handle(), buffer_64k.handle(), image_16k.handle(), VK_IMAGE_LAYOUT_GENERAL, 1, &region);
1583     m_errorMonitor->VerifyFound();
1584 
1585     // image/buffer too small on copy to buffer
1586     region.imageExtent = {64, 64, 1};
1587     region.imageOffset = {0, 0, 0};
1588     region.bufferOffset = 4;
1589     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
1590                                          "VUID-vkCmdCopyImageToBuffer-pRegions-00183");  // buffer too small
1591     vkCmdCopyImageToBuffer(m_commandBuffer->handle(), image_64k.handle(), VK_IMAGE_LAYOUT_GENERAL, buffer_16k.handle(), 1, &region);
1592     m_errorMonitor->VerifyFound();
1593 
1594     region.imageExtent = {64, 65, 1};
1595     region.bufferOffset = 0;
1596     m_errorMonitor->SetUnexpectedError("VUID-VkBufferImageCopy-imageOffset-00198");
1597     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
1598                                          "VUID-vkCmdCopyImageToBuffer-pRegions-00182");  // image too small
1599     vkCmdCopyImageToBuffer(m_commandBuffer->handle(), image_16k.handle(), VK_IMAGE_LAYOUT_GENERAL, buffer_64k.handle(), 1, &region);
1600     m_errorMonitor->VerifyFound();
1601 
1602     // buffer size OK but rowlength causes loose packing
1603     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdCopyImageToBuffer-pRegions-00183");
1604     region.imageExtent = {64, 64, 1};
1605     region.bufferRowLength = 68;
1606     vkCmdCopyImageToBuffer(m_commandBuffer->handle(), image_16k.handle(), VK_IMAGE_LAYOUT_GENERAL, buffer_16k.handle(), 1, &region);
1607     m_errorMonitor->VerifyFound();
1608 
1609     // An extent with zero area should produce a warning, but no error
1610     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_WARNING_BIT_EXT | VK_DEBUG_REPORT_ERROR_BIT_EXT, "} has zero area");
1611     region.imageExtent.width = 0;
1612     vkCmdCopyImageToBuffer(m_commandBuffer->handle(), image_16k.handle(), VK_IMAGE_LAYOUT_GENERAL, buffer_16k.handle(), 1, &region);
1613     m_errorMonitor->VerifyFound();
1614 
1615     // aspect bits
1616     region.imageExtent = {64, 64, 1};
1617     region.bufferRowLength = 0;
1618     region.bufferImageHeight = 0;
1619     if (!missing_ds_support) {
1620         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
1621                                              "VUID-VkBufferImageCopy-aspectMask-00212");  // more than 1 aspect bit set
1622         region.imageSubresource.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT;
1623         vkCmdCopyImageToBuffer(m_commandBuffer->handle(), image_16k_depth.handle(), VK_IMAGE_LAYOUT_GENERAL, buffer_16k.handle(), 1,
1624                                &region);
1625         m_errorMonitor->VerifyFound();
1626 
1627         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
1628                                              "VUID-VkBufferImageCopy-aspectMask-00211");  // different mis-matched aspect
1629         region.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
1630         vkCmdCopyImageToBuffer(m_commandBuffer->handle(), image_16k_depth.handle(), VK_IMAGE_LAYOUT_GENERAL, buffer_16k.handle(), 1,
1631                                &region);
1632         m_errorMonitor->VerifyFound();
1633     }
1634 
1635     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
1636                                          "VUID-VkBufferImageCopy-aspectMask-00211");  // mis-matched aspect
1637     region.imageSubresource.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT;
1638     vkCmdCopyImageToBuffer(m_commandBuffer->handle(), image_16k.handle(), VK_IMAGE_LAYOUT_GENERAL, buffer_16k.handle(), 1, &region);
1639     m_errorMonitor->VerifyFound();
1640     region.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
1641 
1642     // Out-of-range mip levels should fail
1643     region.imageSubresource.mipLevel = image_16k.create_info().mipLevels + 1;
1644     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdCopyImageToBuffer-imageSubresource-01703");
1645     m_errorMonitor->SetUnexpectedError("VUID-VkBufferImageCopy-imageOffset-00197");
1646     m_errorMonitor->SetUnexpectedError("VUID-VkBufferImageCopy-imageOffset-00198");
1647     m_errorMonitor->SetUnexpectedError("VUID-VkBufferImageCopy-imageOffset-00200");
1648     m_errorMonitor->SetDesiredFailureMsg(
1649         VK_DEBUG_REPORT_ERROR_BIT_EXT,
1650         "VUID-vkCmdCopyImageToBuffer-pRegions-00182");  // unavoidable "region exceeds image bounds" for non-existent mip
1651     vkCmdCopyImageToBuffer(m_commandBuffer->handle(), image_16k.handle(), VK_IMAGE_LAYOUT_GENERAL, buffer_16k.handle(), 1, &region);
1652     m_errorMonitor->VerifyFound();
1653     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdCopyBufferToImage-imageSubresource-01701");
1654     m_errorMonitor->SetUnexpectedError("VUID-VkBufferImageCopy-imageOffset-00197");
1655     m_errorMonitor->SetUnexpectedError("VUID-VkBufferImageCopy-imageOffset-00198");
1656     m_errorMonitor->SetUnexpectedError("VUID-VkBufferImageCopy-imageOffset-00200");
1657     m_errorMonitor->SetDesiredFailureMsg(
1658         VK_DEBUG_REPORT_ERROR_BIT_EXT,
1659         "VUID-vkCmdCopyBufferToImage-pRegions-00172");  // unavoidable "region exceeds image bounds" for non-existent mip
1660     vkCmdCopyBufferToImage(m_commandBuffer->handle(), buffer_16k.handle(), image_16k.handle(), VK_IMAGE_LAYOUT_GENERAL, 1, &region);
1661     m_errorMonitor->VerifyFound();
1662     region.imageSubresource.mipLevel = 0;
1663 
1664     // Out-of-range array layers should fail
1665     region.imageSubresource.baseArrayLayer = image_16k.create_info().arrayLayers;
1666     region.imageSubresource.layerCount = 1;
1667     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdCopyImageToBuffer-imageSubresource-01704");
1668     vkCmdCopyImageToBuffer(m_commandBuffer->handle(), image_16k.handle(), VK_IMAGE_LAYOUT_GENERAL, buffer_16k.handle(), 1, &region);
1669     m_errorMonitor->VerifyFound();
1670     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdCopyBufferToImage-imageSubresource-01702");
1671     vkCmdCopyBufferToImage(m_commandBuffer->handle(), buffer_16k.handle(), image_16k.handle(), VK_IMAGE_LAYOUT_GENERAL, 1, &region);
1672     m_errorMonitor->VerifyFound();
1673     region.imageSubresource.baseArrayLayer = 0;
1674 
1675     // Layout mismatch should fail
1676     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdCopyImageToBuffer-srcImageLayout-00189");
1677     vkCmdCopyImageToBuffer(m_commandBuffer->handle(), image_16k.handle(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, buffer_16k.handle(),
1678                            1, &region);
1679     m_errorMonitor->VerifyFound();
1680     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdCopyBufferToImage-dstImageLayout-00180");
1681     vkCmdCopyBufferToImage(m_commandBuffer->handle(), buffer_16k.handle(), image_16k.handle(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
1682                            1, &region);
1683     m_errorMonitor->VerifyFound();
1684 
1685     // Test Depth/Stencil copies
1686     if (missing_ds_support) {
1687         printf("%s Depth / Stencil formats unsupported - skipping D/S tests.\n", kSkipPrefix);
1688     } else {
1689         VkBufferImageCopy ds_region = {};
1690         ds_region.bufferOffset = 0;
1691         ds_region.bufferRowLength = 0;
1692         ds_region.bufferImageHeight = 0;
1693         ds_region.imageSubresource.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT;
1694         ds_region.imageSubresource.mipLevel = 0;
1695         ds_region.imageSubresource.baseArrayLayer = 0;
1696         ds_region.imageSubresource.layerCount = 1;
1697         ds_region.imageOffset = {0, 0, 0};
1698         ds_region.imageExtent = {256, 256, 1};
1699 
1700         // Depth copies that should succeed
1701         m_errorMonitor->ExpectSuccess();  // Extract 4b depth per texel, pack into 256k buffer
1702         vkCmdCopyImageToBuffer(m_commandBuffer->handle(), ds_image_4D_1S.handle(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
1703                                buffer_256k.handle(), 1, &ds_region);
1704         m_errorMonitor->VerifyNotFound();
1705 
1706         m_errorMonitor->ExpectSuccess();  // Extract 3b depth per texel, pack (loose) into 256k buffer
1707         vkCmdCopyImageToBuffer(m_commandBuffer->handle(), ds_image_3D_1S.handle(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
1708                                buffer_256k.handle(), 1, &ds_region);
1709         m_errorMonitor->VerifyNotFound();
1710 
1711         m_errorMonitor->ExpectSuccess();  // Copy 2b depth per texel, into 128k buffer
1712         vkCmdCopyImageToBuffer(m_commandBuffer->handle(), ds_image_2D.handle(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
1713                                buffer_128k.handle(), 1, &ds_region);
1714         m_errorMonitor->VerifyNotFound();
1715 
1716         // Depth copies that should fail
1717         ds_region.bufferOffset = 4;
1718         m_errorMonitor->SetDesiredFailureMsg(
1719             VK_DEBUG_REPORT_ERROR_BIT_EXT,
1720             "VUID-vkCmdCopyImageToBuffer-pRegions-00183");  // Extract 4b depth per texel, pack into 256k buffer
1721         vkCmdCopyImageToBuffer(m_commandBuffer->handle(), ds_image_4D_1S.handle(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
1722                                buffer_256k.handle(), 1, &ds_region);
1723         m_errorMonitor->VerifyFound();
1724 
1725         m_errorMonitor->SetDesiredFailureMsg(
1726             VK_DEBUG_REPORT_ERROR_BIT_EXT,
1727             "VUID-vkCmdCopyImageToBuffer-pRegions-00183");  // Extract 3b depth per texel, pack (loose) into 256k buffer
1728         vkCmdCopyImageToBuffer(m_commandBuffer->handle(), ds_image_3D_1S.handle(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
1729                                buffer_256k.handle(), 1, &ds_region);
1730         m_errorMonitor->VerifyFound();
1731 
1732         m_errorMonitor->SetDesiredFailureMsg(
1733             VK_DEBUG_REPORT_ERROR_BIT_EXT,
1734             "VUID-vkCmdCopyImageToBuffer-pRegions-00183");  // Copy 2b depth per texel, into 128k buffer
1735         vkCmdCopyImageToBuffer(m_commandBuffer->handle(), ds_image_2D.handle(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
1736                                buffer_128k.handle(), 1, &ds_region);
1737         m_errorMonitor->VerifyFound();
1738 
1739         // Stencil copies that should succeed
1740         ds_region.bufferOffset = 0;
1741         ds_region.imageSubresource.aspectMask = VK_IMAGE_ASPECT_STENCIL_BIT;
1742         m_errorMonitor->ExpectSuccess();  // Extract 1b stencil per texel, pack into 64k buffer
1743         vkCmdCopyImageToBuffer(m_commandBuffer->handle(), ds_image_4D_1S.handle(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
1744                                buffer_64k.handle(), 1, &ds_region);
1745         m_errorMonitor->VerifyNotFound();
1746 
1747         m_errorMonitor->ExpectSuccess();  // Extract 1b stencil per texel, pack into 64k buffer
1748         vkCmdCopyImageToBuffer(m_commandBuffer->handle(), ds_image_3D_1S.handle(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
1749                                buffer_64k.handle(), 1, &ds_region);
1750         m_errorMonitor->VerifyNotFound();
1751 
1752         m_errorMonitor->ExpectSuccess();  // Copy 1b depth per texel, into 64k buffer
1753         vkCmdCopyImageToBuffer(m_commandBuffer->handle(), ds_image_1S.handle(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
1754                                buffer_64k.handle(), 1, &ds_region);
1755         m_errorMonitor->VerifyNotFound();
1756 
1757         // Stencil copies that should fail
1758         m_errorMonitor->SetDesiredFailureMsg(
1759             VK_DEBUG_REPORT_ERROR_BIT_EXT,
1760             "VUID-vkCmdCopyImageToBuffer-pRegions-00183");  // Extract 1b stencil per texel, pack into 64k buffer
1761         vkCmdCopyImageToBuffer(m_commandBuffer->handle(), ds_image_4D_1S.handle(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
1762                                buffer_16k.handle(), 1, &ds_region);
1763         m_errorMonitor->VerifyFound();
1764 
1765         m_errorMonitor->SetDesiredFailureMsg(
1766             VK_DEBUG_REPORT_ERROR_BIT_EXT,
1767             "VUID-vkCmdCopyImageToBuffer-pRegions-00183");  // Extract 1b stencil per texel, pack into 64k buffer
1768         ds_region.bufferRowLength = 260;
1769         vkCmdCopyImageToBuffer(m_commandBuffer->handle(), ds_image_3D_1S.handle(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
1770                                buffer_64k.handle(), 1, &ds_region);
1771         m_errorMonitor->VerifyFound();
1772 
1773         ds_region.bufferRowLength = 0;
1774         ds_region.bufferOffset = 4;
1775         m_errorMonitor->SetDesiredFailureMsg(
1776             VK_DEBUG_REPORT_ERROR_BIT_EXT,
1777             "VUID-vkCmdCopyImageToBuffer-pRegions-00183");  // Copy 1b depth per texel, into 64k buffer
1778         vkCmdCopyImageToBuffer(m_commandBuffer->handle(), ds_image_1S.handle(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
1779                                buffer_64k.handle(), 1, &ds_region);
1780         m_errorMonitor->VerifyFound();
1781     }
1782 
1783     // Test compressed formats, if supported
1784     VkPhysicalDeviceFeatures device_features = {};
1785     ASSERT_NO_FATAL_FAILURE(GetPhysicalDeviceFeatures(&device_features));
1786     if (!(device_features.textureCompressionBC || device_features.textureCompressionETC2 ||
1787           device_features.textureCompressionASTC_LDR)) {
1788         printf("%s No compressed formats supported - block compression tests skipped.\n", kSkipPrefix);
1789     } else {
1790         VkImageObj image_16k_4x4comp(m_device);   // 128^2 texels as 32^2 compressed (4x4) blocks, 16k
1791         VkImageObj image_NPOT_4x4comp(m_device);  // 130^2 texels as 33^2 compressed (4x4) blocks
1792         if (device_features.textureCompressionBC) {
1793             image_16k_4x4comp.Init(128, 128, 1, VK_FORMAT_BC3_SRGB_BLOCK, VK_IMAGE_USAGE_TRANSFER_SRC_BIT, VK_IMAGE_TILING_OPTIMAL,
1794                                    0);
1795             image_NPOT_4x4comp.Init(130, 130, 1, VK_FORMAT_BC3_SRGB_BLOCK, VK_IMAGE_USAGE_TRANSFER_SRC_BIT, VK_IMAGE_TILING_OPTIMAL,
1796                                     0);
1797         } else if (device_features.textureCompressionETC2) {
1798             image_16k_4x4comp.Init(128, 128, 1, VK_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK, VK_IMAGE_USAGE_TRANSFER_SRC_BIT,
1799                                    VK_IMAGE_TILING_OPTIMAL, 0);
1800             image_NPOT_4x4comp.Init(130, 130, 1, VK_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK, VK_IMAGE_USAGE_TRANSFER_SRC_BIT,
1801                                     VK_IMAGE_TILING_OPTIMAL, 0);
1802         } else {
1803             image_16k_4x4comp.Init(128, 128, 1, VK_FORMAT_ASTC_4x4_UNORM_BLOCK, VK_IMAGE_USAGE_TRANSFER_SRC_BIT,
1804                                    VK_IMAGE_TILING_OPTIMAL, 0);
1805             image_NPOT_4x4comp.Init(130, 130, 1, VK_FORMAT_ASTC_4x4_UNORM_BLOCK, VK_IMAGE_USAGE_TRANSFER_SRC_BIT,
1806                                     VK_IMAGE_TILING_OPTIMAL, 0);
1807         }
1808         ASSERT_TRUE(image_16k_4x4comp.initialized());
1809 
1810         // Just fits
1811         m_errorMonitor->ExpectSuccess();
1812         region.imageExtent = {128, 128, 1};
1813         vkCmdCopyImageToBuffer(m_commandBuffer->handle(), image_16k_4x4comp.handle(), VK_IMAGE_LAYOUT_GENERAL, buffer_16k.handle(),
1814                                1, &region);
1815         m_errorMonitor->VerifyNotFound();
1816 
1817         // with offset, too big for buffer
1818         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdCopyImageToBuffer-pRegions-00183");
1819         region.bufferOffset = 16;
1820         vkCmdCopyImageToBuffer(m_commandBuffer->handle(), image_16k_4x4comp.handle(), VK_IMAGE_LAYOUT_GENERAL, buffer_16k.handle(),
1821                                1, &region);
1822         m_errorMonitor->VerifyFound();
1823         region.bufferOffset = 0;
1824 
1825         // extents that are not a multiple of compressed block size
1826         m_errorMonitor->SetDesiredFailureMsg(
1827             VK_DEBUG_REPORT_ERROR_BIT_EXT,
1828             "VUID-VkBufferImageCopy-imageExtent-00207");  // extent width not a multiple of block size
1829         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
1830                                              "VUID-vkCmdCopyImageToBuffer-imageOffset-01794");  // image transfer granularity
1831         region.imageExtent.width = 66;
1832         vkCmdCopyImageToBuffer(m_commandBuffer->handle(), image_NPOT_4x4comp.handle(), VK_IMAGE_LAYOUT_GENERAL, buffer_16k.handle(),
1833                                1, &region);
1834         m_errorMonitor->VerifyFound();
1835         region.imageExtent.width = 128;
1836 
1837         m_errorMonitor->SetDesiredFailureMsg(
1838             VK_DEBUG_REPORT_ERROR_BIT_EXT,
1839             "VUID-VkBufferImageCopy-imageExtent-00208");  // extent height not a multiple of block size
1840         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
1841                                              "VUID-vkCmdCopyImageToBuffer-imageOffset-01794");  // image transfer granularity
1842         region.imageExtent.height = 2;
1843         vkCmdCopyImageToBuffer(m_commandBuffer->handle(), image_NPOT_4x4comp.handle(), VK_IMAGE_LAYOUT_GENERAL, buffer_16k.handle(),
1844                                1, &region);
1845         m_errorMonitor->VerifyFound();
1846         region.imageExtent.height = 128;
1847 
1848         // TODO: All available compressed formats are 2D, with block depth of 1. Unable to provoke VU_01277.
1849 
1850         // non-multiple extents are allowed if at the far edge of a non-block-multiple image - these should pass
1851         m_errorMonitor->ExpectSuccess();
1852         region.imageExtent.width = 66;
1853         region.imageOffset.x = 64;
1854         vkCmdCopyImageToBuffer(m_commandBuffer->handle(), image_NPOT_4x4comp.handle(), VK_IMAGE_LAYOUT_GENERAL, buffer_16k.handle(),
1855                                1, &region);
1856         region.imageExtent.width = 16;
1857         region.imageOffset.x = 0;
1858         region.imageExtent.height = 2;
1859         region.imageOffset.y = 128;
1860         vkCmdCopyImageToBuffer(m_commandBuffer->handle(), image_NPOT_4x4comp.handle(), VK_IMAGE_LAYOUT_GENERAL, buffer_16k.handle(),
1861                                1, &region);
1862         m_errorMonitor->VerifyNotFound();
1863         region.imageOffset = {0, 0, 0};
1864 
1865         // buffer offset must be a multiple of texel block size (16)
1866         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkBufferImageCopy-bufferOffset-00206");
1867         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkBufferImageCopy-bufferOffset-00193");
1868         region.imageExtent = {64, 64, 1};
1869         region.bufferOffset = 24;
1870         vkCmdCopyImageToBuffer(m_commandBuffer->handle(), image_16k_4x4comp.handle(), VK_IMAGE_LAYOUT_GENERAL, buffer_16k.handle(),
1871                                1, &region);
1872         m_errorMonitor->VerifyFound();
1873 
1874         // rowlength not a multiple of block width (4)
1875         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkBufferImageCopy-bufferRowLength-00203");
1876         region.bufferOffset = 0;
1877         region.bufferRowLength = 130;
1878         region.bufferImageHeight = 0;
1879         vkCmdCopyImageToBuffer(m_commandBuffer->handle(), image_16k_4x4comp.handle(), VK_IMAGE_LAYOUT_GENERAL, buffer_64k.handle(),
1880                                1, &region);
1881         m_errorMonitor->VerifyFound();
1882 
1883         // imageheight not a multiple of block height (4)
1884         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkBufferImageCopy-bufferImageHeight-00204");
1885         region.bufferRowLength = 0;
1886         region.bufferImageHeight = 130;
1887         vkCmdCopyImageToBuffer(m_commandBuffer->handle(), image_16k_4x4comp.handle(), VK_IMAGE_LAYOUT_GENERAL, buffer_64k.handle(),
1888                                1, &region);
1889         m_errorMonitor->VerifyFound();
1890     }
1891 }
1892 
TEST_F(VkLayerTest,MiscImageLayerTests)1893 TEST_F(VkLayerTest, MiscImageLayerTests) {
1894     TEST_DESCRIPTION("Image-related tests that don't belong elsewhere");
1895 
1896     ASSERT_NO_FATAL_FAILURE(Init());
1897 
1898     // TODO: Ideally we should check if a format is supported, before using it.
1899     VkImageObj image(m_device);
1900     image.Init(128, 128, 1, VK_FORMAT_R16G16B16A16_UINT, VK_IMAGE_USAGE_TRANSFER_DST_BIT, VK_IMAGE_TILING_OPTIMAL, 0);  // 64bpp
1901     ASSERT_TRUE(image.initialized());
1902     VkBufferObj buffer;
1903     VkMemoryPropertyFlags reqs = 0;
1904     buffer.init_as_src(*m_device, 128 * 128 * 8, reqs);
1905     VkBufferImageCopy region = {};
1906     region.bufferRowLength = 128;
1907     region.bufferImageHeight = 128;
1908     region.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
1909     // layerCount can't be 0 - Expect MISMATCHED_IMAGE_ASPECT
1910     region.imageSubresource.layerCount = 1;
1911     region.imageExtent.height = 4;
1912     region.imageExtent.width = 4;
1913     region.imageExtent.depth = 1;
1914 
1915     VkImageObj image2(m_device);
1916     image2.Init(128, 128, 1, VK_FORMAT_R8G8_UNORM, VK_IMAGE_USAGE_TRANSFER_DST_BIT, VK_IMAGE_TILING_OPTIMAL, 0);  // 16bpp
1917     ASSERT_TRUE(image2.initialized());
1918     VkBufferObj buffer2;
1919     VkMemoryPropertyFlags reqs2 = 0;
1920     buffer2.init_as_src(*m_device, 128 * 128 * 2, reqs2);
1921     VkBufferImageCopy region2 = {};
1922     region2.bufferRowLength = 128;
1923     region2.bufferImageHeight = 128;
1924     region2.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
1925     // layerCount can't be 0 - Expect MISMATCHED_IMAGE_ASPECT
1926     region2.imageSubresource.layerCount = 1;
1927     region2.imageExtent.height = 4;
1928     region2.imageExtent.width = 4;
1929     region2.imageExtent.depth = 1;
1930     m_commandBuffer->begin();
1931 
1932     // Image must have offset.z of 0 and extent.depth of 1
1933     // Introduce failure by setting imageExtent.depth to 0
1934     region.imageExtent.depth = 0;
1935     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkBufferImageCopy-srcImage-00201");
1936     vkCmdCopyBufferToImage(m_commandBuffer->handle(), buffer.handle(), image.handle(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1,
1937                            &region);
1938     m_errorMonitor->VerifyFound();
1939 
1940     region.imageExtent.depth = 1;
1941 
1942     // Image must have offset.z of 0 and extent.depth of 1
1943     // Introduce failure by setting imageOffset.z to 4
1944     // Note: Also (unavoidably) triggers 'region exceeds image' #1228
1945     region.imageOffset.z = 4;
1946     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkBufferImageCopy-srcImage-00201");
1947     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkBufferImageCopy-imageOffset-00200");
1948     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdCopyBufferToImage-pRegions-00172");
1949     vkCmdCopyBufferToImage(m_commandBuffer->handle(), buffer.handle(), image.handle(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1,
1950                            &region);
1951     m_errorMonitor->VerifyFound();
1952 
1953     region.imageOffset.z = 0;
1954     // BufferOffset must be a multiple of the calling command's VkImage parameter's texel size
1955     // Introduce failure by setting bufferOffset to 1 and 1/2 texels
1956     region.bufferOffset = 4;
1957     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkBufferImageCopy-bufferOffset-00193");
1958     vkCmdCopyBufferToImage(m_commandBuffer->handle(), buffer.handle(), image.handle(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1,
1959                            &region);
1960     m_errorMonitor->VerifyFound();
1961 
1962     // BufferOffset must be a multiple of 4
1963     // Introduce failure by setting bufferOffset to a value not divisible by 4
1964     region2.bufferOffset = 6;
1965     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkBufferImageCopy-bufferOffset-00194");
1966     vkCmdCopyBufferToImage(m_commandBuffer->handle(), buffer2.handle(), image2.handle(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1,
1967                            &region2);
1968     m_errorMonitor->VerifyFound();
1969 
1970     // BufferRowLength must be 0, or greater than or equal to the width member of imageExtent
1971     region.bufferOffset = 0;
1972     region.imageExtent.height = 128;
1973     region.imageExtent.width = 128;
1974     // Introduce failure by setting bufferRowLength > 0 but less than width
1975     region.bufferRowLength = 64;
1976     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkBufferImageCopy-bufferRowLength-00195");
1977     vkCmdCopyBufferToImage(m_commandBuffer->handle(), buffer.handle(), image.handle(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1,
1978                            &region);
1979     m_errorMonitor->VerifyFound();
1980 
1981     // BufferImageHeight must be 0, or greater than or equal to the height member of imageExtent
1982     region.bufferRowLength = 128;
1983     // Introduce failure by setting bufferRowHeight > 0 but less than height
1984     region.bufferImageHeight = 64;
1985     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkBufferImageCopy-bufferImageHeight-00196");
1986     vkCmdCopyBufferToImage(m_commandBuffer->handle(), buffer.handle(), image.handle(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1,
1987                            &region);
1988     m_errorMonitor->VerifyFound();
1989 
1990     region.bufferImageHeight = 128;
1991     VkImageObj intImage1(m_device);
1992     intImage1.Init(128, 128, 1, VK_FORMAT_R8_UNORM, VK_IMAGE_USAGE_TRANSFER_SRC_BIT, VK_IMAGE_TILING_OPTIMAL, 0);
1993     intImage1.SetLayout(VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_GENERAL);
1994     VkImageObj intImage2(m_device);
1995     intImage2.Init(128, 128, 1, VK_FORMAT_R8_UNORM, VK_IMAGE_USAGE_TRANSFER_DST_BIT, VK_IMAGE_TILING_OPTIMAL, 0);
1996     intImage2.SetLayout(VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_GENERAL);
1997     VkImageBlit blitRegion = {};
1998     blitRegion.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
1999     blitRegion.srcSubresource.baseArrayLayer = 0;
2000     blitRegion.srcSubresource.layerCount = 1;
2001     blitRegion.srcSubresource.mipLevel = 0;
2002     blitRegion.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
2003     blitRegion.dstSubresource.baseArrayLayer = 0;
2004     blitRegion.dstSubresource.layerCount = 1;
2005     blitRegion.dstSubresource.mipLevel = 0;
2006     blitRegion.srcOffsets[0] = {128, 0, 0};
2007     blitRegion.srcOffsets[1] = {128, 128, 1};
2008     blitRegion.dstOffsets[0] = {0, 128, 0};
2009     blitRegion.dstOffsets[1] = {128, 128, 1};
2010 
2011     // Look for NULL-blit warning
2012     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_WARNING_BIT_EXT,
2013                                          "vkCmdBlitImage(): pRegions[0].srcOffsets specify a zero-volume area.");
2014     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_WARNING_BIT_EXT,
2015                                          "vkCmdBlitImage(): pRegions[0].dstOffsets specify a zero-volume area.");
2016     vkCmdBlitImage(m_commandBuffer->handle(), intImage1.handle(), intImage1.Layout(), intImage2.handle(), intImage2.Layout(), 1,
2017                    &blitRegion, VK_FILTER_LINEAR);
2018     m_errorMonitor->VerifyFound();
2019 }
2020 
TEST_F(VkLayerTest,CopyImageTypeExtentMismatch)2021 TEST_F(VkLayerTest, CopyImageTypeExtentMismatch) {
2022     // Image copy tests where format type and extents don't match
2023     ASSERT_NO_FATAL_FAILURE(Init());
2024 
2025     VkImageCreateInfo ci;
2026     ci.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
2027     ci.pNext = NULL;
2028     ci.flags = 0;
2029     ci.imageType = VK_IMAGE_TYPE_1D;
2030     ci.format = VK_FORMAT_R8G8B8A8_UNORM;
2031     ci.extent = {32, 1, 1};
2032     ci.mipLevels = 1;
2033     ci.arrayLayers = 1;
2034     ci.samples = VK_SAMPLE_COUNT_1_BIT;
2035     ci.tiling = VK_IMAGE_TILING_OPTIMAL;
2036     ci.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
2037     ci.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
2038     ci.queueFamilyIndexCount = 0;
2039     ci.pQueueFamilyIndices = NULL;
2040     ci.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
2041 
2042     // Create 1D image
2043     VkImageObj image_1D(m_device);
2044     image_1D.init(&ci);
2045     ASSERT_TRUE(image_1D.initialized());
2046 
2047     // 2D image
2048     ci.imageType = VK_IMAGE_TYPE_2D;
2049     ci.extent = {32, 32, 1};
2050     VkImageObj image_2D(m_device);
2051     image_2D.init(&ci);
2052     ASSERT_TRUE(image_2D.initialized());
2053 
2054     // 3D image
2055     ci.imageType = VK_IMAGE_TYPE_3D;
2056     ci.extent = {32, 32, 8};
2057     VkImageObj image_3D(m_device);
2058     image_3D.init(&ci);
2059     ASSERT_TRUE(image_3D.initialized());
2060 
2061     // 2D image array
2062     ci.imageType = VK_IMAGE_TYPE_2D;
2063     ci.extent = {32, 32, 1};
2064     ci.arrayLayers = 8;
2065     VkImageObj image_2D_array(m_device);
2066     image_2D_array.init(&ci);
2067     ASSERT_TRUE(image_2D_array.initialized());
2068 
2069     m_commandBuffer->begin();
2070 
2071     VkImageCopy copy_region;
2072     copy_region.extent = {32, 1, 1};
2073     copy_region.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
2074     copy_region.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
2075     copy_region.srcSubresource.mipLevel = 0;
2076     copy_region.dstSubresource.mipLevel = 0;
2077     copy_region.srcSubresource.baseArrayLayer = 0;
2078     copy_region.dstSubresource.baseArrayLayer = 0;
2079     copy_region.srcSubresource.layerCount = 1;
2080     copy_region.dstSubresource.layerCount = 1;
2081     copy_region.srcOffset = {0, 0, 0};
2082     copy_region.dstOffset = {0, 0, 0};
2083 
2084     // Sanity check
2085     m_errorMonitor->ExpectSuccess();
2086     m_commandBuffer->CopyImage(image_1D.image(), VK_IMAGE_LAYOUT_GENERAL, image_2D.image(), VK_IMAGE_LAYOUT_GENERAL, 1,
2087                                &copy_region);
2088     m_errorMonitor->VerifyNotFound();
2089 
2090     // 1D texture w/ offset.y > 0. Source = VU 09c00124, dest = 09c00130
2091     copy_region.srcOffset.y = 1;
2092     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkImageCopy-srcImage-00146");
2093     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkImageCopy-srcOffset-00145");  // also y-dim overrun
2094     m_commandBuffer->CopyImage(image_1D.image(), VK_IMAGE_LAYOUT_GENERAL, image_2D.image(), VK_IMAGE_LAYOUT_GENERAL, 1,
2095                                &copy_region);
2096     m_errorMonitor->VerifyFound();
2097     copy_region.srcOffset.y = 0;
2098     copy_region.dstOffset.y = 1;
2099     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkImageCopy-dstImage-00152");
2100     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkImageCopy-dstOffset-00151");  // also y-dim overrun
2101     m_commandBuffer->CopyImage(image_2D.image(), VK_IMAGE_LAYOUT_GENERAL, image_1D.image(), VK_IMAGE_LAYOUT_GENERAL, 1,
2102                                &copy_region);
2103     m_errorMonitor->VerifyFound();
2104     copy_region.dstOffset.y = 0;
2105 
2106     // 1D texture w/ extent.height > 1. Source = VU 09c00124, dest = 09c00130
2107     copy_region.extent.height = 2;
2108     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkImageCopy-srcImage-00146");
2109     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkImageCopy-srcOffset-00145");  // also y-dim overrun
2110     m_commandBuffer->CopyImage(image_1D.image(), VK_IMAGE_LAYOUT_GENERAL, image_2D.image(), VK_IMAGE_LAYOUT_GENERAL, 1,
2111                                &copy_region);
2112     m_errorMonitor->VerifyFound();
2113     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkImageCopy-dstImage-00152");
2114     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkImageCopy-dstOffset-00151");  // also y-dim overrun
2115     m_commandBuffer->CopyImage(image_2D.image(), VK_IMAGE_LAYOUT_GENERAL, image_1D.image(), VK_IMAGE_LAYOUT_GENERAL, 1,
2116                                &copy_region);
2117     m_errorMonitor->VerifyFound();
2118     copy_region.extent.height = 1;
2119 
2120     // 1D texture w/ offset.z > 0. Source = VU 09c00df2, dest = 09c00df4
2121     copy_region.srcOffset.z = 1;
2122     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkImageCopy-srcImage-01785");
2123     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkImageCopy-srcOffset-00147");  // also z-dim overrun
2124     m_commandBuffer->CopyImage(image_1D.image(), VK_IMAGE_LAYOUT_GENERAL, image_2D.image(), VK_IMAGE_LAYOUT_GENERAL, 1,
2125                                &copy_region);
2126     m_errorMonitor->VerifyFound();
2127     copy_region.srcOffset.z = 0;
2128     copy_region.dstOffset.z = 1;
2129     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkImageCopy-dstImage-01786");
2130     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkImageCopy-dstOffset-00153");  // also z-dim overrun
2131     m_commandBuffer->CopyImage(image_2D.image(), VK_IMAGE_LAYOUT_GENERAL, image_1D.image(), VK_IMAGE_LAYOUT_GENERAL, 1,
2132                                &copy_region);
2133     m_errorMonitor->VerifyFound();
2134     copy_region.dstOffset.z = 0;
2135 
2136     // 1D texture w/ extent.depth > 1. Source = VU 09c00df2, dest = 09c00df4
2137     copy_region.extent.depth = 2;
2138     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkImageCopy-srcImage-01785");
2139     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
2140                                          "VUID-VkImageCopy-srcOffset-00147");  // also z-dim overrun (src)
2141     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
2142                                          "VUID-VkImageCopy-dstOffset-00153");  // also z-dim overrun (dst)
2143     m_commandBuffer->CopyImage(image_1D.image(), VK_IMAGE_LAYOUT_GENERAL, image_2D.image(), VK_IMAGE_LAYOUT_GENERAL, 1,
2144                                &copy_region);
2145     m_errorMonitor->VerifyFound();
2146     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkImageCopy-dstImage-01786");
2147     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
2148                                          "VUID-VkImageCopy-srcOffset-00147");  // also z-dim overrun (src)
2149     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
2150                                          "VUID-VkImageCopy-dstOffset-00153");  // also z-dim overrun (dst)
2151     m_commandBuffer->CopyImage(image_2D.image(), VK_IMAGE_LAYOUT_GENERAL, image_1D.image(), VK_IMAGE_LAYOUT_GENERAL, 1,
2152                                &copy_region);
2153     m_errorMonitor->VerifyFound();
2154     copy_region.extent.depth = 1;
2155 
2156     // 2D texture w/ offset.z > 0. Source = VU 09c00df6, dest = 09c00df8
2157     copy_region.extent = {16, 16, 1};
2158     copy_region.srcOffset.z = 4;
2159     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkImageCopy-srcImage-01787");
2160     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
2161                                          "VUID-VkImageCopy-srcOffset-00147");  // also z-dim overrun (src)
2162     m_commandBuffer->CopyImage(image_2D.image(), VK_IMAGE_LAYOUT_GENERAL, image_3D.image(), VK_IMAGE_LAYOUT_GENERAL, 1,
2163                                &copy_region);
2164     m_errorMonitor->VerifyFound();
2165     copy_region.srcOffset.z = 0;
2166     copy_region.dstOffset.z = 1;
2167     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkImageCopy-dstImage-01788");
2168     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
2169                                          "VUID-VkImageCopy-dstOffset-00153");  // also z-dim overrun (dst)
2170     m_commandBuffer->CopyImage(image_3D.image(), VK_IMAGE_LAYOUT_GENERAL, image_2D.image(), VK_IMAGE_LAYOUT_GENERAL, 1,
2171                                &copy_region);
2172     m_errorMonitor->VerifyFound();
2173     copy_region.dstOffset.z = 0;
2174 
2175     // 3D texture accessing an array layer other than 0. VU 09c0011a
2176     copy_region.extent = {4, 4, 1};
2177     copy_region.srcSubresource.baseArrayLayer = 1;
2178     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkImageCopy-srcImage-00141");
2179     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
2180                                          "VUID-vkCmdCopyImage-srcSubresource-01698");  // also 'too many layers'
2181     m_commandBuffer->CopyImage(image_3D.image(), VK_IMAGE_LAYOUT_GENERAL, image_2D.image(), VK_IMAGE_LAYOUT_GENERAL, 1,
2182                                &copy_region);
2183     m_errorMonitor->VerifyFound();
2184     m_commandBuffer->end();
2185 }
2186 
TEST_F(VkLayerTest,CopyImageTypeExtentMismatchMaintenance1)2187 TEST_F(VkLayerTest, CopyImageTypeExtentMismatchMaintenance1) {
2188     // Image copy tests where format type and extents don't match and the Maintenance1 extension is enabled
2189     ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor));
2190     if (DeviceExtensionSupported(gpu(), nullptr, VK_KHR_MAINTENANCE1_EXTENSION_NAME)) {
2191         m_device_extension_names.push_back(VK_KHR_MAINTENANCE1_EXTENSION_NAME);
2192     } else {
2193         printf("%s Maintenance1 extension cannot be enabled, test skipped.\n", kSkipPrefix);
2194         return;
2195     }
2196     ASSERT_NO_FATAL_FAILURE(InitState());
2197 
2198     VkFormat image_format = VK_FORMAT_R8G8B8A8_UNORM;
2199     VkFormatProperties format_props;
2200     // TODO: Remove this check if or when devsim handles extensions.
2201     // The chosen format has mandatory support the transfer src and dst format features when Maitenance1 is enabled. However, our
2202     // use of devsim and the mock ICD violate this guarantee.
2203     vkGetPhysicalDeviceFormatProperties(m_device->phy().handle(), image_format, &format_props);
2204     if (!(format_props.optimalTilingFeatures & VK_FORMAT_FEATURE_TRANSFER_SRC_BIT)) {
2205         printf("%s Maintenance1 extension is not supported.\n", kSkipPrefix);
2206         return;
2207     }
2208 
2209     VkImageCreateInfo ci;
2210     ci.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
2211     ci.pNext = NULL;
2212     ci.flags = 0;
2213     ci.imageType = VK_IMAGE_TYPE_1D;
2214     ci.format = image_format;
2215     ci.extent = {32, 1, 1};
2216     ci.mipLevels = 1;
2217     ci.arrayLayers = 1;
2218     ci.samples = VK_SAMPLE_COUNT_1_BIT;
2219     ci.tiling = VK_IMAGE_TILING_OPTIMAL;
2220     ci.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
2221     ci.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
2222     ci.queueFamilyIndexCount = 0;
2223     ci.pQueueFamilyIndices = NULL;
2224     ci.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
2225 
2226     // Create 1D image
2227     VkImageObj image_1D(m_device);
2228     image_1D.init(&ci);
2229     ASSERT_TRUE(image_1D.initialized());
2230 
2231     // 2D image
2232     ci.imageType = VK_IMAGE_TYPE_2D;
2233     ci.extent = {32, 32, 1};
2234     VkImageObj image_2D(m_device);
2235     image_2D.init(&ci);
2236     ASSERT_TRUE(image_2D.initialized());
2237 
2238     // 3D image
2239     ci.imageType = VK_IMAGE_TYPE_3D;
2240     ci.extent = {32, 32, 8};
2241     VkImageObj image_3D(m_device);
2242     image_3D.init(&ci);
2243     ASSERT_TRUE(image_3D.initialized());
2244 
2245     // 2D image array
2246     ci.imageType = VK_IMAGE_TYPE_2D;
2247     ci.extent = {32, 32, 1};
2248     ci.arrayLayers = 8;
2249     VkImageObj image_2D_array(m_device);
2250     image_2D_array.init(&ci);
2251     ASSERT_TRUE(image_2D_array.initialized());
2252 
2253     m_commandBuffer->begin();
2254 
2255     VkImageCopy copy_region;
2256     copy_region.extent = {32, 1, 1};
2257     copy_region.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
2258     copy_region.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
2259     copy_region.srcSubresource.mipLevel = 0;
2260     copy_region.dstSubresource.mipLevel = 0;
2261     copy_region.srcSubresource.baseArrayLayer = 0;
2262     copy_region.dstSubresource.baseArrayLayer = 0;
2263     copy_region.srcSubresource.layerCount = 1;
2264     copy_region.dstSubresource.layerCount = 1;
2265     copy_region.srcOffset = {0, 0, 0};
2266     copy_region.dstOffset = {0, 0, 0};
2267 
2268     // Copy from layer not present
2269     copy_region.srcSubresource.baseArrayLayer = 4;
2270     copy_region.srcSubresource.layerCount = 6;
2271     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdCopyImage-srcSubresource-01698");
2272     m_commandBuffer->CopyImage(image_2D_array.image(), VK_IMAGE_LAYOUT_GENERAL, image_3D.image(), VK_IMAGE_LAYOUT_GENERAL, 1,
2273                                &copy_region);
2274     m_errorMonitor->VerifyFound();
2275     copy_region.srcSubresource.baseArrayLayer = 0;
2276     copy_region.srcSubresource.layerCount = 1;
2277 
2278     // Copy to layer not present
2279     copy_region.dstSubresource.baseArrayLayer = 1;
2280     copy_region.dstSubresource.layerCount = 8;
2281     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdCopyImage-dstSubresource-01699");
2282     m_commandBuffer->CopyImage(image_3D.image(), VK_IMAGE_LAYOUT_GENERAL, image_2D_array.image(), VK_IMAGE_LAYOUT_GENERAL, 1,
2283                                &copy_region);
2284     m_errorMonitor->VerifyFound();
2285     copy_region.dstSubresource.layerCount = 1;
2286 
2287     m_commandBuffer->end();
2288 }
2289 
TEST_F(VkLayerTest,CopyImageCompressedBlockAlignment)2290 TEST_F(VkLayerTest, CopyImageCompressedBlockAlignment) {
2291     // Image copy tests on compressed images with block alignment errors
2292     SetTargetApiVersion(VK_API_VERSION_1_1);
2293     ASSERT_NO_FATAL_FAILURE(Init());
2294 
2295     // Select a compressed format and verify support
2296     VkPhysicalDeviceFeatures device_features = {};
2297     ASSERT_NO_FATAL_FAILURE(GetPhysicalDeviceFeatures(&device_features));
2298     VkFormat compressed_format = VK_FORMAT_UNDEFINED;
2299     if (device_features.textureCompressionBC) {
2300         compressed_format = VK_FORMAT_BC3_SRGB_BLOCK;
2301     } else if (device_features.textureCompressionETC2) {
2302         compressed_format = VK_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK;
2303     } else if (device_features.textureCompressionASTC_LDR) {
2304         compressed_format = VK_FORMAT_ASTC_4x4_UNORM_BLOCK;
2305     }
2306 
2307     VkImageCreateInfo ci;
2308     ci.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
2309     ci.pNext = NULL;
2310     ci.flags = 0;
2311     ci.imageType = VK_IMAGE_TYPE_2D;
2312     ci.format = compressed_format;
2313     ci.extent = {64, 64, 1};
2314     ci.mipLevels = 1;
2315     ci.arrayLayers = 1;
2316     ci.samples = VK_SAMPLE_COUNT_1_BIT;
2317     ci.tiling = VK_IMAGE_TILING_OPTIMAL;
2318     ci.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
2319     ci.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
2320     ci.queueFamilyIndexCount = 0;
2321     ci.pQueueFamilyIndices = NULL;
2322     ci.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
2323 
2324     VkImageFormatProperties img_prop = {};
2325     if (VK_SUCCESS != vkGetPhysicalDeviceImageFormatProperties(m_device->phy().handle(), ci.format, ci.imageType, ci.tiling,
2326                                                                ci.usage, ci.flags, &img_prop)) {
2327         printf("%s No compressed formats supported - CopyImageCompressedBlockAlignment skipped.\n", kSkipPrefix);
2328         return;
2329     }
2330 
2331     // Create images
2332     VkImageObj image_1(m_device);
2333     image_1.init(&ci);
2334     ASSERT_TRUE(image_1.initialized());
2335 
2336     ci.extent = {62, 62, 1};  // slightly smaller and not divisible by block size
2337     VkImageObj image_2(m_device);
2338     image_2.init(&ci);
2339     ASSERT_TRUE(image_2.initialized());
2340 
2341     m_commandBuffer->begin();
2342 
2343     VkImageCopy copy_region;
2344     copy_region.extent = {48, 48, 1};
2345     copy_region.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
2346     copy_region.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
2347     copy_region.srcSubresource.mipLevel = 0;
2348     copy_region.dstSubresource.mipLevel = 0;
2349     copy_region.srcSubresource.baseArrayLayer = 0;
2350     copy_region.dstSubresource.baseArrayLayer = 0;
2351     copy_region.srcSubresource.layerCount = 1;
2352     copy_region.dstSubresource.layerCount = 1;
2353     copy_region.srcOffset = {0, 0, 0};
2354     copy_region.dstOffset = {0, 0, 0};
2355 
2356     // Sanity check
2357     m_errorMonitor->ExpectSuccess();
2358     m_commandBuffer->CopyImage(image_1.image(), VK_IMAGE_LAYOUT_GENERAL, image_2.image(), VK_IMAGE_LAYOUT_GENERAL, 1, &copy_region);
2359     m_errorMonitor->VerifyNotFound();
2360 
2361     std::string vuid;
2362     bool ycbcr = (DeviceExtensionEnabled(VK_KHR_SAMPLER_YCBCR_CONVERSION_EXTENSION_NAME) ||
2363                   (DeviceValidationVersion() >= VK_API_VERSION_1_1));
2364 
2365     // Src, Dest offsets must be multiples of compressed block sizes {4, 4, 1}
2366     // Image transfer granularity gets set to compressed block size, so an ITG error is also (unavoidably) triggered.
2367     vuid = ycbcr ? "VUID-VkImageCopy-srcImage-01727" : "VUID-VkImageCopy-srcOffset-00157";
2368     copy_region.srcOffset = {2, 4, 0};  // source width
2369     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, vuid);
2370     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
2371                                          "VUID-vkCmdCopyImage-srcOffset-01783");  // srcOffset image transfer granularity
2372     m_commandBuffer->CopyImage(image_1.image(), VK_IMAGE_LAYOUT_GENERAL, image_2.image(), VK_IMAGE_LAYOUT_GENERAL, 1, &copy_region);
2373     m_errorMonitor->VerifyFound();
2374     copy_region.srcOffset = {12, 1, 0};  // source height
2375     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, vuid);
2376     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
2377                                          "VUID-vkCmdCopyImage-srcOffset-01783");  // srcOffset image transfer granularity
2378     m_commandBuffer->CopyImage(image_1.image(), VK_IMAGE_LAYOUT_GENERAL, image_2.image(), VK_IMAGE_LAYOUT_GENERAL, 1, &copy_region);
2379     m_errorMonitor->VerifyFound();
2380     copy_region.srcOffset = {0, 0, 0};
2381 
2382     vuid = ycbcr ? "VUID-VkImageCopy-dstImage-01731" : "VUID-VkImageCopy-dstOffset-00162";
2383     copy_region.dstOffset = {1, 0, 0};  // dest width
2384     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, vuid);
2385     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
2386                                          "VUID-vkCmdCopyImage-dstOffset-01784");  // dstOffset image transfer granularity
2387     m_commandBuffer->CopyImage(image_1.image(), VK_IMAGE_LAYOUT_GENERAL, image_2.image(), VK_IMAGE_LAYOUT_GENERAL, 1, &copy_region);
2388     m_errorMonitor->VerifyFound();
2389     copy_region.dstOffset = {4, 1, 0};  // dest height
2390     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, vuid);
2391     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
2392                                          "VUID-vkCmdCopyImage-dstOffset-01784");  // dstOffset image transfer granularity
2393     m_commandBuffer->CopyImage(image_1.image(), VK_IMAGE_LAYOUT_GENERAL, image_2.image(), VK_IMAGE_LAYOUT_GENERAL, 1, &copy_region);
2394     m_errorMonitor->VerifyFound();
2395     copy_region.dstOffset = {0, 0, 0};
2396 
2397     // Copy extent must be multiples of compressed block sizes {4, 4, 1} if not full width/height
2398     vuid = ycbcr ? "VUID-VkImageCopy-srcImage-01728" : "VUID-VkImageCopy-extent-00158";
2399     copy_region.extent = {62, 60, 1};  // source width
2400     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, vuid);
2401     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
2402                                          "VUID-vkCmdCopyImage-srcOffset-01783");  // src extent image transfer granularity
2403     m_commandBuffer->CopyImage(image_1.image(), VK_IMAGE_LAYOUT_GENERAL, image_2.image(), VK_IMAGE_LAYOUT_GENERAL, 1, &copy_region);
2404     m_errorMonitor->VerifyFound();
2405     vuid = ycbcr ? "VUID-VkImageCopy-srcImage-01729" : "VUID-VkImageCopy-extent-00159";
2406     copy_region.extent = {60, 62, 1};  // source height
2407     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, vuid);
2408     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
2409                                          "VUID-vkCmdCopyImage-srcOffset-01783");  // src extent image transfer granularity
2410     m_commandBuffer->CopyImage(image_1.image(), VK_IMAGE_LAYOUT_GENERAL, image_2.image(), VK_IMAGE_LAYOUT_GENERAL, 1, &copy_region);
2411     m_errorMonitor->VerifyFound();
2412 
2413     vuid = ycbcr ? "VUID-VkImageCopy-dstImage-01732" : "VUID-VkImageCopy-extent-00163";
2414     copy_region.extent = {62, 60, 1};  // dest width
2415     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, vuid);
2416     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
2417                                          "VUID-vkCmdCopyImage-dstOffset-01784");  // dst extent image transfer granularity
2418     m_commandBuffer->CopyImage(image_2.image(), VK_IMAGE_LAYOUT_GENERAL, image_1.image(), VK_IMAGE_LAYOUT_GENERAL, 1, &copy_region);
2419     m_errorMonitor->VerifyFound();
2420     vuid = ycbcr ? "VUID-VkImageCopy-dstImage-01733" : "VUID-VkImageCopy-extent-00164";
2421     copy_region.extent = {60, 62, 1};  // dest height
2422     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, vuid);
2423     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
2424                                          "VUID-vkCmdCopyImage-dstOffset-01784");  // dst extent image transfer granularity
2425     m_commandBuffer->CopyImage(image_2.image(), VK_IMAGE_LAYOUT_GENERAL, image_1.image(), VK_IMAGE_LAYOUT_GENERAL, 1, &copy_region);
2426     m_errorMonitor->VerifyFound();
2427 
2428     // Note: "VUID-VkImageCopy-extent-00160", "VUID-VkImageCopy-extent-00165", "VUID-VkImageCopy-srcImage-01730",
2429     // "VUID-VkImageCopy-dstImage-01734"
2430     //       There are currently no supported compressed formats with a block depth other than 1,
2431     //       so impossible to create a 'not a multiple' condition for depth.
2432     m_commandBuffer->end();
2433 }
2434 
TEST_F(VkLayerTest,CopyImageSinglePlane422Alignment)2435 TEST_F(VkLayerTest, CopyImageSinglePlane422Alignment) {
2436     // Image copy tests on single-plane _422 formats with block alignment errors
2437 
2438     // Enable KHR multiplane req'd extensions
2439     bool mp_extensions = InstanceExtensionSupported(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME,
2440                                                     VK_KHR_GET_MEMORY_REQUIREMENTS_2_SPEC_VERSION);
2441     if (mp_extensions) {
2442         m_instance_extension_names.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
2443     }
2444     ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor));
2445     mp_extensions = mp_extensions && DeviceExtensionSupported(gpu(), nullptr, VK_KHR_MAINTENANCE1_EXTENSION_NAME);
2446     mp_extensions = mp_extensions && DeviceExtensionSupported(gpu(), nullptr, VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME);
2447     mp_extensions = mp_extensions && DeviceExtensionSupported(gpu(), nullptr, VK_KHR_BIND_MEMORY_2_EXTENSION_NAME);
2448     mp_extensions = mp_extensions && DeviceExtensionSupported(gpu(), nullptr, VK_KHR_SAMPLER_YCBCR_CONVERSION_EXTENSION_NAME);
2449     if (mp_extensions) {
2450         m_device_extension_names.push_back(VK_KHR_MAINTENANCE1_EXTENSION_NAME);
2451         m_device_extension_names.push_back(VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME);
2452         m_device_extension_names.push_back(VK_KHR_BIND_MEMORY_2_EXTENSION_NAME);
2453         m_device_extension_names.push_back(VK_KHR_SAMPLER_YCBCR_CONVERSION_EXTENSION_NAME);
2454     } else {
2455         printf("%s test requires KHR multiplane extensions, not available.  Skipping.\n", kSkipPrefix);
2456         return;
2457     }
2458     ASSERT_NO_FATAL_FAILURE(InitState());
2459 
2460     // Select a _422 format and verify support
2461     VkImageCreateInfo ci = {};
2462     ci.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
2463     ci.pNext = NULL;
2464     ci.flags = 0;
2465     ci.imageType = VK_IMAGE_TYPE_2D;
2466     ci.format = VK_FORMAT_G8B8G8R8_422_UNORM_KHR;
2467     ci.tiling = VK_IMAGE_TILING_OPTIMAL;
2468     ci.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
2469     ci.mipLevels = 1;
2470     ci.arrayLayers = 1;
2471     ci.samples = VK_SAMPLE_COUNT_1_BIT;
2472     ci.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
2473     ci.queueFamilyIndexCount = 0;
2474     ci.pQueueFamilyIndices = NULL;
2475     ci.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
2476 
2477     // Verify formats
2478     VkFormatFeatureFlags features = VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT;
2479     bool supported = ImageFormatAndFeaturesSupported(instance(), gpu(), ci, features);
2480     if (!supported) {
2481         printf("%s Single-plane _422 image format not supported.  Skipping test.\n", kSkipPrefix);
2482         return;  // Assume there's low ROI on searching for different mp formats
2483     }
2484 
2485     // Create images
2486     ci.extent = {64, 64, 1};
2487     VkImageObj image_422(m_device);
2488     image_422.init(&ci);
2489     ASSERT_TRUE(image_422.initialized());
2490 
2491     ci.extent = {64, 64, 1};
2492     ci.format = VK_FORMAT_R8G8B8A8_UNORM;
2493     VkImageObj image_ucmp(m_device);
2494     image_ucmp.init(&ci);
2495     ASSERT_TRUE(image_ucmp.initialized());
2496 
2497     m_commandBuffer->begin();
2498 
2499     VkImageCopy copy_region;
2500     copy_region.extent = {48, 48, 1};
2501     copy_region.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
2502     copy_region.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
2503     copy_region.srcSubresource.mipLevel = 0;
2504     copy_region.dstSubresource.mipLevel = 0;
2505     copy_region.srcSubresource.baseArrayLayer = 0;
2506     copy_region.dstSubresource.baseArrayLayer = 0;
2507     copy_region.srcSubresource.layerCount = 1;
2508     copy_region.dstSubresource.layerCount = 1;
2509     copy_region.srcOffset = {0, 0, 0};
2510     copy_region.dstOffset = {0, 0, 0};
2511 
2512     // Src offsets must be multiples of compressed block sizes
2513     copy_region.srcOffset = {3, 4, 0};  // source offset x
2514     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkImageCopy-srcImage-01727");
2515     m_commandBuffer->CopyImage(image_422.image(), VK_IMAGE_LAYOUT_GENERAL, image_ucmp.image(), VK_IMAGE_LAYOUT_GENERAL, 1,
2516                                &copy_region);
2517     m_errorMonitor->VerifyFound();
2518     copy_region.srcOffset = {0, 0, 0};
2519 
2520     // Dst offsets must be multiples of compressed block sizes
2521     copy_region.dstOffset = {1, 0, 0};
2522     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkImageCopy-dstImage-01731");
2523     m_commandBuffer->CopyImage(image_ucmp.image(), VK_IMAGE_LAYOUT_GENERAL, image_422.image(), VK_IMAGE_LAYOUT_GENERAL, 1,
2524                                &copy_region);
2525     m_errorMonitor->VerifyFound();
2526     copy_region.dstOffset = {0, 0, 0};
2527 
2528     // Copy extent must be multiples of compressed block sizes if not full width/height
2529     copy_region.extent = {31, 60, 1};  // 422 source, extent.x
2530     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkImageCopy-srcImage-01728");
2531     m_commandBuffer->CopyImage(image_422.image(), VK_IMAGE_LAYOUT_GENERAL, image_ucmp.image(), VK_IMAGE_LAYOUT_GENERAL, 1,
2532                                &copy_region);
2533     m_errorMonitor->VerifyFound();
2534 
2535     // 422 dest, extent.x
2536     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkImageCopy-dstImage-01732");
2537     m_commandBuffer->CopyImage(image_ucmp.image(), VK_IMAGE_LAYOUT_GENERAL, image_422.image(), VK_IMAGE_LAYOUT_GENERAL, 1,
2538                                &copy_region);
2539     m_errorMonitor->VerifyFound();
2540     copy_region.dstOffset = {0, 0, 0};
2541 
2542     m_commandBuffer->end();
2543 }
2544 
TEST_F(VkLayerTest,CopyImageMultiplaneAspectBits)2545 TEST_F(VkLayerTest, CopyImageMultiplaneAspectBits) {
2546     // Image copy tests on multiplane images with aspect errors
2547 
2548     // Enable KHR multiplane req'd extensions
2549     bool mp_extensions = InstanceExtensionSupported(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME,
2550                                                     VK_KHR_GET_MEMORY_REQUIREMENTS_2_SPEC_VERSION);
2551     if (mp_extensions) {
2552         m_instance_extension_names.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
2553     }
2554     ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor));
2555     mp_extensions = mp_extensions && DeviceExtensionSupported(gpu(), nullptr, VK_KHR_MAINTENANCE1_EXTENSION_NAME);
2556     mp_extensions = mp_extensions && DeviceExtensionSupported(gpu(), nullptr, VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME);
2557     mp_extensions = mp_extensions && DeviceExtensionSupported(gpu(), nullptr, VK_KHR_BIND_MEMORY_2_EXTENSION_NAME);
2558     mp_extensions = mp_extensions && DeviceExtensionSupported(gpu(), nullptr, VK_KHR_SAMPLER_YCBCR_CONVERSION_EXTENSION_NAME);
2559     if (mp_extensions) {
2560         m_device_extension_names.push_back(VK_KHR_MAINTENANCE1_EXTENSION_NAME);
2561         m_device_extension_names.push_back(VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME);
2562         m_device_extension_names.push_back(VK_KHR_BIND_MEMORY_2_EXTENSION_NAME);
2563         m_device_extension_names.push_back(VK_KHR_SAMPLER_YCBCR_CONVERSION_EXTENSION_NAME);
2564     } else {
2565         printf("%s test requires KHR multiplane extensions, not available.  Skipping.\n", kSkipPrefix);
2566         return;
2567     }
2568     ASSERT_NO_FATAL_FAILURE(InitState());
2569 
2570     // Select multi-plane formats and verify support
2571     VkFormat mp3_format = VK_FORMAT_G8_B8_R8_3PLANE_422_UNORM_KHR;
2572     VkFormat mp2_format = VK_FORMAT_G8_B8R8_2PLANE_422_UNORM_KHR;
2573 
2574     VkImageCreateInfo ci = {};
2575     ci.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
2576     ci.pNext = NULL;
2577     ci.flags = 0;
2578     ci.imageType = VK_IMAGE_TYPE_2D;
2579     ci.format = mp2_format;
2580     ci.extent = {256, 256, 1};
2581     ci.tiling = VK_IMAGE_TILING_OPTIMAL;
2582     ci.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
2583     ci.mipLevels = 1;
2584     ci.arrayLayers = 1;
2585     ci.samples = VK_SAMPLE_COUNT_1_BIT;
2586     ci.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
2587     ci.queueFamilyIndexCount = 0;
2588     ci.pQueueFamilyIndices = NULL;
2589     ci.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
2590 
2591     // Verify formats
2592     VkFormatFeatureFlags features = VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT;
2593     bool supported = ImageFormatAndFeaturesSupported(instance(), gpu(), ci, features);
2594     ci.format = VK_FORMAT_D24_UNORM_S8_UINT;
2595     supported = supported && ImageFormatAndFeaturesSupported(instance(), gpu(), ci, features);
2596     ci.format = mp3_format;
2597     supported = supported && ImageFormatAndFeaturesSupported(instance(), gpu(), ci, features);
2598     if (!supported) {
2599         printf("%s Multiplane image formats or optimally tiled depth-stencil buffers not supported.  Skipping test.\n",
2600                kSkipPrefix);
2601         return;  // Assume there's low ROI on searching for different mp formats
2602     }
2603 
2604     // Create images
2605     VkImageObj mp3_image(m_device);
2606     mp3_image.init(&ci);
2607     ASSERT_TRUE(mp3_image.initialized());
2608 
2609     ci.format = mp2_format;
2610     VkImageObj mp2_image(m_device);
2611     mp2_image.init(&ci);
2612     ASSERT_TRUE(mp2_image.initialized());
2613 
2614     ci.format = VK_FORMAT_D24_UNORM_S8_UINT;
2615     VkImageObj sp_image(m_device);
2616     sp_image.init(&ci);
2617     ASSERT_TRUE(sp_image.initialized());
2618 
2619     m_commandBuffer->begin();
2620 
2621     VkImageCopy copy_region;
2622     copy_region.extent = {128, 128, 1};
2623     copy_region.srcSubresource.aspectMask = VK_IMAGE_ASPECT_PLANE_2_BIT_KHR;
2624     copy_region.dstSubresource.aspectMask = VK_IMAGE_ASPECT_PLANE_2_BIT_KHR;
2625     copy_region.srcSubresource.mipLevel = 0;
2626     copy_region.dstSubresource.mipLevel = 0;
2627     copy_region.srcSubresource.baseArrayLayer = 0;
2628     copy_region.dstSubresource.baseArrayLayer = 0;
2629     copy_region.srcSubresource.layerCount = 1;
2630     copy_region.dstSubresource.layerCount = 1;
2631     copy_region.srcOffset = {0, 0, 0};
2632     copy_region.dstOffset = {0, 0, 0};
2633 
2634     m_errorMonitor->SetUnexpectedError("VUID-vkCmdCopyImage-srcImage-00135");
2635     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkImageCopy-srcImage-01552");
2636     m_commandBuffer->CopyImage(mp2_image.image(), VK_IMAGE_LAYOUT_GENERAL, mp3_image.image(), VK_IMAGE_LAYOUT_GENERAL, 1,
2637                                &copy_region);
2638     m_errorMonitor->VerifyFound();
2639 
2640     m_errorMonitor->SetUnexpectedError("VUID-vkCmdCopyImage-srcImage-00135");
2641     copy_region.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
2642     copy_region.dstSubresource.aspectMask = VK_IMAGE_ASPECT_PLANE_0_BIT_KHR;
2643     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkImageCopy-srcImage-01553");
2644     m_commandBuffer->CopyImage(mp3_image.image(), VK_IMAGE_LAYOUT_GENERAL, mp2_image.image(), VK_IMAGE_LAYOUT_GENERAL, 1,
2645                                &copy_region);
2646     m_errorMonitor->VerifyFound();
2647 
2648     copy_region.srcSubresource.aspectMask = VK_IMAGE_ASPECT_PLANE_1_BIT_KHR;
2649     copy_region.dstSubresource.aspectMask = VK_IMAGE_ASPECT_PLANE_2_BIT_KHR;
2650     m_errorMonitor->SetUnexpectedError("VUID-vkCmdCopyImage-srcImage-00135");
2651     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkImageCopy-dstImage-01554");
2652     m_commandBuffer->CopyImage(mp3_image.image(), VK_IMAGE_LAYOUT_GENERAL, mp2_image.image(), VK_IMAGE_LAYOUT_GENERAL, 1,
2653                                &copy_region);
2654     m_errorMonitor->VerifyFound();
2655 
2656     copy_region.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
2657     m_errorMonitor->SetUnexpectedError("VUID-vkCmdCopyImage-srcImage-00135");
2658     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkImageCopy-dstImage-01555");
2659     m_commandBuffer->CopyImage(mp2_image.image(), VK_IMAGE_LAYOUT_GENERAL, mp3_image.image(), VK_IMAGE_LAYOUT_GENERAL, 1,
2660                                &copy_region);
2661     m_errorMonitor->VerifyFound();
2662 
2663     copy_region.dstSubresource.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT;
2664     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkImageCopy-srcImage-01556");
2665     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "dest image depth/stencil formats");  // also
2666     m_commandBuffer->CopyImage(mp2_image.image(), VK_IMAGE_LAYOUT_GENERAL, sp_image.image(), VK_IMAGE_LAYOUT_GENERAL, 1,
2667                                &copy_region);
2668     m_errorMonitor->VerifyFound();
2669 
2670     copy_region.srcSubresource.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT;
2671     copy_region.dstSubresource.aspectMask = VK_IMAGE_ASPECT_PLANE_2_BIT_KHR;
2672     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkImageCopy-dstImage-01557");
2673     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "dest image depth/stencil formats");  // also
2674     m_commandBuffer->CopyImage(sp_image.image(), VK_IMAGE_LAYOUT_GENERAL, mp3_image.image(), VK_IMAGE_LAYOUT_GENERAL, 1,
2675                                &copy_region);
2676     m_errorMonitor->VerifyFound();
2677 
2678     m_commandBuffer->end();
2679 }
2680 
TEST_F(VkLayerTest,CopyImageSrcSizeExceeded)2681 TEST_F(VkLayerTest, CopyImageSrcSizeExceeded) {
2682     // Image copy with source region specified greater than src image size
2683     ASSERT_NO_FATAL_FAILURE(Init());
2684 
2685     // Create images with full mip chain
2686     VkImageCreateInfo ci;
2687     ci.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
2688     ci.pNext = NULL;
2689     ci.flags = 0;
2690     ci.imageType = VK_IMAGE_TYPE_3D;
2691     ci.format = VK_FORMAT_R8G8B8A8_UNORM;
2692     ci.extent = {32, 32, 8};
2693     ci.mipLevels = 6;
2694     ci.arrayLayers = 1;
2695     ci.samples = VK_SAMPLE_COUNT_1_BIT;
2696     ci.tiling = VK_IMAGE_TILING_OPTIMAL;
2697     ci.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
2698     ci.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
2699     ci.queueFamilyIndexCount = 0;
2700     ci.pQueueFamilyIndices = NULL;
2701     ci.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
2702 
2703     VkImageObj src_image(m_device);
2704     src_image.init(&ci);
2705     ASSERT_TRUE(src_image.initialized());
2706 
2707     // Dest image with one more mip level
2708     ci.extent = {64, 64, 16};
2709     ci.mipLevels = 7;
2710     ci.usage = VK_IMAGE_USAGE_TRANSFER_DST_BIT;
2711     VkImageObj dst_image(m_device);
2712     dst_image.init(&ci);
2713     ASSERT_TRUE(dst_image.initialized());
2714 
2715     m_commandBuffer->begin();
2716 
2717     VkImageCopy copy_region;
2718     copy_region.extent = {32, 32, 8};
2719     copy_region.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
2720     copy_region.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
2721     copy_region.srcSubresource.mipLevel = 0;
2722     copy_region.dstSubresource.mipLevel = 0;
2723     copy_region.srcSubresource.baseArrayLayer = 0;
2724     copy_region.dstSubresource.baseArrayLayer = 0;
2725     copy_region.srcSubresource.layerCount = 1;
2726     copy_region.dstSubresource.layerCount = 1;
2727     copy_region.srcOffset = {0, 0, 0};
2728     copy_region.dstOffset = {0, 0, 0};
2729 
2730     m_errorMonitor->ExpectSuccess();
2731     m_commandBuffer->CopyImage(src_image.image(), VK_IMAGE_LAYOUT_GENERAL, dst_image.image(), VK_IMAGE_LAYOUT_GENERAL, 1,
2732                                &copy_region);
2733     m_errorMonitor->VerifyNotFound();
2734 
2735     // Source exceeded in x-dim, VU 01202
2736     copy_region.srcOffset.x = 4;
2737     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
2738                                          "VUID-vkCmdCopyImage-pRegions-00122");  // General "contained within" VU
2739     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkImageCopy-srcOffset-00144");
2740     m_commandBuffer->CopyImage(src_image.image(), VK_IMAGE_LAYOUT_GENERAL, dst_image.image(), VK_IMAGE_LAYOUT_GENERAL, 1,
2741                                &copy_region);
2742     m_errorMonitor->VerifyFound();
2743 
2744     // Source exceeded in y-dim, VU 01203
2745     copy_region.srcOffset.x = 0;
2746     copy_region.extent.height = 48;
2747     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdCopyImage-pRegions-00122");
2748     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkImageCopy-srcOffset-00145");
2749     m_commandBuffer->CopyImage(src_image.image(), VK_IMAGE_LAYOUT_GENERAL, dst_image.image(), VK_IMAGE_LAYOUT_GENERAL, 1,
2750                                &copy_region);
2751     m_errorMonitor->VerifyFound();
2752 
2753     // Source exceeded in z-dim, VU 01204
2754     copy_region.extent = {4, 4, 4};
2755     copy_region.srcSubresource.mipLevel = 2;
2756     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdCopyImage-pRegions-00122");
2757     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkImageCopy-srcOffset-00147");
2758     m_commandBuffer->CopyImage(src_image.image(), VK_IMAGE_LAYOUT_GENERAL, dst_image.image(), VK_IMAGE_LAYOUT_GENERAL, 1,
2759                                &copy_region);
2760     m_errorMonitor->VerifyFound();
2761 
2762     m_commandBuffer->end();
2763 }
2764 
TEST_F(VkLayerTest,CopyImageDstSizeExceeded)2765 TEST_F(VkLayerTest, CopyImageDstSizeExceeded) {
2766     // Image copy with dest region specified greater than dest image size
2767     ASSERT_NO_FATAL_FAILURE(Init());
2768 
2769     // Create images with full mip chain
2770     VkImageCreateInfo ci;
2771     ci.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
2772     ci.pNext = NULL;
2773     ci.flags = 0;
2774     ci.imageType = VK_IMAGE_TYPE_3D;
2775     ci.format = VK_FORMAT_R8G8B8A8_UNORM;
2776     ci.extent = {32, 32, 8};
2777     ci.mipLevels = 6;
2778     ci.arrayLayers = 1;
2779     ci.samples = VK_SAMPLE_COUNT_1_BIT;
2780     ci.tiling = VK_IMAGE_TILING_OPTIMAL;
2781     ci.usage = VK_IMAGE_USAGE_TRANSFER_DST_BIT;
2782     ci.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
2783     ci.queueFamilyIndexCount = 0;
2784     ci.pQueueFamilyIndices = NULL;
2785     ci.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
2786 
2787     VkImageObj dst_image(m_device);
2788     dst_image.init(&ci);
2789     ASSERT_TRUE(dst_image.initialized());
2790 
2791     // Src image with one more mip level
2792     ci.extent = {64, 64, 16};
2793     ci.mipLevels = 7;
2794     ci.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
2795     VkImageObj src_image(m_device);
2796     src_image.init(&ci);
2797     ASSERT_TRUE(src_image.initialized());
2798 
2799     m_commandBuffer->begin();
2800 
2801     VkImageCopy copy_region;
2802     copy_region.extent = {32, 32, 8};
2803     copy_region.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
2804     copy_region.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
2805     copy_region.srcSubresource.mipLevel = 0;
2806     copy_region.dstSubresource.mipLevel = 0;
2807     copy_region.srcSubresource.baseArrayLayer = 0;
2808     copy_region.dstSubresource.baseArrayLayer = 0;
2809     copy_region.srcSubresource.layerCount = 1;
2810     copy_region.dstSubresource.layerCount = 1;
2811     copy_region.srcOffset = {0, 0, 0};
2812     copy_region.dstOffset = {0, 0, 0};
2813 
2814     m_errorMonitor->ExpectSuccess();
2815     m_commandBuffer->CopyImage(src_image.image(), VK_IMAGE_LAYOUT_GENERAL, dst_image.image(), VK_IMAGE_LAYOUT_GENERAL, 1,
2816                                &copy_region);
2817     m_errorMonitor->VerifyNotFound();
2818 
2819     // Dest exceeded in x-dim, VU 01205
2820     copy_region.dstOffset.x = 4;
2821     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
2822                                          "VUID-vkCmdCopyImage-pRegions-00123");  // General "contained within" VU
2823     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkImageCopy-dstOffset-00150");
2824     m_commandBuffer->CopyImage(src_image.image(), VK_IMAGE_LAYOUT_GENERAL, dst_image.image(), VK_IMAGE_LAYOUT_GENERAL, 1,
2825                                &copy_region);
2826     m_errorMonitor->VerifyFound();
2827 
2828     // Dest exceeded in y-dim, VU 01206
2829     copy_region.dstOffset.x = 0;
2830     copy_region.extent.height = 48;
2831     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdCopyImage-pRegions-00123");
2832     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkImageCopy-dstOffset-00151");
2833     m_commandBuffer->CopyImage(src_image.image(), VK_IMAGE_LAYOUT_GENERAL, dst_image.image(), VK_IMAGE_LAYOUT_GENERAL, 1,
2834                                &copy_region);
2835     m_errorMonitor->VerifyFound();
2836 
2837     // Dest exceeded in z-dim, VU 01207
2838     copy_region.extent = {4, 4, 4};
2839     copy_region.dstSubresource.mipLevel = 2;
2840     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdCopyImage-pRegions-00123");
2841     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkImageCopy-dstOffset-00153");
2842     m_commandBuffer->CopyImage(src_image.image(), VK_IMAGE_LAYOUT_GENERAL, dst_image.image(), VK_IMAGE_LAYOUT_GENERAL, 1,
2843                                &copy_region);
2844     m_errorMonitor->VerifyFound();
2845 
2846     m_commandBuffer->end();
2847 }
2848 
TEST_F(VkLayerTest,CopyImageFormatSizeMismatch)2849 TEST_F(VkLayerTest, CopyImageFormatSizeMismatch) {
2850     VkResult err;
2851     bool pass;
2852 
2853     // Create color images with different format sizes and try to copy between them
2854     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdCopyImage-srcImage-00135");
2855 
2856     SetTargetApiVersion(VK_API_VERSION_1_1);
2857     ASSERT_NO_FATAL_FAILURE(Init(nullptr, nullptr, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT));
2858 
2859     // Create two images of different types and try to copy between them
2860     VkImage srcImage;
2861     VkImage dstImage;
2862     VkDeviceMemory srcMem;
2863     VkDeviceMemory destMem;
2864     VkMemoryRequirements memReqs;
2865 
2866     VkImageCreateInfo image_create_info = {};
2867     image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
2868     image_create_info.pNext = NULL;
2869     image_create_info.imageType = VK_IMAGE_TYPE_2D;
2870     image_create_info.format = VK_FORMAT_B8G8R8A8_UNORM;
2871     image_create_info.extent.width = 32;
2872     image_create_info.extent.height = 32;
2873     image_create_info.extent.depth = 1;
2874     image_create_info.mipLevels = 1;
2875     image_create_info.arrayLayers = 1;
2876     image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
2877     image_create_info.tiling = VK_IMAGE_TILING_LINEAR;
2878     image_create_info.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
2879     image_create_info.flags = 0;
2880 
2881     err = vkCreateImage(m_device->device(), &image_create_info, NULL, &srcImage);
2882     ASSERT_VK_SUCCESS(err);
2883 
2884     image_create_info.usage = VK_IMAGE_USAGE_TRANSFER_DST_BIT;
2885     // Introduce failure by creating second image with a different-sized format.
2886     image_create_info.format = VK_FORMAT_R5G5B5A1_UNORM_PACK16;
2887     VkFormatProperties properties;
2888     vkGetPhysicalDeviceFormatProperties(m_device->phy().handle(), image_create_info.format, &properties);
2889     if (properties.optimalTilingFeatures == 0) {
2890         vkDestroyImage(m_device->device(), srcImage, NULL);
2891         printf("%s Image format not supported; skipped.\n", kSkipPrefix);
2892         return;
2893     }
2894 
2895     err = vkCreateImage(m_device->device(), &image_create_info, NULL, &dstImage);
2896     ASSERT_VK_SUCCESS(err);
2897 
2898     // Allocate memory
2899     VkMemoryAllocateInfo memAlloc = {};
2900     memAlloc.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
2901     memAlloc.pNext = NULL;
2902     memAlloc.allocationSize = 0;
2903     memAlloc.memoryTypeIndex = 0;
2904 
2905     vkGetImageMemoryRequirements(m_device->device(), srcImage, &memReqs);
2906     memAlloc.allocationSize = memReqs.size;
2907     pass = m_device->phy().set_memory_type(memReqs.memoryTypeBits, &memAlloc, 0);
2908     ASSERT_TRUE(pass);
2909     err = vkAllocateMemory(m_device->device(), &memAlloc, NULL, &srcMem);
2910     ASSERT_VK_SUCCESS(err);
2911 
2912     vkGetImageMemoryRequirements(m_device->device(), dstImage, &memReqs);
2913     memAlloc.allocationSize = memReqs.size;
2914     pass = m_device->phy().set_memory_type(memReqs.memoryTypeBits, &memAlloc, 0);
2915     ASSERT_TRUE(pass);
2916     err = vkAllocateMemory(m_device->device(), &memAlloc, NULL, &destMem);
2917     ASSERT_VK_SUCCESS(err);
2918 
2919     err = vkBindImageMemory(m_device->device(), srcImage, srcMem, 0);
2920     ASSERT_VK_SUCCESS(err);
2921     err = vkBindImageMemory(m_device->device(), dstImage, destMem, 0);
2922     ASSERT_VK_SUCCESS(err);
2923 
2924     m_commandBuffer->begin();
2925     VkImageCopy copyRegion;
2926     copyRegion.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
2927     copyRegion.srcSubresource.mipLevel = 0;
2928     copyRegion.srcSubresource.baseArrayLayer = 0;
2929     copyRegion.srcSubresource.layerCount = 1;
2930     copyRegion.srcOffset.x = 0;
2931     copyRegion.srcOffset.y = 0;
2932     copyRegion.srcOffset.z = 0;
2933     copyRegion.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
2934     copyRegion.dstSubresource.mipLevel = 0;
2935     copyRegion.dstSubresource.baseArrayLayer = 0;
2936     copyRegion.dstSubresource.layerCount = 1;
2937     copyRegion.dstOffset.x = 0;
2938     copyRegion.dstOffset.y = 0;
2939     copyRegion.dstOffset.z = 0;
2940     copyRegion.extent.width = 1;
2941     copyRegion.extent.height = 1;
2942     copyRegion.extent.depth = 1;
2943     m_commandBuffer->CopyImage(srcImage, VK_IMAGE_LAYOUT_GENERAL, dstImage, VK_IMAGE_LAYOUT_GENERAL, 1, &copyRegion);
2944     m_commandBuffer->end();
2945 
2946     m_errorMonitor->VerifyFound();
2947 
2948     vkDestroyImage(m_device->device(), dstImage, NULL);
2949     vkFreeMemory(m_device->device(), destMem, NULL);
2950 
2951     // Copy to multiplane image with mismatched sizes
2952     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdCopyImage-srcImage-00135");
2953 
2954     VkImageCreateInfo ci;
2955     ci.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
2956     ci.pNext = NULL;
2957     ci.flags = 0;
2958     ci.imageType = VK_IMAGE_TYPE_2D;
2959     ci.format = VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM;
2960     ci.extent = {32, 32, 1};
2961     ci.mipLevels = 1;
2962     ci.arrayLayers = 1;
2963     ci.samples = VK_SAMPLE_COUNT_1_BIT;
2964     ci.tiling = VK_IMAGE_TILING_LINEAR;
2965     ci.usage = VK_IMAGE_USAGE_TRANSFER_DST_BIT;
2966     ci.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
2967     ci.queueFamilyIndexCount = 0;
2968     ci.pQueueFamilyIndices = NULL;
2969     ci.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
2970 
2971     VkFormatFeatureFlags features = VK_FORMAT_FEATURE_TRANSFER_DST_BIT;
2972     bool supported = ImageFormatAndFeaturesSupported(instance(), gpu(), ci, features);
2973     bool ycbcr = (DeviceExtensionEnabled(VK_KHR_SAMPLER_YCBCR_CONVERSION_EXTENSION_NAME) ||
2974                   (DeviceValidationVersion() >= VK_API_VERSION_1_1));
2975     if (!supported || !ycbcr) {
2976         printf("%s Image format not supported; skipped multiplanar copy test.\n", kSkipPrefix);
2977         vkDestroyImage(m_device->device(), srcImage, NULL);
2978         vkFreeMemory(m_device->device(), srcMem, NULL);
2979         return;
2980     }
2981 
2982     VkImageObj mpImage(m_device);
2983     mpImage.init(&ci);
2984     ASSERT_TRUE(mpImage.initialized());
2985     copyRegion.dstSubresource.aspectMask = VK_IMAGE_ASPECT_PLANE_0_BIT;
2986     vkResetCommandBuffer(m_commandBuffer->handle(), 0);
2987     m_commandBuffer->begin();
2988     m_commandBuffer->CopyImage(srcImage, VK_IMAGE_LAYOUT_GENERAL, mpImage.handle(), VK_IMAGE_LAYOUT_GENERAL, 1, &copyRegion);
2989     m_commandBuffer->end();
2990 
2991     m_errorMonitor->VerifyFound();
2992 
2993     vkDestroyImage(m_device->device(), srcImage, NULL);
2994     vkFreeMemory(m_device->device(), srcMem, NULL);
2995 }
2996 
TEST_F(VkLayerTest,CopyImageDepthStencilFormatMismatch)2997 TEST_F(VkLayerTest, CopyImageDepthStencilFormatMismatch) {
2998     ASSERT_NO_FATAL_FAILURE(Init());
2999     auto depth_format = FindSupportedDepthStencilFormat(gpu());
3000     if (!depth_format) {
3001         printf("%s Couldn't depth stencil image format.\n", kSkipPrefix);
3002         return;
3003     }
3004 
3005     VkFormatProperties properties;
3006     vkGetPhysicalDeviceFormatProperties(m_device->phy().handle(), VK_FORMAT_D32_SFLOAT, &properties);
3007     if (properties.optimalTilingFeatures == 0) {
3008         printf("%s Image format not supported; skipped.\n", kSkipPrefix);
3009         return;
3010     }
3011 
3012     VkImageObj srcImage(m_device);
3013     srcImage.Init(32, 32, 1, VK_FORMAT_D32_SFLOAT, VK_IMAGE_USAGE_TRANSFER_SRC_BIT, VK_IMAGE_TILING_OPTIMAL);
3014     ASSERT_TRUE(srcImage.initialized());
3015     VkImageObj dstImage(m_device);
3016     dstImage.Init(32, 32, 1, depth_format, VK_IMAGE_USAGE_TRANSFER_DST_BIT, VK_IMAGE_TILING_OPTIMAL);
3017     ASSERT_TRUE(dstImage.initialized());
3018 
3019     // Create two images of different types and try to copy between them
3020 
3021     m_commandBuffer->begin();
3022     VkImageCopy copyRegion;
3023     copyRegion.srcSubresource.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT;
3024     copyRegion.srcSubresource.mipLevel = 0;
3025     copyRegion.srcSubresource.baseArrayLayer = 0;
3026     copyRegion.srcSubresource.layerCount = 1;
3027     copyRegion.srcOffset.x = 0;
3028     copyRegion.srcOffset.y = 0;
3029     copyRegion.srcOffset.z = 0;
3030     copyRegion.dstSubresource.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT;
3031     copyRegion.dstSubresource.mipLevel = 0;
3032     copyRegion.dstSubresource.baseArrayLayer = 0;
3033     copyRegion.dstSubresource.layerCount = 1;
3034     copyRegion.dstOffset.x = 0;
3035     copyRegion.dstOffset.y = 0;
3036     copyRegion.dstOffset.z = 0;
3037     copyRegion.extent.width = 1;
3038     copyRegion.extent.height = 1;
3039     copyRegion.extent.depth = 1;
3040 
3041     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
3042                                          "vkCmdCopyImage called with unmatched source and dest image depth");
3043     m_commandBuffer->CopyImage(srcImage.handle(), VK_IMAGE_LAYOUT_GENERAL, dstImage.handle(), VK_IMAGE_LAYOUT_GENERAL, 1,
3044                                &copyRegion);
3045     m_commandBuffer->end();
3046 
3047     m_errorMonitor->VerifyFound();
3048 }
3049 
TEST_F(VkLayerTest,CopyImageSampleCountMismatch)3050 TEST_F(VkLayerTest, CopyImageSampleCountMismatch) {
3051     TEST_DESCRIPTION("Image copies with sample count mis-matches");
3052 
3053     ASSERT_NO_FATAL_FAILURE(Init());
3054 
3055     VkImageFormatProperties image_format_properties;
3056     vkGetPhysicalDeviceImageFormatProperties(gpu(), VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_TYPE_2D, VK_IMAGE_TILING_OPTIMAL,
3057                                              VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT, 0,
3058                                              &image_format_properties);
3059 
3060     if ((0 == (VK_SAMPLE_COUNT_2_BIT & image_format_properties.sampleCounts)) ||
3061         (0 == (VK_SAMPLE_COUNT_4_BIT & image_format_properties.sampleCounts))) {
3062         printf("%s Image multi-sample support not found; skipped.\n", kSkipPrefix);
3063         return;
3064     }
3065 
3066     VkImageCreateInfo ci;
3067     ci.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
3068     ci.pNext = NULL;
3069     ci.flags = 0;
3070     ci.imageType = VK_IMAGE_TYPE_2D;
3071     ci.format = VK_FORMAT_R8G8B8A8_UNORM;
3072     ci.extent = {128, 128, 1};
3073     ci.mipLevels = 1;
3074     ci.arrayLayers = 1;
3075     ci.samples = VK_SAMPLE_COUNT_1_BIT;
3076     ci.tiling = VK_IMAGE_TILING_OPTIMAL;
3077     ci.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
3078     ci.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
3079     ci.queueFamilyIndexCount = 0;
3080     ci.pQueueFamilyIndices = NULL;
3081     ci.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
3082 
3083     VkImageObj image1(m_device);
3084     image1.init(&ci);
3085     ASSERT_TRUE(image1.initialized());
3086 
3087     ci.samples = VK_SAMPLE_COUNT_2_BIT;
3088     VkImageObj image2(m_device);
3089     image2.init(&ci);
3090     ASSERT_TRUE(image2.initialized());
3091 
3092     ci.samples = VK_SAMPLE_COUNT_4_BIT;
3093     VkImageObj image4(m_device);
3094     image4.init(&ci);
3095     ASSERT_TRUE(image4.initialized());
3096 
3097     m_commandBuffer->begin();
3098 
3099     VkImageCopy copyRegion;
3100     copyRegion.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
3101     copyRegion.srcSubresource.mipLevel = 0;
3102     copyRegion.srcSubresource.baseArrayLayer = 0;
3103     copyRegion.srcSubresource.layerCount = 1;
3104     copyRegion.srcOffset = {0, 0, 0};
3105     copyRegion.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
3106     copyRegion.dstSubresource.mipLevel = 0;
3107     copyRegion.dstSubresource.baseArrayLayer = 0;
3108     copyRegion.dstSubresource.layerCount = 1;
3109     copyRegion.dstOffset = {0, 0, 0};
3110     copyRegion.extent = {128, 128, 1};
3111 
3112     // Copy a single sample image to/from a multi-sample image
3113     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdCopyImage-srcImage-00136");
3114     vkCmdCopyImage(m_commandBuffer->handle(), image1.handle(), VK_IMAGE_LAYOUT_GENERAL, image4.handle(), VK_IMAGE_LAYOUT_GENERAL, 1,
3115                    &copyRegion);
3116     m_errorMonitor->VerifyFound();
3117 
3118     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdCopyImage-srcImage-00136");
3119     vkCmdCopyImage(m_commandBuffer->handle(), image2.handle(), VK_IMAGE_LAYOUT_GENERAL, image1.handle(), VK_IMAGE_LAYOUT_GENERAL, 1,
3120                    &copyRegion);
3121     m_errorMonitor->VerifyFound();
3122 
3123     // Copy between multi-sample images with different sample counts
3124     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdCopyImage-srcImage-00136");
3125     vkCmdCopyImage(m_commandBuffer->handle(), image2.handle(), VK_IMAGE_LAYOUT_GENERAL, image4.handle(), VK_IMAGE_LAYOUT_GENERAL, 1,
3126                    &copyRegion);
3127     m_errorMonitor->VerifyFound();
3128 
3129     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdCopyImage-srcImage-00136");
3130     vkCmdCopyImage(m_commandBuffer->handle(), image4.handle(), VK_IMAGE_LAYOUT_GENERAL, image2.handle(), VK_IMAGE_LAYOUT_GENERAL, 1,
3131                    &copyRegion);
3132     m_errorMonitor->VerifyFound();
3133 
3134     m_commandBuffer->end();
3135 }
3136 
TEST_F(VkLayerTest,CopyImageAspectMismatch)3137 TEST_F(VkLayerTest, CopyImageAspectMismatch) {
3138     TEST_DESCRIPTION("Image copies with aspect mask errors");
3139     SetTargetApiVersion(VK_API_VERSION_1_1);
3140     ASSERT_NO_FATAL_FAILURE(Init());
3141     auto ds_format = FindSupportedDepthStencilFormat(gpu());
3142     if (!ds_format) {
3143         printf("%s Couldn't find depth stencil format.\n", kSkipPrefix);
3144         return;
3145     }
3146 
3147     VkFormatProperties properties;
3148     vkGetPhysicalDeviceFormatProperties(m_device->phy().handle(), VK_FORMAT_D32_SFLOAT, &properties);
3149     if (properties.optimalTilingFeatures == 0) {
3150         printf("%s Image format VK_FORMAT_D32_SFLOAT not supported; skipped.\n", kSkipPrefix);
3151         return;
3152     }
3153     VkImageObj color_image(m_device), ds_image(m_device), depth_image(m_device);
3154     color_image.Init(128, 128, 1, VK_FORMAT_R32_SFLOAT, VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT);
3155     depth_image.Init(128, 128, 1, VK_FORMAT_D32_SFLOAT, VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT,
3156                      VK_IMAGE_TILING_OPTIMAL, 0);
3157     ds_image.Init(128, 128, 1, ds_format, VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT,
3158                   VK_IMAGE_TILING_OPTIMAL, 0);
3159     ASSERT_TRUE(color_image.initialized());
3160     ASSERT_TRUE(depth_image.initialized());
3161     ASSERT_TRUE(ds_image.initialized());
3162 
3163     VkImageCopy copyRegion;
3164     copyRegion.srcSubresource.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT;
3165     copyRegion.srcSubresource.mipLevel = 0;
3166     copyRegion.srcSubresource.baseArrayLayer = 0;
3167     copyRegion.srcSubresource.layerCount = 1;
3168     copyRegion.srcOffset = {0, 0, 0};
3169     copyRegion.dstSubresource.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT;
3170     copyRegion.dstSubresource.mipLevel = 0;
3171     copyRegion.dstSubresource.baseArrayLayer = 0;
3172     copyRegion.dstSubresource.layerCount = 1;
3173     copyRegion.dstOffset = {64, 0, 0};
3174     copyRegion.extent = {64, 128, 1};
3175 
3176     // Submitting command before command buffer is in recording state
3177     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
3178                                          "You must call vkBeginCommandBuffer");  // "VUID-vkCmdCopyImage-commandBuffer-recording");
3179     vkCmdCopyImage(m_commandBuffer->handle(), depth_image.handle(), VK_IMAGE_LAYOUT_GENERAL, depth_image.handle(),
3180                    VK_IMAGE_LAYOUT_GENERAL, 1, &copyRegion);
3181     m_errorMonitor->VerifyFound();
3182 
3183     m_commandBuffer->begin();
3184 
3185     // Src and dest aspect masks don't match
3186     copyRegion.dstSubresource.aspectMask = VK_IMAGE_ASPECT_STENCIL_BIT;
3187     bool ycbcr = (DeviceExtensionEnabled(VK_KHR_SAMPLER_YCBCR_CONVERSION_EXTENSION_NAME) ||
3188                   (DeviceValidationVersion() >= VK_API_VERSION_1_1));
3189     std::string vuid = (ycbcr ? "VUID-VkImageCopy-srcImage-01551" : "VUID-VkImageCopy-aspectMask-00137");
3190     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, vuid);
3191     vkCmdCopyImage(m_commandBuffer->handle(), ds_image.handle(), VK_IMAGE_LAYOUT_GENERAL, ds_image.handle(),
3192                    VK_IMAGE_LAYOUT_GENERAL, 1, &copyRegion);
3193     m_errorMonitor->VerifyFound();
3194     copyRegion.dstSubresource.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT;
3195 
3196     // Illegal combinations of aspect bits
3197     copyRegion.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT | VK_IMAGE_ASPECT_DEPTH_BIT;  // color must be alone
3198     copyRegion.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
3199     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkImageSubresourceLayers-aspectMask-00167");
3200     // These aspect/format mismatches are redundant but unavoidable here
3201     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkImageCopy-aspectMask-00142");
3202     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, vuid);
3203     vkCmdCopyImage(m_commandBuffer->handle(), color_image.handle(), VK_IMAGE_LAYOUT_GENERAL, color_image.handle(),
3204                    VK_IMAGE_LAYOUT_GENERAL, 1, &copyRegion);
3205     m_errorMonitor->VerifyFound();
3206     // same test for dstSubresource
3207     copyRegion.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
3208     copyRegion.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT | VK_IMAGE_ASPECT_DEPTH_BIT;  // color must be alone
3209     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkImageSubresourceLayers-aspectMask-00167");
3210     // These aspect/format mismatches are redundant but unavoidable here
3211     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkImageCopy-aspectMask-00143");
3212     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, vuid);
3213     vkCmdCopyImage(m_commandBuffer->handle(), color_image.handle(), VK_IMAGE_LAYOUT_GENERAL, color_image.handle(),
3214                    VK_IMAGE_LAYOUT_GENERAL, 1, &copyRegion);
3215     m_errorMonitor->VerifyFound();
3216 
3217     // Metadata aspect is illegal
3218     copyRegion.srcSubresource.aspectMask = VK_IMAGE_ASPECT_METADATA_BIT;
3219     copyRegion.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
3220     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkImageSubresourceLayers-aspectMask-00168");
3221     // These aspect/format mismatches are redundant but unavoidable here
3222     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, vuid);
3223     vkCmdCopyImage(m_commandBuffer->handle(), color_image.handle(), VK_IMAGE_LAYOUT_GENERAL, color_image.handle(),
3224                    VK_IMAGE_LAYOUT_GENERAL, 1, &copyRegion);
3225     m_errorMonitor->VerifyFound();
3226     // same test for dstSubresource
3227     copyRegion.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
3228     copyRegion.dstSubresource.aspectMask = VK_IMAGE_ASPECT_METADATA_BIT;
3229     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkImageSubresourceLayers-aspectMask-00168");
3230     // These aspect/format mismatches are redundant but unavoidable here
3231     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, vuid);
3232     vkCmdCopyImage(m_commandBuffer->handle(), color_image.handle(), VK_IMAGE_LAYOUT_GENERAL, color_image.handle(),
3233                    VK_IMAGE_LAYOUT_GENERAL, 1, &copyRegion);
3234     m_errorMonitor->VerifyFound();
3235 
3236     copyRegion.srcSubresource.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT;
3237     copyRegion.dstSubresource.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT;
3238 
3239     // Aspect mask doesn't match source image format
3240     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkImageCopy-aspectMask-00142");
3241     // Again redundant but unavoidable
3242     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "unmatched source and dest image depth/stencil formats");
3243     vkCmdCopyImage(m_commandBuffer->handle(), color_image.handle(), VK_IMAGE_LAYOUT_GENERAL, depth_image.handle(),
3244                    VK_IMAGE_LAYOUT_GENERAL, 1, &copyRegion);
3245     m_errorMonitor->VerifyFound();
3246 
3247     // Aspect mask doesn't match dest image format
3248     copyRegion.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
3249     copyRegion.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
3250     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkImageCopy-aspectMask-00143");
3251     // Again redundant but unavoidable
3252     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "unmatched source and dest image depth/stencil formats");
3253     vkCmdCopyImage(m_commandBuffer->handle(), color_image.handle(), VK_IMAGE_LAYOUT_GENERAL, depth_image.handle(),
3254                    VK_IMAGE_LAYOUT_GENERAL, 1, &copyRegion);
3255     m_errorMonitor->VerifyFound();
3256 
3257     m_commandBuffer->end();
3258 }
3259 
TEST_F(VkLayerTest,ResolveImageLowSampleCount)3260 TEST_F(VkLayerTest, ResolveImageLowSampleCount) {
3261     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
3262                                          "vkCmdResolveImage called with source sample count less than 2.");
3263 
3264     ASSERT_NO_FATAL_FAILURE(Init());
3265 
3266     // Create two images of sample count 1 and try to Resolve between them
3267 
3268     VkImageCreateInfo image_create_info = {};
3269     image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
3270     image_create_info.pNext = NULL;
3271     image_create_info.imageType = VK_IMAGE_TYPE_2D;
3272     image_create_info.format = VK_FORMAT_B8G8R8A8_UNORM;
3273     image_create_info.extent.width = 32;
3274     image_create_info.extent.height = 1;
3275     image_create_info.extent.depth = 1;
3276     image_create_info.mipLevels = 1;
3277     image_create_info.arrayLayers = 1;
3278     image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
3279     image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL;
3280     image_create_info.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
3281     image_create_info.flags = 0;
3282 
3283     VkImageObj srcImage(m_device);
3284     srcImage.init(&image_create_info);
3285     ASSERT_TRUE(srcImage.initialized());
3286 
3287     VkImageObj dstImage(m_device);
3288     dstImage.init(&image_create_info);
3289     ASSERT_TRUE(dstImage.initialized());
3290 
3291     m_commandBuffer->begin();
3292     VkImageResolve resolveRegion;
3293     resolveRegion.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
3294     resolveRegion.srcSubresource.mipLevel = 0;
3295     resolveRegion.srcSubresource.baseArrayLayer = 0;
3296     resolveRegion.srcSubresource.layerCount = 1;
3297     resolveRegion.srcOffset.x = 0;
3298     resolveRegion.srcOffset.y = 0;
3299     resolveRegion.srcOffset.z = 0;
3300     resolveRegion.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
3301     resolveRegion.dstSubresource.mipLevel = 0;
3302     resolveRegion.dstSubresource.baseArrayLayer = 0;
3303     resolveRegion.dstSubresource.layerCount = 1;
3304     resolveRegion.dstOffset.x = 0;
3305     resolveRegion.dstOffset.y = 0;
3306     resolveRegion.dstOffset.z = 0;
3307     resolveRegion.extent.width = 1;
3308     resolveRegion.extent.height = 1;
3309     resolveRegion.extent.depth = 1;
3310     m_commandBuffer->ResolveImage(srcImage.handle(), VK_IMAGE_LAYOUT_GENERAL, dstImage.handle(), VK_IMAGE_LAYOUT_GENERAL, 1,
3311                                   &resolveRegion);
3312     m_commandBuffer->end();
3313 
3314     m_errorMonitor->VerifyFound();
3315 }
3316 
TEST_F(VkLayerTest,ResolveImageHighSampleCount)3317 TEST_F(VkLayerTest, ResolveImageHighSampleCount) {
3318     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
3319                                          "vkCmdResolveImage called with dest sample count greater than 1.");
3320 
3321     ASSERT_NO_FATAL_FAILURE(Init());
3322 
3323     // Create two images of sample count 4 and try to Resolve between them
3324 
3325     VkImageCreateInfo image_create_info = {};
3326     image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
3327     image_create_info.pNext = NULL;
3328     image_create_info.imageType = VK_IMAGE_TYPE_2D;
3329     image_create_info.format = VK_FORMAT_B8G8R8A8_UNORM;
3330     image_create_info.extent.width = 32;
3331     image_create_info.extent.height = 1;
3332     image_create_info.extent.depth = 1;
3333     image_create_info.mipLevels = 1;
3334     image_create_info.arrayLayers = 1;
3335     image_create_info.samples = VK_SAMPLE_COUNT_4_BIT;
3336     image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL;
3337     // Note: Some implementations expect color attachment usage for any
3338     // multisample surface
3339     image_create_info.usage =
3340         VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
3341     image_create_info.flags = 0;
3342 
3343     VkImageObj srcImage(m_device);
3344     srcImage.init(&image_create_info);
3345     ASSERT_TRUE(srcImage.initialized());
3346 
3347     VkImageObj dstImage(m_device);
3348     dstImage.init(&image_create_info);
3349     ASSERT_TRUE(dstImage.initialized());
3350 
3351     m_commandBuffer->begin();
3352     // Need memory barrier to VK_IMAGE_LAYOUT_GENERAL for source and dest?
3353     // VK_IMAGE_LAYOUT_UNDEFINED = 0,
3354     // VK_IMAGE_LAYOUT_GENERAL = 1,
3355     VkImageResolve resolveRegion;
3356     resolveRegion.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
3357     resolveRegion.srcSubresource.mipLevel = 0;
3358     resolveRegion.srcSubresource.baseArrayLayer = 0;
3359     resolveRegion.srcSubresource.layerCount = 1;
3360     resolveRegion.srcOffset.x = 0;
3361     resolveRegion.srcOffset.y = 0;
3362     resolveRegion.srcOffset.z = 0;
3363     resolveRegion.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
3364     resolveRegion.dstSubresource.mipLevel = 0;
3365     resolveRegion.dstSubresource.baseArrayLayer = 0;
3366     resolveRegion.dstSubresource.layerCount = 1;
3367     resolveRegion.dstOffset.x = 0;
3368     resolveRegion.dstOffset.y = 0;
3369     resolveRegion.dstOffset.z = 0;
3370     resolveRegion.extent.width = 1;
3371     resolveRegion.extent.height = 1;
3372     resolveRegion.extent.depth = 1;
3373     m_commandBuffer->ResolveImage(srcImage.handle(), VK_IMAGE_LAYOUT_GENERAL, dstImage.handle(), VK_IMAGE_LAYOUT_GENERAL, 1,
3374                                   &resolveRegion);
3375     m_commandBuffer->end();
3376 
3377     m_errorMonitor->VerifyFound();
3378 }
3379 
TEST_F(VkLayerTest,ResolveImageFormatMismatch)3380 TEST_F(VkLayerTest, ResolveImageFormatMismatch) {
3381     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_WARNING_BIT_EXT,
3382                                          "vkCmdResolveImage called with unmatched source and dest formats.");
3383 
3384     ASSERT_NO_FATAL_FAILURE(Init());
3385 
3386     // Create two images of different types and try to copy between them
3387     VkImageObj srcImage(m_device);
3388     VkImageObj dstImage(m_device);
3389 
3390     VkImageCreateInfo image_create_info = {};
3391     image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
3392     image_create_info.pNext = NULL;
3393     image_create_info.imageType = VK_IMAGE_TYPE_2D;
3394     image_create_info.format = VK_FORMAT_B8G8R8A8_UNORM;
3395     image_create_info.extent.width = 32;
3396     image_create_info.extent.height = 1;
3397     image_create_info.extent.depth = 1;
3398     image_create_info.mipLevels = 1;
3399     image_create_info.arrayLayers = 1;
3400     image_create_info.samples = VK_SAMPLE_COUNT_2_BIT;
3401     image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL;
3402     // Note: Some implementations expect color attachment usage for any
3403     // multisample surface
3404     image_create_info.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
3405     image_create_info.flags = 0;
3406     srcImage.init(&image_create_info);
3407 
3408     // Set format to something other than source image
3409     image_create_info.format = VK_FORMAT_R32_SFLOAT;
3410     // Note: Some implementations expect color attachment usage for any
3411     // multisample surface
3412     image_create_info.usage = VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
3413     image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
3414     dstImage.init(&image_create_info);
3415 
3416     m_commandBuffer->begin();
3417     // Need memory barrier to VK_IMAGE_LAYOUT_GENERAL for source and dest?
3418     // VK_IMAGE_LAYOUT_UNDEFINED = 0,
3419     // VK_IMAGE_LAYOUT_GENERAL = 1,
3420     VkImageResolve resolveRegion;
3421     resolveRegion.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
3422     resolveRegion.srcSubresource.mipLevel = 0;
3423     resolveRegion.srcSubresource.baseArrayLayer = 0;
3424     resolveRegion.srcSubresource.layerCount = 1;
3425     resolveRegion.srcOffset.x = 0;
3426     resolveRegion.srcOffset.y = 0;
3427     resolveRegion.srcOffset.z = 0;
3428     resolveRegion.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
3429     resolveRegion.dstSubresource.mipLevel = 0;
3430     resolveRegion.dstSubresource.baseArrayLayer = 0;
3431     resolveRegion.dstSubresource.layerCount = 1;
3432     resolveRegion.dstOffset.x = 0;
3433     resolveRegion.dstOffset.y = 0;
3434     resolveRegion.dstOffset.z = 0;
3435     resolveRegion.extent.width = 1;
3436     resolveRegion.extent.height = 1;
3437     resolveRegion.extent.depth = 1;
3438     m_commandBuffer->ResolveImage(srcImage.handle(), VK_IMAGE_LAYOUT_GENERAL, dstImage.handle(), VK_IMAGE_LAYOUT_GENERAL, 1,
3439                                   &resolveRegion);
3440     m_commandBuffer->end();
3441 
3442     m_errorMonitor->VerifyFound();
3443 }
3444 
TEST_F(VkLayerTest,ResolveImageTypeMismatch)3445 TEST_F(VkLayerTest, ResolveImageTypeMismatch) {
3446     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_WARNING_BIT_EXT,
3447                                          "vkCmdResolveImage called with unmatched source and dest image types.");
3448 
3449     ASSERT_NO_FATAL_FAILURE(Init());
3450 
3451     // Create two images of different types and try to copy between them
3452     VkImageObj srcImage(m_device);
3453     VkImageObj dstImage(m_device);
3454 
3455     VkImageCreateInfo image_create_info = {};
3456     image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
3457     image_create_info.pNext = NULL;
3458     image_create_info.imageType = VK_IMAGE_TYPE_2D;
3459     image_create_info.format = VK_FORMAT_B8G8R8A8_UNORM;
3460     image_create_info.extent.width = 32;
3461     image_create_info.extent.height = 1;
3462     image_create_info.extent.depth = 1;
3463     image_create_info.mipLevels = 1;
3464     image_create_info.arrayLayers = 1;
3465     image_create_info.samples = VK_SAMPLE_COUNT_2_BIT;
3466     image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL;
3467     // Note: Some implementations expect color attachment usage for any
3468     // multisample surface
3469     image_create_info.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
3470     image_create_info.flags = 0;
3471     srcImage.init(&image_create_info);
3472 
3473     image_create_info.imageType = VK_IMAGE_TYPE_1D;
3474     // Note: Some implementations expect color attachment usage for any
3475     // multisample surface
3476     image_create_info.usage = VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
3477     image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
3478     dstImage.init(&image_create_info);
3479 
3480     m_commandBuffer->begin();
3481     // Need memory barrier to VK_IMAGE_LAYOUT_GENERAL for source and dest?
3482     // VK_IMAGE_LAYOUT_UNDEFINED = 0,
3483     // VK_IMAGE_LAYOUT_GENERAL = 1,
3484     VkImageResolve resolveRegion;
3485     resolveRegion.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
3486     resolveRegion.srcSubresource.mipLevel = 0;
3487     resolveRegion.srcSubresource.baseArrayLayer = 0;
3488     resolveRegion.srcSubresource.layerCount = 1;
3489     resolveRegion.srcOffset.x = 0;
3490     resolveRegion.srcOffset.y = 0;
3491     resolveRegion.srcOffset.z = 0;
3492     resolveRegion.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
3493     resolveRegion.dstSubresource.mipLevel = 0;
3494     resolveRegion.dstSubresource.baseArrayLayer = 0;
3495     resolveRegion.dstSubresource.layerCount = 1;
3496     resolveRegion.dstOffset.x = 0;
3497     resolveRegion.dstOffset.y = 0;
3498     resolveRegion.dstOffset.z = 0;
3499     resolveRegion.extent.width = 1;
3500     resolveRegion.extent.height = 1;
3501     resolveRegion.extent.depth = 1;
3502     m_commandBuffer->ResolveImage(srcImage.handle(), VK_IMAGE_LAYOUT_GENERAL, dstImage.handle(), VK_IMAGE_LAYOUT_GENERAL, 1,
3503                                   &resolveRegion);
3504     m_commandBuffer->end();
3505 
3506     m_errorMonitor->VerifyFound();
3507 }
3508 
TEST_F(VkLayerTest,ResolveImageLayoutMismatch)3509 TEST_F(VkLayerTest, ResolveImageLayoutMismatch) {
3510     ASSERT_NO_FATAL_FAILURE(Init());
3511 
3512     // Create two images of different types and try to copy between them
3513     VkImageObj srcImage(m_device);
3514     VkImageObj dstImage(m_device);
3515 
3516     VkImageCreateInfo image_create_info = {};
3517     image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
3518     image_create_info.pNext = NULL;
3519     image_create_info.imageType = VK_IMAGE_TYPE_2D;
3520     image_create_info.format = VK_FORMAT_B8G8R8A8_UNORM;
3521     image_create_info.extent.width = 32;
3522     image_create_info.extent.height = 32;
3523     image_create_info.extent.depth = 1;
3524     image_create_info.mipLevels = 1;
3525     image_create_info.arrayLayers = 1;
3526     image_create_info.samples = VK_SAMPLE_COUNT_2_BIT;
3527     image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL;
3528     image_create_info.usage =
3529         VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
3530     // Note: Some implementations expect color attachment usage for any
3531     // multisample surface
3532     image_create_info.flags = 0;
3533     srcImage.init(&image_create_info);
3534     ASSERT_TRUE(srcImage.initialized());
3535 
3536     // Note: Some implementations expect color attachment usage for any
3537     // multisample surface
3538     image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
3539     dstImage.init(&image_create_info);
3540     ASSERT_TRUE(dstImage.initialized());
3541 
3542     m_commandBuffer->begin();
3543     // source image must have valid contents before resolve
3544     VkClearColorValue clear_color = {{0, 0, 0, 0}};
3545     VkImageSubresourceRange subresource = {};
3546     subresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
3547     subresource.layerCount = 1;
3548     subresource.levelCount = 1;
3549     srcImage.SetLayout(m_commandBuffer, VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
3550     m_commandBuffer->ClearColorImage(srcImage.image(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &clear_color, 1, &subresource);
3551     srcImage.SetLayout(m_commandBuffer, VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL);
3552     dstImage.SetLayout(m_commandBuffer, VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
3553 
3554     VkImageResolve resolveRegion;
3555     resolveRegion.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
3556     resolveRegion.srcSubresource.mipLevel = 0;
3557     resolveRegion.srcSubresource.baseArrayLayer = 0;
3558     resolveRegion.srcSubresource.layerCount = 1;
3559     resolveRegion.srcOffset.x = 0;
3560     resolveRegion.srcOffset.y = 0;
3561     resolveRegion.srcOffset.z = 0;
3562     resolveRegion.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
3563     resolveRegion.dstSubresource.mipLevel = 0;
3564     resolveRegion.dstSubresource.baseArrayLayer = 0;
3565     resolveRegion.dstSubresource.layerCount = 1;
3566     resolveRegion.dstOffset.x = 0;
3567     resolveRegion.dstOffset.y = 0;
3568     resolveRegion.dstOffset.z = 0;
3569     resolveRegion.extent.width = 1;
3570     resolveRegion.extent.height = 1;
3571     resolveRegion.extent.depth = 1;
3572     // source image layout mismatch
3573     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdResolveImage-srcImageLayout-00260");
3574     m_commandBuffer->ResolveImage(srcImage.image(), VK_IMAGE_LAYOUT_GENERAL, dstImage.image(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
3575                                   1, &resolveRegion);
3576     m_errorMonitor->VerifyFound();
3577     // dst image layout mismatch
3578     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdResolveImage-dstImageLayout-00262");
3579     m_commandBuffer->ResolveImage(srcImage.image(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, dstImage.image(), VK_IMAGE_LAYOUT_GENERAL,
3580                                   1, &resolveRegion);
3581     m_errorMonitor->VerifyFound();
3582     m_commandBuffer->end();
3583 }
3584 
TEST_F(VkLayerTest,ResolveInvalidSubresource)3585 TEST_F(VkLayerTest, ResolveInvalidSubresource) {
3586     ASSERT_NO_FATAL_FAILURE(Init());
3587 
3588     // Create two images of different types and try to copy between them
3589     VkImageObj srcImage(m_device);
3590     VkImageObj dstImage(m_device);
3591 
3592     VkImageCreateInfo image_create_info = {};
3593     image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
3594     image_create_info.pNext = NULL;
3595     image_create_info.imageType = VK_IMAGE_TYPE_2D;
3596     image_create_info.format = VK_FORMAT_B8G8R8A8_UNORM;
3597     image_create_info.extent.width = 32;
3598     image_create_info.extent.height = 32;
3599     image_create_info.extent.depth = 1;
3600     image_create_info.mipLevels = 1;
3601     image_create_info.arrayLayers = 1;
3602     image_create_info.samples = VK_SAMPLE_COUNT_2_BIT;
3603     image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL;
3604     image_create_info.usage =
3605         VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
3606     // Note: Some implementations expect color attachment usage for any
3607     // multisample surface
3608     image_create_info.flags = 0;
3609     srcImage.init(&image_create_info);
3610     ASSERT_TRUE(srcImage.initialized());
3611 
3612     // Note: Some implementations expect color attachment usage for any
3613     // multisample surface
3614     image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
3615     dstImage.init(&image_create_info);
3616     ASSERT_TRUE(dstImage.initialized());
3617 
3618     m_commandBuffer->begin();
3619     // source image must have valid contents before resolve
3620     VkClearColorValue clear_color = {{0, 0, 0, 0}};
3621     VkImageSubresourceRange subresource = {};
3622     subresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
3623     subresource.layerCount = 1;
3624     subresource.levelCount = 1;
3625     srcImage.SetLayout(m_commandBuffer, VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
3626     m_commandBuffer->ClearColorImage(srcImage.image(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &clear_color, 1, &subresource);
3627     srcImage.SetLayout(m_commandBuffer, VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL);
3628     dstImage.SetLayout(m_commandBuffer, VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
3629 
3630     VkImageResolve resolveRegion;
3631     resolveRegion.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
3632     resolveRegion.srcSubresource.mipLevel = 0;
3633     resolveRegion.srcSubresource.baseArrayLayer = 0;
3634     resolveRegion.srcSubresource.layerCount = 1;
3635     resolveRegion.srcOffset.x = 0;
3636     resolveRegion.srcOffset.y = 0;
3637     resolveRegion.srcOffset.z = 0;
3638     resolveRegion.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
3639     resolveRegion.dstSubresource.mipLevel = 0;
3640     resolveRegion.dstSubresource.baseArrayLayer = 0;
3641     resolveRegion.dstSubresource.layerCount = 1;
3642     resolveRegion.dstOffset.x = 0;
3643     resolveRegion.dstOffset.y = 0;
3644     resolveRegion.dstOffset.z = 0;
3645     resolveRegion.extent.width = 1;
3646     resolveRegion.extent.height = 1;
3647     resolveRegion.extent.depth = 1;
3648     // invalid source mip level
3649     resolveRegion.srcSubresource.mipLevel = image_create_info.mipLevels;
3650     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdResolveImage-srcSubresource-01709");
3651     m_commandBuffer->ResolveImage(srcImage.image(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, dstImage.image(),
3652                                   VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &resolveRegion);
3653     m_errorMonitor->VerifyFound();
3654     resolveRegion.srcSubresource.mipLevel = 0;
3655     // invalid dest mip level
3656     resolveRegion.dstSubresource.mipLevel = image_create_info.mipLevels;
3657     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdResolveImage-dstSubresource-01710");
3658     m_commandBuffer->ResolveImage(srcImage.image(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, dstImage.image(),
3659                                   VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &resolveRegion);
3660     m_errorMonitor->VerifyFound();
3661     resolveRegion.dstSubresource.mipLevel = 0;
3662     // invalid source array layer range
3663     resolveRegion.srcSubresource.baseArrayLayer = image_create_info.arrayLayers;
3664     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdResolveImage-srcSubresource-01711");
3665     m_commandBuffer->ResolveImage(srcImage.image(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, dstImage.image(),
3666                                   VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &resolveRegion);
3667     m_errorMonitor->VerifyFound();
3668     resolveRegion.srcSubresource.baseArrayLayer = 0;
3669     // invalid dest array layer range
3670     resolveRegion.dstSubresource.baseArrayLayer = image_create_info.arrayLayers;
3671     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdResolveImage-dstSubresource-01712");
3672     m_commandBuffer->ResolveImage(srcImage.image(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, dstImage.image(),
3673                                   VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &resolveRegion);
3674     m_errorMonitor->VerifyFound();
3675     resolveRegion.dstSubresource.baseArrayLayer = 0;
3676 
3677     m_commandBuffer->end();
3678 }
3679 
TEST_F(VkLayerTest,ClearImageErrors)3680 TEST_F(VkLayerTest, ClearImageErrors) {
3681     TEST_DESCRIPTION("Call ClearColorImage w/ a depth|stencil image and ClearDepthStencilImage with a color image.");
3682 
3683     ASSERT_NO_FATAL_FAILURE(Init());
3684     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
3685 
3686     m_commandBuffer->begin();
3687 
3688     // Color image
3689     VkClearColorValue clear_color;
3690     memset(clear_color.uint32, 0, sizeof(uint32_t) * 4);
3691     const VkFormat color_format = VK_FORMAT_B8G8R8A8_UNORM;
3692     const int32_t img_width = 32;
3693     const int32_t img_height = 32;
3694     VkImageCreateInfo image_create_info = {};
3695     image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
3696     image_create_info.pNext = NULL;
3697     image_create_info.imageType = VK_IMAGE_TYPE_2D;
3698     image_create_info.format = color_format;
3699     image_create_info.extent.width = img_width;
3700     image_create_info.extent.height = img_height;
3701     image_create_info.extent.depth = 1;
3702     image_create_info.mipLevels = 1;
3703     image_create_info.arrayLayers = 1;
3704     image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
3705     image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL;
3706 
3707     image_create_info.usage = VK_IMAGE_USAGE_SAMPLED_BIT;
3708     vk_testing::Image color_image_no_transfer;
3709     color_image_no_transfer.init(*m_device, image_create_info);
3710 
3711     image_create_info.usage = VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
3712     vk_testing::Image color_image;
3713     color_image.init(*m_device, image_create_info);
3714 
3715     const VkImageSubresourceRange color_range = vk_testing::Image::subresource_range(image_create_info, VK_IMAGE_ASPECT_COLOR_BIT);
3716 
3717     // Depth/Stencil image
3718     VkClearDepthStencilValue clear_value = {0};
3719     VkImageCreateInfo ds_image_create_info = vk_testing::Image::create_info();
3720     ds_image_create_info.imageType = VK_IMAGE_TYPE_2D;
3721     ds_image_create_info.format = VK_FORMAT_D16_UNORM;
3722     ds_image_create_info.extent.width = 64;
3723     ds_image_create_info.extent.height = 64;
3724     ds_image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL;
3725     ds_image_create_info.usage = VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
3726 
3727     vk_testing::Image ds_image;
3728     ds_image.init(*m_device, ds_image_create_info);
3729 
3730     const VkImageSubresourceRange ds_range = vk_testing::Image::subresource_range(ds_image_create_info, VK_IMAGE_ASPECT_DEPTH_BIT);
3731 
3732     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "vkCmdClearColorImage called with depth/stencil image.");
3733 
3734     vkCmdClearColorImage(m_commandBuffer->handle(), ds_image.handle(), VK_IMAGE_LAYOUT_GENERAL, &clear_color, 1, &color_range);
3735 
3736     m_errorMonitor->VerifyFound();
3737 
3738     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
3739                                          "vkCmdClearColorImage called with image created without VK_IMAGE_USAGE_TRANSFER_DST_BIT");
3740 
3741     vkCmdClearColorImage(m_commandBuffer->handle(), color_image_no_transfer.handle(), VK_IMAGE_LAYOUT_GENERAL, &clear_color, 1,
3742                          &color_range);
3743 
3744     m_errorMonitor->VerifyFound();
3745 
3746     // Call CmdClearDepthStencilImage with color image
3747     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
3748                                          "vkCmdClearDepthStencilImage called without a depth/stencil image.");
3749 
3750     vkCmdClearDepthStencilImage(m_commandBuffer->handle(), color_image.handle(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &clear_value,
3751                                 1, &ds_range);
3752 
3753     m_errorMonitor->VerifyFound();
3754 }
3755 
TEST_F(VkLayerTest,CommandQueueFlags)3756 TEST_F(VkLayerTest, CommandQueueFlags) {
3757     TEST_DESCRIPTION(
3758         "Allocate a command buffer on a queue that does not support graphics and try to issue a graphics-only command");
3759 
3760     ASSERT_NO_FATAL_FAILURE(Init());
3761 
3762     uint32_t queueFamilyIndex = m_device->QueueFamilyWithoutCapabilities(VK_QUEUE_GRAPHICS_BIT);
3763     if (queueFamilyIndex == UINT32_MAX) {
3764         printf("%s Non-graphics queue family not found; skipped.\n", kSkipPrefix);
3765         return;
3766     } else {
3767         // Create command pool on a non-graphics queue
3768         VkCommandPoolObj command_pool(m_device, queueFamilyIndex);
3769 
3770         // Setup command buffer on pool
3771         VkCommandBufferObj command_buffer(m_device, &command_pool);
3772         command_buffer.begin();
3773 
3774         // Issue a graphics only command
3775         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdSetViewport-commandBuffer-cmdpool");
3776         VkViewport viewport = {0, 0, 16, 16, 0, 1};
3777         command_buffer.SetViewport(0, 1, &viewport);
3778         m_errorMonitor->VerifyFound();
3779     }
3780 }
3781 
TEST_F(VkLayerTest,ExecuteUnrecordedSecondaryCB)3782 TEST_F(VkLayerTest, ExecuteUnrecordedSecondaryCB) {
3783     TEST_DESCRIPTION("Attempt vkCmdExecuteCommands with a CB in the initial state");
3784     ASSERT_NO_FATAL_FAILURE(Init());
3785     VkCommandBufferObj secondary(m_device, m_commandPool, VK_COMMAND_BUFFER_LEVEL_SECONDARY);
3786     // never record secondary
3787 
3788     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdExecuteCommands-pCommandBuffers-00089");
3789     m_commandBuffer->begin();
3790     vkCmdExecuteCommands(m_commandBuffer->handle(), 1, &secondary.handle());
3791     m_errorMonitor->VerifyFound();
3792     m_commandBuffer->end();
3793 }
3794 
TEST_F(VkLayerTest,ExecuteSecondaryCBWithLayoutMismatch)3795 TEST_F(VkLayerTest, ExecuteSecondaryCBWithLayoutMismatch) {
3796     TEST_DESCRIPTION("Attempt vkCmdExecuteCommands with a CB with incorrect initial layout.");
3797 
3798     ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor));
3799     ASSERT_NO_FATAL_FAILURE(InitState(nullptr, nullptr, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT));
3800 
3801     VkImageCreateInfo image_create_info = {};
3802     image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
3803     image_create_info.pNext = NULL;
3804     image_create_info.imageType = VK_IMAGE_TYPE_2D;
3805     image_create_info.format = VK_FORMAT_B8G8R8A8_UNORM;
3806     image_create_info.extent.width = 32;
3807     image_create_info.extent.height = 1;
3808     image_create_info.extent.depth = 1;
3809     image_create_info.mipLevels = 1;
3810     image_create_info.arrayLayers = 1;
3811     image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
3812     image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL;
3813     image_create_info.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
3814     image_create_info.flags = 0;
3815 
3816     VkImageSubresource image_sub = VkImageObj::subresource(VK_IMAGE_ASPECT_COLOR_BIT, 0, 0);
3817     VkImageSubresourceRange image_sub_range = VkImageObj::subresource_range(image_sub);
3818 
3819     VkImageObj image(m_device);
3820     image.init(&image_create_info);
3821     ASSERT_TRUE(image.initialized());
3822     VkImageMemoryBarrier image_barrier =
3823         image.image_memory_barrier(0, 0, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_GENERAL, image_sub_range);
3824 
3825     auto pipeline = [&image_barrier](const VkCommandBufferObj &cb, VkImageLayout old_layout, VkImageLayout new_layout) {
3826         image_barrier.oldLayout = old_layout;
3827         image_barrier.newLayout = new_layout;
3828         vkCmdPipelineBarrier(cb.handle(), VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, 0, nullptr, 0,
3829                              nullptr, 1, &image_barrier);
3830     };
3831 
3832     // Validate that mismatched use of image layout in secondary command buffer is caught at record time
3833     VkCommandBufferObj secondary(m_device, m_commandPool, VK_COMMAND_BUFFER_LEVEL_SECONDARY);
3834     secondary.begin();
3835     pipeline(secondary, VK_IMAGE_LAYOUT_GENERAL, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
3836     secondary.end();
3837 
3838     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "UNASSIGNED-vkCmdExecuteCommands-commandBuffer-00001");
3839     m_commandBuffer->begin();
3840     pipeline(*m_commandBuffer, VK_IMAGE_LAYOUT_GENERAL, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL);
3841     vkCmdExecuteCommands(m_commandBuffer->handle(), 1, &secondary.handle());
3842     m_errorMonitor->VerifyFound();
3843 
3844     // Validate that we've tracked the changes from the secondary CB correctly
3845     m_errorMonitor->ExpectSuccess();
3846     pipeline(*m_commandBuffer, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_GENERAL);
3847     m_errorMonitor->VerifyNotFound();
3848     m_commandBuffer->end();
3849 
3850     m_commandBuffer->reset();
3851     secondary.reset();
3852 
3853     // Validate that UNDEFINED doesn't false positive on us
3854     secondary.begin();
3855     pipeline(secondary, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
3856     secondary.end();
3857     m_commandBuffer->begin();
3858     pipeline(*m_commandBuffer, VK_IMAGE_LAYOUT_GENERAL, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
3859     m_errorMonitor->ExpectSuccess();
3860     vkCmdExecuteCommands(m_commandBuffer->handle(), 1, &secondary.handle());
3861     m_errorMonitor->VerifyNotFound();
3862     m_commandBuffer->end();
3863 }
3864 
TEST_F(VkLayerTest,SetDynViewportParamTests)3865 TEST_F(VkLayerTest, SetDynViewportParamTests) {
3866     TEST_DESCRIPTION("Test parameters of vkCmdSetViewport without multiViewport feature");
3867 
3868     SetTargetApiVersion(VK_API_VERSION_1_1);
3869     VkPhysicalDeviceFeatures features{};
3870     ASSERT_NO_FATAL_FAILURE(Init(&features));
3871 
3872     const VkViewport vp = {0.0, 0.0, 64.0, 64.0, 0.0, 1.0};
3873     const VkViewport viewports[] = {vp, vp};
3874 
3875     m_commandBuffer->begin();
3876 
3877     // array tests
3878     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdSetViewport-firstViewport-01224");
3879     vkCmdSetViewport(m_commandBuffer->handle(), 1, 1, viewports);
3880     m_errorMonitor->VerifyFound();
3881 
3882     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdSetViewport-viewportCount-arraylength");
3883     vkCmdSetViewport(m_commandBuffer->handle(), 0, 0, nullptr);
3884     m_errorMonitor->VerifyFound();
3885 
3886     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdSetViewport-viewportCount-01225");
3887     vkCmdSetViewport(m_commandBuffer->handle(), 0, 2, viewports);
3888     m_errorMonitor->VerifyFound();
3889 
3890     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdSetViewport-firstViewport-01224");
3891     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdSetViewport-viewportCount-01225");
3892     vkCmdSetViewport(m_commandBuffer->handle(), 1, 2, viewports);
3893     m_errorMonitor->VerifyFound();
3894 
3895     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdSetViewport-pViewports-parameter");
3896     vkCmdSetViewport(m_commandBuffer->handle(), 0, 1, nullptr);
3897     m_errorMonitor->VerifyFound();
3898 
3899     // core viewport tests
3900     using std::vector;
3901     struct TestCase {
3902         VkViewport vp;
3903         std::string veid;
3904     };
3905 
3906     // not necessarily boundary values (unspecified cast rounding), but guaranteed to be over limit
3907     const auto one_past_max_w = NearestGreater(static_cast<float>(m_device->props.limits.maxViewportDimensions[0]));
3908     const auto one_past_max_h = NearestGreater(static_cast<float>(m_device->props.limits.maxViewportDimensions[1]));
3909 
3910     const auto min_bound = m_device->props.limits.viewportBoundsRange[0];
3911     const auto max_bound = m_device->props.limits.viewportBoundsRange[1];
3912     const auto one_before_min_bounds = NearestSmaller(min_bound);
3913     const auto one_past_max_bounds = NearestGreater(max_bound);
3914 
3915     const auto below_zero = NearestSmaller(0.0f);
3916     const auto past_one = NearestGreater(1.0f);
3917 
3918     vector<TestCase> test_cases = {
3919         {{0.0, 0.0, 0.0, 64.0, 0.0, 1.0}, "VUID-VkViewport-width-01770"},
3920         {{0.0, 0.0, one_past_max_w, 64.0, 0.0, 1.0}, "VUID-VkViewport-width-01771"},
3921         {{0.0, 0.0, NAN, 64.0, 0.0, 1.0}, "VUID-VkViewport-width-01770"},
3922         {{0.0, 0.0, 64.0, one_past_max_h, 0.0, 1.0}, "VUID-VkViewport-height-01773"},
3923         {{one_before_min_bounds, 0.0, 64.0, 64.0, 0.0, 1.0}, "VUID-VkViewport-x-01774"},
3924         {{one_past_max_bounds, 0.0, 64.0, 64.0, 0.0, 1.0}, "VUID-VkViewport-x-01232"},
3925         {{NAN, 0.0, 64.0, 64.0, 0.0, 1.0}, "VUID-VkViewport-x-01774"},
3926         {{0.0, one_before_min_bounds, 64.0, 64.0, 0.0, 1.0}, "VUID-VkViewport-y-01775"},
3927         {{0.0, NAN, 64.0, 64.0, 0.0, 1.0}, "VUID-VkViewport-y-01775"},
3928         {{max_bound, 0.0, 1.0, 64.0, 0.0, 1.0}, "VUID-VkViewport-x-01232"},
3929         {{0.0, max_bound, 64.0, 1.0, 0.0, 1.0}, "VUID-VkViewport-y-01233"},
3930         {{0.0, 0.0, 64.0, 64.0, below_zero, 1.0}, "VUID-VkViewport-minDepth-01234"},
3931         {{0.0, 0.0, 64.0, 64.0, past_one, 1.0}, "VUID-VkViewport-minDepth-01234"},
3932         {{0.0, 0.0, 64.0, 64.0, NAN, 1.0}, "VUID-VkViewport-minDepth-01234"},
3933         {{0.0, 0.0, 64.0, 64.0, 0.0, below_zero}, "VUID-VkViewport-maxDepth-01235"},
3934         {{0.0, 0.0, 64.0, 64.0, 0.0, past_one}, "VUID-VkViewport-maxDepth-01235"},
3935         {{0.0, 0.0, 64.0, 64.0, 0.0, NAN}, "VUID-VkViewport-maxDepth-01235"},
3936     };
3937 
3938     if (DeviceValidationVersion() < VK_API_VERSION_1_1) {
3939         test_cases.push_back({{0.0, 0.0, 64.0, 0.0, 0.0, 1.0}, "VUID-VkViewport-height-01772"});
3940         test_cases.push_back({{0.0, 0.0, 64.0, NAN, 0.0, 1.0}, "VUID-VkViewport-height-01772"});
3941     } else {
3942         test_cases.push_back({{0.0, 0.0, 64.0, NAN, 0.0, 1.0}, "VUID-VkViewport-height-01773"});
3943     }
3944 
3945     for (const auto &test_case : test_cases) {
3946         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, test_case.veid);
3947         vkCmdSetViewport(m_commandBuffer->handle(), 0, 1, &test_case.vp);
3948         m_errorMonitor->VerifyFound();
3949     }
3950 }
3951 
TEST_F(VkLayerTest,SetDynViewportParamMaintenance1Tests)3952 TEST_F(VkLayerTest, SetDynViewportParamMaintenance1Tests) {
3953     TEST_DESCRIPTION("Verify errors are detected on misuse of SetViewport with a negative viewport extension enabled.");
3954 
3955     ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor));
3956 
3957     if (DeviceExtensionSupported(gpu(), nullptr, VK_KHR_MAINTENANCE1_EXTENSION_NAME)) {
3958         m_device_extension_names.push_back(VK_KHR_MAINTENANCE1_EXTENSION_NAME);
3959     } else {
3960         printf("%s VK_KHR_maintenance1 extension not supported -- skipping test\n", kSkipPrefix);
3961         return;
3962     }
3963     ASSERT_NO_FATAL_FAILURE(InitState());
3964 
3965     NegHeightViewportTests(m_device, m_commandBuffer, m_errorMonitor);
3966 }
3967 
TEST_F(VkLayerTest,SetDynViewportParamMultiviewportTests)3968 TEST_F(VkLayerTest, SetDynViewportParamMultiviewportTests) {
3969     TEST_DESCRIPTION("Test parameters of vkCmdSetViewport with multiViewport feature enabled");
3970 
3971     ASSERT_NO_FATAL_FAILURE(Init());
3972 
3973     if (!m_device->phy().features().multiViewport) {
3974         printf("%s VkPhysicalDeviceFeatures::multiViewport is not supported -- skipping test.\n", kSkipPrefix);
3975         return;
3976     }
3977 
3978     const auto max_viewports = m_device->props.limits.maxViewports;
3979     const uint32_t too_many_viewports = 65536 + 1;  // let's say this is too much to allocate pViewports for
3980 
3981     m_commandBuffer->begin();
3982 
3983     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdSetViewport-viewportCount-arraylength");
3984     vkCmdSetViewport(m_commandBuffer->handle(), 0, 0, nullptr);
3985     m_errorMonitor->VerifyFound();
3986 
3987     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdSetViewport-pViewports-parameter");
3988     vkCmdSetViewport(m_commandBuffer->handle(), 0, max_viewports, nullptr);
3989     m_errorMonitor->VerifyFound();
3990 
3991     if (max_viewports >= too_many_viewports) {
3992         printf(
3993             "%s VkPhysicalDeviceLimits::maxViewports is too large to practically test against -- skipping "
3994             "part of "
3995             "test.\n",
3996             kSkipPrefix);
3997         return;
3998     }
3999 
4000     const VkViewport vp = {0.0, 0.0, 64.0, 64.0, 0.0, 1.0};
4001     const std::vector<VkViewport> viewports(max_viewports + 1, vp);
4002 
4003     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdSetViewport-firstViewport-01223");
4004     vkCmdSetViewport(m_commandBuffer->handle(), 0, max_viewports + 1, viewports.data());
4005     m_errorMonitor->VerifyFound();
4006 
4007     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdSetViewport-firstViewport-01223");
4008     vkCmdSetViewport(m_commandBuffer->handle(), max_viewports, 1, viewports.data());
4009     m_errorMonitor->VerifyFound();
4010 
4011     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdSetViewport-firstViewport-01223");
4012     vkCmdSetViewport(m_commandBuffer->handle(), 1, max_viewports, viewports.data());
4013     m_errorMonitor->VerifyFound();
4014 
4015     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdSetViewport-viewportCount-arraylength");
4016     vkCmdSetViewport(m_commandBuffer->handle(), 1, 0, viewports.data());
4017     m_errorMonitor->VerifyFound();
4018 }
4019 
TEST_F(VkLayerTest,BadRenderPassScopeSecondaryCmdBuffer)4020 TEST_F(VkLayerTest, BadRenderPassScopeSecondaryCmdBuffer) {
4021     TEST_DESCRIPTION(
4022         "Test secondary buffers executed in wrong render pass scope wrt VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT");
4023 
4024     ASSERT_NO_FATAL_FAILURE(Init());
4025     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
4026 
4027     VkCommandBufferObj sec_cmdbuff_inside_rp(m_device, m_commandPool, VK_COMMAND_BUFFER_LEVEL_SECONDARY);
4028     VkCommandBufferObj sec_cmdbuff_outside_rp(m_device, m_commandPool, VK_COMMAND_BUFFER_LEVEL_SECONDARY);
4029 
4030     const VkCommandBufferInheritanceInfo cmdbuff_ii = {
4031         VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO,
4032         nullptr,  // pNext
4033         m_renderPass,
4034         0,  // subpass
4035         m_framebuffer,
4036     };
4037     const VkCommandBufferBeginInfo cmdbuff_bi_tmpl = {VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,
4038                                                       nullptr,  // pNext
4039                                                       VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT, &cmdbuff_ii};
4040 
4041     VkCommandBufferBeginInfo cmdbuff_inside_rp_bi = cmdbuff_bi_tmpl;
4042     cmdbuff_inside_rp_bi.flags |= VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT;
4043     sec_cmdbuff_inside_rp.begin(&cmdbuff_inside_rp_bi);
4044     sec_cmdbuff_inside_rp.end();
4045 
4046     VkCommandBufferBeginInfo cmdbuff_outside_rp_bi = cmdbuff_bi_tmpl;
4047     cmdbuff_outside_rp_bi.flags &= ~VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT;
4048     sec_cmdbuff_outside_rp.begin(&cmdbuff_outside_rp_bi);
4049     sec_cmdbuff_outside_rp.end();
4050 
4051     m_commandBuffer->begin();
4052 
4053     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdExecuteCommands-pCommandBuffers-00100");
4054     vkCmdExecuteCommands(m_commandBuffer->handle(), 1, &sec_cmdbuff_inside_rp.handle());
4055     m_errorMonitor->VerifyFound();
4056 
4057     const VkRenderPassBeginInfo rp_bi{VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,
4058                                       nullptr,  // pNext
4059                                       m_renderPass,
4060                                       m_framebuffer,
4061                                       {{0, 0}, {32, 32}},
4062                                       static_cast<uint32_t>(m_renderPassClearValues.size()),
4063                                       m_renderPassClearValues.data()};
4064     vkCmdBeginRenderPass(m_commandBuffer->handle(), &rp_bi, VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS);
4065 
4066     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdExecuteCommands-pCommandBuffers-00096");
4067     vkCmdExecuteCommands(m_commandBuffer->handle(), 1, &sec_cmdbuff_outside_rp.handle());
4068     m_errorMonitor->VerifyFound();
4069 }
4070 
TEST_F(VkLayerTest,SecondaryCommandBufferClearColorAttachmentsRenderArea)4071 TEST_F(VkLayerTest, SecondaryCommandBufferClearColorAttachmentsRenderArea) {
4072     TEST_DESCRIPTION(
4073         "Create a secondary command buffer with CmdClearAttachments call that has a rect outside of renderPass renderArea");
4074     ASSERT_NO_FATAL_FAILURE(Init());
4075     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
4076 
4077     VkCommandBufferAllocateInfo command_buffer_allocate_info = {};
4078     command_buffer_allocate_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
4079     command_buffer_allocate_info.commandPool = m_commandPool->handle();
4080     command_buffer_allocate_info.level = VK_COMMAND_BUFFER_LEVEL_SECONDARY;
4081     command_buffer_allocate_info.commandBufferCount = 1;
4082 
4083     VkCommandBuffer secondary_command_buffer;
4084     ASSERT_VK_SUCCESS(vkAllocateCommandBuffers(m_device->device(), &command_buffer_allocate_info, &secondary_command_buffer));
4085     VkCommandBufferBeginInfo command_buffer_begin_info = {};
4086     VkCommandBufferInheritanceInfo command_buffer_inheritance_info = {};
4087     command_buffer_inheritance_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO;
4088     command_buffer_inheritance_info.renderPass = m_renderPass;
4089     command_buffer_inheritance_info.framebuffer = m_framebuffer;
4090 
4091     command_buffer_begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
4092     command_buffer_begin_info.flags =
4093         VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT | VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT;
4094     command_buffer_begin_info.pInheritanceInfo = &command_buffer_inheritance_info;
4095 
4096     vkBeginCommandBuffer(secondary_command_buffer, &command_buffer_begin_info);
4097     VkClearAttachment color_attachment;
4098     color_attachment.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
4099     color_attachment.clearValue.color.float32[0] = 0;
4100     color_attachment.clearValue.color.float32[1] = 0;
4101     color_attachment.clearValue.color.float32[2] = 0;
4102     color_attachment.clearValue.color.float32[3] = 0;
4103     color_attachment.colorAttachment = 0;
4104     // x extent of 257 exceeds render area of 256
4105     VkClearRect clear_rect = {{{0, 0}, {257, 32}}, 0, 1};
4106     vkCmdClearAttachments(secondary_command_buffer, 1, &color_attachment, 1, &clear_rect);
4107     vkEndCommandBuffer(secondary_command_buffer);
4108     m_commandBuffer->begin();
4109     vkCmdBeginRenderPass(m_commandBuffer->handle(), &m_renderPassBeginInfo, VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS);
4110 
4111     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdClearAttachments-pRects-00016");
4112     vkCmdExecuteCommands(m_commandBuffer->handle(), 1, &secondary_command_buffer);
4113     m_errorMonitor->VerifyFound();
4114 
4115     vkCmdEndRenderPass(m_commandBuffer->handle());
4116     m_commandBuffer->end();
4117 }
4118 
TEST_F(VkLayerTest,PushDescriptorSetCmdPushBadArgs)4119 TEST_F(VkLayerTest, PushDescriptorSetCmdPushBadArgs) {
4120     TEST_DESCRIPTION("Attempt to push a push descriptor set with incorrect arguments.");
4121     if (InstanceExtensionSupported(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME)) {
4122         m_instance_extension_names.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
4123     } else {
4124         printf("%s %s Extension not supported, skipping tests\n", kSkipPrefix,
4125                VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
4126         return;
4127     }
4128 
4129     ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor));
4130     if (DeviceExtensionSupported(gpu(), nullptr, VK_KHR_PUSH_DESCRIPTOR_EXTENSION_NAME)) {
4131         m_device_extension_names.push_back(VK_KHR_PUSH_DESCRIPTOR_EXTENSION_NAME);
4132     } else {
4133         printf("%s %s Extension not supported, skipping tests\n", kSkipPrefix, VK_KHR_PUSH_DESCRIPTOR_EXTENSION_NAME);
4134         return;
4135     }
4136     ASSERT_NO_FATAL_FAILURE(InitState());
4137 
4138     auto push_descriptor_prop = GetPushDescriptorProperties(instance(), gpu());
4139     if (push_descriptor_prop.maxPushDescriptors < 1) {
4140         // Some implementations report an invalid maxPushDescriptors of 0
4141         printf("%s maxPushDescriptors is zero, skipping tests\n", kSkipPrefix);
4142         return;
4143     }
4144 
4145     // Create ordinary and push descriptor set layout
4146     VkDescriptorSetLayoutBinding binding = {0, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1, VK_SHADER_STAGE_FRAGMENT_BIT, nullptr};
4147     const VkDescriptorSetLayoutObj ds_layout(m_device, {binding});
4148     ASSERT_TRUE(ds_layout.initialized());
4149     const VkDescriptorSetLayoutObj push_ds_layout(m_device, {binding}, VK_DESCRIPTOR_SET_LAYOUT_CREATE_PUSH_DESCRIPTOR_BIT_KHR);
4150     ASSERT_TRUE(push_ds_layout.initialized());
4151 
4152     // Now use the descriptor set layouts to create a pipeline layout
4153     const VkPipelineLayoutObj pipeline_layout(m_device, {&push_ds_layout, &ds_layout});
4154     ASSERT_TRUE(pipeline_layout.initialized());
4155 
4156     // Create a descriptor to push
4157     const uint32_t buffer_data[4] = {4, 5, 6, 7};
4158     VkConstantBufferObj buffer_obj(m_device, sizeof(buffer_data), &buffer_data);
4159     ASSERT_TRUE(buffer_obj.initialized());
4160 
4161     // Create a "write" struct, noting that the buffer_info cannot be a temporary arg (the return from write_descriptor_set
4162     // references its data), and the DescriptorSet() can be temporary, because the value is ignored
4163     VkDescriptorBufferInfo buffer_info = {buffer_obj.handle(), 0, VK_WHOLE_SIZE};
4164 
4165     VkWriteDescriptorSet descriptor_write = vk_testing::Device::write_descriptor_set(
4166         vk_testing::DescriptorSet(), 0, 0, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1, &buffer_info);
4167 
4168     // Find address of extension call and make the call
4169     PFN_vkCmdPushDescriptorSetKHR vkCmdPushDescriptorSetKHR =
4170         (PFN_vkCmdPushDescriptorSetKHR)vkGetDeviceProcAddr(m_device->device(), "vkCmdPushDescriptorSetKHR");
4171     ASSERT_TRUE(vkCmdPushDescriptorSetKHR != nullptr);
4172 
4173     // Section 1: Queue family matching/capabilities.
4174     // Create command pool on a non-graphics queue
4175     const uint32_t no_gfx_qfi = m_device->QueueFamilyMatching(VK_QUEUE_COMPUTE_BIT, VK_QUEUE_GRAPHICS_BIT);
4176     const uint32_t transfer_only_qfi =
4177         m_device->QueueFamilyMatching(VK_QUEUE_TRANSFER_BIT, (VK_QUEUE_COMPUTE_BIT | VK_QUEUE_GRAPHICS_BIT));
4178     if ((UINT32_MAX == transfer_only_qfi) && (UINT32_MAX == no_gfx_qfi)) {
4179         printf("%s No compute or transfer only queue family, skipping bindpoint and queue tests.\n", kSkipPrefix);
4180     } else {
4181         const uint32_t err_qfi = (UINT32_MAX == no_gfx_qfi) ? transfer_only_qfi : no_gfx_qfi;
4182 
4183         VkCommandPoolObj command_pool(m_device, err_qfi);
4184         ASSERT_TRUE(command_pool.initialized());
4185         VkCommandBufferObj command_buffer(m_device, &command_pool);
4186         ASSERT_TRUE(command_buffer.initialized());
4187         command_buffer.begin();
4188 
4189         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
4190                                              "VUID-vkCmdPushDescriptorSetKHR-pipelineBindPoint-00363");
4191         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkWriteDescriptorSet-descriptorType-00330");
4192         if (err_qfi == transfer_only_qfi) {
4193             // This as this queue neither supports the gfx or compute bindpoints, we'll get two errors
4194             m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
4195                                                  "VUID-vkCmdPushDescriptorSetKHR-commandBuffer-cmdpool");
4196         }
4197         vkCmdPushDescriptorSetKHR(command_buffer.handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_layout.handle(), 0, 1,
4198                                   &descriptor_write);
4199         m_errorMonitor->VerifyFound();
4200         command_buffer.end();
4201 
4202         // If we succeed in testing only one condition above, we need to test the other below.
4203         if ((UINT32_MAX != transfer_only_qfi) && (err_qfi != transfer_only_qfi)) {
4204             // Need to test the neither compute/gfx supported case separately.
4205             VkCommandPoolObj tran_command_pool(m_device, transfer_only_qfi);
4206             ASSERT_TRUE(tran_command_pool.initialized());
4207             VkCommandBufferObj tran_command_buffer(m_device, &tran_command_pool);
4208             ASSERT_TRUE(tran_command_buffer.initialized());
4209             tran_command_buffer.begin();
4210 
4211             // We can't avoid getting *both* errors in this case
4212             m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
4213                                                  "VUID-vkCmdPushDescriptorSetKHR-pipelineBindPoint-00363");
4214             m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkWriteDescriptorSet-descriptorType-00330");
4215             m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
4216                                                  "VUID-vkCmdPushDescriptorSetKHR-commandBuffer-cmdpool");
4217             vkCmdPushDescriptorSetKHR(tran_command_buffer.handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_layout.handle(), 0, 1,
4218                                       &descriptor_write);
4219             m_errorMonitor->VerifyFound();
4220             tran_command_buffer.end();
4221         }
4222     }
4223 
4224     // Push to the non-push binding
4225     m_commandBuffer->begin();
4226     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdPushDescriptorSetKHR-set-00365");
4227     vkCmdPushDescriptorSetKHR(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_layout.handle(), 1, 1,
4228                               &descriptor_write);
4229     m_errorMonitor->VerifyFound();
4230 
4231     // Specify set out of bounds
4232     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdPushDescriptorSetKHR-set-00364");
4233     vkCmdPushDescriptorSetKHR(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_layout.handle(), 2, 1,
4234                               &descriptor_write);
4235     m_errorMonitor->VerifyFound();
4236     m_commandBuffer->end();
4237 
4238     // This is a test for VUID-vkCmdPushDescriptorSetKHR-commandBuffer-recording
4239     // TODO: Add VALIDATION_ERROR_ code support to core_validation::ValidateCmd
4240     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
4241                                          "You must call vkBeginCommandBuffer() before this call to vkCmdPushDescriptorSetKHR()");
4242     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkWriteDescriptorSet-descriptorType-00330");
4243     vkCmdPushDescriptorSetKHR(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_layout.handle(), 0, 1,
4244                               &descriptor_write);
4245     m_errorMonitor->VerifyFound();
4246 }
4247 
TEST_F(VkLayerTest,SetDynScissorParamTests)4248 TEST_F(VkLayerTest, SetDynScissorParamTests) {
4249     TEST_DESCRIPTION("Test parameters of vkCmdSetScissor without multiViewport feature");
4250 
4251     VkPhysicalDeviceFeatures features{};
4252     ASSERT_NO_FATAL_FAILURE(Init(&features));
4253 
4254     const VkRect2D scissor = {{0, 0}, {16, 16}};
4255     const VkRect2D scissors[] = {scissor, scissor};
4256 
4257     m_commandBuffer->begin();
4258 
4259     // array tests
4260     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdSetScissor-firstScissor-00593");
4261     vkCmdSetScissor(m_commandBuffer->handle(), 1, 1, scissors);
4262     m_errorMonitor->VerifyFound();
4263 
4264     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdSetScissor-scissorCount-arraylength");
4265     vkCmdSetScissor(m_commandBuffer->handle(), 0, 0, nullptr);
4266     m_errorMonitor->VerifyFound();
4267 
4268     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdSetScissor-scissorCount-00594");
4269     vkCmdSetScissor(m_commandBuffer->handle(), 0, 2, scissors);
4270     m_errorMonitor->VerifyFound();
4271 
4272     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdSetScissor-firstScissor-00593");
4273     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdSetScissor-scissorCount-00594");
4274     vkCmdSetScissor(m_commandBuffer->handle(), 1, 2, scissors);
4275     m_errorMonitor->VerifyFound();
4276 
4277     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdSetScissor-pScissors-parameter");
4278     vkCmdSetScissor(m_commandBuffer->handle(), 0, 1, nullptr);
4279     m_errorMonitor->VerifyFound();
4280 
4281     struct TestCase {
4282         VkRect2D scissor;
4283         std::string vuid;
4284     };
4285 
4286     std::vector<TestCase> test_cases = {{{{-1, 0}, {16, 16}}, "VUID-vkCmdSetScissor-x-00595"},
4287                                         {{{0, -1}, {16, 16}}, "VUID-vkCmdSetScissor-x-00595"},
4288                                         {{{1, 0}, {INT32_MAX, 16}}, "VUID-vkCmdSetScissor-offset-00596"},
4289                                         {{{INT32_MAX, 0}, {1, 16}}, "VUID-vkCmdSetScissor-offset-00596"},
4290                                         {{{0, 0}, {uint32_t{INT32_MAX} + 1, 16}}, "VUID-vkCmdSetScissor-offset-00596"},
4291                                         {{{0, 1}, {16, INT32_MAX}}, "VUID-vkCmdSetScissor-offset-00597"},
4292                                         {{{0, INT32_MAX}, {16, 1}}, "VUID-vkCmdSetScissor-offset-00597"},
4293                                         {{{0, 0}, {16, uint32_t{INT32_MAX} + 1}}, "VUID-vkCmdSetScissor-offset-00597"}};
4294 
4295     for (const auto &test_case : test_cases) {
4296         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, test_case.vuid);
4297         vkCmdSetScissor(m_commandBuffer->handle(), 0, 1, &test_case.scissor);
4298         m_errorMonitor->VerifyFound();
4299     }
4300 
4301     m_commandBuffer->end();
4302 }
4303 
TEST_F(VkLayerTest,SetDynScissorParamMultiviewportTests)4304 TEST_F(VkLayerTest, SetDynScissorParamMultiviewportTests) {
4305     TEST_DESCRIPTION("Test parameters of vkCmdSetScissor with multiViewport feature enabled");
4306 
4307     ASSERT_NO_FATAL_FAILURE(Init());
4308 
4309     if (!m_device->phy().features().multiViewport) {
4310         printf("%s VkPhysicalDeviceFeatures::multiViewport is not supported -- skipping test.\n", kSkipPrefix);
4311         return;
4312     }
4313 
4314     const auto max_scissors = m_device->props.limits.maxViewports;
4315     const uint32_t too_many_scissors = 65536 + 1;  // let's say this is too much to allocate pScissors for
4316 
4317     m_commandBuffer->begin();
4318 
4319     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdSetScissor-scissorCount-arraylength");
4320     vkCmdSetScissor(m_commandBuffer->handle(), 0, 0, nullptr);
4321     m_errorMonitor->VerifyFound();
4322 
4323     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdSetScissor-pScissors-parameter");
4324     vkCmdSetScissor(m_commandBuffer->handle(), 0, max_scissors, nullptr);
4325     m_errorMonitor->VerifyFound();
4326 
4327     if (max_scissors >= too_many_scissors) {
4328         printf(
4329             "%s VkPhysicalDeviceLimits::maxViewports is too large to practically test against -- skipping "
4330             "part of "
4331             "test.\n",
4332             kSkipPrefix);
4333         return;
4334     }
4335 
4336     const VkRect2D scissor = {{0, 0}, {16, 16}};
4337     const std::vector<VkRect2D> scissors(max_scissors + 1, scissor);
4338 
4339     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdSetScissor-firstScissor-00592");
4340     vkCmdSetScissor(m_commandBuffer->handle(), 0, max_scissors + 1, scissors.data());
4341     m_errorMonitor->VerifyFound();
4342 
4343     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdSetScissor-firstScissor-00592");
4344     vkCmdSetScissor(m_commandBuffer->handle(), max_scissors, 1, scissors.data());
4345     m_errorMonitor->VerifyFound();
4346 
4347     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdSetScissor-firstScissor-00592");
4348     vkCmdSetScissor(m_commandBuffer->handle(), 1, max_scissors, scissors.data());
4349     m_errorMonitor->VerifyFound();
4350 
4351     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdSetScissor-scissorCount-arraylength");
4352     vkCmdSetScissor(m_commandBuffer->handle(), 1, 0, scissors.data());
4353     m_errorMonitor->VerifyFound();
4354 }
4355 
TEST_F(VkLayerTest,DrawIndirect)4356 TEST_F(VkLayerTest, DrawIndirect) {
4357     TEST_DESCRIPTION("Test covered valid usage for vkCmdDrawIndirect");
4358 
4359     ASSERT_NO_FATAL_FAILURE(Init());
4360     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
4361 
4362     CreatePipelineHelper pipe(*this);
4363     pipe.InitInfo();
4364     const VkDynamicState dyn_states[] = {VK_DYNAMIC_STATE_VIEWPORT, VK_DYNAMIC_STATE_SCISSOR};
4365     VkPipelineDynamicStateCreateInfo dyn_state_ci = {};
4366     dyn_state_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO;
4367     dyn_state_ci.dynamicStateCount = size(dyn_states);
4368     dyn_state_ci.pDynamicStates = dyn_states;
4369     pipe.dyn_state_ci_ = dyn_state_ci;
4370     pipe.InitState();
4371     pipe.CreateGraphicsPipeline();
4372 
4373     m_commandBuffer->begin();
4374     m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
4375 
4376     vkCmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.pipeline_);
4377     vkCmdBindDescriptorSets(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.pipeline_layout_.handle(), 0, 1,
4378                             &pipe.descriptor_set_->set_, 0, NULL);
4379 
4380     VkViewport viewport = {0, 0, 16, 16, 0, 1};
4381     vkCmdSetViewport(m_commandBuffer->handle(), 0, 1, &viewport);
4382     VkRect2D scissor = {{0, 0}, {16, 16}};
4383     vkCmdSetScissor(m_commandBuffer->handle(), 0, 1, &scissor);
4384 
4385     VkBufferCreateInfo buffer_create_info = {VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO};
4386     buffer_create_info.usage = VK_BUFFER_USAGE_VERTEX_BUFFER_BIT;
4387     buffer_create_info.size = sizeof(VkDrawIndirectCommand);
4388     VkBufferObj draw_buffer;
4389     draw_buffer.init(*m_device, buffer_create_info);
4390 
4391     // VUID-vkCmdDrawIndirect-buffer-02709
4392     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdDrawIndirect-buffer-02709");
4393     vkCmdDrawIndirect(m_commandBuffer->handle(), draw_buffer.handle(), 0, 1, sizeof(VkDrawIndirectCommand));
4394     m_errorMonitor->VerifyFound();
4395 
4396     m_commandBuffer->EndRenderPass();
4397     m_commandBuffer->end();
4398 }
4399 
TEST_F(VkLayerTest,DrawIndirectCountKHR)4400 TEST_F(VkLayerTest, DrawIndirectCountKHR) {
4401     TEST_DESCRIPTION("Test covered valid usage for vkCmdDrawIndirectCountKHR");
4402 
4403     ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor));
4404     if (DeviceExtensionSupported(gpu(), nullptr, VK_KHR_DRAW_INDIRECT_COUNT_EXTENSION_NAME)) {
4405         m_device_extension_names.push_back(VK_KHR_DRAW_INDIRECT_COUNT_EXTENSION_NAME);
4406     } else {
4407         printf("             VK_KHR_draw_indirect_count Extension not supported, skipping test\n");
4408         return;
4409     }
4410     ASSERT_NO_FATAL_FAILURE(InitState());
4411     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
4412 
4413     VkMemoryRequirements memory_requirements;
4414     VkMemoryAllocateInfo memory_allocate_info = {VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO};
4415 
4416     auto vkCmdDrawIndirectCountKHR =
4417         (PFN_vkCmdDrawIndirectCountKHR)vkGetDeviceProcAddr(m_device->device(), "vkCmdDrawIndirectCountKHR");
4418 
4419     CreatePipelineHelper pipe(*this);
4420     pipe.InitInfo();
4421     const VkDynamicState dyn_states[] = {VK_DYNAMIC_STATE_VIEWPORT, VK_DYNAMIC_STATE_SCISSOR};
4422     VkPipelineDynamicStateCreateInfo dyn_state_ci = {};
4423     dyn_state_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO;
4424     dyn_state_ci.dynamicStateCount = size(dyn_states);
4425     dyn_state_ci.pDynamicStates = dyn_states;
4426     pipe.dyn_state_ci_ = dyn_state_ci;
4427     pipe.InitState();
4428     pipe.CreateGraphicsPipeline();
4429 
4430     m_commandBuffer->begin();
4431     m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
4432 
4433     vkCmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.pipeline_);
4434     vkCmdBindDescriptorSets(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.pipeline_layout_.handle(), 0, 1,
4435                             &pipe.descriptor_set_->set_, 0, NULL);
4436 
4437     VkViewport viewport = {0, 0, 16, 16, 0, 1};
4438     vkCmdSetViewport(m_commandBuffer->handle(), 0, 1, &viewport);
4439     VkRect2D scissor = {{0, 0}, {16, 16}};
4440     vkCmdSetScissor(m_commandBuffer->handle(), 0, 1, &scissor);
4441 
4442     VkBufferCreateInfo buffer_create_info = {VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO};
4443     buffer_create_info.size = sizeof(VkDrawIndirectCommand);
4444     buffer_create_info.usage = VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT;
4445     VkBuffer draw_buffer;
4446     vkCreateBuffer(m_device->device(), &buffer_create_info, nullptr, &draw_buffer);
4447 
4448     VkBufferCreateInfo count_buffer_create_info = {VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO};
4449     count_buffer_create_info.size = sizeof(uint32_t);
4450     count_buffer_create_info.usage = VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT;
4451     VkBufferObj count_buffer;
4452     count_buffer.init(*m_device, count_buffer_create_info);
4453 
4454     // VUID-vkCmdDrawIndirectCountKHR-buffer-02708
4455     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdDrawIndirectCountKHR-buffer-02708");
4456     vkCmdDrawIndirectCountKHR(m_commandBuffer->handle(), draw_buffer, 0, count_buffer.handle(), 0, 1,
4457                               sizeof(VkDrawIndirectCommand));
4458     m_errorMonitor->VerifyFound();
4459 
4460     vkGetBufferMemoryRequirements(m_device->device(), draw_buffer, &memory_requirements);
4461     memory_allocate_info.allocationSize = memory_requirements.size;
4462     m_device->phy().set_memory_type(memory_requirements.memoryTypeBits, &memory_allocate_info, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT);
4463     VkDeviceMemory draw_buffer_memory;
4464     vkAllocateMemory(m_device->device(), &memory_allocate_info, NULL, &draw_buffer_memory);
4465     vkBindBufferMemory(m_device->device(), draw_buffer, draw_buffer_memory, 0);
4466 
4467     VkBuffer count_buffer_unbound;
4468     vkCreateBuffer(m_device->device(), &count_buffer_create_info, nullptr, &count_buffer_unbound);
4469 
4470     // VUID-vkCmdDrawIndirectCountKHR-countBuffer-02714
4471     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdDrawIndirectCountKHR-countBuffer-02714");
4472     vkCmdDrawIndirectCountKHR(m_commandBuffer->handle(), draw_buffer, 0, count_buffer_unbound, 0, 1, sizeof(VkDrawIndirectCommand));
4473     m_errorMonitor->VerifyFound();
4474 
4475     // VUID-vkCmdDrawIndirectCountKHR-offset-02710
4476     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdDrawIndirectCountKHR-offset-02710");
4477     vkCmdDrawIndirectCountKHR(m_commandBuffer->handle(), draw_buffer, 1, count_buffer.handle(), 0, 1,
4478                               sizeof(VkDrawIndirectCommand));
4479     m_errorMonitor->VerifyFound();
4480 
4481     // VUID-vkCmdDrawIndirectCountKHR-countBufferOffset-02716
4482     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdDrawIndirectCountKHR-countBufferOffset-02716");
4483     vkCmdDrawIndirectCountKHR(m_commandBuffer->handle(), draw_buffer, 0, count_buffer.handle(), 1, 1,
4484                               sizeof(VkDrawIndirectCommand));
4485     m_errorMonitor->VerifyFound();
4486 
4487     // VUID-vkCmdDrawIndirectCountKHR-stride-03110
4488     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdDrawIndirectCountKHR-stride-03110");
4489     vkCmdDrawIndirectCountKHR(m_commandBuffer->handle(), draw_buffer, 0, count_buffer.handle(), 0, 1, 1);
4490     m_errorMonitor->VerifyFound();
4491 
4492     // TODO: These covered VUIDs aren't tested. There is also no test coverage for the core Vulkan 1.0 vkCmdDraw* equivalent of
4493     // these:
4494     //     VUID-vkCmdDrawIndirectCountKHR-renderPass-02684
4495     //     VUID-vkCmdDrawIndirectCountKHR-subpass-02685
4496     //     VUID-vkCmdDrawIndirectCountKHR-commandBuffer-02701
4497 
4498     m_commandBuffer->EndRenderPass();
4499     m_commandBuffer->end();
4500 
4501     vkDestroyBuffer(m_device->device(), draw_buffer, 0);
4502     vkDestroyBuffer(m_device->device(), count_buffer_unbound, 0);
4503 
4504     vkFreeMemory(m_device->device(), draw_buffer_memory, 0);
4505 }
4506 
TEST_F(VkLayerTest,DrawIndexedIndirectCountKHR)4507 TEST_F(VkLayerTest, DrawIndexedIndirectCountKHR) {
4508     TEST_DESCRIPTION("Test covered valid usage for vkCmdDrawIndexedIndirectCountKHR");
4509 
4510     ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor));
4511     if (DeviceExtensionSupported(gpu(), nullptr, VK_KHR_DRAW_INDIRECT_COUNT_EXTENSION_NAME)) {
4512         m_device_extension_names.push_back(VK_KHR_DRAW_INDIRECT_COUNT_EXTENSION_NAME);
4513     } else {
4514         printf("             VK_KHR_draw_indirect_count Extension not supported, skipping test\n");
4515         return;
4516     }
4517     ASSERT_NO_FATAL_FAILURE(InitState());
4518     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
4519 
4520     auto vkCmdDrawIndexedIndirectCountKHR =
4521         (PFN_vkCmdDrawIndexedIndirectCountKHR)vkGetDeviceProcAddr(m_device->device(), "vkCmdDrawIndexedIndirectCountKHR");
4522 
4523     CreatePipelineHelper pipe(*this);
4524     pipe.InitInfo();
4525     const VkDynamicState dyn_states[] = {VK_DYNAMIC_STATE_VIEWPORT, VK_DYNAMIC_STATE_SCISSOR};
4526     VkPipelineDynamicStateCreateInfo dyn_state_ci = {};
4527     dyn_state_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO;
4528     dyn_state_ci.dynamicStateCount = size(dyn_states);
4529     dyn_state_ci.pDynamicStates = dyn_states;
4530     pipe.dyn_state_ci_ = dyn_state_ci;
4531     pipe.InitState();
4532     pipe.CreateGraphicsPipeline();
4533 
4534     m_commandBuffer->begin();
4535     m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
4536 
4537     vkCmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.pipeline_);
4538     vkCmdBindDescriptorSets(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.pipeline_layout_.handle(), 0, 1,
4539                             &pipe.descriptor_set_->set_, 0, NULL);
4540 
4541     VkViewport viewport = {0, 0, 16, 16, 0, 1};
4542     vkCmdSetViewport(m_commandBuffer->handle(), 0, 1, &viewport);
4543     VkRect2D scissor = {{0, 0}, {16, 16}};
4544     vkCmdSetScissor(m_commandBuffer->handle(), 0, 1, &scissor);
4545 
4546     VkBufferCreateInfo buffer_create_info = {VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO};
4547     buffer_create_info.size = sizeof(VkDrawIndexedIndirectCommand);
4548     buffer_create_info.usage = VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT;
4549     VkBufferObj draw_buffer;
4550     draw_buffer.init(*m_device, buffer_create_info);
4551 
4552     VkBufferCreateInfo count_buffer_create_info = {VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO};
4553     count_buffer_create_info.size = sizeof(uint32_t);
4554     count_buffer_create_info.usage = VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT;
4555     VkBufferObj count_buffer;
4556     count_buffer.init(*m_device, count_buffer_create_info);
4557 
4558     VkBufferCreateInfo index_buffer_create_info = {VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO};
4559     index_buffer_create_info.size = sizeof(uint32_t);
4560     index_buffer_create_info.usage = VK_BUFFER_USAGE_INDEX_BUFFER_BIT;
4561     VkBufferObj index_buffer;
4562     index_buffer.init(*m_device, index_buffer_create_info);
4563 
4564     // VUID-vkCmdDrawIndexedIndirectCountKHR-commandBuffer-02701 (partial - only tests whether the index buffer is bound)
4565     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
4566                                          "VUID-vkCmdDrawIndexedIndirectCountKHR-commandBuffer-02701");
4567     vkCmdDrawIndexedIndirectCountKHR(m_commandBuffer->handle(), draw_buffer.handle(), 0, count_buffer.handle(), 0, 1,
4568                                      sizeof(VkDrawIndexedIndirectCommand));
4569     m_errorMonitor->VerifyFound();
4570 
4571     vkCmdBindIndexBuffer(m_commandBuffer->handle(), index_buffer.handle(), 0, VK_INDEX_TYPE_UINT32);
4572 
4573     VkBuffer draw_buffer_unbound;
4574     vkCreateBuffer(m_device->device(), &count_buffer_create_info, nullptr, &draw_buffer_unbound);
4575 
4576     // VUID-vkCmdDrawIndexedIndirectCountKHR-buffer-02708
4577     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdDrawIndexedIndirectCountKHR-buffer-02708");
4578     vkCmdDrawIndexedIndirectCountKHR(m_commandBuffer->handle(), draw_buffer_unbound, 0, count_buffer.handle(), 0, 1,
4579                                      sizeof(VkDrawIndexedIndirectCommand));
4580     m_errorMonitor->VerifyFound();
4581 
4582     VkBuffer count_buffer_unbound;
4583     vkCreateBuffer(m_device->device(), &count_buffer_create_info, nullptr, &count_buffer_unbound);
4584 
4585     // VUID-vkCmdDrawIndexedIndirectCountKHR-countBuffer-02714
4586     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdDrawIndexedIndirectCountKHR-countBuffer-02714");
4587     vkCmdDrawIndexedIndirectCountKHR(m_commandBuffer->handle(), draw_buffer.handle(), 0, count_buffer_unbound, 0, 1,
4588                                      sizeof(VkDrawIndexedIndirectCommand));
4589     m_errorMonitor->VerifyFound();
4590 
4591     // VUID-vkCmdDrawIndexedIndirectCountKHR-offset-02710
4592     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdDrawIndexedIndirectCountKHR-offset-02710");
4593     vkCmdDrawIndexedIndirectCountKHR(m_commandBuffer->handle(), draw_buffer.handle(), 1, count_buffer.handle(), 0, 1,
4594                                      sizeof(VkDrawIndexedIndirectCommand));
4595     m_errorMonitor->VerifyFound();
4596 
4597     // VUID-vkCmdDrawIndexedIndirectCountKHR-countBufferOffset-02716
4598     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
4599                                          "VUID-vkCmdDrawIndexedIndirectCountKHR-countBufferOffset-02716");
4600     vkCmdDrawIndexedIndirectCountKHR(m_commandBuffer->handle(), draw_buffer.handle(), 0, count_buffer.handle(), 1, 1,
4601                                      sizeof(VkDrawIndexedIndirectCommand));
4602     m_errorMonitor->VerifyFound();
4603 
4604     // VUID-vkCmdDrawIndexedIndirectCountKHR-stride-03142
4605     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdDrawIndexedIndirectCountKHR-stride-03142");
4606     vkCmdDrawIndexedIndirectCountKHR(m_commandBuffer->handle(), draw_buffer.handle(), 0, count_buffer.handle(), 0, 1, 1);
4607     m_errorMonitor->VerifyFound();
4608 
4609     // TODO: These covered VUIDs aren't tested. There is also no test coverage for the core Vulkan 1.0 vkCmdDraw* equivalent of
4610     // these:
4611     //     VUID-vkCmdDrawIndexedIndirectCountKHR-renderPass-02684
4612     //     VUID-vkCmdDrawIndexedIndirectCountKHR-subpass-02685
4613     //     VUID-vkCmdDrawIndexedIndirectCountKHR-commandBuffer-02701 (partial)
4614 
4615     m_commandBuffer->EndRenderPass();
4616     m_commandBuffer->end();
4617 
4618     vkDestroyBuffer(m_device->device(), draw_buffer_unbound, 0);
4619     vkDestroyBuffer(m_device->device(), count_buffer_unbound, 0);
4620 }
4621 
TEST_F(VkLayerTest,ExclusiveScissorNV)4622 TEST_F(VkLayerTest, ExclusiveScissorNV) {
4623     TEST_DESCRIPTION("Test VK_NV_scissor_exclusive with multiViewport disabled.");
4624 
4625     if (InstanceExtensionSupported(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME)) {
4626         m_instance_extension_names.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
4627     } else {
4628         printf("%s Did not find required instance extension %s; skipped.\n", kSkipPrefix,
4629                VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
4630         return;
4631     }
4632     ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor));
4633     std::array<const char *, 1> required_device_extensions = {{VK_NV_SCISSOR_EXCLUSIVE_EXTENSION_NAME}};
4634     for (auto device_extension : required_device_extensions) {
4635         if (DeviceExtensionSupported(gpu(), nullptr, device_extension)) {
4636             m_device_extension_names.push_back(device_extension);
4637         } else {
4638             printf("%s %s Extension not supported, skipping tests\n", kSkipPrefix, device_extension);
4639             return;
4640         }
4641     }
4642 
4643     PFN_vkGetPhysicalDeviceFeatures2KHR vkGetPhysicalDeviceFeatures2KHR =
4644         (PFN_vkGetPhysicalDeviceFeatures2KHR)vkGetInstanceProcAddr(instance(), "vkGetPhysicalDeviceFeatures2KHR");
4645     ASSERT_TRUE(vkGetPhysicalDeviceFeatures2KHR != nullptr);
4646 
4647     // Create a device that enables exclusive scissor but disables multiViewport
4648     auto exclusive_scissor_features = lvl_init_struct<VkPhysicalDeviceExclusiveScissorFeaturesNV>();
4649     auto features2 = lvl_init_struct<VkPhysicalDeviceFeatures2KHR>(&exclusive_scissor_features);
4650     vkGetPhysicalDeviceFeatures2KHR(gpu(), &features2);
4651 
4652     features2.features.multiViewport = VK_FALSE;
4653 
4654     ASSERT_NO_FATAL_FAILURE(InitState(nullptr, &features2));
4655     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
4656 
4657     if (m_device->phy().properties().limits.maxViewports) {
4658         printf("%s Device doesn't support the necessary number of viewports, skipping test.\n", kSkipPrefix);
4659         return;
4660     }
4661 
4662     // Based on PSOViewportStateTests
4663     {
4664         VkViewport viewport = {0.0f, 0.0f, 64.0f, 64.0f, 0.0f, 1.0f};
4665         VkViewport viewports[] = {viewport, viewport};
4666         VkRect2D scissor = {{0, 0}, {64, 64}};
4667         VkRect2D scissors[100] = {scissor, scissor};
4668 
4669         using std::vector;
4670         struct TestCase {
4671             uint32_t viewport_count;
4672             VkViewport *viewports;
4673             uint32_t scissor_count;
4674             VkRect2D *scissors;
4675             uint32_t exclusive_scissor_count;
4676             VkRect2D *exclusive_scissors;
4677 
4678             vector<std::string> vuids;
4679         };
4680 
4681         vector<TestCase> test_cases = {
4682             {1,
4683              viewports,
4684              1,
4685              scissors,
4686              2,
4687              scissors,
4688              {"VUID-VkPipelineViewportExclusiveScissorStateCreateInfoNV-exclusiveScissorCount-02027",
4689               "VUID-VkPipelineViewportExclusiveScissorStateCreateInfoNV-exclusiveScissorCount-02029"}},
4690             {1,
4691              viewports,
4692              1,
4693              scissors,
4694              100,
4695              scissors,
4696              {"VUID-VkPipelineViewportExclusiveScissorStateCreateInfoNV-exclusiveScissorCount-02027",
4697               "VUID-VkPipelineViewportExclusiveScissorStateCreateInfoNV-exclusiveScissorCount-02028",
4698               "VUID-VkPipelineViewportExclusiveScissorStateCreateInfoNV-exclusiveScissorCount-02029"}},
4699             {1,
4700              viewports,
4701              1,
4702              scissors,
4703              1,
4704              nullptr,
4705              {"VUID-VkPipelineViewportExclusiveScissorStateCreateInfoNV-pDynamicStates-02030"}},
4706         };
4707 
4708         for (const auto &test_case : test_cases) {
4709             VkPipelineViewportExclusiveScissorStateCreateInfoNV exc = {
4710                 VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_EXCLUSIVE_SCISSOR_STATE_CREATE_INFO_NV};
4711 
4712             const auto break_vp = [&test_case, &exc](CreatePipelineHelper &helper) {
4713                 helper.vp_state_ci_.viewportCount = test_case.viewport_count;
4714                 helper.vp_state_ci_.pViewports = test_case.viewports;
4715                 helper.vp_state_ci_.scissorCount = test_case.scissor_count;
4716                 helper.vp_state_ci_.pScissors = test_case.scissors;
4717                 helper.vp_state_ci_.pNext = &exc;
4718 
4719                 exc.exclusiveScissorCount = test_case.exclusive_scissor_count;
4720                 exc.pExclusiveScissors = test_case.exclusive_scissors;
4721             };
4722             CreatePipelineHelper::OneshotTest(*this, break_vp, VK_DEBUG_REPORT_ERROR_BIT_EXT, test_case.vuids);
4723         }
4724     }
4725 
4726     // Based on SetDynScissorParamTests
4727     {
4728         auto vkCmdSetExclusiveScissorNV =
4729             (PFN_vkCmdSetExclusiveScissorNV)vkGetDeviceProcAddr(m_device->device(), "vkCmdSetExclusiveScissorNV");
4730 
4731         const VkRect2D scissor = {{0, 0}, {16, 16}};
4732         const VkRect2D scissors[] = {scissor, scissor};
4733 
4734         m_commandBuffer->begin();
4735 
4736         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
4737                                              "VUID-vkCmdSetExclusiveScissorNV-firstExclusiveScissor-02035");
4738         vkCmdSetExclusiveScissorNV(m_commandBuffer->handle(), 1, 1, scissors);
4739         m_errorMonitor->VerifyFound();
4740 
4741         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
4742                                              "vkCmdSetExclusiveScissorNV: parameter exclusiveScissorCount must be greater than 0");
4743         vkCmdSetExclusiveScissorNV(m_commandBuffer->handle(), 0, 0, nullptr);
4744         m_errorMonitor->VerifyFound();
4745 
4746         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
4747                                              "VUID-vkCmdSetExclusiveScissorNV-exclusiveScissorCount-02036");
4748         vkCmdSetExclusiveScissorNV(m_commandBuffer->handle(), 0, 2, scissors);
4749         m_errorMonitor->VerifyFound();
4750 
4751         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
4752                                              "vkCmdSetExclusiveScissorNV: parameter exclusiveScissorCount must be greater than 0");
4753         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
4754                                              "VUID-vkCmdSetExclusiveScissorNV-firstExclusiveScissor-02035");
4755         vkCmdSetExclusiveScissorNV(m_commandBuffer->handle(), 1, 0, scissors);
4756         m_errorMonitor->VerifyFound();
4757 
4758         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
4759                                              "VUID-vkCmdSetExclusiveScissorNV-firstExclusiveScissor-02035");
4760         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
4761                                              "VUID-vkCmdSetExclusiveScissorNV-exclusiveScissorCount-02036");
4762         vkCmdSetExclusiveScissorNV(m_commandBuffer->handle(), 1, 2, scissors);
4763         m_errorMonitor->VerifyFound();
4764 
4765         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
4766                                              "vkCmdSetExclusiveScissorNV: required parameter pExclusiveScissors specified as NULL");
4767         vkCmdSetExclusiveScissorNV(m_commandBuffer->handle(), 0, 1, nullptr);
4768         m_errorMonitor->VerifyFound();
4769 
4770         struct TestCase {
4771             VkRect2D scissor;
4772             std::string vuid;
4773         };
4774 
4775         std::vector<TestCase> test_cases = {
4776             {{{-1, 0}, {16, 16}}, "VUID-vkCmdSetExclusiveScissorNV-x-02037"},
4777             {{{0, -1}, {16, 16}}, "VUID-vkCmdSetExclusiveScissorNV-x-02037"},
4778             {{{1, 0}, {INT32_MAX, 16}}, "VUID-vkCmdSetExclusiveScissorNV-offset-02038"},
4779             {{{INT32_MAX, 0}, {1, 16}}, "VUID-vkCmdSetExclusiveScissorNV-offset-02038"},
4780             {{{0, 0}, {uint32_t{INT32_MAX} + 1, 16}}, "VUID-vkCmdSetExclusiveScissorNV-offset-02038"},
4781             {{{0, 1}, {16, INT32_MAX}}, "VUID-vkCmdSetExclusiveScissorNV-offset-02039"},
4782             {{{0, INT32_MAX}, {16, 1}}, "VUID-vkCmdSetExclusiveScissorNV-offset-02039"},
4783             {{{0, 0}, {16, uint32_t{INT32_MAX} + 1}}, "VUID-vkCmdSetExclusiveScissorNV-offset-02039"}};
4784 
4785         for (const auto &test_case : test_cases) {
4786             m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, test_case.vuid);
4787             vkCmdSetExclusiveScissorNV(m_commandBuffer->handle(), 0, 1, &test_case.scissor);
4788             m_errorMonitor->VerifyFound();
4789         }
4790 
4791         m_commandBuffer->end();
4792     }
4793 }
4794 
TEST_F(VkLayerTest,MeshShaderNV)4795 TEST_F(VkLayerTest, MeshShaderNV) {
4796     TEST_DESCRIPTION("Test VK_NV_mesh_shader.");
4797 
4798     if (InstanceExtensionSupported(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME)) {
4799         m_instance_extension_names.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
4800     } else {
4801         printf("%s Did not find required instance extension %s; skipped.\n", kSkipPrefix,
4802                VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
4803         return;
4804     }
4805     ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor));
4806     std::array<const char *, 1> required_device_extensions = {{VK_NV_MESH_SHADER_EXTENSION_NAME}};
4807     for (auto device_extension : required_device_extensions) {
4808         if (DeviceExtensionSupported(gpu(), nullptr, device_extension)) {
4809             m_device_extension_names.push_back(device_extension);
4810         } else {
4811             printf("%s %s Extension not supported, skipping tests\n", kSkipPrefix, device_extension);
4812             return;
4813         }
4814     }
4815 
4816     if (DeviceIsMockICD() || DeviceSimulation()) {
4817         printf("%sNot suppored by MockICD, skipping tests\n", kSkipPrefix);
4818         return;
4819     }
4820 
4821     PFN_vkGetPhysicalDeviceFeatures2KHR vkGetPhysicalDeviceFeatures2KHR =
4822         (PFN_vkGetPhysicalDeviceFeatures2KHR)vkGetInstanceProcAddr(instance(), "vkGetPhysicalDeviceFeatures2KHR");
4823     ASSERT_TRUE(vkGetPhysicalDeviceFeatures2KHR != nullptr);
4824 
4825     // Create a device that enables mesh_shader
4826     auto mesh_shader_features = lvl_init_struct<VkPhysicalDeviceMeshShaderFeaturesNV>();
4827     auto features2 = lvl_init_struct<VkPhysicalDeviceFeatures2KHR>(&mesh_shader_features);
4828     vkGetPhysicalDeviceFeatures2KHR(gpu(), &features2);
4829     features2.features.multiDrawIndirect = VK_FALSE;
4830 
4831     ASSERT_NO_FATAL_FAILURE(InitState(nullptr, &features2));
4832     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
4833 
4834     static const char vertShaderText[] =
4835         "#version 450\n"
4836         "vec2 vertices[3];\n"
4837         "void main() {\n"
4838         "      vertices[0] = vec2(-1.0, -1.0);\n"
4839         "      vertices[1] = vec2( 1.0, -1.0);\n"
4840         "      vertices[2] = vec2( 0.0,  1.0);\n"
4841         "   gl_Position = vec4(vertices[gl_VertexIndex % 3], 0.0, 1.0);\n"
4842         "   gl_PointSize = 1.0f;\n"
4843         "}\n";
4844 
4845     static const char meshShaderText[] =
4846         "#version 450\n"
4847         "#extension GL_NV_mesh_shader : require\n"
4848         "layout(local_size_x = 1) in;\n"
4849         "layout(max_vertices = 3) out;\n"
4850         "layout(max_primitives = 1) out;\n"
4851         "layout(triangles) out;\n"
4852         "void main() {\n"
4853         "      gl_MeshVerticesNV[0].gl_Position = vec4(-1.0, -1.0, 0, 1);\n"
4854         "      gl_MeshVerticesNV[1].gl_Position = vec4( 1.0, -1.0, 0, 1);\n"
4855         "      gl_MeshVerticesNV[2].gl_Position = vec4( 0.0,  1.0, 0, 1);\n"
4856         "      gl_PrimitiveIndicesNV[0] = 0;\n"
4857         "      gl_PrimitiveIndicesNV[1] = 1;\n"
4858         "      gl_PrimitiveIndicesNV[2] = 2;\n"
4859         "      gl_PrimitiveCountNV = 1;\n"
4860         "}\n";
4861 
4862     VkShaderObj vs(m_device, vertShaderText, VK_SHADER_STAGE_VERTEX_BIT, this);
4863     VkShaderObj ms(m_device, meshShaderText, VK_SHADER_STAGE_MESH_BIT_NV, this);
4864     VkShaderObj fs(m_device, bindStateFragShaderText, VK_SHADER_STAGE_FRAGMENT_BIT, this);
4865 
4866     // Test pipeline creation
4867     {
4868         // can't mix mesh with vertex
4869         const auto break_vp = [&](CreatePipelineHelper &helper) {
4870             helper.shader_stages_ = {vs.GetStageCreateInfo(), fs.GetStageCreateInfo(), ms.GetStageCreateInfo()};
4871         };
4872         CreatePipelineHelper::OneshotTest(*this, break_vp, VK_DEBUG_REPORT_ERROR_BIT_EXT,
4873                                           vector<std::string>({"VUID-VkGraphicsPipelineCreateInfo-pStages-02095"}));
4874 
4875         // vertex or mesh must be present
4876         const auto break_vp2 = [&](CreatePipelineHelper &helper) { helper.shader_stages_ = {fs.GetStageCreateInfo()}; };
4877         CreatePipelineHelper::OneshotTest(*this, break_vp2, VK_DEBUG_REPORT_ERROR_BIT_EXT,
4878                                           vector<std::string>({"VUID-VkGraphicsPipelineCreateInfo-stage-02096"}));
4879 
4880         // vertexinput and inputassembly must be valid when vertex stage is present
4881         const auto break_vp3 = [&](CreatePipelineHelper &helper) {
4882             helper.shader_stages_ = {vs.GetStageCreateInfo(), fs.GetStageCreateInfo()};
4883             helper.gp_ci_.pVertexInputState = nullptr;
4884             helper.gp_ci_.pInputAssemblyState = nullptr;
4885         };
4886         CreatePipelineHelper::OneshotTest(*this, break_vp3, VK_DEBUG_REPORT_ERROR_BIT_EXT,
4887                                           vector<std::string>({"VUID-VkGraphicsPipelineCreateInfo-pStages-02097",
4888                                                                "VUID-VkGraphicsPipelineCreateInfo-pStages-02098"}));
4889     }
4890 
4891     PFN_vkCmdDrawMeshTasksIndirectNV vkCmdDrawMeshTasksIndirectNV =
4892         (PFN_vkCmdDrawMeshTasksIndirectNV)vkGetInstanceProcAddr(instance(), "vkCmdDrawMeshTasksIndirectNV");
4893 
4894     VkBufferCreateInfo buffer_create_info = {VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO};
4895     buffer_create_info.size = sizeof(uint32_t);
4896     buffer_create_info.usage = VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT;
4897     VkBuffer buffer;
4898     VkResult result = vkCreateBuffer(m_device->device(), &buffer_create_info, nullptr, &buffer);
4899     ASSERT_VK_SUCCESS(result);
4900 
4901     m_commandBuffer->begin();
4902 
4903     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdDrawMeshTasksIndirectNV-drawCount-02146");
4904     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdDrawMeshTasksIndirectNV-drawCount-02718");
4905     vkCmdDrawMeshTasksIndirectNV(m_commandBuffer->handle(), buffer, 0, 2, 0);
4906     m_errorMonitor->VerifyFound();
4907 
4908     m_commandBuffer->end();
4909 
4910     vkDestroyBuffer(m_device->device(), buffer, 0);
4911 }
4912 
TEST_F(VkLayerTest,MeshShaderDisabledNV)4913 TEST_F(VkLayerTest, MeshShaderDisabledNV) {
4914     TEST_DESCRIPTION("Test VK_NV_mesh_shader VUs with NV_mesh_shader disabled.");
4915     ASSERT_NO_FATAL_FAILURE(Init());
4916     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
4917 
4918     VkEvent event;
4919     VkEventCreateInfo event_create_info{};
4920     event_create_info.sType = VK_STRUCTURE_TYPE_EVENT_CREATE_INFO;
4921     vkCreateEvent(m_device->device(), &event_create_info, nullptr, &event);
4922 
4923     m_commandBuffer->begin();
4924 
4925     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdSetEvent-stageMask-02107");
4926     vkCmdSetEvent(m_commandBuffer->handle(), event, VK_PIPELINE_STAGE_MESH_SHADER_BIT_NV);
4927     m_errorMonitor->VerifyFound();
4928 
4929     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdSetEvent-stageMask-02108");
4930     vkCmdSetEvent(m_commandBuffer->handle(), event, VK_PIPELINE_STAGE_TASK_SHADER_BIT_NV);
4931     m_errorMonitor->VerifyFound();
4932 
4933     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdResetEvent-stageMask-02109");
4934     vkCmdResetEvent(m_commandBuffer->handle(), event, VK_PIPELINE_STAGE_MESH_SHADER_BIT_NV);
4935     m_errorMonitor->VerifyFound();
4936 
4937     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdResetEvent-stageMask-02110");
4938     vkCmdResetEvent(m_commandBuffer->handle(), event, VK_PIPELINE_STAGE_TASK_SHADER_BIT_NV);
4939     m_errorMonitor->VerifyFound();
4940 
4941     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdWaitEvents-srcStageMask-02111");
4942     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdWaitEvents-dstStageMask-02113");
4943     vkCmdWaitEvents(m_commandBuffer->handle(), 1, &event, VK_PIPELINE_STAGE_MESH_SHADER_BIT_NV,
4944                     VK_PIPELINE_STAGE_MESH_SHADER_BIT_NV, 0, nullptr, 0, nullptr, 0, nullptr);
4945     m_errorMonitor->VerifyFound();
4946 
4947     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdWaitEvents-srcStageMask-02112");
4948     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdWaitEvents-dstStageMask-02114");
4949     vkCmdWaitEvents(m_commandBuffer->handle(), 1, &event, VK_PIPELINE_STAGE_TASK_SHADER_BIT_NV,
4950                     VK_PIPELINE_STAGE_TASK_SHADER_BIT_NV, 0, nullptr, 0, nullptr, 0, nullptr);
4951     m_errorMonitor->VerifyFound();
4952 
4953     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdPipelineBarrier-srcStageMask-02115");
4954     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdPipelineBarrier-dstStageMask-02117");
4955     vkCmdPipelineBarrier(m_commandBuffer->handle(), VK_PIPELINE_STAGE_MESH_SHADER_BIT_NV, VK_PIPELINE_STAGE_MESH_SHADER_BIT_NV, 0,
4956                          0, nullptr, 0, nullptr, 0, nullptr);
4957     m_errorMonitor->VerifyFound();
4958 
4959     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdPipelineBarrier-srcStageMask-02116");
4960     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-vkCmdPipelineBarrier-dstStageMask-02118");
4961     vkCmdPipelineBarrier(m_commandBuffer->handle(), VK_PIPELINE_STAGE_TASK_SHADER_BIT_NV, VK_PIPELINE_STAGE_TASK_SHADER_BIT_NV, 0,
4962                          0, nullptr, 0, nullptr, 0, nullptr);
4963     m_errorMonitor->VerifyFound();
4964 
4965     m_commandBuffer->end();
4966 
4967     VkSemaphoreCreateInfo semaphore_create_info = {};
4968     semaphore_create_info.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO;
4969     VkSemaphore semaphore;
4970     ASSERT_VK_SUCCESS(vkCreateSemaphore(m_device->device(), &semaphore_create_info, nullptr, &semaphore));
4971 
4972     VkPipelineStageFlags stage_flags = VK_PIPELINE_STAGE_MESH_SHADER_BIT_NV | VK_PIPELINE_STAGE_TASK_SHADER_BIT_NV;
4973     VkSubmitInfo submit_info = {};
4974 
4975     // Signal the semaphore so the next test can wait on it.
4976     submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
4977     submit_info.signalSemaphoreCount = 1;
4978     submit_info.pSignalSemaphores = &semaphore;
4979     vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
4980     m_errorMonitor->VerifyNotFound();
4981 
4982     submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
4983     submit_info.signalSemaphoreCount = 0;
4984     submit_info.pSignalSemaphores = nullptr;
4985     submit_info.waitSemaphoreCount = 1;
4986     submit_info.pWaitSemaphores = &semaphore;
4987     submit_info.pWaitDstStageMask = &stage_flags;
4988 
4989     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkSubmitInfo-pWaitDstStageMask-02089");
4990     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VUID-VkSubmitInfo-pWaitDstStageMask-02090");
4991     vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
4992     m_errorMonitor->VerifyFound();
4993 
4994     vkQueueWaitIdle(m_device->m_queue);
4995 
4996     VkShaderObj vs(m_device, bindStateVertShaderText, VK_SHADER_STAGE_VERTEX_BIT, this);
4997     VkPipelineShaderStageCreateInfo meshStage = {VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO};
4998     meshStage = vs.GetStageCreateInfo();
4999     meshStage.stage = VK_SHADER_STAGE_MESH_BIT_NV;
5000     VkPipelineShaderStageCreateInfo taskStage = {VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO};
5001     taskStage = vs.GetStageCreateInfo();
5002     taskStage.stage = VK_SHADER_STAGE_TASK_BIT_NV;
5003 
5004     // mesh and task shaders not supported
5005     const auto break_vp = [&](CreatePipelineHelper &helper) {
5006         helper.shader_stages_ = {meshStage, taskStage, vs.GetStageCreateInfo()};
5007     };
5008     CreatePipelineHelper::OneshotTest(
5009         *this, break_vp, VK_DEBUG_REPORT_ERROR_BIT_EXT,
5010         vector<std::string>({"VUID-VkPipelineShaderStageCreateInfo-pName-00707", "VUID-VkPipelineShaderStageCreateInfo-pName-00707",
5011                              "VUID-VkPipelineShaderStageCreateInfo-stage-02091",
5012                              "VUID-VkPipelineShaderStageCreateInfo-stage-02092"}));
5013 
5014     vkDestroyEvent(m_device->device(), event, nullptr);
5015     vkDestroySemaphore(m_device->device(), semaphore, nullptr);
5016 }
5017