blob: d506017a6eb57365e97f4708cd41d18e189a6deb [file] [log] [blame]
unknown088160a2019-05-23 17:43:13 -06001/*
sfricke-samsung6d97e562020-01-07 22:01:00 -08002 * Copyright (c) 2015-2020 The Khronos Group Inc.
3 * Copyright (c) 2015-2020 Valve Corporation
4 * Copyright (c) 2015-2020 LunarG, Inc.
5 * Copyright (c) 2015-2020 Google, Inc.
unknown088160a2019-05-23 17:43:13 -06006 *
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 <olvaffe@gmail.com>
14 * Author: Chris Forbes <chrisf@ijw.co.nz>
15 * Author: Courtney Goeltzenleuchter <courtney@LunarG.com>
16 * Author: Mark Lobodzinski <mark@lunarg.com>
17 * Author: Mike Stroyan <mike@LunarG.com>
18 * Author: Tobin Ehlis <tobine@google.com>
19 * Author: Tony Barbour <tony@LunarG.com>
20 * Author: Cody Northrop <cnorthrop@google.com>
21 * Author: Dave Houlton <daveh@lunarg.com>
22 * Author: Jeremy Kniager <jeremyk@lunarg.com>
23 * Author: Shannon McPherson <shannon@lunarg.com>
24 * Author: John Zulauf <jzulauf@lunarg.com>
25 */
26
27#include "cast_utils.h"
28#include "layer_validation_tests.h"
29
30TEST_F(VkLayerTest, InvalidCommandPoolConsistency) {
31 TEST_DESCRIPTION("Allocate command buffers from one command pool and attempt to delete them from another.");
32
Mark Lobodzinski20310782020-02-28 14:25:17 -070033 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkFreeCommandBuffers-pCommandBuffers-parent");
unknown088160a2019-05-23 17:43:13 -060034
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
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -060044 vk::CreateCommandPool(m_device->device(), &pool_create_info, nullptr, &command_pool_one);
unknown088160a2019-05-23 17:43:13 -060045
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -060046 vk::CreateCommandPool(m_device->device(), &pool_create_info, nullptr, &command_pool_two);
unknown088160a2019-05-23 17:43:13 -060047
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;
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -060054 vk::AllocateCommandBuffers(m_device->device(), &command_buffer_allocate_info, &cb);
unknown088160a2019-05-23 17:43:13 -060055
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -060056 vk::FreeCommandBuffers(m_device->device(), command_pool_two, 1, &cb);
unknown088160a2019-05-23 17:43:13 -060057
58 m_errorMonitor->VerifyFound();
59
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -060060 vk::DestroyCommandPool(m_device->device(), command_pool_one, NULL);
61 vk::DestroyCommandPool(m_device->device(), command_pool_two, NULL);
unknown088160a2019-05-23 17:43:13 -060062}
63
64TEST_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
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -060088 VkResult err = vk::CreateRenderPass(m_device->device(), &rpci, nullptr, &rp);
unknown088160a2019-05-23 17:43:13 -060089 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;
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -0600100 err = vk::CreateFramebuffer(m_device->device(), &fbci, nullptr, &fb);
unknown088160a2019-05-23 17:43:13 -0600101 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
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -0600117 vk::CmdBeginRenderPass(m_commandBuffer->handle(), &rpbi, VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS);
unknown088160a2019-05-23 17:43:13 -0600118
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};
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -0600133 vk::BeginCommandBuffer(secondary.handle(), &cbbi);
unknown088160a2019-05-23 17:43:13 -0600134 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;
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -0600148 vk::CmdPipelineBarrier(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);
unknown088160a2019-05-23 17:43:13 -0600150 secondary.end();
151
Shannon McPherson93970b12020-06-12 14:34:35 -0600152 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdPipelineBarrier-image-04073");
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -0600153 vk::CmdExecuteCommands(m_commandBuffer->handle(), 1, &secondary.handle());
unknown088160a2019-05-23 17:43:13 -0600154 m_errorMonitor->VerifyFound();
155
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -0600156 vk::DestroyFramebuffer(m_device->device(), fb, nullptr);
157 vk::DestroyRenderPass(m_device->device(), rp, nullptr);
unknown088160a2019-05-23 17:43:13 -0600158}
159
160TEST_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
Mark Lobodzinski20310782020-02-28 14:25:17 -0700166 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "Dynamic depth bias state not set for this command buffer");
unknown088160a2019-05-23 17:43:13 -0600167 VKTriangleTest(BsoFailDepthBias);
168 m_errorMonitor->VerifyFound();
169}
170
171TEST_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
Mark Lobodzinski20310782020-02-28 14:25:17 -0700177 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "Dynamic line width state not set for this command buffer");
unknown088160a2019-05-23 17:43:13 -0600178 VKTriangleTest(BsoFailLineWidth);
179 m_errorMonitor->VerifyFound();
180}
181
Jeff Bolzf390c6c2019-08-16 16:29:53 -0500182TEST_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 }
Mark Lobodzinski09ce9c42020-03-06 10:02:44 -0700193 ASSERT_NO_FATAL_FAILURE(InitFramework(m_errorMonitor));
Jeff Bolzf390c6c2019-08-16 16:29:53 -0500194 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 =
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -0600205 (PFN_vkGetPhysicalDeviceFeatures2KHR)vk::GetInstanceProcAddr(instance(), "vkGetPhysicalDeviceFeatures2KHR");
Jeff Bolzf390c6c2019-08-16 16:29:53 -0500206 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
Mark Lobodzinski20310782020-02-28 14:25:17 -0700219 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "Dynamic line stipple state not set for this command buffer");
Jeff Bolzf390c6c2019-08-16 16:29:53 -0500220 VKTriangleTest(BsoFailLineStipple);
221 m_errorMonitor->VerifyFound();
222}
223
unknown088160a2019-05-23 17:43:13 -0600224TEST_F(VkLayerTest, DynamicViewportNotBound) {
225 TEST_DESCRIPTION(
226 "Run a simple draw calls to validate failure when Viewport dynamic state is required but not correctly bound.");
227
228 ASSERT_NO_FATAL_FAILURE(Init());
229 // Dynamic viewport state
Mark Lobodzinski20310782020-02-28 14:25:17 -0700230 m_errorMonitor->SetDesiredFailureMsg(kErrorBit,
unknown088160a2019-05-23 17:43:13 -0600231 "Dynamic viewport(s) 0 are used by pipeline state object, but were not provided");
232 VKTriangleTest(BsoFailViewport);
233 m_errorMonitor->VerifyFound();
234}
235
236TEST_F(VkLayerTest, DynamicScissorNotBound) {
237 TEST_DESCRIPTION("Run a simple draw calls to validate failure when Scissor dynamic state is required but not correctly bound.");
238
239 ASSERT_NO_FATAL_FAILURE(Init());
240 // Dynamic scissor state
Mark Lobodzinski20310782020-02-28 14:25:17 -0700241 m_errorMonitor->SetDesiredFailureMsg(kErrorBit,
unknown088160a2019-05-23 17:43:13 -0600242 "Dynamic scissor(s) 0 are used by pipeline state object, but were not provided");
243 VKTriangleTest(BsoFailScissor);
244 m_errorMonitor->VerifyFound();
245}
246
247TEST_F(VkLayerTest, DynamicBlendConstantsNotBound) {
248 TEST_DESCRIPTION(
249 "Run a simple draw calls to validate failure when Blend Constants dynamic state is required but not correctly bound.");
250
251 ASSERT_NO_FATAL_FAILURE(Init());
252 // Dynamic blend constant state
Mark Lobodzinski20310782020-02-28 14:25:17 -0700253 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "Dynamic blend constants state not set for this command buffer");
unknown088160a2019-05-23 17:43:13 -0600254 VKTriangleTest(BsoFailBlend);
255 m_errorMonitor->VerifyFound();
256}
257
258TEST_F(VkLayerTest, DynamicDepthBoundsNotBound) {
259 TEST_DESCRIPTION(
260 "Run a simple draw calls to validate failure when Depth Bounds dynamic state is required but not correctly bound.");
261
262 ASSERT_NO_FATAL_FAILURE(Init());
263 if (!m_device->phy().features().depthBounds) {
264 printf("%s Device does not support depthBounds test; skipped.\n", kSkipPrefix);
265 return;
266 }
267 // Dynamic depth bounds
Mark Lobodzinski20310782020-02-28 14:25:17 -0700268 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "Dynamic depth bounds state not set for this command buffer");
unknown088160a2019-05-23 17:43:13 -0600269 VKTriangleTest(BsoFailDepthBounds);
270 m_errorMonitor->VerifyFound();
271}
272
273TEST_F(VkLayerTest, DynamicStencilReadNotBound) {
274 TEST_DESCRIPTION(
275 "Run a simple draw calls to validate failure when Stencil Read dynamic state is required but not correctly bound.");
276
277 ASSERT_NO_FATAL_FAILURE(Init());
278 // Dynamic stencil read mask
Mark Lobodzinski20310782020-02-28 14:25:17 -0700279 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "Dynamic stencil read mask state not set for this command buffer");
unknown088160a2019-05-23 17:43:13 -0600280 VKTriangleTest(BsoFailStencilReadMask);
281 m_errorMonitor->VerifyFound();
282}
283
284TEST_F(VkLayerTest, DynamicStencilWriteNotBound) {
285 TEST_DESCRIPTION(
286 "Run a simple draw calls to validate failure when Stencil Write dynamic state is required but not correctly bound.");
287
288 ASSERT_NO_FATAL_FAILURE(Init());
289 // Dynamic stencil write mask
Mark Lobodzinski20310782020-02-28 14:25:17 -0700290 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "Dynamic stencil write mask state not set for this command buffer");
unknown088160a2019-05-23 17:43:13 -0600291 VKTriangleTest(BsoFailStencilWriteMask);
292 m_errorMonitor->VerifyFound();
293}
294
295TEST_F(VkLayerTest, DynamicStencilRefNotBound) {
296 TEST_DESCRIPTION(
297 "Run a simple draw calls to validate failure when Stencil Ref dynamic state is required but not correctly bound.");
298
299 ASSERT_NO_FATAL_FAILURE(Init());
300 // Dynamic stencil reference
Mark Lobodzinski20310782020-02-28 14:25:17 -0700301 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "Dynamic stencil reference state not set for this command buffer");
unknown088160a2019-05-23 17:43:13 -0600302 VKTriangleTest(BsoFailStencilReference);
303 m_errorMonitor->VerifyFound();
304}
305
306TEST_F(VkLayerTest, IndexBufferNotBound) {
307 TEST_DESCRIPTION("Run an indexed draw call without an index buffer bound.");
308
309 ASSERT_NO_FATAL_FAILURE(Init());
Mark Lobodzinski20310782020-02-28 14:25:17 -0700310 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "Index buffer object not bound to this command buffer when Indexed ");
unknown088160a2019-05-23 17:43:13 -0600311 VKTriangleTest(BsoFailIndexBuffer);
312 m_errorMonitor->VerifyFound();
313}
314
315TEST_F(VkLayerTest, IndexBufferBadSize) {
316 TEST_DESCRIPTION("Run indexed draw call with bad index buffer size.");
317
318 ASSERT_NO_FATAL_FAILURE(Init(nullptr, nullptr, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT));
Mark Lobodzinski20310782020-02-28 14:25:17 -0700319 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "vkCmdDrawIndexed() index size ");
unknown088160a2019-05-23 17:43:13 -0600320 VKTriangleTest(BsoFailIndexBufferBadSize);
321 m_errorMonitor->VerifyFound();
322}
323
324TEST_F(VkLayerTest, IndexBufferBadOffset) {
325 TEST_DESCRIPTION("Run indexed draw call with bad index buffer offset.");
326
327 ASSERT_NO_FATAL_FAILURE(Init(nullptr, nullptr, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT));
Mark Lobodzinski20310782020-02-28 14:25:17 -0700328 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "vkCmdDrawIndexed() index size ");
unknown088160a2019-05-23 17:43:13 -0600329 VKTriangleTest(BsoFailIndexBufferBadOffset);
330 m_errorMonitor->VerifyFound();
331}
332
333TEST_F(VkLayerTest, IndexBufferBadBindSize) {
334 TEST_DESCRIPTION("Run bind index buffer with a size greater than the index buffer.");
335
336 ASSERT_NO_FATAL_FAILURE(Init(nullptr, nullptr, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT));
Mark Lobodzinski20310782020-02-28 14:25:17 -0700337 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "vkCmdDrawIndexed() index size ");
unknown088160a2019-05-23 17:43:13 -0600338 VKTriangleTest(BsoFailIndexBufferBadMapSize);
339 m_errorMonitor->VerifyFound();
340}
341
342TEST_F(VkLayerTest, IndexBufferBadBindOffset) {
343 TEST_DESCRIPTION("Run bind index buffer with an offset greater than the size of the index buffer.");
344
345 ASSERT_NO_FATAL_FAILURE(Init(nullptr, nullptr, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT));
Mark Lobodzinski20310782020-02-28 14:25:17 -0700346 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "vkCmdDrawIndexed() index size ");
unknown088160a2019-05-23 17:43:13 -0600347 VKTriangleTest(BsoFailIndexBufferBadMapOffset);
348 m_errorMonitor->VerifyFound();
349}
350
351TEST_F(VkLayerTest, MissingClearAttachment) {
352 TEST_DESCRIPTION("Points to a wrong colorAttachment index in a VkClearAttachment structure passed to vkCmdClearAttachments");
353 ASSERT_NO_FATAL_FAILURE(Init());
Mark Lobodzinski20310782020-02-28 14:25:17 -0700354 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdClearAttachments-aspectMask-02501");
unknown088160a2019-05-23 17:43:13 -0600355
356 VKTriangleTest(BsoFailCmdClearAttachments);
357 m_errorMonitor->VerifyFound();
358}
359
Mark Lobodzinskicd0204c2019-11-11 16:59:18 -0700360TEST_F(VkLayerTest, SecondaryCommandbufferAsPrimary) {
361 TEST_DESCRIPTION("Create a secondary command buffer and pass it to QueueSubmit.");
Mark Lobodzinski20310782020-02-28 14:25:17 -0700362 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkSubmitInfo-pCommandBuffers-00075");
Mark Lobodzinskicd0204c2019-11-11 16:59:18 -0700363
364 ASSERT_NO_FATAL_FAILURE(Init());
365
366 VkCommandBufferObj secondary(m_device, m_commandPool, VK_COMMAND_BUFFER_LEVEL_SECONDARY);
367 secondary.begin();
368 secondary.ClearAllBuffers(m_renderTargets, m_clear_color, nullptr, m_depth_clear_color, m_stencil_clear_color);
369 secondary.end();
370
371 VkSubmitInfo submit_info;
372 submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
373 submit_info.pNext = NULL;
374 submit_info.waitSemaphoreCount = 0;
375 submit_info.pWaitSemaphores = NULL;
376 submit_info.pWaitDstStageMask = NULL;
377 submit_info.commandBufferCount = 1;
378 submit_info.pCommandBuffers = &secondary.handle();
379 submit_info.signalSemaphoreCount = 0;
380 submit_info.pSignalSemaphores = NULL;
381
382 vk::QueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
383 m_errorMonitor->VerifyFound();
384}
385
unknown088160a2019-05-23 17:43:13 -0600386TEST_F(VkLayerTest, CommandBufferTwoSubmits) {
Mark Lobodzinski20310782020-02-28 14:25:17 -0700387 m_errorMonitor->SetDesiredFailureMsg(kErrorBit,
unknown088160a2019-05-23 17:43:13 -0600388 "was begun w/ VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT set, but has been submitted");
389
390 ASSERT_NO_FATAL_FAILURE(Init());
391 ASSERT_NO_FATAL_FAILURE(InitViewport());
392 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
393
394 // We luck out b/c by default the framework creates CB w/ the
395 // VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT set
396 m_commandBuffer->begin();
397 m_commandBuffer->ClearAllBuffers(m_renderTargets, m_clear_color, nullptr, m_depth_clear_color, m_stencil_clear_color);
398 m_commandBuffer->end();
399
400 // Bypass framework since it does the waits automatically
401 VkResult err = VK_SUCCESS;
402 VkSubmitInfo submit_info;
403 submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
404 submit_info.pNext = NULL;
405 submit_info.waitSemaphoreCount = 0;
406 submit_info.pWaitSemaphores = NULL;
407 submit_info.pWaitDstStageMask = NULL;
408 submit_info.commandBufferCount = 1;
409 submit_info.pCommandBuffers = &m_commandBuffer->handle();
410 submit_info.signalSemaphoreCount = 0;
411 submit_info.pSignalSemaphores = NULL;
412
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -0600413 err = vk::QueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
unknown088160a2019-05-23 17:43:13 -0600414 ASSERT_VK_SUCCESS(err);
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -0600415 vk::QueueWaitIdle(m_device->m_queue);
unknown088160a2019-05-23 17:43:13 -0600416
417 // Cause validation error by re-submitting cmd buffer that should only be
418 // submitted once
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -0600419 err = vk::QueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
420 vk::QueueWaitIdle(m_device->m_queue);
unknown088160a2019-05-23 17:43:13 -0600421
422 m_errorMonitor->VerifyFound();
423}
424
425TEST_F(VkLayerTest, InvalidPushConstants) {
426 ASSERT_NO_FATAL_FAILURE(Init());
427 ASSERT_NO_FATAL_FAILURE(InitViewport());
428 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
429
430 VkPipelineLayout pipeline_layout;
431 VkPushConstantRange pc_range = {};
432 VkPipelineLayoutCreateInfo pipeline_layout_ci = {};
433 pipeline_layout_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
434 pipeline_layout_ci.pushConstantRangeCount = 1;
435 pipeline_layout_ci.pPushConstantRanges = &pc_range;
436
437 //
438 // Check for invalid push constant ranges in pipeline layouts.
439 //
440 struct PipelineLayoutTestCase {
441 VkPushConstantRange const range;
442 char const *msg;
443 };
444
445 const uint32_t too_big = m_device->props.limits.maxPushConstantsSize + 0x4;
446 const std::array<PipelineLayoutTestCase, 10> range_tests = {{
447 {{VK_SHADER_STAGE_VERTEX_BIT, 0, 0}, "vkCreatePipelineLayout() call has push constants index 0 with size 0."},
448 {{VK_SHADER_STAGE_VERTEX_BIT, 0, 1}, "vkCreatePipelineLayout() call has push constants index 0 with size 1."},
449 {{VK_SHADER_STAGE_VERTEX_BIT, 4, 1}, "vkCreatePipelineLayout() call has push constants index 0 with size 1."},
450 {{VK_SHADER_STAGE_VERTEX_BIT, 4, 0}, "vkCreatePipelineLayout() call has push constants index 0 with size 0."},
451 {{VK_SHADER_STAGE_VERTEX_BIT, 1, 4}, "vkCreatePipelineLayout() call has push constants index 0 with offset 1. Offset must"},
452 {{VK_SHADER_STAGE_VERTEX_BIT, 0, too_big}, "vkCreatePipelineLayout() call has push constants index 0 with offset "},
453 {{VK_SHADER_STAGE_VERTEX_BIT, too_big, too_big}, "vkCreatePipelineLayout() call has push constants index 0 with offset "},
454 {{VK_SHADER_STAGE_VERTEX_BIT, too_big, 4}, "vkCreatePipelineLayout() call has push constants index 0 with offset "},
455 {{VK_SHADER_STAGE_VERTEX_BIT, 0xFFFFFFF0, 0x00000020},
456 "vkCreatePipelineLayout() call has push constants index 0 with offset "},
457 {{VK_SHADER_STAGE_VERTEX_BIT, 0x00000020, 0xFFFFFFF0},
458 "vkCreatePipelineLayout() call has push constants index 0 with offset "},
459 }};
460
461 // Check for invalid offset and size
462 for (const auto &iter : range_tests) {
463 pc_range = iter.range;
Mark Lobodzinski20310782020-02-28 14:25:17 -0700464 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, iter.msg);
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -0600465 vk::CreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipeline_layout);
unknown088160a2019-05-23 17:43:13 -0600466 m_errorMonitor->VerifyFound();
467 }
468
469 // Check for invalid stage flag
470 pc_range.offset = 0;
471 pc_range.size = 16;
472 pc_range.stageFlags = 0;
473 m_errorMonitor->SetDesiredFailureMsg(
Mark Lobodzinski20310782020-02-28 14:25:17 -0700474 kErrorBit, "vkCreatePipelineLayout: value of pCreateInfo->pPushConstantRanges[0].stageFlags must not be 0");
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -0600475 vk::CreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipeline_layout);
unknown088160a2019-05-23 17:43:13 -0600476 m_errorMonitor->VerifyFound();
477
478 // Check for duplicate stage flags in a list of push constant ranges.
479 // A shader can only have one push constant block and that block is mapped
480 // to the push constant range that has that shader's stage flag set.
481 // The shader's stage flag can only appear once in all the ranges, so the
482 // implementation can find the one and only range to map it to.
483 const uint32_t ranges_per_test = 5;
484 struct DuplicateStageFlagsTestCase {
485 VkPushConstantRange const ranges[ranges_per_test];
486 std::vector<char const *> const msg;
487 };
488 // Overlapping ranges are OK, but a stage flag can appear only once.
489 const std::array<DuplicateStageFlagsTestCase, 3> duplicate_stageFlags_tests = {
490 {
491 {{{VK_SHADER_STAGE_VERTEX_BIT, 0, 4},
492 {VK_SHADER_STAGE_VERTEX_BIT, 0, 4},
493 {VK_SHADER_STAGE_VERTEX_BIT, 0, 4},
494 {VK_SHADER_STAGE_VERTEX_BIT, 0, 4},
495 {VK_SHADER_STAGE_VERTEX_BIT, 0, 4}},
496 {
497 "vkCreatePipelineLayout() Duplicate stage flags found in ranges 0 and 1.",
498 "vkCreatePipelineLayout() Duplicate stage flags found in ranges 0 and 2.",
499 "vkCreatePipelineLayout() Duplicate stage flags found in ranges 0 and 3.",
500 "vkCreatePipelineLayout() Duplicate stage flags found in ranges 0 and 4.",
501 "vkCreatePipelineLayout() Duplicate stage flags found in ranges 1 and 2.",
502 "vkCreatePipelineLayout() Duplicate stage flags found in ranges 1 and 3.",
503 "vkCreatePipelineLayout() Duplicate stage flags found in ranges 1 and 4.",
504 "vkCreatePipelineLayout() Duplicate stage flags found in ranges 2 and 3.",
505 "vkCreatePipelineLayout() Duplicate stage flags found in ranges 2 and 4.",
506 "vkCreatePipelineLayout() Duplicate stage flags found in ranges 3 and 4.",
507 }},
508 {{{VK_SHADER_STAGE_VERTEX_BIT, 0, 4},
509 {VK_SHADER_STAGE_GEOMETRY_BIT, 0, 4},
510 {VK_SHADER_STAGE_FRAGMENT_BIT, 0, 4},
511 {VK_SHADER_STAGE_VERTEX_BIT, 0, 4},
512 {VK_SHADER_STAGE_GEOMETRY_BIT, 0, 4}},
513 {
514 "vkCreatePipelineLayout() Duplicate stage flags found in ranges 0 and 3.",
515 "vkCreatePipelineLayout() Duplicate stage flags found in ranges 1 and 4.",
516 }},
517 {{{VK_SHADER_STAGE_FRAGMENT_BIT, 0, 4},
518 {VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT, 0, 4},
519 {VK_SHADER_STAGE_VERTEX_BIT, 0, 4},
520 {VK_SHADER_STAGE_VERTEX_BIT, 0, 4},
521 {VK_SHADER_STAGE_GEOMETRY_BIT, 0, 4}},
522 {
523 "vkCreatePipelineLayout() Duplicate stage flags found in ranges 2 and 3.",
524 }},
525 },
526 };
527
528 for (const auto &iter : duplicate_stageFlags_tests) {
529 pipeline_layout_ci.pPushConstantRanges = iter.ranges;
530 pipeline_layout_ci.pushConstantRangeCount = ranges_per_test;
Mark Lobodzinski20310782020-02-28 14:25:17 -0700531 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, iter.msg.begin(), iter.msg.end());
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -0600532 vk::CreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipeline_layout);
unknown088160a2019-05-23 17:43:13 -0600533 m_errorMonitor->VerifyFound();
534 }
535
536 //
537 // CmdPushConstants tests
538 //
539
540 // Setup a pipeline layout with ranges: [0,32) [16,80)
541 const std::vector<VkPushConstantRange> pc_range2 = {{VK_SHADER_STAGE_VERTEX_BIT, 16, 64},
542 {VK_SHADER_STAGE_FRAGMENT_BIT, 0, 32}};
543 const VkPipelineLayoutObj pipeline_layout_obj(m_device, {}, pc_range2);
544
545 const uint8_t dummy_values[100] = {};
546
547 m_commandBuffer->begin();
548 m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
549
550 // Check for invalid stage flag
551 // Note that VU 00996 isn't reached due to parameter validation
Mark Lobodzinski20310782020-02-28 14:25:17 -0700552 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "vkCmdPushConstants: value of stageFlags must not be 0");
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -0600553 vk::CmdPushConstants(m_commandBuffer->handle(), pipeline_layout_obj.handle(), 0, 0, 16, dummy_values);
unknown088160a2019-05-23 17:43:13 -0600554 m_errorMonitor->VerifyFound();
555
556 // Positive tests for the overlapping ranges
557 m_errorMonitor->ExpectSuccess();
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -0600558 vk::CmdPushConstants(m_commandBuffer->handle(), pipeline_layout_obj.handle(), VK_SHADER_STAGE_FRAGMENT_BIT, 0, 16,
559 dummy_values);
unknown088160a2019-05-23 17:43:13 -0600560 m_errorMonitor->VerifyNotFound();
561 m_errorMonitor->ExpectSuccess();
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -0600562 vk::CmdPushConstants(m_commandBuffer->handle(), pipeline_layout_obj.handle(), VK_SHADER_STAGE_VERTEX_BIT, 32, 48, dummy_values);
unknown088160a2019-05-23 17:43:13 -0600563 m_errorMonitor->VerifyNotFound();
564 m_errorMonitor->ExpectSuccess();
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -0600565 vk::CmdPushConstants(m_commandBuffer->handle(), pipeline_layout_obj.handle(),
566 VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT, 16, 16, dummy_values);
unknown088160a2019-05-23 17:43:13 -0600567 m_errorMonitor->VerifyNotFound();
568
569 // Wrong cmd stages for extant range
570 // No range for all cmd stages -- "VUID-vkCmdPushConstants-offset-01795" VUID-vkCmdPushConstants-offset-01795
Mark Lobodzinski20310782020-02-28 14:25:17 -0700571 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdPushConstants-offset-01795");
unknown088160a2019-05-23 17:43:13 -0600572 // Missing cmd stages for found overlapping range -- "VUID-vkCmdPushConstants-offset-01796" VUID-vkCmdPushConstants-offset-01796
Mark Lobodzinski20310782020-02-28 14:25:17 -0700573 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdPushConstants-offset-01796");
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -0600574 vk::CmdPushConstants(m_commandBuffer->handle(), pipeline_layout_obj.handle(), VK_SHADER_STAGE_GEOMETRY_BIT, 0, 16,
575 dummy_values);
unknown088160a2019-05-23 17:43:13 -0600576 m_errorMonitor->VerifyFound();
577
578 // Wrong no extant range
Mark Lobodzinski20310782020-02-28 14:25:17 -0700579 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdPushConstants-offset-01795");
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -0600580 vk::CmdPushConstants(m_commandBuffer->handle(), pipeline_layout_obj.handle(), VK_SHADER_STAGE_FRAGMENT_BIT, 80, 4,
581 dummy_values);
unknown088160a2019-05-23 17:43:13 -0600582 m_errorMonitor->VerifyFound();
583
584 // Wrong overlapping extent
Mark Lobodzinski20310782020-02-28 14:25:17 -0700585 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdPushConstants-offset-01795");
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -0600586 vk::CmdPushConstants(m_commandBuffer->handle(), pipeline_layout_obj.handle(),
587 VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT, 0, 20, dummy_values);
unknown088160a2019-05-23 17:43:13 -0600588 m_errorMonitor->VerifyFound();
589
590 // Wrong stage flags for valid overlapping range
Mark Lobodzinski20310782020-02-28 14:25:17 -0700591 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdPushConstants-offset-01796");
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -0600592 vk::CmdPushConstants(m_commandBuffer->handle(), pipeline_layout_obj.handle(), VK_SHADER_STAGE_VERTEX_BIT, 16, 16, dummy_values);
unknown088160a2019-05-23 17:43:13 -0600593 m_errorMonitor->VerifyFound();
594
595 m_commandBuffer->EndRenderPass();
596 m_commandBuffer->end();
597}
598
599TEST_F(VkLayerTest, NoBeginCommandBuffer) {
Mark Lobodzinski20310782020-02-28 14:25:17 -0700600 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "You must call vkBeginCommandBuffer() before this call to ");
unknown088160a2019-05-23 17:43:13 -0600601
602 ASSERT_NO_FATAL_FAILURE(Init());
603 VkCommandBufferObj commandBuffer(m_device, m_commandPool);
604 // Call EndCommandBuffer() w/o calling BeginCommandBuffer()
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -0600605 vk::EndCommandBuffer(commandBuffer.handle());
unknown088160a2019-05-23 17:43:13 -0600606
607 m_errorMonitor->VerifyFound();
608}
609
610TEST_F(VkLayerTest, SecondaryCommandBufferNullRenderpass) {
611 ASSERT_NO_FATAL_FAILURE(Init());
612
613 VkCommandBufferObj cb(m_device, m_commandPool, VK_COMMAND_BUFFER_LEVEL_SECONDARY);
614
615 // Force the failure by not setting the Renderpass and Framebuffer fields
616 VkCommandBufferInheritanceInfo cmd_buf_hinfo = {};
617 cmd_buf_hinfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO;
618
619 VkCommandBufferBeginInfo cmd_buf_info = {};
620 cmd_buf_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
621 cmd_buf_info.pNext = NULL;
622 cmd_buf_info.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT | VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT;
623 cmd_buf_info.pInheritanceInfo = &cmd_buf_hinfo;
624
Mark Lobodzinski20310782020-02-28 14:25:17 -0700625 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkCommandBufferBeginInfo-flags-00053");
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -0600626 vk::BeginCommandBuffer(cb.handle(), &cmd_buf_info);
unknown088160a2019-05-23 17:43:13 -0600627 m_errorMonitor->VerifyFound();
628}
629
630TEST_F(VkLayerTest, SecondaryCommandBufferRerecordedExplicitReset) {
631 ASSERT_NO_FATAL_FAILURE(Init());
632
Mark Lobodzinski20310782020-02-28 14:25:17 -0700633 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "was destroyed or rerecorded");
unknown088160a2019-05-23 17:43:13 -0600634
635 // A pool we can reset in.
636 VkCommandPoolObj pool(m_device, m_device->graphics_queue_node_index_, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT);
637 VkCommandBufferObj secondary(m_device, &pool, VK_COMMAND_BUFFER_LEVEL_SECONDARY);
638
639 secondary.begin();
640 secondary.end();
641
642 m_commandBuffer->begin();
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -0600643 vk::CmdExecuteCommands(m_commandBuffer->handle(), 1, &secondary.handle());
unknown088160a2019-05-23 17:43:13 -0600644
645 // rerecording of secondary
646 secondary.reset(); // explicit reset here.
647 secondary.begin();
648 secondary.end();
649
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -0600650 vk::CmdExecuteCommands(m_commandBuffer->handle(), 1, &secondary.handle());
unknown088160a2019-05-23 17:43:13 -0600651 m_errorMonitor->VerifyFound();
652}
653
654TEST_F(VkLayerTest, SecondaryCommandBufferRerecordedNoReset) {
655 ASSERT_NO_FATAL_FAILURE(Init());
656
Mark Lobodzinski20310782020-02-28 14:25:17 -0700657 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "was destroyed or rerecorded");
unknown088160a2019-05-23 17:43:13 -0600658
659 // A pool we can reset in.
660 VkCommandPoolObj pool(m_device, m_device->graphics_queue_node_index_, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT);
661 VkCommandBufferObj secondary(m_device, &pool, VK_COMMAND_BUFFER_LEVEL_SECONDARY);
662
663 secondary.begin();
664 secondary.end();
665
666 m_commandBuffer->begin();
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -0600667 vk::CmdExecuteCommands(m_commandBuffer->handle(), 1, &secondary.handle());
unknown088160a2019-05-23 17:43:13 -0600668
669 // rerecording of secondary
670 secondary.begin(); // implicit reset in begin
671 secondary.end();
672
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -0600673 vk::CmdExecuteCommands(m_commandBuffer->handle(), 1, &secondary.handle());
unknown088160a2019-05-23 17:43:13 -0600674 m_errorMonitor->VerifyFound();
675}
676
677TEST_F(VkLayerTest, CascadedInvalidation) {
678 ASSERT_NO_FATAL_FAILURE(Init());
679
680 VkEventCreateInfo eci = {VK_STRUCTURE_TYPE_EVENT_CREATE_INFO, nullptr, 0};
681 VkEvent event;
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -0600682 vk::CreateEvent(m_device->device(), &eci, nullptr, &event);
unknown088160a2019-05-23 17:43:13 -0600683
684 VkCommandBufferObj secondary(m_device, m_commandPool, VK_COMMAND_BUFFER_LEVEL_SECONDARY);
685 secondary.begin();
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -0600686 vk::CmdSetEvent(secondary.handle(), event, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT);
unknown088160a2019-05-23 17:43:13 -0600687 secondary.end();
688
689 m_commandBuffer->begin();
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -0600690 vk::CmdExecuteCommands(m_commandBuffer->handle(), 1, &secondary.handle());
unknown088160a2019-05-23 17:43:13 -0600691 m_commandBuffer->end();
692
693 // destroying the event should invalidate both primary and secondary CB
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -0600694 vk::DestroyEvent(m_device->device(), event, nullptr);
unknown088160a2019-05-23 17:43:13 -0600695
Mark Lobodzinski20310782020-02-28 14:25:17 -0700696 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "UNASSIGNED-CoreValidation-DrawState-InvalidCommandBuffer-VkEvent");
unknown088160a2019-05-23 17:43:13 -0600697 m_commandBuffer->QueueCommandBuffer(false);
698 m_errorMonitor->VerifyFound();
699}
700
701TEST_F(VkLayerTest, CommandBufferResetErrors) {
702 // Cause error due to Begin while recording CB
703 // Then cause 2 errors for attempting to reset CB w/o having
704 // VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT set for the pool from
705 // which CBs were allocated. Note that this bit is off by default.
Mark Lobodzinski20310782020-02-28 14:25:17 -0700706 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkBeginCommandBuffer-commandBuffer-00049");
unknown088160a2019-05-23 17:43:13 -0600707
708 ASSERT_NO_FATAL_FAILURE(Init());
709
710 // Calls AllocateCommandBuffers
711 VkCommandBufferObj commandBuffer(m_device, m_commandPool);
712
713 // Force the failure by setting the Renderpass and Framebuffer fields with (fake) data
714 VkCommandBufferInheritanceInfo cmd_buf_hinfo = {};
715 cmd_buf_hinfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO;
716 VkCommandBufferBeginInfo cmd_buf_info = {};
717 cmd_buf_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
718 cmd_buf_info.pNext = NULL;
719 cmd_buf_info.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT;
720 cmd_buf_info.pInheritanceInfo = &cmd_buf_hinfo;
721
722 // Begin CB to transition to recording state
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -0600723 vk::BeginCommandBuffer(commandBuffer.handle(), &cmd_buf_info);
unknown088160a2019-05-23 17:43:13 -0600724 // Can't re-begin. This should trigger error
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -0600725 vk::BeginCommandBuffer(commandBuffer.handle(), &cmd_buf_info);
unknown088160a2019-05-23 17:43:13 -0600726 m_errorMonitor->VerifyFound();
727
Mark Lobodzinski20310782020-02-28 14:25:17 -0700728 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkResetCommandBuffer-commandBuffer-00046");
unknown088160a2019-05-23 17:43:13 -0600729 VkCommandBufferResetFlags flags = 0; // Don't care about flags for this test
730 // Reset attempt will trigger error due to incorrect CommandPool state
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -0600731 vk::ResetCommandBuffer(commandBuffer.handle(), flags);
unknown088160a2019-05-23 17:43:13 -0600732 m_errorMonitor->VerifyFound();
733
Mark Lobodzinski20310782020-02-28 14:25:17 -0700734 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkBeginCommandBuffer-commandBuffer-00050");
unknown088160a2019-05-23 17:43:13 -0600735 // Transition CB to RECORDED state
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -0600736 vk::EndCommandBuffer(commandBuffer.handle());
unknown088160a2019-05-23 17:43:13 -0600737 // Now attempting to Begin will implicitly reset, which triggers error
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -0600738 vk::BeginCommandBuffer(commandBuffer.handle(), &cmd_buf_info);
unknown088160a2019-05-23 17:43:13 -0600739 m_errorMonitor->VerifyFound();
740}
741
sfricke-samsungae9f00a2020-05-28 20:48:49 -0700742TEST_F(VkLayerTest, CommandBufferPrimaryFlags) {
743 ASSERT_NO_FATAL_FAILURE(Init());
744
745 // Calls AllocateCommandBuffers
746 VkCommandBufferObj commandBuffer(m_device, m_commandPool);
747
748 VkCommandBufferBeginInfo cmd_buf_info = {};
749 cmd_buf_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
750 cmd_buf_info.pNext = NULL;
751 cmd_buf_info.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT | VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT;
752
753 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkBeginCommandBuffer-commandBuffer-02840");
754 vk::BeginCommandBuffer(commandBuffer.handle(), &cmd_buf_info);
755 m_errorMonitor->VerifyFound();
756}
757
unknown088160a2019-05-23 17:43:13 -0600758TEST_F(VkLayerTest, ClearColorAttachmentsOutsideRenderPass) {
759 // Call CmdClearAttachmentss outside of an active RenderPass
760
Mark Lobodzinski20310782020-02-28 14:25:17 -0700761 m_errorMonitor->SetDesiredFailureMsg(kErrorBit,
unknown088160a2019-05-23 17:43:13 -0600762 "vkCmdClearAttachments(): This call must be issued inside an active render pass");
763
764 ASSERT_NO_FATAL_FAILURE(Init());
765 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
766
767 // Start no RenderPass
768 m_commandBuffer->begin();
769
770 VkClearAttachment color_attachment;
771 color_attachment.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
772 color_attachment.clearValue.color.float32[0] = 0;
773 color_attachment.clearValue.color.float32[1] = 0;
774 color_attachment.clearValue.color.float32[2] = 0;
775 color_attachment.clearValue.color.float32[3] = 0;
776 color_attachment.colorAttachment = 0;
Mark Lobodzinskid5447512019-06-28 09:56:36 -0600777 VkClearRect clear_rect = {{{0, 0}, {32, 32}}, 0, 1};
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -0600778 vk::CmdClearAttachments(m_commandBuffer->handle(), 1, &color_attachment, 1, &clear_rect);
unknown088160a2019-05-23 17:43:13 -0600779
780 m_errorMonitor->VerifyFound();
781}
782
Mark Lobodzinski7d7da062019-06-27 16:01:39 -0600783TEST_F(VkLayerTest, ClearColorAttachmentsZeroLayercount) {
784 TEST_DESCRIPTION("Call CmdClearAttachments with a pRect having a layerCount of zero.");
785
Mark Lobodzinski20310782020-02-28 14:25:17 -0700786 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdClearAttachments-layerCount-01934");
Mark Lobodzinski7d7da062019-06-27 16:01:39 -0600787
788 ASSERT_NO_FATAL_FAILURE(Init());
789 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
790
791 m_commandBuffer->begin();
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -0600792 vk::CmdBeginRenderPass(m_commandBuffer->handle(), &renderPassBeginInfo(), VK_SUBPASS_CONTENTS_INLINE);
Mark Lobodzinski7d7da062019-06-27 16:01:39 -0600793
794 VkClearAttachment color_attachment;
795 color_attachment.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
796 color_attachment.clearValue.color.float32[0] = 0;
797 color_attachment.clearValue.color.float32[1] = 0;
798 color_attachment.clearValue.color.float32[2] = 0;
799 color_attachment.clearValue.color.float32[3] = 0;
800 color_attachment.colorAttachment = 0;
801 VkClearRect clear_rect = {{{0, 0}, {32, 32}}};
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -0600802 vk::CmdClearAttachments(m_commandBuffer->handle(), 1, &color_attachment, 1, &clear_rect);
Mark Lobodzinski7d7da062019-06-27 16:01:39 -0600803
804 m_errorMonitor->VerifyFound();
805}
806
sfricke-samsungf0f3d8b2020-04-25 02:20:47 -0700807TEST_F(VkLayerTest, ClearColorAttachmentsZeroExtent) {
808 TEST_DESCRIPTION("Call CmdClearAttachments with a pRect having a rect2D extent of zero.");
809
810 ASSERT_NO_FATAL_FAILURE(Init());
811 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
812
813 m_commandBuffer->begin();
814 vk::CmdBeginRenderPass(m_commandBuffer->handle(), &renderPassBeginInfo(), VK_SUBPASS_CONTENTS_INLINE);
815
816 VkClearAttachment color_attachment;
817 color_attachment.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
818 color_attachment.clearValue.color.float32[0] = 0;
819 color_attachment.clearValue.color.float32[1] = 0;
820 color_attachment.clearValue.color.float32[2] = 0;
821 color_attachment.clearValue.color.float32[3] = 0;
822 color_attachment.colorAttachment = 0;
823 VkClearRect clear_rect = {};
824 clear_rect.rect.offset = {0, 0};
825 clear_rect.baseArrayLayer = 0;
826 clear_rect.layerCount = 1;
827
828 clear_rect.rect.extent = {0, 1};
829 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdClearAttachments-rect-02682");
830 vk::CmdClearAttachments(m_commandBuffer->handle(), 1, &color_attachment, 1, &clear_rect);
831 m_errorMonitor->VerifyFound();
832
833 clear_rect.rect.extent = {1, 0};
834 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdClearAttachments-rect-02683");
835 vk::CmdClearAttachments(m_commandBuffer->handle(), 1, &color_attachment, 1, &clear_rect);
836 m_errorMonitor->VerifyFound();
837}
838
unknown088160a2019-05-23 17:43:13 -0600839TEST_F(VkLayerTest, ExecuteCommandsPrimaryCB) {
840 TEST_DESCRIPTION("Attempt vkCmdExecuteCommands with a primary command buffer (should only be secondary)");
841
842 ASSERT_NO_FATAL_FAILURE(Init());
843 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
844
845 // An empty primary command buffer
846 VkCommandBufferObj cb(m_device, m_commandPool);
847 cb.begin();
848 cb.end();
849
850 m_commandBuffer->begin();
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -0600851 vk::CmdBeginRenderPass(m_commandBuffer->handle(), &renderPassBeginInfo(), VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS);
unknown088160a2019-05-23 17:43:13 -0600852 VkCommandBuffer handle = cb.handle();
853
Mark Lobodzinski20310782020-02-28 14:25:17 -0700854 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdExecuteCommands-pCommandBuffers-00088");
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -0600855 vk::CmdExecuteCommands(m_commandBuffer->handle(), 1, &handle);
unknown088160a2019-05-23 17:43:13 -0600856 m_errorMonitor->VerifyFound();
857
858 m_errorMonitor->SetUnexpectedError("All elements of pCommandBuffers must not be in the pending state");
859
860 m_commandBuffer->EndRenderPass();
861 m_commandBuffer->end();
862}
863
Petr Kraus8e53cf02020-01-03 05:30:04 +0100864TEST_F(VkLayerTest, ExecuteCommandsToSecondaryCB) {
865 TEST_DESCRIPTION("Attempt vkCmdExecuteCommands to a Secondary command buffer");
866
867 ASSERT_NO_FATAL_FAILURE(Init());
868
869 VkCommandBufferObj main_cb(m_device, m_commandPool, VK_COMMAND_BUFFER_LEVEL_SECONDARY);
870 VkCommandBufferObj secondary_cb(m_device, m_commandPool, VK_COMMAND_BUFFER_LEVEL_SECONDARY);
871 secondary_cb.begin();
872 secondary_cb.end();
873
874 main_cb.begin();
Mark Lobodzinski20310782020-02-28 14:25:17 -0700875 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdExecuteCommands-bufferlevel");
Petr Kraus8e53cf02020-01-03 05:30:04 +0100876 vk::CmdExecuteCommands(main_cb.handle(), 1, &secondary_cb.handle());
877 m_errorMonitor->VerifyFound();
878}
879
unknown088160a2019-05-23 17:43:13 -0600880TEST_F(VkLayerTest, InvalidVertexAttributeAlignment) {
881 TEST_DESCRIPTION("Check for proper aligment of attribAddress which depends on a bound pipeline and on a bound vertex buffer");
882
883 ASSERT_NO_FATAL_FAILURE(Init());
884 ASSERT_NO_FATAL_FAILURE(InitViewport());
885 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
886
887 const VkPipelineLayoutObj pipeline_layout(m_device);
888
889 struct VboEntry {
890 uint16_t input0[2];
891 uint32_t input1;
892 float input2[4];
893 };
894
895 const unsigned vbo_entry_count = 3;
896 const VboEntry vbo_data[vbo_entry_count] = {};
897
898 VkConstantBufferObj vbo(m_device, static_cast<int>(sizeof(VboEntry) * vbo_entry_count),
899 reinterpret_cast<const void *>(vbo_data), VK_BUFFER_USAGE_VERTEX_BUFFER_BIT);
900
901 VkVertexInputBindingDescription input_binding;
902 input_binding.binding = 0;
903 input_binding.stride = sizeof(VboEntry);
904 input_binding.inputRate = VK_VERTEX_INPUT_RATE_VERTEX;
905
906 VkVertexInputAttributeDescription input_attribs[3];
907
908 input_attribs[0].binding = 0;
909 // Location switch between attrib[0] and attrib[1] is intentional
910 input_attribs[0].location = 1;
911 input_attribs[0].format = VK_FORMAT_A8B8G8R8_UNORM_PACK32;
912 input_attribs[0].offset = offsetof(VboEntry, input1);
913
914 input_attribs[1].binding = 0;
915 input_attribs[1].location = 0;
916 input_attribs[1].format = VK_FORMAT_R16G16_UNORM;
917 input_attribs[1].offset = offsetof(VboEntry, input0);
918
919 input_attribs[2].binding = 0;
920 input_attribs[2].location = 2;
921 input_attribs[2].format = VK_FORMAT_R32G32B32A32_SFLOAT;
922 input_attribs[2].offset = offsetof(VboEntry, input2);
923
924 char const *vsSource =
925 "#version 450\n"
926 "\n"
927 "layout(location = 0) in vec2 input0;"
928 "layout(location = 1) in vec4 input1;"
929 "layout(location = 2) in vec4 input2;"
930 "\n"
931 "void main(){\n"
932 " gl_Position = input1 + input2;\n"
933 " gl_Position.xy += input0;\n"
934 "}\n";
unknown088160a2019-05-23 17:43:13 -0600935
936 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
locke-lunarg8e2c91b2019-06-11 17:53:26 -0600937 VkShaderObj fs(m_device, bindStateFragShaderText, VK_SHADER_STAGE_FRAGMENT_BIT, this);
unknown088160a2019-05-23 17:43:13 -0600938
939 VkPipelineObj pipe1(m_device);
940 pipe1.AddDefaultColorAttachment();
941 pipe1.AddShader(&vs);
942 pipe1.AddShader(&fs);
943 pipe1.AddVertexInputBindings(&input_binding, 1);
944 pipe1.AddVertexInputAttribs(&input_attribs[0], 3);
945 pipe1.SetViewport(m_viewports);
946 pipe1.SetScissor(m_scissors);
947 pipe1.CreateVKPipeline(pipeline_layout.handle(), renderPass());
948
949 input_binding.stride = 6;
950
951 VkPipelineObj pipe2(m_device);
952 pipe2.AddDefaultColorAttachment();
953 pipe2.AddShader(&vs);
954 pipe2.AddShader(&fs);
955 pipe2.AddVertexInputBindings(&input_binding, 1);
956 pipe2.AddVertexInputAttribs(&input_attribs[0], 3);
957 pipe2.SetViewport(m_viewports);
958 pipe2.SetScissor(m_scissors);
959 pipe2.CreateVKPipeline(pipeline_layout.handle(), renderPass());
960
961 m_commandBuffer->begin();
962 m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
963
964 // Test with invalid buffer offset
965 VkDeviceSize offset = 1;
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -0600966 vk::CmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe1.handle());
967 vk::CmdBindVertexBuffers(m_commandBuffer->handle(), 0, 1, &vbo.handle(), &offset);
Mark Lobodzinski20310782020-02-28 14:25:17 -0700968 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "Invalid attribAddress alignment for vertex attribute 0");
969 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "Invalid attribAddress alignment for vertex attribute 1");
970 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "Invalid attribAddress alignment for vertex attribute 2");
unknown088160a2019-05-23 17:43:13 -0600971 m_commandBuffer->Draw(1, 0, 0, 0);
972 m_errorMonitor->VerifyFound();
973
974 // Test with invalid buffer stride
975 offset = 0;
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -0600976 vk::CmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe2.handle());
977 vk::CmdBindVertexBuffers(m_commandBuffer->handle(), 0, 1, &vbo.handle(), &offset);
Mark Lobodzinski20310782020-02-28 14:25:17 -0700978 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "Invalid attribAddress alignment for vertex attribute 0");
unknown088160a2019-05-23 17:43:13 -0600979 // Attribute[1] is aligned properly even with a wrong stride
Mark Lobodzinski20310782020-02-28 14:25:17 -0700980 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "Invalid attribAddress alignment for vertex attribute 2");
unknown088160a2019-05-23 17:43:13 -0600981 m_commandBuffer->Draw(1, 0, 0, 0);
982 m_errorMonitor->VerifyFound();
983
984 m_commandBuffer->EndRenderPass();
985 m_commandBuffer->end();
986}
987
988TEST_F(VkLayerTest, NonSimultaneousSecondaryMarksPrimary) {
989 ASSERT_NO_FATAL_FAILURE(Init());
locke-lunarg77b9f7c2019-06-18 00:06:03 -0600990 const char *simultaneous_use_message = "UNASSIGNED-CoreValidation-DrawState-InvalidCommandBufferSimultaneousUse";
unknown088160a2019-05-23 17:43:13 -0600991
992 VkCommandBufferObj secondary(m_device, m_commandPool, VK_COMMAND_BUFFER_LEVEL_SECONDARY);
993
994 secondary.begin();
995 secondary.end();
996
997 VkCommandBufferBeginInfo cbbi = {
998 VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,
999 nullptr,
1000 VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT,
1001 nullptr,
1002 };
1003
1004 m_commandBuffer->begin(&cbbi);
Mark Lobodzinski20310782020-02-28 14:25:17 -07001005 m_errorMonitor->SetDesiredFailureMsg(kWarningBit, simultaneous_use_message);
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06001006 vk::CmdExecuteCommands(m_commandBuffer->handle(), 1, &secondary.handle());
unknown088160a2019-05-23 17:43:13 -06001007 m_errorMonitor->VerifyFound();
1008 m_commandBuffer->end();
1009}
1010
1011TEST_F(VkLayerTest, SimultaneousUseSecondaryTwoExecutes) {
1012 ASSERT_NO_FATAL_FAILURE(Init());
1013
John Zulauff1640d12019-08-13 15:39:58 -06001014 const char *simultaneous_use_message = "VUID-vkCmdExecuteCommands-pCommandBuffers-00092";
unknown088160a2019-05-23 17:43:13 -06001015
1016 VkCommandBufferObj secondary(m_device, m_commandPool, VK_COMMAND_BUFFER_LEVEL_SECONDARY);
1017
1018 VkCommandBufferInheritanceInfo inh = {
1019 VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO,
1020 nullptr,
1021 };
1022 VkCommandBufferBeginInfo cbbi = {VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, nullptr, 0, &inh};
1023
1024 secondary.begin(&cbbi);
1025 secondary.end();
1026
1027 m_commandBuffer->begin();
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06001028 vk::CmdExecuteCommands(m_commandBuffer->handle(), 1, &secondary.handle());
Mark Lobodzinski20310782020-02-28 14:25:17 -07001029 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, simultaneous_use_message);
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06001030 vk::CmdExecuteCommands(m_commandBuffer->handle(), 1, &secondary.handle());
unknown088160a2019-05-23 17:43:13 -06001031 m_errorMonitor->VerifyFound();
1032 m_commandBuffer->end();
1033}
1034
1035TEST_F(VkLayerTest, SimultaneousUseSecondarySingleExecute) {
1036 ASSERT_NO_FATAL_FAILURE(Init());
1037
1038 // variation on previous test executing the same CB twice in the same
1039 // CmdExecuteCommands call
1040
John Zulauff1640d12019-08-13 15:39:58 -06001041 const char *simultaneous_use_message = "VUID-vkCmdExecuteCommands-pCommandBuffers-00093";
unknown088160a2019-05-23 17:43:13 -06001042
1043 VkCommandBufferObj secondary(m_device, m_commandPool, VK_COMMAND_BUFFER_LEVEL_SECONDARY);
1044
1045 VkCommandBufferInheritanceInfo inh = {
1046 VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO,
1047 nullptr,
1048 };
1049 VkCommandBufferBeginInfo cbbi = {VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, nullptr, 0, &inh};
1050
1051 secondary.begin(&cbbi);
1052 secondary.end();
1053
1054 m_commandBuffer->begin();
1055 VkCommandBuffer cbs[] = {secondary.handle(), secondary.handle()};
Mark Lobodzinski20310782020-02-28 14:25:17 -07001056 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, simultaneous_use_message);
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06001057 vk::CmdExecuteCommands(m_commandBuffer->handle(), 2, cbs);
unknown088160a2019-05-23 17:43:13 -06001058 m_errorMonitor->VerifyFound();
1059 m_commandBuffer->end();
1060}
1061
1062TEST_F(VkLayerTest, SimultaneousUseOneShot) {
1063 TEST_DESCRIPTION("Submit the same command buffer twice in one submit looking for simultaneous use and one time submit errors");
1064 const char *simultaneous_use_message = "is already in use and is not marked for simultaneous use";
1065 const char *one_shot_message = "VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT set, but has been submitted";
1066 ASSERT_NO_FATAL_FAILURE(Init());
1067
1068 VkCommandBuffer cmd_bufs[2];
1069 VkCommandBufferAllocateInfo alloc_info;
1070 alloc_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
1071 alloc_info.pNext = NULL;
1072 alloc_info.commandBufferCount = 2;
1073 alloc_info.commandPool = m_commandPool->handle();
1074 alloc_info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06001075 vk::AllocateCommandBuffers(m_device->device(), &alloc_info, cmd_bufs);
unknown088160a2019-05-23 17:43:13 -06001076
1077 VkCommandBufferBeginInfo cb_binfo;
1078 cb_binfo.pNext = NULL;
1079 cb_binfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
1080 cb_binfo.pInheritanceInfo = VK_NULL_HANDLE;
1081 cb_binfo.flags = 0;
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06001082 vk::BeginCommandBuffer(cmd_bufs[0], &cb_binfo);
unknown088160a2019-05-23 17:43:13 -06001083 VkViewport viewport = {0, 0, 16, 16, 0, 1};
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06001084 vk::CmdSetViewport(cmd_bufs[0], 0, 1, &viewport);
1085 vk::EndCommandBuffer(cmd_bufs[0]);
unknown088160a2019-05-23 17:43:13 -06001086 VkCommandBuffer duplicates[2] = {cmd_bufs[0], cmd_bufs[0]};
1087
1088 VkSubmitInfo submit_info = {};
1089 submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
1090 submit_info.commandBufferCount = 2;
1091 submit_info.pCommandBuffers = duplicates;
Mark Lobodzinski20310782020-02-28 14:25:17 -07001092 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, simultaneous_use_message);
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06001093 vk::QueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
unknown088160a2019-05-23 17:43:13 -06001094 m_errorMonitor->VerifyFound();
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06001095 vk::QueueWaitIdle(m_device->m_queue);
unknown088160a2019-05-23 17:43:13 -06001096
1097 // Set one time use and now look for one time submit
1098 duplicates[0] = duplicates[1] = cmd_bufs[1];
1099 cb_binfo.flags = VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT | VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT;
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06001100 vk::BeginCommandBuffer(cmd_bufs[1], &cb_binfo);
1101 vk::CmdSetViewport(cmd_bufs[1], 0, 1, &viewport);
1102 vk::EndCommandBuffer(cmd_bufs[1]);
Mark Lobodzinski20310782020-02-28 14:25:17 -07001103 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, one_shot_message);
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06001104 vk::QueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
unknown088160a2019-05-23 17:43:13 -06001105 m_errorMonitor->VerifyFound();
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06001106 vk::QueueWaitIdle(m_device->m_queue);
unknown088160a2019-05-23 17:43:13 -06001107}
1108
1109TEST_F(VkLayerTest, DrawTimeImageViewTypeMismatchWithPipeline) {
1110 TEST_DESCRIPTION(
1111 "Test that an error is produced when an image view type does not match the dimensionality declared in the shader");
1112
Mark Lobodzinski20310782020-02-28 14:25:17 -07001113 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "requires an image view of type VK_IMAGE_VIEW_TYPE_3D");
unknown088160a2019-05-23 17:43:13 -06001114
1115 ASSERT_NO_FATAL_FAILURE(Init());
1116 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
1117
unknown088160a2019-05-23 17:43:13 -06001118 char const *fsSource =
1119 "#version 450\n"
1120 "\n"
1121 "layout(set=0, binding=0) uniform sampler3D s;\n"
1122 "layout(location=0) out vec4 color;\n"
1123 "void main() {\n"
1124 " color = texture(s, vec3(0));\n"
1125 "}\n";
locke-lunarg8e2c91b2019-06-11 17:53:26 -06001126 VkShaderObj vs(m_device, bindStateVertShaderText, VK_SHADER_STAGE_VERTEX_BIT, this);
unknown088160a2019-05-23 17:43:13 -06001127 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
1128
1129 VkPipelineObj pipe(m_device);
1130 pipe.AddShader(&vs);
1131 pipe.AddShader(&fs);
1132 pipe.AddDefaultColorAttachment();
1133
1134 VkTextureObj texture(m_device, nullptr);
1135 VkSamplerObj sampler(m_device);
1136
1137 VkDescriptorSetObj descriptorSet(m_device);
1138 descriptorSet.AppendSamplerTexture(&sampler, &texture);
1139 descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
1140
1141 VkResult err = pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass());
1142 ASSERT_VK_SUCCESS(err);
1143
1144 m_commandBuffer->begin();
1145 m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
1146
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06001147 vk::CmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.handle());
unknown088160a2019-05-23 17:43:13 -06001148 m_commandBuffer->BindDescriptorSet(descriptorSet);
1149
1150 VkViewport viewport = {0, 0, 16, 16, 0, 1};
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06001151 vk::CmdSetViewport(m_commandBuffer->handle(), 0, 1, &viewport);
unknown088160a2019-05-23 17:43:13 -06001152 VkRect2D scissor = {{0, 0}, {16, 16}};
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06001153 vk::CmdSetScissor(m_commandBuffer->handle(), 0, 1, &scissor);
unknown088160a2019-05-23 17:43:13 -06001154
1155 // error produced here.
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06001156 vk::CmdDraw(m_commandBuffer->handle(), 3, 1, 0, 0);
unknown088160a2019-05-23 17:43:13 -06001157
1158 m_errorMonitor->VerifyFound();
1159
1160 m_commandBuffer->EndRenderPass();
1161 m_commandBuffer->end();
1162}
1163
1164TEST_F(VkLayerTest, DrawTimeImageMultisampleMismatchWithPipeline) {
1165 TEST_DESCRIPTION(
1166 "Test that an error is produced when a multisampled images are consumed via singlesample images types in the shader, or "
1167 "vice versa.");
1168
Mark Lobodzinski20310782020-02-28 14:25:17 -07001169 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "requires bound image to have multiple samples");
unknown088160a2019-05-23 17:43:13 -06001170
1171 ASSERT_NO_FATAL_FAILURE(Init());
1172 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
1173
unknown088160a2019-05-23 17:43:13 -06001174 char const *fsSource =
1175 "#version 450\n"
1176 "\n"
1177 "layout(set=0, binding=0) uniform sampler2DMS s;\n"
1178 "layout(location=0) out vec4 color;\n"
1179 "void main() {\n"
1180 " color = texelFetch(s, ivec2(0), 0);\n"
1181 "}\n";
locke-lunarg8e2c91b2019-06-11 17:53:26 -06001182 VkShaderObj vs(m_device, bindStateVertShaderText, VK_SHADER_STAGE_VERTEX_BIT, this);
unknown088160a2019-05-23 17:43:13 -06001183 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
1184
1185 VkPipelineObj pipe(m_device);
1186 pipe.AddShader(&vs);
1187 pipe.AddShader(&fs);
1188 pipe.AddDefaultColorAttachment();
1189
1190 VkTextureObj texture(m_device, nullptr); // THIS LINE CAUSES CRASH ON MALI
1191 VkSamplerObj sampler(m_device);
1192
1193 VkDescriptorSetObj descriptorSet(m_device);
1194 descriptorSet.AppendSamplerTexture(&sampler, &texture);
1195 descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
1196
1197 VkResult err = pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass());
1198 ASSERT_VK_SUCCESS(err);
1199
1200 m_commandBuffer->begin();
1201 m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
1202
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06001203 vk::CmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.handle());
unknown088160a2019-05-23 17:43:13 -06001204 m_commandBuffer->BindDescriptorSet(descriptorSet);
1205
1206 VkViewport viewport = {0, 0, 16, 16, 0, 1};
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06001207 vk::CmdSetViewport(m_commandBuffer->handle(), 0, 1, &viewport);
unknown088160a2019-05-23 17:43:13 -06001208 VkRect2D scissor = {{0, 0}, {16, 16}};
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06001209 vk::CmdSetScissor(m_commandBuffer->handle(), 0, 1, &scissor);
unknown088160a2019-05-23 17:43:13 -06001210
1211 // error produced here.
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06001212 vk::CmdDraw(m_commandBuffer->handle(), 3, 1, 0, 0);
unknown088160a2019-05-23 17:43:13 -06001213
1214 m_errorMonitor->VerifyFound();
1215
1216 m_commandBuffer->EndRenderPass();
1217 m_commandBuffer->end();
1218}
1219
1220TEST_F(VkLayerTest, DrawTimeImageComponentTypeMismatchWithPipeline) {
1221 TEST_DESCRIPTION(
1222 "Test that an error is produced when the component type of an imageview disagrees with the type in the shader.");
1223
Mark Lobodzinski20310782020-02-28 14:25:17 -07001224 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "SINT component type, but bound descriptor");
unknown088160a2019-05-23 17:43:13 -06001225
1226 ASSERT_NO_FATAL_FAILURE(Init());
1227 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
1228
unknown088160a2019-05-23 17:43:13 -06001229 char const *fsSource =
1230 "#version 450\n"
1231 "\n"
1232 "layout(set=0, binding=0) uniform isampler2D s;\n"
1233 "layout(location=0) out vec4 color;\n"
1234 "void main() {\n"
1235 " color = texelFetch(s, ivec2(0), 0);\n"
1236 "}\n";
locke-lunarg8e2c91b2019-06-11 17:53:26 -06001237 VkShaderObj vs(m_device, bindStateVertShaderText, VK_SHADER_STAGE_VERTEX_BIT, this);
unknown088160a2019-05-23 17:43:13 -06001238 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
1239
1240 VkPipelineObj pipe(m_device);
1241 pipe.AddShader(&vs);
1242 pipe.AddShader(&fs);
1243 pipe.AddDefaultColorAttachment();
1244
1245 VkTextureObj texture(m_device, nullptr); // UNORM texture by default, incompatible with isampler2D
1246 VkSamplerObj sampler(m_device);
1247
1248 VkDescriptorSetObj descriptorSet(m_device);
1249 descriptorSet.AppendSamplerTexture(&sampler, &texture);
1250 descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
1251
1252 VkResult err = pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass());
1253 ASSERT_VK_SUCCESS(err);
1254
1255 m_commandBuffer->begin();
1256 m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
1257
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06001258 vk::CmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.handle());
unknown088160a2019-05-23 17:43:13 -06001259 m_commandBuffer->BindDescriptorSet(descriptorSet);
1260
1261 VkViewport viewport = {0, 0, 16, 16, 0, 1};
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06001262 vk::CmdSetViewport(m_commandBuffer->handle(), 0, 1, &viewport);
unknown088160a2019-05-23 17:43:13 -06001263 VkRect2D scissor = {{0, 0}, {16, 16}};
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06001264 vk::CmdSetScissor(m_commandBuffer->handle(), 0, 1, &scissor);
unknown088160a2019-05-23 17:43:13 -06001265
1266 // error produced here.
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06001267 vk::CmdDraw(m_commandBuffer->handle(), 3, 1, 0, 0);
unknown088160a2019-05-23 17:43:13 -06001268
1269 m_errorMonitor->VerifyFound();
1270
1271 m_commandBuffer->EndRenderPass();
1272 m_commandBuffer->end();
1273}
1274
unknown088160a2019-05-23 17:43:13 -06001275TEST_F(VkLayerTest, CopyImageLayerCountMismatch) {
1276 TEST_DESCRIPTION(
1277 "Try to copy between images with the source subresource having a different layerCount than the destination subresource");
sfricke-samsung30b094c2020-05-30 11:42:11 -07001278 ASSERT_NO_FATAL_FAILURE(InitFramework(m_errorMonitor));
1279 bool maintenance1 = false;
1280 if (DeviceExtensionSupported(gpu(), nullptr, VK_KHR_MAINTENANCE1_EXTENSION_NAME)) {
1281 m_device_extension_names.push_back(VK_KHR_MAINTENANCE1_EXTENSION_NAME);
1282 maintenance1 = true;
1283 }
1284 ASSERT_NO_FATAL_FAILURE(InitState());
1285
1286 VkFormat image_format = VK_FORMAT_B8G8R8A8_UNORM;
1287 VkFormatProperties format_props;
1288 vk::GetPhysicalDeviceFormatProperties(m_device->phy().handle(), image_format, &format_props);
1289 if ((format_props.optimalTilingFeatures & (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT)) == 0) {
1290 printf("%s Transfer for format is not supported.\n", kSkipPrefix);
1291 return;
1292 }
unknown088160a2019-05-23 17:43:13 -06001293
1294 // Create two images to copy between
1295 VkImageObj src_image_obj(m_device);
1296 VkImageObj dst_image_obj(m_device);
1297
1298 VkImageCreateInfo image_create_info = {};
1299 image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
1300 image_create_info.pNext = NULL;
1301 image_create_info.imageType = VK_IMAGE_TYPE_2D;
sfricke-samsung30b094c2020-05-30 11:42:11 -07001302 image_create_info.format = image_format;
unknown088160a2019-05-23 17:43:13 -06001303 image_create_info.extent.width = 32;
1304 image_create_info.extent.height = 32;
1305 image_create_info.extent.depth = 1;
1306 image_create_info.mipLevels = 1;
1307 image_create_info.arrayLayers = 4;
1308 image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
1309 image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL;
1310 image_create_info.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
1311 image_create_info.flags = 0;
1312
1313 src_image_obj.init(&image_create_info);
1314 ASSERT_TRUE(src_image_obj.initialized());
1315
1316 image_create_info.usage = VK_IMAGE_USAGE_TRANSFER_DST_BIT;
1317 dst_image_obj.init(&image_create_info);
1318 ASSERT_TRUE(dst_image_obj.initialized());
1319
1320 m_commandBuffer->begin();
1321 VkImageCopy copyRegion;
1322 copyRegion.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
1323 copyRegion.srcSubresource.mipLevel = 0;
1324 copyRegion.srcSubresource.baseArrayLayer = 0;
1325 copyRegion.srcSubresource.layerCount = 1;
1326 copyRegion.srcOffset.x = 0;
1327 copyRegion.srcOffset.y = 0;
1328 copyRegion.srcOffset.z = 0;
1329 copyRegion.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
1330 copyRegion.dstSubresource.mipLevel = 0;
1331 copyRegion.dstSubresource.baseArrayLayer = 0;
1332 // Introduce failure by forcing the dst layerCount to differ from src
1333 copyRegion.dstSubresource.layerCount = 3;
1334 copyRegion.dstOffset.x = 0;
1335 copyRegion.dstOffset.y = 0;
1336 copyRegion.dstOffset.z = 0;
1337 copyRegion.extent.width = 1;
1338 copyRegion.extent.height = 1;
1339 copyRegion.extent.depth = 1;
1340
sfricke-samsung30b094c2020-05-30 11:42:11 -07001341 const char *vuid = (maintenance1 == true) ? "VUID-VkImageCopy-extent-00140" : "VUID-VkImageCopy-layerCount-00138";
1342 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, vuid);
unknown088160a2019-05-23 17:43:13 -06001343 m_commandBuffer->CopyImage(src_image_obj.image(), VK_IMAGE_LAYOUT_GENERAL, dst_image_obj.image(), VK_IMAGE_LAYOUT_GENERAL, 1,
1344 &copyRegion);
1345 m_errorMonitor->VerifyFound();
1346}
1347
1348TEST_F(VkLayerTest, CompressedImageMipCopyTests) {
1349 TEST_DESCRIPTION("Image/Buffer copies for higher mip levels");
1350
1351 ASSERT_NO_FATAL_FAILURE(Init());
1352
1353 VkPhysicalDeviceFeatures device_features = {};
1354 ASSERT_NO_FATAL_FAILURE(GetPhysicalDeviceFeatures(&device_features));
1355 VkFormat compressed_format = VK_FORMAT_UNDEFINED;
1356 if (device_features.textureCompressionBC) {
1357 compressed_format = VK_FORMAT_BC3_SRGB_BLOCK;
1358 } else if (device_features.textureCompressionETC2) {
1359 compressed_format = VK_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK;
1360 } else if (device_features.textureCompressionASTC_LDR) {
1361 compressed_format = VK_FORMAT_ASTC_4x4_UNORM_BLOCK;
1362 } else {
1363 printf("%s No compressed formats supported - CompressedImageMipCopyTests skipped.\n", kSkipPrefix);
1364 return;
1365 }
1366
1367 VkImageCreateInfo ci;
1368 ci.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
1369 ci.pNext = NULL;
1370 ci.flags = 0;
1371 ci.imageType = VK_IMAGE_TYPE_2D;
1372 ci.format = compressed_format;
1373 ci.extent = {32, 32, 1};
1374 ci.mipLevels = 6;
1375 ci.arrayLayers = 1;
1376 ci.samples = VK_SAMPLE_COUNT_1_BIT;
1377 ci.tiling = VK_IMAGE_TILING_OPTIMAL;
1378 ci.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
1379 ci.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
1380 ci.queueFamilyIndexCount = 0;
1381 ci.pQueueFamilyIndices = NULL;
1382 ci.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
1383
1384 VkImageObj image(m_device);
1385 image.init(&ci);
1386 ASSERT_TRUE(image.initialized());
1387
1388 VkImageObj odd_image(m_device);
1389 ci.extent = {31, 32, 1}; // Mips are [31,32] [15,16] [7,8] [3,4], [1,2] [1,1]
1390 odd_image.init(&ci);
1391 ASSERT_TRUE(odd_image.initialized());
1392
1393 // Allocate buffers
1394 VkMemoryPropertyFlags reqs = 0;
1395 VkBufferObj buffer_1024, buffer_64, buffer_16, buffer_8;
1396 buffer_1024.init_as_src_and_dst(*m_device, 1024, reqs);
1397 buffer_64.init_as_src_and_dst(*m_device, 64, reqs);
1398 buffer_16.init_as_src_and_dst(*m_device, 16, reqs);
1399 buffer_8.init_as_src_and_dst(*m_device, 8, reqs);
1400
1401 VkBufferImageCopy region = {};
1402 region.bufferRowLength = 0;
1403 region.bufferImageHeight = 0;
1404 region.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
1405 region.imageSubresource.layerCount = 1;
1406 region.imageOffset = {0, 0, 0};
1407 region.bufferOffset = 0;
1408
1409 // start recording
1410 m_commandBuffer->begin();
1411
locke-lunargdf00db02020-03-04 19:00:57 -07001412 VkMemoryBarrier mem_barriers[3];
1413 mem_barriers[0] = lvl_init_struct<VkMemoryBarrier>();
1414 mem_barriers[0].srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
1415 mem_barriers[0].dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
1416 mem_barriers[1] = lvl_init_struct<VkMemoryBarrier>();
1417 mem_barriers[1].srcAccessMask = VK_ACCESS_TRANSFER_READ_BIT;
1418 mem_barriers[1].dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
1419 mem_barriers[2] = lvl_init_struct<VkMemoryBarrier>();
1420 mem_barriers[2].srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
1421 mem_barriers[2].dstAccessMask = VK_ACCESS_TRANSFER_READ_BIT;
1422
unknown088160a2019-05-23 17:43:13 -06001423 // Mip level copies that work - 5 levels
1424 m_errorMonitor->ExpectSuccess();
1425
1426 // Mip 0 should fit in 1k buffer - 1k texels @ 1b each
1427 region.imageExtent = {32, 32, 1};
1428 region.imageSubresource.mipLevel = 0;
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06001429 vk::CmdCopyImageToBuffer(m_commandBuffer->handle(), image.handle(), VK_IMAGE_LAYOUT_GENERAL, buffer_1024.handle(), 1, &region);
locke-lunargdf00db02020-03-04 19:00:57 -07001430
1431 vk::CmdPipelineBarrier(m_commandBuffer->handle(), VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, 1,
1432 &mem_barriers[2], 0, nullptr, 0, nullptr);
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06001433 vk::CmdCopyBufferToImage(m_commandBuffer->handle(), buffer_1024.handle(), image.handle(), VK_IMAGE_LAYOUT_GENERAL, 1, &region);
unknown088160a2019-05-23 17:43:13 -06001434
1435 // Mip 2 should fit in 64b buffer - 64 texels @ 1b each
1436 region.imageExtent = {8, 8, 1};
1437 region.imageSubresource.mipLevel = 2;
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06001438 vk::CmdCopyImageToBuffer(m_commandBuffer->handle(), image.handle(), VK_IMAGE_LAYOUT_GENERAL, buffer_64.handle(), 1, &region);
locke-lunargdf00db02020-03-04 19:00:57 -07001439
1440 vk::CmdPipelineBarrier(m_commandBuffer->handle(), VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, 2,
1441 &mem_barriers[1], 0, nullptr, 0, nullptr);
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06001442 vk::CmdCopyBufferToImage(m_commandBuffer->handle(), buffer_64.handle(), image.handle(), VK_IMAGE_LAYOUT_GENERAL, 1, &region);
unknown088160a2019-05-23 17:43:13 -06001443
1444 // Mip 3 should fit in 16b buffer - 16 texels @ 1b each
1445 region.imageExtent = {4, 4, 1};
1446 region.imageSubresource.mipLevel = 3;
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06001447 vk::CmdCopyImageToBuffer(m_commandBuffer->handle(), image.handle(), VK_IMAGE_LAYOUT_GENERAL, buffer_16.handle(), 1, &region);
locke-lunargdf00db02020-03-04 19:00:57 -07001448
1449 vk::CmdPipelineBarrier(m_commandBuffer->handle(), VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, 2,
1450 &mem_barriers[1], 0, nullptr, 0, nullptr);
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06001451 vk::CmdCopyBufferToImage(m_commandBuffer->handle(), buffer_16.handle(), image.handle(), VK_IMAGE_LAYOUT_GENERAL, 1, &region);
unknown088160a2019-05-23 17:43:13 -06001452
1453 // Mip 4&5 should fit in 16b buffer with no complaint - 4 & 1 texels @ 1b each
1454 region.imageExtent = {2, 2, 1};
1455 region.imageSubresource.mipLevel = 4;
locke-lunargdf00db02020-03-04 19:00:57 -07001456
1457 vk::CmdPipelineBarrier(m_commandBuffer->handle(), VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, 1,
1458 &mem_barriers[0], 0, nullptr, 0, nullptr);
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06001459 vk::CmdCopyImageToBuffer(m_commandBuffer->handle(), image.handle(), VK_IMAGE_LAYOUT_GENERAL, buffer_16.handle(), 1, &region);
locke-lunargdf00db02020-03-04 19:00:57 -07001460
1461 vk::CmdPipelineBarrier(m_commandBuffer->handle(), VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, 2,
1462 &mem_barriers[1], 0, nullptr, 0, nullptr);
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06001463 vk::CmdCopyBufferToImage(m_commandBuffer->handle(), buffer_16.handle(), image.handle(), VK_IMAGE_LAYOUT_GENERAL, 1, &region);
unknown088160a2019-05-23 17:43:13 -06001464
1465 region.imageExtent = {1, 1, 1};
1466 region.imageSubresource.mipLevel = 5;
locke-lunargdf00db02020-03-04 19:00:57 -07001467
1468 vk::CmdPipelineBarrier(m_commandBuffer->handle(), VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, 1,
1469 &mem_barriers[0], 0, nullptr, 0, nullptr);
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06001470 vk::CmdCopyImageToBuffer(m_commandBuffer->handle(), image.handle(), VK_IMAGE_LAYOUT_GENERAL, buffer_16.handle(), 1, &region);
locke-lunargdf00db02020-03-04 19:00:57 -07001471
1472 vk::CmdPipelineBarrier(m_commandBuffer->handle(), VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, 2,
1473 &mem_barriers[1], 0, nullptr, 0, nullptr);
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06001474 vk::CmdCopyBufferToImage(m_commandBuffer->handle(), buffer_16.handle(), image.handle(), VK_IMAGE_LAYOUT_GENERAL, 1, &region);
unknown088160a2019-05-23 17:43:13 -06001475 m_errorMonitor->VerifyNotFound();
1476
1477 // Buffer must accommodate a full compressed block, regardless of texel count
Mark Lobodzinski20310782020-02-28 14:25:17 -07001478 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdCopyImageToBuffer-pRegions-00183");
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06001479 vk::CmdCopyImageToBuffer(m_commandBuffer->handle(), image.handle(), VK_IMAGE_LAYOUT_GENERAL, buffer_8.handle(), 1, &region);
unknown088160a2019-05-23 17:43:13 -06001480 m_errorMonitor->VerifyFound();
Mark Lobodzinski20310782020-02-28 14:25:17 -07001481 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdCopyBufferToImage-pRegions-00171");
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06001482 vk::CmdCopyBufferToImage(m_commandBuffer->handle(), buffer_8.handle(), image.handle(), VK_IMAGE_LAYOUT_GENERAL, 1, &region);
unknown088160a2019-05-23 17:43:13 -06001483 m_errorMonitor->VerifyFound();
1484
sfricke-samsung3a10b922020-05-13 23:23:16 -07001485 std::string vuid;
1486 bool ycbcr = (DeviceExtensionEnabled(VK_KHR_SAMPLER_YCBCR_CONVERSION_EXTENSION_NAME) ||
1487 (DeviceValidationVersion() >= VK_API_VERSION_1_1));
1488
unknown088160a2019-05-23 17:43:13 -06001489 // Copy width < compressed block size, but not the full mip width
1490 region.imageExtent = {1, 2, 1};
1491 region.imageSubresource.mipLevel = 4;
sfricke-samsung3a10b922020-05-13 23:23:16 -07001492 vuid = ycbcr ? "VUID-VkBufferImageCopy-None-01739" : "VUID-VkBufferImageCopy-imageExtent-00207";
1493 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, vuid); // width not a multiple of compressed block width
Mark Lobodzinski20310782020-02-28 14:25:17 -07001494 m_errorMonitor->SetDesiredFailureMsg(kErrorBit,
unknown088160a2019-05-23 17:43:13 -06001495 "VUID-vkCmdCopyImageToBuffer-imageOffset-01794"); // image transfer granularity
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06001496 vk::CmdCopyImageToBuffer(m_commandBuffer->handle(), image.handle(), VK_IMAGE_LAYOUT_GENERAL, buffer_16.handle(), 1, &region);
unknown088160a2019-05-23 17:43:13 -06001497 m_errorMonitor->VerifyFound();
sfricke-samsung3a10b922020-05-13 23:23:16 -07001498 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, vuid); // width not a multiple of compressed block width
Mark Lobodzinski20310782020-02-28 14:25:17 -07001499 m_errorMonitor->SetDesiredFailureMsg(kErrorBit,
unknown088160a2019-05-23 17:43:13 -06001500 "VUID-vkCmdCopyBufferToImage-imageOffset-01793"); // image transfer granularity
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06001501 vk::CmdCopyBufferToImage(m_commandBuffer->handle(), buffer_16.handle(), image.handle(), VK_IMAGE_LAYOUT_GENERAL, 1, &region);
unknown088160a2019-05-23 17:43:13 -06001502 m_errorMonitor->VerifyFound();
1503
1504 // Copy height < compressed block size but not the full mip height
1505 region.imageExtent = {2, 1, 1};
sfricke-samsung3a10b922020-05-13 23:23:16 -07001506 vuid = ycbcr ? "VUID-VkBufferImageCopy-None-01740" : "VUID-VkBufferImageCopy-imageExtent-00208";
1507 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, vuid); // height not a multiple of compressed block width
Mark Lobodzinski20310782020-02-28 14:25:17 -07001508 m_errorMonitor->SetDesiredFailureMsg(kErrorBit,
unknown088160a2019-05-23 17:43:13 -06001509 "VUID-vkCmdCopyImageToBuffer-imageOffset-01794"); // image transfer granularity
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06001510 vk::CmdCopyImageToBuffer(m_commandBuffer->handle(), image.handle(), VK_IMAGE_LAYOUT_GENERAL, buffer_16.handle(), 1, &region);
unknown088160a2019-05-23 17:43:13 -06001511 m_errorMonitor->VerifyFound();
sfricke-samsung3a10b922020-05-13 23:23:16 -07001512 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, vuid); // height not a multiple of compressed block width
Mark Lobodzinski20310782020-02-28 14:25:17 -07001513 m_errorMonitor->SetDesiredFailureMsg(kErrorBit,
unknown088160a2019-05-23 17:43:13 -06001514 "VUID-vkCmdCopyBufferToImage-imageOffset-01793"); // image transfer granularity
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06001515 vk::CmdCopyBufferToImage(m_commandBuffer->handle(), buffer_16.handle(), image.handle(), VK_IMAGE_LAYOUT_GENERAL, 1, &region);
unknown088160a2019-05-23 17:43:13 -06001516 m_errorMonitor->VerifyFound();
1517
1518 // Offsets must be multiple of compressed block size
1519 region.imageOffset = {1, 1, 0};
1520 region.imageExtent = {1, 1, 1};
sfricke-samsung3a10b922020-05-13 23:23:16 -07001521 vuid = ycbcr ? "VUID-VkBufferImageCopy-None-01737" : "VUID-VkBufferImageCopy-imageOffset-00205";
1522 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, vuid); // imageOffset not a multiple of block size
Mark Lobodzinski20310782020-02-28 14:25:17 -07001523 m_errorMonitor->SetDesiredFailureMsg(kErrorBit,
unknown088160a2019-05-23 17:43:13 -06001524 "VUID-vkCmdCopyImageToBuffer-imageOffset-01794"); // image transfer granularity
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06001525 vk::CmdCopyImageToBuffer(m_commandBuffer->handle(), image.handle(), VK_IMAGE_LAYOUT_GENERAL, buffer_16.handle(), 1, &region);
unknown088160a2019-05-23 17:43:13 -06001526 m_errorMonitor->VerifyFound();
sfricke-samsung3a10b922020-05-13 23:23:16 -07001527 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, vuid); // imageOffset not a multiple of block size
Mark Lobodzinski20310782020-02-28 14:25:17 -07001528 m_errorMonitor->SetDesiredFailureMsg(kErrorBit,
unknown088160a2019-05-23 17:43:13 -06001529 "VUID-vkCmdCopyBufferToImage-imageOffset-01793"); // image transfer granularity
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06001530 vk::CmdCopyBufferToImage(m_commandBuffer->handle(), buffer_16.handle(), image.handle(), VK_IMAGE_LAYOUT_GENERAL, 1, &region);
unknown088160a2019-05-23 17:43:13 -06001531 m_errorMonitor->VerifyFound();
1532
1533 // Offset + extent width = mip width - should succeed
1534 region.imageOffset = {4, 4, 0};
1535 region.imageExtent = {3, 4, 1};
1536 region.imageSubresource.mipLevel = 2;
1537 m_errorMonitor->ExpectSuccess();
locke-lunargdf00db02020-03-04 19:00:57 -07001538
1539 vk::CmdPipelineBarrier(m_commandBuffer->handle(), VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, 1,
1540 &mem_barriers[0], 0, nullptr, 0, nullptr);
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06001541 vk::CmdCopyImageToBuffer(m_commandBuffer->handle(), odd_image.handle(), VK_IMAGE_LAYOUT_GENERAL, buffer_16.handle(), 1,
1542 &region);
locke-lunargdf00db02020-03-04 19:00:57 -07001543
1544 vk::CmdPipelineBarrier(m_commandBuffer->handle(), VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, 2,
1545 &mem_barriers[1], 0, nullptr, 0, nullptr);
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06001546 vk::CmdCopyBufferToImage(m_commandBuffer->handle(), buffer_16.handle(), odd_image.handle(), VK_IMAGE_LAYOUT_GENERAL, 1,
1547 &region);
unknown088160a2019-05-23 17:43:13 -06001548 m_errorMonitor->VerifyNotFound();
1549
unknown088160a2019-05-23 17:43:13 -06001550 // Offset + extent width < mip width and not a multiple of block width - should fail
1551 region.imageExtent = {3, 3, 1};
sfricke-samsung3a10b922020-05-13 23:23:16 -07001552 vuid = ycbcr ? "VUID-VkBufferImageCopy-None-01740" : "VUID-VkBufferImageCopy-imageExtent-00208";
1553 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, vuid); // offset+extent not a multiple of block width
Mark Lobodzinski20310782020-02-28 14:25:17 -07001554 m_errorMonitor->SetDesiredFailureMsg(kErrorBit,
unknown088160a2019-05-23 17:43:13 -06001555 "VUID-vkCmdCopyImageToBuffer-imageOffset-01794"); // image transfer granularity
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06001556 vk::CmdCopyImageToBuffer(m_commandBuffer->handle(), odd_image.handle(), VK_IMAGE_LAYOUT_GENERAL, buffer_16.handle(), 1,
1557 &region);
unknown088160a2019-05-23 17:43:13 -06001558 m_errorMonitor->VerifyFound();
sfricke-samsung3a10b922020-05-13 23:23:16 -07001559 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, vuid); // offset+extent not a multiple of block width
Mark Lobodzinski20310782020-02-28 14:25:17 -07001560 m_errorMonitor->SetDesiredFailureMsg(kErrorBit,
unknown088160a2019-05-23 17:43:13 -06001561 "VUID-vkCmdCopyBufferToImage-imageOffset-01793"); // image transfer granularity
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06001562 vk::CmdCopyBufferToImage(m_commandBuffer->handle(), buffer_16.handle(), odd_image.handle(), VK_IMAGE_LAYOUT_GENERAL, 1,
1563 &region);
unknown088160a2019-05-23 17:43:13 -06001564 m_errorMonitor->VerifyFound();
1565}
1566
1567TEST_F(VkLayerTest, ImageBufferCopyTests) {
1568 TEST_DESCRIPTION("Image to buffer and buffer to image tests");
sfricke-samsung6d97e562020-01-07 22:01:00 -08001569
1570 // Enable KHR multiplane req'd extensions for multi-planar copy tests
1571 bool mp_extensions = InstanceExtensionSupported(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME,
1572 VK_KHR_GET_MEMORY_REQUIREMENTS_2_SPEC_VERSION);
1573 if (mp_extensions) {
1574 m_instance_extension_names.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
1575 }
Mark Lobodzinski09ce9c42020-03-06 10:02:44 -07001576 ASSERT_NO_FATAL_FAILURE(InitFramework(m_errorMonitor, nullptr));
sfricke-samsung6d97e562020-01-07 22:01:00 -08001577 mp_extensions = mp_extensions && DeviceExtensionSupported(gpu(), nullptr, VK_KHR_MAINTENANCE1_EXTENSION_NAME);
1578 mp_extensions = mp_extensions && DeviceExtensionSupported(gpu(), nullptr, VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME);
1579 mp_extensions = mp_extensions && DeviceExtensionSupported(gpu(), nullptr, VK_KHR_BIND_MEMORY_2_EXTENSION_NAME);
1580 mp_extensions = mp_extensions && DeviceExtensionSupported(gpu(), nullptr, VK_KHR_SAMPLER_YCBCR_CONVERSION_EXTENSION_NAME);
1581 if (mp_extensions) {
1582 m_device_extension_names.push_back(VK_KHR_MAINTENANCE1_EXTENSION_NAME);
1583 m_device_extension_names.push_back(VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME);
1584 m_device_extension_names.push_back(VK_KHR_BIND_MEMORY_2_EXTENSION_NAME);
1585 m_device_extension_names.push_back(VK_KHR_SAMPLER_YCBCR_CONVERSION_EXTENSION_NAME);
1586 }
1587 ASSERT_NO_FATAL_FAILURE(InitState());
unknown088160a2019-05-23 17:43:13 -06001588
1589 // Bail if any dimension of transfer granularity is 0.
1590 auto index = m_device->graphics_queue_node_index_;
1591 auto queue_family_properties = m_device->phy().queue_properties();
1592 if ((queue_family_properties[index].minImageTransferGranularity.depth == 0) ||
1593 (queue_family_properties[index].minImageTransferGranularity.width == 0) ||
1594 (queue_family_properties[index].minImageTransferGranularity.height == 0)) {
1595 printf("%s Subresource copies are disallowed when xfer granularity (x|y|z) is 0. Skipped.\n", kSkipPrefix);
1596 return;
1597 }
1598
sfricke-samsung6d97e562020-01-07 22:01:00 -08001599 // All VkImageObj must be defined here as if defined inside below scopes will cause image memory to be deleted when out of scope
1600 // and invalidates the entire command buffer. This prevents from having to reset the commmand buffer every scope rgba
Mark Lobodzinski20310782020-02-28 14:25:17 -07001601 VkImageObj image_64k(m_device); // 128^2 texels, 64k
1602 VkImageObj image_16k(m_device); // 64^2 texels, 16k
sfricke-samsung6d97e562020-01-07 22:01:00 -08001603 // depth stencil
unknown088160a2019-05-23 17:43:13 -06001604 VkImageObj image_16k_depth(m_device); // 64^2 texels, depth, 16k
1605 VkImageObj ds_image_4D_1S(m_device); // 256^2 texels, 512kb (256k depth, 64k stencil, 192k pack)
1606 VkImageObj ds_image_3D_1S(m_device); // 256^2 texels, 256kb (192k depth, 64k stencil)
1607 VkImageObj ds_image_2D(m_device); // 256^2 texels, 128k (128k depth)
1608 VkImageObj ds_image_1S(m_device); // 256^2 texels, 64k (64k stencil)
sfricke-samsung6d97e562020-01-07 22:01:00 -08001609 // compression
1610 VkImageObj image_16k_4x4comp(m_device); // 128^2 texels as 32^2 compressed (4x4) blocks, 16k
1611 VkImageObj image_NPOT_4x4comp(m_device); // 130^2 texels as 33^2 compressed (4x4) blocks
1612 // multi-planar
1613 VkImageObj image_multi_planar(m_device); // 128^2 texels in plane_0 and 64^2 texels in plane_1
unknown088160a2019-05-23 17:43:13 -06001614
sfricke-samsung6d97e562020-01-07 22:01:00 -08001615 // Verify R8G8B8A8_UINT format is supported for transfer
1616 bool missing_rgba_support = false;
1617 VkFormatProperties props = {0, 0, 0};
1618 vk::GetPhysicalDeviceFormatProperties(m_device->phy().handle(), VK_FORMAT_R8G8B8A8_UINT, &props);
1619 missing_rgba_support |= (props.bufferFeatures == 0 && props.linearTilingFeatures == 0 && props.optimalTilingFeatures == 0);
1620 missing_rgba_support |= (props.optimalTilingFeatures & VK_FORMAT_FEATURE_TRANSFER_SRC_BIT) == 0;
1621 missing_rgba_support |= (props.optimalTilingFeatures & VK_FORMAT_FEATURE_TRANSFER_DST_BIT) == 0;
1622
1623 if (!missing_rgba_support) {
1624 image_64k.Init(128, 128, 1, VK_FORMAT_R8G8B8A8_UINT,
1625 VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT,
1626 VK_IMAGE_TILING_OPTIMAL, 0);
1627 ASSERT_TRUE(image_64k.initialized());
1628
1629 image_16k.Init(64, 64, 1, VK_FORMAT_R8G8B8A8_UINT,
1630 VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT,
1631 VK_IMAGE_TILING_OPTIMAL, 0);
1632 ASSERT_TRUE(image_16k.initialized());
1633 }
unknown088160a2019-05-23 17:43:13 -06001634
1635 // Verify all needed Depth/Stencil formats are supported
1636 bool missing_ds_support = false;
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06001637 vk::GetPhysicalDeviceFormatProperties(m_device->phy().handle(), VK_FORMAT_D32_SFLOAT_S8_UINT, &props);
unknown088160a2019-05-23 17:43:13 -06001638 missing_ds_support |= (props.bufferFeatures == 0 && props.linearTilingFeatures == 0 && props.optimalTilingFeatures == 0);
1639 missing_ds_support |= (props.optimalTilingFeatures & VK_FORMAT_FEATURE_TRANSFER_SRC_BIT) == 0;
1640 missing_ds_support |= (props.optimalTilingFeatures & VK_FORMAT_FEATURE_TRANSFER_DST_BIT) == 0;
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06001641 vk::GetPhysicalDeviceFormatProperties(m_device->phy().handle(), VK_FORMAT_D24_UNORM_S8_UINT, &props);
unknown088160a2019-05-23 17:43:13 -06001642 missing_ds_support |= (props.bufferFeatures == 0 && props.linearTilingFeatures == 0 && props.optimalTilingFeatures == 0);
1643 missing_ds_support |= (props.optimalTilingFeatures & VK_FORMAT_FEATURE_TRANSFER_SRC_BIT) == 0;
1644 missing_ds_support |= (props.optimalTilingFeatures & VK_FORMAT_FEATURE_TRANSFER_DST_BIT) == 0;
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06001645 vk::GetPhysicalDeviceFormatProperties(m_device->phy().handle(), VK_FORMAT_D16_UNORM, &props);
unknown088160a2019-05-23 17:43:13 -06001646 missing_ds_support |= (props.bufferFeatures == 0 && props.linearTilingFeatures == 0 && props.optimalTilingFeatures == 0);
1647 missing_ds_support |= (props.optimalTilingFeatures & VK_FORMAT_FEATURE_TRANSFER_SRC_BIT) == 0;
1648 missing_ds_support |= (props.optimalTilingFeatures & VK_FORMAT_FEATURE_TRANSFER_DST_BIT) == 0;
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06001649 vk::GetPhysicalDeviceFormatProperties(m_device->phy().handle(), VK_FORMAT_S8_UINT, &props);
unknown088160a2019-05-23 17:43:13 -06001650 missing_ds_support |= (props.bufferFeatures == 0 && props.linearTilingFeatures == 0 && props.optimalTilingFeatures == 0);
1651 missing_ds_support |= (props.optimalTilingFeatures & VK_FORMAT_FEATURE_TRANSFER_SRC_BIT) == 0;
1652 missing_ds_support |= (props.optimalTilingFeatures & VK_FORMAT_FEATURE_TRANSFER_DST_BIT) == 0;
1653
1654 if (!missing_ds_support) {
1655 image_16k_depth.Init(64, 64, 1, VK_FORMAT_D24_UNORM_S8_UINT,
1656 VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT, VK_IMAGE_TILING_OPTIMAL, 0);
1657 ASSERT_TRUE(image_16k_depth.initialized());
1658
1659 ds_image_4D_1S.Init(
1660 256, 256, 1, VK_FORMAT_D32_SFLOAT_S8_UINT,
1661 VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT,
1662 VK_IMAGE_TILING_OPTIMAL, 0);
1663 ASSERT_TRUE(ds_image_4D_1S.initialized());
1664
1665 ds_image_3D_1S.Init(
1666 256, 256, 1, VK_FORMAT_D24_UNORM_S8_UINT,
1667 VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT,
1668 VK_IMAGE_TILING_OPTIMAL, 0);
1669 ASSERT_TRUE(ds_image_3D_1S.initialized());
1670
1671 ds_image_2D.Init(
1672 256, 256, 1, VK_FORMAT_D16_UNORM,
1673 VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT,
1674 VK_IMAGE_TILING_OPTIMAL, 0);
1675 ASSERT_TRUE(ds_image_2D.initialized());
1676
1677 ds_image_1S.Init(
1678 256, 256, 1, VK_FORMAT_S8_UINT,
1679 VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT,
1680 VK_IMAGE_TILING_OPTIMAL, 0);
1681 ASSERT_TRUE(ds_image_1S.initialized());
1682 }
1683
1684 // Allocate buffers
1685 VkBufferObj buffer_256k, buffer_128k, buffer_64k, buffer_16k;
1686 VkMemoryPropertyFlags reqs = 0;
1687 buffer_256k.init_as_src_and_dst(*m_device, 262144, reqs); // 256k
1688 buffer_128k.init_as_src_and_dst(*m_device, 131072, reqs); // 128k
1689 buffer_64k.init_as_src_and_dst(*m_device, 65536, reqs); // 64k
1690 buffer_16k.init_as_src_and_dst(*m_device, 16384, reqs); // 16k
1691
1692 VkBufferImageCopy region = {};
1693 region.bufferRowLength = 0;
1694 region.bufferImageHeight = 0;
1695 region.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
1696 region.imageSubresource.layerCount = 1;
1697 region.imageOffset = {0, 0, 0};
1698 region.imageExtent = {64, 64, 1};
1699 region.bufferOffset = 0;
1700
locke-lunargdf00db02020-03-04 19:00:57 -07001701 VkMemoryBarrier mem_barriers[3];
1702 mem_barriers[0] = lvl_init_struct<VkMemoryBarrier>();
1703 mem_barriers[0].srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
1704 mem_barriers[0].dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
1705 mem_barriers[1] = lvl_init_struct<VkMemoryBarrier>();
1706 mem_barriers[1].srcAccessMask = VK_ACCESS_TRANSFER_READ_BIT;
1707 mem_barriers[1].dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
1708 mem_barriers[2] = lvl_init_struct<VkMemoryBarrier>();
1709 mem_barriers[2].srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
1710 mem_barriers[2].dstAccessMask = VK_ACCESS_TRANSFER_READ_BIT;
1711
sfricke-samsung6d97e562020-01-07 22:01:00 -08001712 if (missing_rgba_support) {
1713 printf("%s R8G8B8A8_UINT transfer unsupported - skipping RGBA tests.\n", kSkipPrefix);
unknown088160a2019-05-23 17:43:13 -06001714
sfricke-samsung6d97e562020-01-07 22:01:00 -08001715 // start recording for future tests
1716 m_commandBuffer->begin();
1717 } else {
1718 // attempt copies before putting command buffer in recording state
Mark Lobodzinski20310782020-02-28 14:25:17 -07001719 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdCopyBufferToImage-commandBuffer-recording");
sfricke-samsung6d97e562020-01-07 22:01:00 -08001720 vk::CmdCopyBufferToImage(m_commandBuffer->handle(), buffer_64k.handle(), image_64k.handle(), VK_IMAGE_LAYOUT_GENERAL, 1,
1721 &region);
unknown088160a2019-05-23 17:43:13 -06001722 m_errorMonitor->VerifyFound();
1723
Mark Lobodzinski20310782020-02-28 14:25:17 -07001724 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdCopyImageToBuffer-commandBuffer-recording");
sfricke-samsung6d97e562020-01-07 22:01:00 -08001725 vk::CmdCopyImageToBuffer(m_commandBuffer->handle(), image_64k.handle(), VK_IMAGE_LAYOUT_GENERAL, buffer_64k.handle(), 1,
1726 &region);
1727 m_errorMonitor->VerifyFound();
1728
1729 // start recording
1730 m_commandBuffer->begin();
1731
1732 // successful copies
1733 m_errorMonitor->ExpectSuccess();
1734 vk::CmdCopyImageToBuffer(m_commandBuffer->handle(), image_16k.handle(), VK_IMAGE_LAYOUT_GENERAL, buffer_16k.handle(), 1,
1735 &region);
locke-lunargdf00db02020-03-04 19:00:57 -07001736
1737 vk::CmdPipelineBarrier(m_commandBuffer->handle(), VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, 1,
1738 &mem_barriers[2], 0, nullptr, 0, nullptr);
sfricke-samsung6d97e562020-01-07 22:01:00 -08001739 vk::CmdCopyBufferToImage(m_commandBuffer->handle(), buffer_16k.handle(), image_16k.handle(), VK_IMAGE_LAYOUT_GENERAL, 1,
1740 &region);
1741 region.imageOffset.x = 16; // 16k copy, offset requires larger image
locke-lunargdf00db02020-03-04 19:00:57 -07001742
1743 vk::CmdPipelineBarrier(m_commandBuffer->handle(), VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, 1,
1744 &mem_barriers[0], 0, nullptr, 0, nullptr);
sfricke-samsung6d97e562020-01-07 22:01:00 -08001745 vk::CmdCopyImageToBuffer(m_commandBuffer->handle(), image_64k.handle(), VK_IMAGE_LAYOUT_GENERAL, buffer_16k.handle(), 1,
1746 &region);
1747 region.imageExtent.height = 78; // > 16k copy requires larger buffer & image
locke-lunargdf00db02020-03-04 19:00:57 -07001748
1749 vk::CmdPipelineBarrier(m_commandBuffer->handle(), VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, 1,
1750 &mem_barriers[1], 0, nullptr, 0, nullptr);
sfricke-samsung6d97e562020-01-07 22:01:00 -08001751 vk::CmdCopyBufferToImage(m_commandBuffer->handle(), buffer_64k.handle(), image_64k.handle(), VK_IMAGE_LAYOUT_GENERAL, 1,
1752 &region);
1753 region.imageOffset.x = 0;
1754 region.imageExtent.height = 64;
1755 region.bufferOffset = 256; // 16k copy with buffer offset, requires larger buffer
locke-lunargdf00db02020-03-04 19:00:57 -07001756
1757 vk::CmdPipelineBarrier(m_commandBuffer->handle(), VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, 2,
1758 &mem_barriers[1], 0, nullptr, 0, nullptr);
sfricke-samsung6d97e562020-01-07 22:01:00 -08001759 vk::CmdCopyImageToBuffer(m_commandBuffer->handle(), image_16k.handle(), VK_IMAGE_LAYOUT_GENERAL, buffer_64k.handle(), 1,
1760 &region);
1761 m_errorMonitor->VerifyNotFound();
1762
1763 // image/buffer too small (extent too large) on copy to image
1764 region.imageExtent = {65, 64, 1};
Mark Lobodzinski20310782020-02-28 14:25:17 -07001765 m_errorMonitor->SetDesiredFailureMsg(kErrorBit,
sfricke-samsung6d97e562020-01-07 22:01:00 -08001766 "VUID-vkCmdCopyBufferToImage-pRegions-00171"); // buffer too small
1767 vk::CmdCopyBufferToImage(m_commandBuffer->handle(), buffer_16k.handle(), image_64k.handle(), VK_IMAGE_LAYOUT_GENERAL, 1,
1768 &region);
1769 m_errorMonitor->VerifyFound();
1770
1771 m_errorMonitor->SetUnexpectedError("VUID-VkBufferImageCopy-imageOffset-00197");
Mark Lobodzinski20310782020-02-28 14:25:17 -07001772 m_errorMonitor->SetDesiredFailureMsg(kErrorBit,
sfricke-samsung6d97e562020-01-07 22:01:00 -08001773 "VUID-vkCmdCopyBufferToImage-pRegions-00172"); // image too small
1774 vk::CmdCopyBufferToImage(m_commandBuffer->handle(), buffer_64k.handle(), image_16k.handle(), VK_IMAGE_LAYOUT_GENERAL, 1,
1775 &region);
1776 m_errorMonitor->VerifyFound();
1777
1778 // image/buffer too small (offset) on copy to image
1779 region.imageExtent = {64, 64, 1};
1780 region.imageOffset = {0, 4, 0};
Mark Lobodzinski20310782020-02-28 14:25:17 -07001781 m_errorMonitor->SetDesiredFailureMsg(kErrorBit,
sfricke-samsung6d97e562020-01-07 22:01:00 -08001782 "VUID-vkCmdCopyBufferToImage-pRegions-00171"); // buffer too small
1783 vk::CmdCopyBufferToImage(m_commandBuffer->handle(), buffer_16k.handle(), image_64k.handle(), VK_IMAGE_LAYOUT_GENERAL, 1,
1784 &region);
1785 m_errorMonitor->VerifyFound();
1786
1787 m_errorMonitor->SetUnexpectedError("VUID-VkBufferImageCopy-imageOffset-00197");
1788 m_errorMonitor->SetUnexpectedError("VUID-VkBufferImageCopy-imageOffset-00198");
Mark Lobodzinski20310782020-02-28 14:25:17 -07001789 m_errorMonitor->SetDesiredFailureMsg(kErrorBit,
sfricke-samsung6d97e562020-01-07 22:01:00 -08001790 "VUID-vkCmdCopyBufferToImage-pRegions-00172"); // image too small
1791 vk::CmdCopyBufferToImage(m_commandBuffer->handle(), buffer_64k.handle(), image_16k.handle(), VK_IMAGE_LAYOUT_GENERAL, 1,
1792 &region);
1793 m_errorMonitor->VerifyFound();
1794
1795 // image/buffer too small on copy to buffer
1796 region.imageExtent = {64, 64, 1};
1797 region.imageOffset = {0, 0, 0};
1798 region.bufferOffset = 4;
Mark Lobodzinski20310782020-02-28 14:25:17 -07001799 m_errorMonitor->SetDesiredFailureMsg(kErrorBit,
sfricke-samsung6d97e562020-01-07 22:01:00 -08001800 "VUID-vkCmdCopyImageToBuffer-pRegions-00183"); // buffer too small
1801 vk::CmdCopyImageToBuffer(m_commandBuffer->handle(), image_64k.handle(), VK_IMAGE_LAYOUT_GENERAL, buffer_16k.handle(), 1,
1802 &region);
1803 m_errorMonitor->VerifyFound();
1804
1805 region.imageExtent = {64, 65, 1};
1806 region.bufferOffset = 0;
1807 m_errorMonitor->SetUnexpectedError("VUID-VkBufferImageCopy-imageOffset-00198");
Mark Lobodzinski20310782020-02-28 14:25:17 -07001808 m_errorMonitor->SetDesiredFailureMsg(kErrorBit,
sfricke-samsung6d97e562020-01-07 22:01:00 -08001809 "VUID-vkCmdCopyImageToBuffer-pRegions-00182"); // image too small
1810 vk::CmdCopyImageToBuffer(m_commandBuffer->handle(), image_16k.handle(), VK_IMAGE_LAYOUT_GENERAL, buffer_64k.handle(), 1,
1811 &region);
1812 m_errorMonitor->VerifyFound();
1813
1814 // buffer size OK but rowlength causes loose packing
Mark Lobodzinski20310782020-02-28 14:25:17 -07001815 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdCopyImageToBuffer-pRegions-00183");
sfricke-samsung6d97e562020-01-07 22:01:00 -08001816 region.imageExtent = {64, 64, 1};
1817 region.bufferRowLength = 68;
1818 vk::CmdCopyImageToBuffer(m_commandBuffer->handle(), image_16k.handle(), VK_IMAGE_LAYOUT_GENERAL, buffer_16k.handle(), 1,
1819 &region);
1820 m_errorMonitor->VerifyFound();
1821
1822 // An extent with zero area should produce a warning, but no error
Mark Lobodzinski20310782020-02-28 14:25:17 -07001823 m_errorMonitor->SetDesiredFailureMsg(kWarningBit | kErrorBit, "} has zero area");
sfricke-samsung6d97e562020-01-07 22:01:00 -08001824 region.imageExtent.width = 0;
1825 vk::CmdCopyImageToBuffer(m_commandBuffer->handle(), image_16k.handle(), VK_IMAGE_LAYOUT_GENERAL, buffer_16k.handle(), 1,
1826 &region);
1827 m_errorMonitor->VerifyFound();
1828
1829 // aspect bits
1830 region.imageExtent = {64, 64, 1};
1831 region.bufferRowLength = 0;
1832 region.bufferImageHeight = 0;
1833 if (!missing_ds_support) {
Mark Lobodzinski20310782020-02-28 14:25:17 -07001834 m_errorMonitor->SetDesiredFailureMsg(kErrorBit,
sfricke-samsung6d97e562020-01-07 22:01:00 -08001835 "VUID-VkBufferImageCopy-aspectMask-00212"); // more than 1 aspect bit set
1836 region.imageSubresource.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT;
1837 vk::CmdCopyImageToBuffer(m_commandBuffer->handle(), image_16k_depth.handle(), VK_IMAGE_LAYOUT_GENERAL,
1838 buffer_16k.handle(), 1, &region);
1839 m_errorMonitor->VerifyFound();
1840
Mark Lobodzinski20310782020-02-28 14:25:17 -07001841 m_errorMonitor->SetDesiredFailureMsg(kErrorBit,
sfricke-samsung6d97e562020-01-07 22:01:00 -08001842 "VUID-VkBufferImageCopy-aspectMask-00211"); // different mis-matched aspect
1843 region.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
1844 vk::CmdCopyImageToBuffer(m_commandBuffer->handle(), image_16k_depth.handle(), VK_IMAGE_LAYOUT_GENERAL,
1845 buffer_16k.handle(), 1, &region);
1846 m_errorMonitor->VerifyFound();
1847 }
1848
Mark Lobodzinski20310782020-02-28 14:25:17 -07001849 m_errorMonitor->SetDesiredFailureMsg(kErrorBit,
sfricke-samsung6d97e562020-01-07 22:01:00 -08001850 "VUID-VkBufferImageCopy-aspectMask-00211"); // mis-matched aspect
1851 region.imageSubresource.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT;
1852 vk::CmdCopyImageToBuffer(m_commandBuffer->handle(), image_16k.handle(), VK_IMAGE_LAYOUT_GENERAL, buffer_16k.handle(), 1,
1853 &region);
1854 m_errorMonitor->VerifyFound();
unknown088160a2019-05-23 17:43:13 -06001855 region.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
sfricke-samsung6d97e562020-01-07 22:01:00 -08001856
1857 // Out-of-range mip levels should fail
1858 region.imageSubresource.mipLevel = image_16k.create_info().mipLevels + 1;
Mark Lobodzinski20310782020-02-28 14:25:17 -07001859 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdCopyImageToBuffer-imageSubresource-01703");
sfricke-samsung6d97e562020-01-07 22:01:00 -08001860 m_errorMonitor->SetUnexpectedError("VUID-VkBufferImageCopy-imageOffset-00197");
1861 m_errorMonitor->SetUnexpectedError("VUID-VkBufferImageCopy-imageOffset-00198");
1862 m_errorMonitor->SetUnexpectedError("VUID-VkBufferImageCopy-imageOffset-00200");
1863 m_errorMonitor->SetDesiredFailureMsg(
Mark Lobodzinski20310782020-02-28 14:25:17 -07001864 kErrorBit,
sfricke-samsung6d97e562020-01-07 22:01:00 -08001865 "VUID-vkCmdCopyImageToBuffer-pRegions-00182"); // unavoidable "region exceeds image bounds" for non-existent mip
1866 vk::CmdCopyImageToBuffer(m_commandBuffer->handle(), image_16k.handle(), VK_IMAGE_LAYOUT_GENERAL, buffer_16k.handle(), 1,
1867 &region);
1868 m_errorMonitor->VerifyFound();
Mark Lobodzinski20310782020-02-28 14:25:17 -07001869 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdCopyBufferToImage-imageSubresource-01701");
sfricke-samsung6d97e562020-01-07 22:01:00 -08001870 m_errorMonitor->SetUnexpectedError("VUID-VkBufferImageCopy-imageOffset-00197");
1871 m_errorMonitor->SetUnexpectedError("VUID-VkBufferImageCopy-imageOffset-00198");
1872 m_errorMonitor->SetUnexpectedError("VUID-VkBufferImageCopy-imageOffset-00200");
1873 m_errorMonitor->SetDesiredFailureMsg(
Mark Lobodzinski20310782020-02-28 14:25:17 -07001874 kErrorBit,
sfricke-samsung6d97e562020-01-07 22:01:00 -08001875 "VUID-vkCmdCopyBufferToImage-pRegions-00172"); // unavoidable "region exceeds image bounds" for non-existent mip
1876 vk::CmdCopyBufferToImage(m_commandBuffer->handle(), buffer_16k.handle(), image_16k.handle(), VK_IMAGE_LAYOUT_GENERAL, 1,
1877 &region);
1878 m_errorMonitor->VerifyFound();
1879 region.imageSubresource.mipLevel = 0;
1880
1881 // Out-of-range array layers should fail
1882 region.imageSubresource.baseArrayLayer = image_16k.create_info().arrayLayers;
1883 region.imageSubresource.layerCount = 1;
Mark Lobodzinski20310782020-02-28 14:25:17 -07001884 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdCopyImageToBuffer-imageSubresource-01704");
sfricke-samsung6d97e562020-01-07 22:01:00 -08001885 vk::CmdCopyImageToBuffer(m_commandBuffer->handle(), image_16k.handle(), VK_IMAGE_LAYOUT_GENERAL, buffer_16k.handle(), 1,
1886 &region);
1887 m_errorMonitor->VerifyFound();
Mark Lobodzinski20310782020-02-28 14:25:17 -07001888 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdCopyBufferToImage-imageSubresource-01702");
sfricke-samsung6d97e562020-01-07 22:01:00 -08001889 vk::CmdCopyBufferToImage(m_commandBuffer->handle(), buffer_16k.handle(), image_16k.handle(), VK_IMAGE_LAYOUT_GENERAL, 1,
1890 &region);
1891 m_errorMonitor->VerifyFound();
1892 region.imageSubresource.baseArrayLayer = 0;
1893
1894 // Layout mismatch should fail
Mark Lobodzinski20310782020-02-28 14:25:17 -07001895 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdCopyImageToBuffer-srcImageLayout-00189");
sfricke-samsung6d97e562020-01-07 22:01:00 -08001896 vk::CmdCopyImageToBuffer(m_commandBuffer->handle(), image_16k.handle(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
1897 buffer_16k.handle(), 1, &region);
1898 m_errorMonitor->VerifyFound();
Mark Lobodzinski20310782020-02-28 14:25:17 -07001899 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdCopyBufferToImage-dstImageLayout-00180");
sfricke-samsung6d97e562020-01-07 22:01:00 -08001900 vk::CmdCopyBufferToImage(m_commandBuffer->handle(), buffer_16k.handle(), image_16k.handle(),
1901 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &region);
unknown088160a2019-05-23 17:43:13 -06001902 m_errorMonitor->VerifyFound();
1903 }
1904
unknown088160a2019-05-23 17:43:13 -06001905 // Test Depth/Stencil copies
1906 if (missing_ds_support) {
1907 printf("%s Depth / Stencil formats unsupported - skipping D/S tests.\n", kSkipPrefix);
1908 } else {
1909 VkBufferImageCopy ds_region = {};
1910 ds_region.bufferOffset = 0;
1911 ds_region.bufferRowLength = 0;
1912 ds_region.bufferImageHeight = 0;
1913 ds_region.imageSubresource.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT;
1914 ds_region.imageSubresource.mipLevel = 0;
1915 ds_region.imageSubresource.baseArrayLayer = 0;
1916 ds_region.imageSubresource.layerCount = 1;
1917 ds_region.imageOffset = {0, 0, 0};
1918 ds_region.imageExtent = {256, 256, 1};
1919
1920 // Depth copies that should succeed
1921 m_errorMonitor->ExpectSuccess(); // Extract 4b depth per texel, pack into 256k buffer
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06001922 vk::CmdCopyImageToBuffer(m_commandBuffer->handle(), ds_image_4D_1S.handle(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
1923 buffer_256k.handle(), 1, &ds_region);
unknown088160a2019-05-23 17:43:13 -06001924 m_errorMonitor->VerifyNotFound();
1925
1926 m_errorMonitor->ExpectSuccess(); // Extract 3b depth per texel, pack (loose) into 256k buffer
locke-lunargdf00db02020-03-04 19:00:57 -07001927 vk::CmdPipelineBarrier(m_commandBuffer->handle(), VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, 1,
1928 &mem_barriers[0], 0, nullptr, 0, nullptr);
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06001929 vk::CmdCopyImageToBuffer(m_commandBuffer->handle(), ds_image_3D_1S.handle(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
1930 buffer_256k.handle(), 1, &ds_region);
unknown088160a2019-05-23 17:43:13 -06001931 m_errorMonitor->VerifyNotFound();
1932
1933 m_errorMonitor->ExpectSuccess(); // Copy 2b depth per texel, into 128k buffer
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06001934 vk::CmdCopyImageToBuffer(m_commandBuffer->handle(), ds_image_2D.handle(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
1935 buffer_128k.handle(), 1, &ds_region);
unknown088160a2019-05-23 17:43:13 -06001936 m_errorMonitor->VerifyNotFound();
1937
1938 // Depth copies that should fail
1939 ds_region.bufferOffset = 4;
1940 m_errorMonitor->SetDesiredFailureMsg(
Mark Lobodzinski20310782020-02-28 14:25:17 -07001941 kErrorBit,
unknown088160a2019-05-23 17:43:13 -06001942 "VUID-vkCmdCopyImageToBuffer-pRegions-00183"); // Extract 4b depth per texel, pack into 256k buffer
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06001943 vk::CmdCopyImageToBuffer(m_commandBuffer->handle(), ds_image_4D_1S.handle(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
1944 buffer_256k.handle(), 1, &ds_region);
unknown088160a2019-05-23 17:43:13 -06001945 m_errorMonitor->VerifyFound();
1946
1947 m_errorMonitor->SetDesiredFailureMsg(
Mark Lobodzinski20310782020-02-28 14:25:17 -07001948 kErrorBit,
unknown088160a2019-05-23 17:43:13 -06001949 "VUID-vkCmdCopyImageToBuffer-pRegions-00183"); // Extract 3b depth per texel, pack (loose) into 256k buffer
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06001950 vk::CmdCopyImageToBuffer(m_commandBuffer->handle(), ds_image_3D_1S.handle(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
1951 buffer_256k.handle(), 1, &ds_region);
unknown088160a2019-05-23 17:43:13 -06001952 m_errorMonitor->VerifyFound();
1953
1954 m_errorMonitor->SetDesiredFailureMsg(
Mark Lobodzinski20310782020-02-28 14:25:17 -07001955 kErrorBit,
unknown088160a2019-05-23 17:43:13 -06001956 "VUID-vkCmdCopyImageToBuffer-pRegions-00183"); // Copy 2b depth per texel, into 128k buffer
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06001957 vk::CmdCopyImageToBuffer(m_commandBuffer->handle(), ds_image_2D.handle(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
1958 buffer_128k.handle(), 1, &ds_region);
unknown088160a2019-05-23 17:43:13 -06001959 m_errorMonitor->VerifyFound();
1960
1961 // Stencil copies that should succeed
1962 ds_region.bufferOffset = 0;
1963 ds_region.imageSubresource.aspectMask = VK_IMAGE_ASPECT_STENCIL_BIT;
1964 m_errorMonitor->ExpectSuccess(); // Extract 1b stencil per texel, pack into 64k buffer
locke-lunargdf00db02020-03-04 19:00:57 -07001965 vk::CmdPipelineBarrier(m_commandBuffer->handle(), VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, 1,
1966 &mem_barriers[0], 0, nullptr, 0, nullptr);
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06001967 vk::CmdCopyImageToBuffer(m_commandBuffer->handle(), ds_image_4D_1S.handle(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
1968 buffer_64k.handle(), 1, &ds_region);
unknown088160a2019-05-23 17:43:13 -06001969 m_errorMonitor->VerifyNotFound();
1970
1971 m_errorMonitor->ExpectSuccess(); // Extract 1b stencil per texel, pack into 64k buffer
locke-lunargdf00db02020-03-04 19:00:57 -07001972 vk::CmdPipelineBarrier(m_commandBuffer->handle(), VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, 1,
1973 &mem_barriers[0], 0, nullptr, 0, nullptr);
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06001974 vk::CmdCopyImageToBuffer(m_commandBuffer->handle(), ds_image_3D_1S.handle(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
1975 buffer_64k.handle(), 1, &ds_region);
unknown088160a2019-05-23 17:43:13 -06001976 m_errorMonitor->VerifyNotFound();
1977
1978 m_errorMonitor->ExpectSuccess(); // Copy 1b depth per texel, into 64k buffer
locke-lunargdf00db02020-03-04 19:00:57 -07001979 vk::CmdPipelineBarrier(m_commandBuffer->handle(), VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, 1,
1980 &mem_barriers[0], 0, nullptr, 0, nullptr);
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06001981 vk::CmdCopyImageToBuffer(m_commandBuffer->handle(), ds_image_1S.handle(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
1982 buffer_64k.handle(), 1, &ds_region);
unknown088160a2019-05-23 17:43:13 -06001983 m_errorMonitor->VerifyNotFound();
1984
1985 // Stencil copies that should fail
1986 m_errorMonitor->SetDesiredFailureMsg(
Mark Lobodzinski20310782020-02-28 14:25:17 -07001987 kErrorBit,
unknown088160a2019-05-23 17:43:13 -06001988 "VUID-vkCmdCopyImageToBuffer-pRegions-00183"); // Extract 1b stencil per texel, pack into 64k buffer
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06001989 vk::CmdCopyImageToBuffer(m_commandBuffer->handle(), ds_image_4D_1S.handle(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
1990 buffer_16k.handle(), 1, &ds_region);
unknown088160a2019-05-23 17:43:13 -06001991 m_errorMonitor->VerifyFound();
1992
1993 m_errorMonitor->SetDesiredFailureMsg(
Mark Lobodzinski20310782020-02-28 14:25:17 -07001994 kErrorBit,
unknown088160a2019-05-23 17:43:13 -06001995 "VUID-vkCmdCopyImageToBuffer-pRegions-00183"); // Extract 1b stencil per texel, pack into 64k buffer
1996 ds_region.bufferRowLength = 260;
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06001997 vk::CmdCopyImageToBuffer(m_commandBuffer->handle(), ds_image_3D_1S.handle(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
1998 buffer_64k.handle(), 1, &ds_region);
unknown088160a2019-05-23 17:43:13 -06001999 m_errorMonitor->VerifyFound();
2000
2001 ds_region.bufferRowLength = 0;
2002 ds_region.bufferOffset = 4;
2003 m_errorMonitor->SetDesiredFailureMsg(
Mark Lobodzinski20310782020-02-28 14:25:17 -07002004 kErrorBit,
unknown088160a2019-05-23 17:43:13 -06002005 "VUID-vkCmdCopyImageToBuffer-pRegions-00183"); // Copy 1b depth per texel, into 64k buffer
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06002006 vk::CmdCopyImageToBuffer(m_commandBuffer->handle(), ds_image_1S.handle(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
2007 buffer_64k.handle(), 1, &ds_region);
unknown088160a2019-05-23 17:43:13 -06002008 m_errorMonitor->VerifyFound();
2009 }
2010
2011 // Test compressed formats, if supported
sfricke-samsung6d97e562020-01-07 22:01:00 -08002012 // Support here requires both feature bit for compression and picked format supports transfer feature bits
unknown088160a2019-05-23 17:43:13 -06002013 VkPhysicalDeviceFeatures device_features = {};
2014 ASSERT_NO_FATAL_FAILURE(GetPhysicalDeviceFeatures(&device_features));
2015 if (!(device_features.textureCompressionBC || device_features.textureCompressionETC2 ||
2016 device_features.textureCompressionASTC_LDR)) {
2017 printf("%s No compressed formats supported - block compression tests skipped.\n", kSkipPrefix);
2018 } else {
sfricke-samsung6d97e562020-01-07 22:01:00 -08002019 // Verify transfer support for each compression format used blow
2020 bool missing_bc_support = false;
2021 bool missing_etc_support = false;
2022 bool missing_astc_support = false;
2023 bool missing_compression_support = false;
2024
2025 vk::GetPhysicalDeviceFormatProperties(m_device->phy().handle(), VK_FORMAT_BC3_SRGB_BLOCK, &props);
2026 missing_bc_support |= (props.bufferFeatures == 0 && props.linearTilingFeatures == 0 && props.optimalTilingFeatures == 0);
2027 missing_bc_support |= (props.optimalTilingFeatures & VK_FORMAT_FEATURE_TRANSFER_SRC_BIT) == 0;
2028 missing_bc_support |= (props.optimalTilingFeatures & VK_FORMAT_FEATURE_TRANSFER_DST_BIT) == 0;
2029
2030 vk::GetPhysicalDeviceFormatProperties(m_device->phy().handle(), VK_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK, &props);
2031 missing_etc_support |= (props.bufferFeatures == 0 && props.linearTilingFeatures == 0 && props.optimalTilingFeatures == 0);
2032 missing_etc_support |= (props.optimalTilingFeatures & VK_FORMAT_FEATURE_TRANSFER_SRC_BIT) == 0;
2033 missing_etc_support |= (props.optimalTilingFeatures & VK_FORMAT_FEATURE_TRANSFER_DST_BIT) == 0;
2034
2035 vk::GetPhysicalDeviceFormatProperties(m_device->phy().handle(), VK_FORMAT_ASTC_4x4_UNORM_BLOCK, &props);
2036 missing_astc_support |= (props.bufferFeatures == 0 && props.linearTilingFeatures == 0 && props.optimalTilingFeatures == 0);
2037 missing_astc_support |= (props.optimalTilingFeatures & VK_FORMAT_FEATURE_TRANSFER_SRC_BIT) == 0;
2038 missing_astc_support |= (props.optimalTilingFeatures & VK_FORMAT_FEATURE_TRANSFER_DST_BIT) == 0;
2039
2040 if (device_features.textureCompressionBC && (!missing_bc_support)) {
unknown088160a2019-05-23 17:43:13 -06002041 image_16k_4x4comp.Init(128, 128, 1, VK_FORMAT_BC3_SRGB_BLOCK, VK_IMAGE_USAGE_TRANSFER_SRC_BIT, VK_IMAGE_TILING_OPTIMAL,
2042 0);
2043 image_NPOT_4x4comp.Init(130, 130, 1, VK_FORMAT_BC3_SRGB_BLOCK, VK_IMAGE_USAGE_TRANSFER_SRC_BIT, VK_IMAGE_TILING_OPTIMAL,
2044 0);
sfricke-samsung6d97e562020-01-07 22:01:00 -08002045 } else if (device_features.textureCompressionETC2 && (!missing_etc_support)) {
unknown088160a2019-05-23 17:43:13 -06002046 image_16k_4x4comp.Init(128, 128, 1, VK_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK, VK_IMAGE_USAGE_TRANSFER_SRC_BIT,
2047 VK_IMAGE_TILING_OPTIMAL, 0);
2048 image_NPOT_4x4comp.Init(130, 130, 1, VK_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK, VK_IMAGE_USAGE_TRANSFER_SRC_BIT,
2049 VK_IMAGE_TILING_OPTIMAL, 0);
sfricke-samsung6d97e562020-01-07 22:01:00 -08002050 } else if (device_features.textureCompressionASTC_LDR && (!missing_astc_support)) {
unknown088160a2019-05-23 17:43:13 -06002051 image_16k_4x4comp.Init(128, 128, 1, VK_FORMAT_ASTC_4x4_UNORM_BLOCK, VK_IMAGE_USAGE_TRANSFER_SRC_BIT,
2052 VK_IMAGE_TILING_OPTIMAL, 0);
2053 image_NPOT_4x4comp.Init(130, 130, 1, VK_FORMAT_ASTC_4x4_UNORM_BLOCK, VK_IMAGE_USAGE_TRANSFER_SRC_BIT,
2054 VK_IMAGE_TILING_OPTIMAL, 0);
sfricke-samsung6d97e562020-01-07 22:01:00 -08002055 } else {
2056 missing_compression_support = true;
unknown088160a2019-05-23 17:43:13 -06002057 }
unknown088160a2019-05-23 17:43:13 -06002058
sfricke-samsung6d97e562020-01-07 22:01:00 -08002059 if (missing_compression_support) {
2060 printf("%s No compressed formats transfers bits are supported - block compression tests skipped.\n", kSkipPrefix);
2061 } else {
2062 ASSERT_TRUE(image_16k_4x4comp.initialized());
sfricke-samsung3a10b922020-05-13 23:23:16 -07002063 std::string vuid;
sfricke-samsung6d97e562020-01-07 22:01:00 -08002064 // Just fits
locke-lunargdf00db02020-03-04 19:00:57 -07002065 vk::CmdPipelineBarrier(m_commandBuffer->handle(), VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, 1,
2066 &mem_barriers[0], 0, nullptr, 0, nullptr);
sfricke-samsung6d97e562020-01-07 22:01:00 -08002067 m_errorMonitor->ExpectSuccess();
2068 region.imageExtent = {128, 128, 1};
2069 vk::CmdCopyImageToBuffer(m_commandBuffer->handle(), image_16k_4x4comp.handle(), VK_IMAGE_LAYOUT_GENERAL,
2070 buffer_16k.handle(), 1, &region);
2071 m_errorMonitor->VerifyNotFound();
unknown088160a2019-05-23 17:43:13 -06002072
sfricke-samsung6d97e562020-01-07 22:01:00 -08002073 // with offset, too big for buffer
Mark Lobodzinski20310782020-02-28 14:25:17 -07002074 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdCopyImageToBuffer-pRegions-00183");
sfricke-samsung6d97e562020-01-07 22:01:00 -08002075 region.bufferOffset = 16;
2076 vk::CmdCopyImageToBuffer(m_commandBuffer->handle(), image_16k_4x4comp.handle(), VK_IMAGE_LAYOUT_GENERAL,
2077 buffer_16k.handle(), 1, &region);
2078 m_errorMonitor->VerifyFound();
2079 region.bufferOffset = 0;
unknown088160a2019-05-23 17:43:13 -06002080
sfricke-samsung6d97e562020-01-07 22:01:00 -08002081 // extents that are not a multiple of compressed block size
sfricke-samsung3a10b922020-05-13 23:23:16 -07002082 vuid = mp_extensions ? "VUID-VkBufferImageCopy-None-01739" : "VUID-VkBufferImageCopy-imageExtent-00207";
2083 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, vuid); // extent width not a multiple of block size
Mark Lobodzinski20310782020-02-28 14:25:17 -07002084 m_errorMonitor->SetDesiredFailureMsg(kErrorBit,
sfricke-samsung6d97e562020-01-07 22:01:00 -08002085 "VUID-vkCmdCopyImageToBuffer-imageOffset-01794"); // image transfer granularity
2086 region.imageExtent.width = 66;
2087 vk::CmdCopyImageToBuffer(m_commandBuffer->handle(), image_NPOT_4x4comp.handle(), VK_IMAGE_LAYOUT_GENERAL,
2088 buffer_16k.handle(), 1, &region);
2089 m_errorMonitor->VerifyFound();
2090 region.imageExtent.width = 128;
unknown088160a2019-05-23 17:43:13 -06002091
sfricke-samsung3a10b922020-05-13 23:23:16 -07002092 vuid = mp_extensions ? "VUID-VkBufferImageCopy-None-01740" : "VUID-VkBufferImageCopy-imageExtent-00208";
2093 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, vuid); // extent height not a multiple of block size
Mark Lobodzinski20310782020-02-28 14:25:17 -07002094 m_errorMonitor->SetDesiredFailureMsg(kErrorBit,
sfricke-samsung6d97e562020-01-07 22:01:00 -08002095 "VUID-vkCmdCopyImageToBuffer-imageOffset-01794"); // image transfer granularity
2096 region.imageExtent.height = 2;
2097 vk::CmdCopyImageToBuffer(m_commandBuffer->handle(), image_NPOT_4x4comp.handle(), VK_IMAGE_LAYOUT_GENERAL,
2098 buffer_16k.handle(), 1, &region);
2099 m_errorMonitor->VerifyFound();
2100 region.imageExtent.height = 128;
unknown088160a2019-05-23 17:43:13 -06002101
sfricke-samsung6d97e562020-01-07 22:01:00 -08002102 // TODO: All available compressed formats are 2D, with block depth of 1. Unable to provoke VU_01277.
unknown088160a2019-05-23 17:43:13 -06002103
sfricke-samsung6d97e562020-01-07 22:01:00 -08002104 // non-multiple extents are allowed if at the far edge of a non-block-multiple image - these should pass
2105 m_errorMonitor->ExpectSuccess();
2106 region.imageExtent.width = 66;
2107 region.imageOffset.x = 64;
locke-lunargdf00db02020-03-04 19:00:57 -07002108 vk::CmdPipelineBarrier(m_commandBuffer->handle(), VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, 1,
2109 &mem_barriers[0], 0, nullptr, 0, nullptr);
sfricke-samsung6d97e562020-01-07 22:01:00 -08002110 vk::CmdCopyImageToBuffer(m_commandBuffer->handle(), image_NPOT_4x4comp.handle(), VK_IMAGE_LAYOUT_GENERAL,
2111 buffer_16k.handle(), 1, &region);
2112 region.imageExtent.width = 16;
2113 region.imageOffset.x = 0;
2114 region.imageExtent.height = 2;
2115 region.imageOffset.y = 128;
locke-lunargdf00db02020-03-04 19:00:57 -07002116 vk::CmdPipelineBarrier(m_commandBuffer->handle(), VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, 1,
2117 &mem_barriers[0], 0, nullptr, 0, nullptr);
sfricke-samsung6d97e562020-01-07 22:01:00 -08002118 vk::CmdCopyImageToBuffer(m_commandBuffer->handle(), image_NPOT_4x4comp.handle(), VK_IMAGE_LAYOUT_GENERAL,
2119 buffer_16k.handle(), 1, &region);
2120 m_errorMonitor->VerifyNotFound();
2121 region.imageOffset = {0, 0, 0};
unknown088160a2019-05-23 17:43:13 -06002122
sfricke-samsung6d97e562020-01-07 22:01:00 -08002123 // buffer offset must be a multiple of texel block size (16)
sfricke-samsung3a10b922020-05-13 23:23:16 -07002124 vuid = mp_extensions ? "VUID-VkBufferImageCopy-None-01738" : "VUID-VkBufferImageCopy-bufferOffset-00206";
2125 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, vuid);
sfricke-samsung125d2b42020-05-28 06:32:43 -07002126 vuid = mp_extensions ? "VUID-VkBufferImageCopy-bufferOffset-01558" : "VUID-VkBufferImageCopy-bufferOffset-00193";
2127 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, vuid);
sfricke-samsung6d97e562020-01-07 22:01:00 -08002128 region.imageExtent = {64, 64, 1};
2129 region.bufferOffset = 24;
2130 vk::CmdCopyImageToBuffer(m_commandBuffer->handle(), image_16k_4x4comp.handle(), VK_IMAGE_LAYOUT_GENERAL,
2131 buffer_16k.handle(), 1, &region);
2132 m_errorMonitor->VerifyFound();
unknown088160a2019-05-23 17:43:13 -06002133
sfricke-samsung6d97e562020-01-07 22:01:00 -08002134 // rowlength not a multiple of block width (4)
sfricke-samsung3a10b922020-05-13 23:23:16 -07002135 vuid = mp_extensions ? "VUID-VkBufferImageCopy-None-01735" : "VUID-VkBufferImageCopy-bufferRowLength-00203";
2136 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, vuid);
sfricke-samsung6d97e562020-01-07 22:01:00 -08002137 region.bufferOffset = 0;
2138 region.bufferRowLength = 130;
2139 region.bufferImageHeight = 0;
2140 vk::CmdCopyImageToBuffer(m_commandBuffer->handle(), image_16k_4x4comp.handle(), VK_IMAGE_LAYOUT_GENERAL,
2141 buffer_64k.handle(), 1, &region);
2142 m_errorMonitor->VerifyFound();
2143
2144 // imageheight not a multiple of block height (4)
sfricke-samsung3a10b922020-05-13 23:23:16 -07002145 vuid = mp_extensions ? "VUID-VkBufferImageCopy-None-01736" : "VUID-VkBufferImageCopy-bufferImageHeight-00204";
2146 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, vuid);
sfricke-samsung6d97e562020-01-07 22:01:00 -08002147 region.bufferRowLength = 0;
2148 region.bufferImageHeight = 130;
2149 vk::CmdCopyImageToBuffer(m_commandBuffer->handle(), image_16k_4x4comp.handle(), VK_IMAGE_LAYOUT_GENERAL,
2150 buffer_64k.handle(), 1, &region);
2151 m_errorMonitor->VerifyFound();
2152 }
2153 }
2154
2155 // Test multi-planar formats, if supported
2156 if (!mp_extensions) {
2157 printf("%s multi-planar extensions not supported; skipped.\n", kSkipPrefix);
2158 } else {
2159 // Try to use G8_B8R8_2PLANE_420_UNORM because need 2-plane format for some tests and likely supported due to copy support
2160 // being required with samplerYcbcrConversion feature
2161 bool missing_mp_support = false;
2162 vk::GetPhysicalDeviceFormatProperties(m_device->phy().handle(), VK_FORMAT_G8_B8R8_2PLANE_420_UNORM, &props);
2163 missing_mp_support |= (props.bufferFeatures == 0 && props.linearTilingFeatures == 0 && props.optimalTilingFeatures == 0);
2164 missing_mp_support |= (props.optimalTilingFeatures & VK_FORMAT_FEATURE_TRANSFER_SRC_BIT) == 0;
2165 missing_mp_support |= (props.optimalTilingFeatures & VK_FORMAT_FEATURE_TRANSFER_DST_BIT) == 0;
2166
2167 if (missing_mp_support) {
2168 printf("%s VK_FORMAT_G8_B8R8_2PLANE_420_UNORM transfer not supported; skipped.\n", kSkipPrefix);
2169 } else {
2170 VkBufferImageCopy mp_region = {};
2171 mp_region.bufferOffset = 0;
2172 mp_region.bufferRowLength = 0;
2173 mp_region.bufferImageHeight = 0;
2174 mp_region.imageSubresource.mipLevel = 0;
2175 mp_region.imageSubresource.baseArrayLayer = 0;
2176 mp_region.imageSubresource.layerCount = 1;
2177 mp_region.imageOffset = {0, 0, 0};
2178 mp_region.imageExtent = {128, 128, 1};
2179
2180 // YUV420 means 1/2 width and height so plane_0 is 128x128 and plane_1 is 64x64 here
2181 image_multi_planar.Init(128, 128, 1, VK_FORMAT_G8_B8R8_2PLANE_420_UNORM, VK_IMAGE_USAGE_TRANSFER_DST_BIT,
2182 VK_IMAGE_TILING_OPTIMAL, 0);
2183 ASSERT_TRUE(image_multi_planar.initialized());
2184
2185 // Copies into a mutli-planar image aspect properly
2186 m_errorMonitor->ExpectSuccess();
2187 mp_region.imageSubresource.aspectMask = VK_IMAGE_ASPECT_PLANE_0_BIT;
locke-lunargdf00db02020-03-04 19:00:57 -07002188 vk::CmdPipelineBarrier(m_commandBuffer->handle(), VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, 1,
2189 &mem_barriers[2], 0, nullptr, 0, nullptr);
sfricke-samsung6d97e562020-01-07 22:01:00 -08002190 vk::CmdCopyBufferToImage(m_commandBuffer->handle(), buffer_16k.handle(), image_multi_planar.handle(),
2191 VK_IMAGE_LAYOUT_GENERAL, 1, &mp_region);
2192 m_errorMonitor->VerifyNotFound();
2193
2194 // uses plane_2 without being 3 planar format
Mark Lobodzinski20310782020-02-28 14:25:17 -07002195 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkBufferImageCopy-aspectMask-01560");
sfricke-samsung6d97e562020-01-07 22:01:00 -08002196 mp_region.imageSubresource.aspectMask = VK_IMAGE_ASPECT_PLANE_2_BIT;
2197 vk::CmdCopyBufferToImage(m_commandBuffer->handle(), buffer_16k.handle(), image_multi_planar.handle(),
2198 VK_IMAGE_LAYOUT_GENERAL, 1, &mp_region);
2199 m_errorMonitor->VerifyFound();
2200
2201 // uses single-plane aspect mask
Mark Lobodzinski20310782020-02-28 14:25:17 -07002202 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkBufferImageCopy-aspectMask-01560");
sfricke-samsung6d97e562020-01-07 22:01:00 -08002203 mp_region.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
2204 vk::CmdCopyBufferToImage(m_commandBuffer->handle(), buffer_16k.handle(), image_multi_planar.handle(),
2205 VK_IMAGE_LAYOUT_GENERAL, 1, &mp_region);
2206 m_errorMonitor->VerifyFound();
sfricke-samsungb616d3f2020-06-03 22:00:34 -07002207
2208 // buffer offset must be a multiple of texel block size for VK_FORMAT_R8G8_UNORM (2)
2209 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkBufferImageCopy-bufferOffset-01559");
sfricke-samsungb616d3f2020-06-03 22:00:34 -07002210 mp_region.imageSubresource.aspectMask = VK_IMAGE_ASPECT_PLANE_1_BIT;
2211 mp_region.bufferOffset = 5;
2212 mp_region.imageExtent = {8, 8, 1};
2213 vk::CmdCopyBufferToImage(m_commandBuffer->handle(), buffer_16k.handle(), image_multi_planar.handle(),
2214 VK_IMAGE_LAYOUT_GENERAL, 1, &mp_region);
2215 m_errorMonitor->VerifyFound();
sfricke-samsung6d97e562020-01-07 22:01:00 -08002216 }
unknown088160a2019-05-23 17:43:13 -06002217 }
2218}
2219
2220TEST_F(VkLayerTest, MiscImageLayerTests) {
2221 TEST_DESCRIPTION("Image-related tests that don't belong elsewhere");
2222
2223 ASSERT_NO_FATAL_FAILURE(Init());
2224
2225 // TODO: Ideally we should check if a format is supported, before using it.
2226 VkImageObj image(m_device);
2227 image.Init(128, 128, 1, VK_FORMAT_R16G16B16A16_UINT, VK_IMAGE_USAGE_TRANSFER_DST_BIT, VK_IMAGE_TILING_OPTIMAL, 0); // 64bpp
2228 ASSERT_TRUE(image.initialized());
2229 VkBufferObj buffer;
2230 VkMemoryPropertyFlags reqs = 0;
2231 buffer.init_as_src(*m_device, 128 * 128 * 8, reqs);
2232 VkBufferImageCopy region = {};
2233 region.bufferRowLength = 128;
2234 region.bufferImageHeight = 128;
2235 region.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
2236 // layerCount can't be 0 - Expect MISMATCHED_IMAGE_ASPECT
2237 region.imageSubresource.layerCount = 1;
2238 region.imageExtent.height = 4;
2239 region.imageExtent.width = 4;
2240 region.imageExtent.depth = 1;
2241
2242 VkImageObj image2(m_device);
2243 image2.Init(128, 128, 1, VK_FORMAT_R8G8_UNORM, VK_IMAGE_USAGE_TRANSFER_DST_BIT, VK_IMAGE_TILING_OPTIMAL, 0); // 16bpp
2244 ASSERT_TRUE(image2.initialized());
2245 VkBufferObj buffer2;
2246 VkMemoryPropertyFlags reqs2 = 0;
2247 buffer2.init_as_src(*m_device, 128 * 128 * 2, reqs2);
unknown088160a2019-05-23 17:43:13 -06002248 m_commandBuffer->begin();
2249
2250 // Image must have offset.z of 0 and extent.depth of 1
2251 // Introduce failure by setting imageExtent.depth to 0
2252 region.imageExtent.depth = 0;
Mark Lobodzinski20310782020-02-28 14:25:17 -07002253 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkBufferImageCopy-srcImage-00201");
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06002254 vk::CmdCopyBufferToImage(m_commandBuffer->handle(), buffer.handle(), image.handle(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1,
2255 &region);
unknown088160a2019-05-23 17:43:13 -06002256 m_errorMonitor->VerifyFound();
2257
2258 region.imageExtent.depth = 1;
2259
2260 // Image must have offset.z of 0 and extent.depth of 1
2261 // Introduce failure by setting imageOffset.z to 4
2262 // Note: Also (unavoidably) triggers 'region exceeds image' #1228
2263 region.imageOffset.z = 4;
Mark Lobodzinski20310782020-02-28 14:25:17 -07002264 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkBufferImageCopy-srcImage-00201");
2265 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkBufferImageCopy-imageOffset-00200");
2266 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdCopyBufferToImage-pRegions-00172");
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06002267 vk::CmdCopyBufferToImage(m_commandBuffer->handle(), buffer.handle(), image.handle(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1,
2268 &region);
unknown088160a2019-05-23 17:43:13 -06002269 m_errorMonitor->VerifyFound();
2270
2271 region.imageOffset.z = 0;
2272 // BufferOffset must be a multiple of the calling command's VkImage parameter's texel size
2273 // Introduce failure by setting bufferOffset to 1 and 1/2 texels
2274 region.bufferOffset = 4;
Mark Lobodzinski20310782020-02-28 14:25:17 -07002275 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkBufferImageCopy-bufferOffset-00193");
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06002276 vk::CmdCopyBufferToImage(m_commandBuffer->handle(), buffer.handle(), image.handle(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1,
2277 &region);
unknown088160a2019-05-23 17:43:13 -06002278 m_errorMonitor->VerifyFound();
2279
unknown088160a2019-05-23 17:43:13 -06002280 // BufferRowLength must be 0, or greater than or equal to the width member of imageExtent
2281 region.bufferOffset = 0;
2282 region.imageExtent.height = 128;
2283 region.imageExtent.width = 128;
2284 // Introduce failure by setting bufferRowLength > 0 but less than width
2285 region.bufferRowLength = 64;
Mark Lobodzinski20310782020-02-28 14:25:17 -07002286 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkBufferImageCopy-bufferRowLength-00195");
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06002287 vk::CmdCopyBufferToImage(m_commandBuffer->handle(), buffer.handle(), image.handle(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1,
2288 &region);
unknown088160a2019-05-23 17:43:13 -06002289 m_errorMonitor->VerifyFound();
2290
2291 // BufferImageHeight must be 0, or greater than or equal to the height member of imageExtent
2292 region.bufferRowLength = 128;
2293 // Introduce failure by setting bufferRowHeight > 0 but less than height
2294 region.bufferImageHeight = 64;
Mark Lobodzinski20310782020-02-28 14:25:17 -07002295 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkBufferImageCopy-bufferImageHeight-00196");
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06002296 vk::CmdCopyBufferToImage(m_commandBuffer->handle(), buffer.handle(), image.handle(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1,
2297 &region);
unknown088160a2019-05-23 17:43:13 -06002298 m_errorMonitor->VerifyFound();
2299
2300 region.bufferImageHeight = 128;
2301 VkImageObj intImage1(m_device);
2302 intImage1.Init(128, 128, 1, VK_FORMAT_R8_UNORM, VK_IMAGE_USAGE_TRANSFER_SRC_BIT, VK_IMAGE_TILING_OPTIMAL, 0);
2303 intImage1.SetLayout(VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_GENERAL);
2304 VkImageObj intImage2(m_device);
2305 intImage2.Init(128, 128, 1, VK_FORMAT_R8_UNORM, VK_IMAGE_USAGE_TRANSFER_DST_BIT, VK_IMAGE_TILING_OPTIMAL, 0);
2306 intImage2.SetLayout(VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_GENERAL);
2307 VkImageBlit blitRegion = {};
2308 blitRegion.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
2309 blitRegion.srcSubresource.baseArrayLayer = 0;
2310 blitRegion.srcSubresource.layerCount = 1;
2311 blitRegion.srcSubresource.mipLevel = 0;
2312 blitRegion.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
2313 blitRegion.dstSubresource.baseArrayLayer = 0;
2314 blitRegion.dstSubresource.layerCount = 1;
2315 blitRegion.dstSubresource.mipLevel = 0;
2316 blitRegion.srcOffsets[0] = {128, 0, 0};
2317 blitRegion.srcOffsets[1] = {128, 128, 1};
2318 blitRegion.dstOffsets[0] = {0, 128, 0};
2319 blitRegion.dstOffsets[1] = {128, 128, 1};
2320
2321 // Look for NULL-blit warning
Mark Lobodzinski20310782020-02-28 14:25:17 -07002322 m_errorMonitor->SetDesiredFailureMsg(kWarningBit, "vkCmdBlitImage(): pRegions[0].srcOffsets specify a zero-volume area.");
2323 m_errorMonitor->SetDesiredFailureMsg(kWarningBit, "vkCmdBlitImage(): pRegions[0].dstOffsets specify a zero-volume area.");
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06002324 vk::CmdBlitImage(m_commandBuffer->handle(), intImage1.handle(), intImage1.Layout(), intImage2.handle(), intImage2.Layout(), 1,
2325 &blitRegion, VK_FILTER_LINEAR);
unknown088160a2019-05-23 17:43:13 -06002326 m_errorMonitor->VerifyFound();
2327}
2328
2329TEST_F(VkLayerTest, CopyImageTypeExtentMismatch) {
2330 // Image copy tests where format type and extents don't match
2331 ASSERT_NO_FATAL_FAILURE(Init());
2332
sfricke-samsung30b094c2020-05-30 11:42:11 -07002333 // Tests are designed to run without Maintenance1 which was promoted in 1.1
2334 if (DeviceValidationVersion() >= VK_API_VERSION_1_1) {
2335 printf("%s Tests for 1.0 only, test skipped.\n", kSkipPrefix);
2336 return;
2337 }
2338
unknown088160a2019-05-23 17:43:13 -06002339 VkImageCreateInfo ci;
2340 ci.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
2341 ci.pNext = NULL;
2342 ci.flags = 0;
2343 ci.imageType = VK_IMAGE_TYPE_1D;
2344 ci.format = VK_FORMAT_R8G8B8A8_UNORM;
2345 ci.extent = {32, 1, 1};
2346 ci.mipLevels = 1;
2347 ci.arrayLayers = 1;
2348 ci.samples = VK_SAMPLE_COUNT_1_BIT;
2349 ci.tiling = VK_IMAGE_TILING_OPTIMAL;
2350 ci.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
2351 ci.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
2352 ci.queueFamilyIndexCount = 0;
2353 ci.pQueueFamilyIndices = NULL;
2354 ci.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
2355
2356 // Create 1D image
2357 VkImageObj image_1D(m_device);
2358 image_1D.init(&ci);
2359 ASSERT_TRUE(image_1D.initialized());
2360
2361 // 2D image
2362 ci.imageType = VK_IMAGE_TYPE_2D;
2363 ci.extent = {32, 32, 1};
2364 VkImageObj image_2D(m_device);
2365 image_2D.init(&ci);
2366 ASSERT_TRUE(image_2D.initialized());
2367
2368 // 3D image
2369 ci.imageType = VK_IMAGE_TYPE_3D;
2370 ci.extent = {32, 32, 8};
2371 VkImageObj image_3D(m_device);
2372 image_3D.init(&ci);
2373 ASSERT_TRUE(image_3D.initialized());
2374
2375 // 2D image array
2376 ci.imageType = VK_IMAGE_TYPE_2D;
2377 ci.extent = {32, 32, 1};
2378 ci.arrayLayers = 8;
2379 VkImageObj image_2D_array(m_device);
2380 image_2D_array.init(&ci);
2381 ASSERT_TRUE(image_2D_array.initialized());
2382
2383 m_commandBuffer->begin();
2384
2385 VkImageCopy copy_region;
2386 copy_region.extent = {32, 1, 1};
2387 copy_region.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
2388 copy_region.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
2389 copy_region.srcSubresource.mipLevel = 0;
2390 copy_region.dstSubresource.mipLevel = 0;
2391 copy_region.srcSubresource.baseArrayLayer = 0;
2392 copy_region.dstSubresource.baseArrayLayer = 0;
2393 copy_region.srcSubresource.layerCount = 1;
2394 copy_region.dstSubresource.layerCount = 1;
2395 copy_region.srcOffset = {0, 0, 0};
2396 copy_region.dstOffset = {0, 0, 0};
2397
2398 // Sanity check
2399 m_errorMonitor->ExpectSuccess();
2400 m_commandBuffer->CopyImage(image_1D.image(), VK_IMAGE_LAYOUT_GENERAL, image_2D.image(), VK_IMAGE_LAYOUT_GENERAL, 1,
2401 &copy_region);
2402 m_errorMonitor->VerifyNotFound();
2403
2404 // 1D texture w/ offset.y > 0. Source = VU 09c00124, dest = 09c00130
2405 copy_region.srcOffset.y = 1;
Mark Lobodzinski20310782020-02-28 14:25:17 -07002406 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkImageCopy-srcImage-00146");
2407 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkImageCopy-srcOffset-00145"); // also y-dim overrun
unknown088160a2019-05-23 17:43:13 -06002408 m_commandBuffer->CopyImage(image_1D.image(), VK_IMAGE_LAYOUT_GENERAL, image_2D.image(), VK_IMAGE_LAYOUT_GENERAL, 1,
2409 &copy_region);
2410 m_errorMonitor->VerifyFound();
2411 copy_region.srcOffset.y = 0;
2412 copy_region.dstOffset.y = 1;
Mark Lobodzinski20310782020-02-28 14:25:17 -07002413 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkImageCopy-dstImage-00152");
2414 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkImageCopy-dstOffset-00151"); // also y-dim overrun
unknown088160a2019-05-23 17:43:13 -06002415 m_commandBuffer->CopyImage(image_2D.image(), VK_IMAGE_LAYOUT_GENERAL, image_1D.image(), VK_IMAGE_LAYOUT_GENERAL, 1,
2416 &copy_region);
2417 m_errorMonitor->VerifyFound();
2418 copy_region.dstOffset.y = 0;
2419
2420 // 1D texture w/ extent.height > 1. Source = VU 09c00124, dest = 09c00130
2421 copy_region.extent.height = 2;
Mark Lobodzinski20310782020-02-28 14:25:17 -07002422 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkImageCopy-srcImage-00146");
2423 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkImageCopy-srcOffset-00145"); // also y-dim overrun
unknown088160a2019-05-23 17:43:13 -06002424 m_commandBuffer->CopyImage(image_1D.image(), VK_IMAGE_LAYOUT_GENERAL, image_2D.image(), VK_IMAGE_LAYOUT_GENERAL, 1,
2425 &copy_region);
2426 m_errorMonitor->VerifyFound();
Mark Lobodzinski20310782020-02-28 14:25:17 -07002427 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkImageCopy-dstImage-00152");
2428 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkImageCopy-dstOffset-00151"); // also y-dim overrun
unknown088160a2019-05-23 17:43:13 -06002429 m_commandBuffer->CopyImage(image_2D.image(), VK_IMAGE_LAYOUT_GENERAL, image_1D.image(), VK_IMAGE_LAYOUT_GENERAL, 1,
2430 &copy_region);
2431 m_errorMonitor->VerifyFound();
2432 copy_region.extent.height = 1;
2433
2434 // 1D texture w/ offset.z > 0. Source = VU 09c00df2, dest = 09c00df4
2435 copy_region.srcOffset.z = 1;
Mark Lobodzinski20310782020-02-28 14:25:17 -07002436 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkImageCopy-srcImage-01785");
2437 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkImageCopy-srcOffset-00147"); // also z-dim overrun
unknown088160a2019-05-23 17:43:13 -06002438 m_commandBuffer->CopyImage(image_1D.image(), VK_IMAGE_LAYOUT_GENERAL, image_2D.image(), VK_IMAGE_LAYOUT_GENERAL, 1,
2439 &copy_region);
2440 m_errorMonitor->VerifyFound();
2441 copy_region.srcOffset.z = 0;
2442 copy_region.dstOffset.z = 1;
Mark Lobodzinski20310782020-02-28 14:25:17 -07002443 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkImageCopy-dstImage-01786");
2444 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkImageCopy-dstOffset-00153"); // also z-dim overrun
unknown088160a2019-05-23 17:43:13 -06002445 m_commandBuffer->CopyImage(image_2D.image(), VK_IMAGE_LAYOUT_GENERAL, image_1D.image(), VK_IMAGE_LAYOUT_GENERAL, 1,
2446 &copy_region);
2447 m_errorMonitor->VerifyFound();
2448 copy_region.dstOffset.z = 0;
2449
2450 // 1D texture w/ extent.depth > 1. Source = VU 09c00df2, dest = 09c00df4
2451 copy_region.extent.depth = 2;
Mark Lobodzinski20310782020-02-28 14:25:17 -07002452 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkImageCopy-srcImage-01785");
2453 m_errorMonitor->SetDesiredFailureMsg(kErrorBit,
unknown088160a2019-05-23 17:43:13 -06002454 "VUID-VkImageCopy-srcOffset-00147"); // also z-dim overrun (src)
Mark Lobodzinski20310782020-02-28 14:25:17 -07002455 m_errorMonitor->SetDesiredFailureMsg(kErrorBit,
unknown088160a2019-05-23 17:43:13 -06002456 "VUID-VkImageCopy-dstOffset-00153"); // also z-dim overrun (dst)
Mark Lobodzinski20310782020-02-28 14:25:17 -07002457 m_errorMonitor->SetDesiredFailureMsg(kErrorBit,
sfricke-samsung211ee9c2020-02-13 23:38:39 -08002458 "VUID-VkImageCopy-srcImage-01789"); // 2D needs to be 1 pre-Vulkan 1.1
unknown088160a2019-05-23 17:43:13 -06002459 m_commandBuffer->CopyImage(image_1D.image(), VK_IMAGE_LAYOUT_GENERAL, image_2D.image(), VK_IMAGE_LAYOUT_GENERAL, 1,
2460 &copy_region);
2461 m_errorMonitor->VerifyFound();
Mark Lobodzinski20310782020-02-28 14:25:17 -07002462 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkImageCopy-dstImage-01786");
2463 m_errorMonitor->SetDesiredFailureMsg(kErrorBit,
unknown088160a2019-05-23 17:43:13 -06002464 "VUID-VkImageCopy-srcOffset-00147"); // also z-dim overrun (src)
Mark Lobodzinski20310782020-02-28 14:25:17 -07002465 m_errorMonitor->SetDesiredFailureMsg(kErrorBit,
unknown088160a2019-05-23 17:43:13 -06002466 "VUID-VkImageCopy-dstOffset-00153"); // also z-dim overrun (dst)
Mark Lobodzinski20310782020-02-28 14:25:17 -07002467 m_errorMonitor->SetDesiredFailureMsg(kErrorBit,
sfricke-samsung211ee9c2020-02-13 23:38:39 -08002468 "VUID-VkImageCopy-srcImage-01789"); // 2D needs to be 1 pre-Vulkan 1.1
unknown088160a2019-05-23 17:43:13 -06002469 m_commandBuffer->CopyImage(image_2D.image(), VK_IMAGE_LAYOUT_GENERAL, image_1D.image(), VK_IMAGE_LAYOUT_GENERAL, 1,
2470 &copy_region);
2471 m_errorMonitor->VerifyFound();
2472 copy_region.extent.depth = 1;
2473
2474 // 2D texture w/ offset.z > 0. Source = VU 09c00df6, dest = 09c00df8
2475 copy_region.extent = {16, 16, 1};
2476 copy_region.srcOffset.z = 4;
Mark Lobodzinski20310782020-02-28 14:25:17 -07002477 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkImageCopy-srcImage-01787");
2478 m_errorMonitor->SetDesiredFailureMsg(kErrorBit,
unknown088160a2019-05-23 17:43:13 -06002479 "VUID-VkImageCopy-srcOffset-00147"); // also z-dim overrun (src)
2480 m_commandBuffer->CopyImage(image_2D.image(), VK_IMAGE_LAYOUT_GENERAL, image_3D.image(), VK_IMAGE_LAYOUT_GENERAL, 1,
2481 &copy_region);
2482 m_errorMonitor->VerifyFound();
2483 copy_region.srcOffset.z = 0;
2484 copy_region.dstOffset.z = 1;
Mark Lobodzinski20310782020-02-28 14:25:17 -07002485 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkImageCopy-dstImage-01788");
2486 m_errorMonitor->SetDesiredFailureMsg(kErrorBit,
unknown088160a2019-05-23 17:43:13 -06002487 "VUID-VkImageCopy-dstOffset-00153"); // also z-dim overrun (dst)
2488 m_commandBuffer->CopyImage(image_3D.image(), VK_IMAGE_LAYOUT_GENERAL, image_2D.image(), VK_IMAGE_LAYOUT_GENERAL, 1,
2489 &copy_region);
2490 m_errorMonitor->VerifyFound();
2491 copy_region.dstOffset.z = 0;
2492
2493 // 3D texture accessing an array layer other than 0. VU 09c0011a
2494 copy_region.extent = {4, 4, 1};
2495 copy_region.srcSubresource.baseArrayLayer = 1;
sfricke-samsung30b094c2020-05-30 11:42:11 -07002496 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkImageCopy-srcImage-00139");
Mark Lobodzinski20310782020-02-28 14:25:17 -07002497 m_errorMonitor->SetDesiredFailureMsg(kErrorBit,
unknown088160a2019-05-23 17:43:13 -06002498 "VUID-vkCmdCopyImage-srcSubresource-01698"); // also 'too many layers'
2499 m_commandBuffer->CopyImage(image_3D.image(), VK_IMAGE_LAYOUT_GENERAL, image_2D.image(), VK_IMAGE_LAYOUT_GENERAL, 1,
2500 &copy_region);
2501 m_errorMonitor->VerifyFound();
sfricke-samsung211ee9c2020-02-13 23:38:39 -08002502 copy_region.srcSubresource.baseArrayLayer = 0;
2503
unknown088160a2019-05-23 17:43:13 -06002504 m_commandBuffer->end();
2505}
2506
2507TEST_F(VkLayerTest, CopyImageTypeExtentMismatchMaintenance1) {
2508 // Image copy tests where format type and extents don't match and the Maintenance1 extension is enabled
Mark Lobodzinski09ce9c42020-03-06 10:02:44 -07002509 ASSERT_NO_FATAL_FAILURE(InitFramework(m_errorMonitor));
unknown088160a2019-05-23 17:43:13 -06002510 if (DeviceExtensionSupported(gpu(), nullptr, VK_KHR_MAINTENANCE1_EXTENSION_NAME)) {
2511 m_device_extension_names.push_back(VK_KHR_MAINTENANCE1_EXTENSION_NAME);
2512 } else {
2513 printf("%s Maintenance1 extension cannot be enabled, test skipped.\n", kSkipPrefix);
2514 return;
2515 }
2516 ASSERT_NO_FATAL_FAILURE(InitState());
2517
2518 VkFormat image_format = VK_FORMAT_R8G8B8A8_UNORM;
2519 VkFormatProperties format_props;
2520 // TODO: Remove this check if or when devsim handles extensions.
2521 // The chosen format has mandatory support the transfer src and dst format features when Maitenance1 is enabled. However, our
2522 // use of devsim and the mock ICD violate this guarantee.
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06002523 vk::GetPhysicalDeviceFormatProperties(m_device->phy().handle(), image_format, &format_props);
unknown088160a2019-05-23 17:43:13 -06002524 if (!(format_props.optimalTilingFeatures & VK_FORMAT_FEATURE_TRANSFER_SRC_BIT)) {
2525 printf("%s Maintenance1 extension is not supported.\n", kSkipPrefix);
2526 return;
2527 }
2528
2529 VkImageCreateInfo ci;
2530 ci.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
2531 ci.pNext = NULL;
2532 ci.flags = 0;
2533 ci.imageType = VK_IMAGE_TYPE_1D;
2534 ci.format = image_format;
2535 ci.extent = {32, 1, 1};
2536 ci.mipLevels = 1;
2537 ci.arrayLayers = 1;
2538 ci.samples = VK_SAMPLE_COUNT_1_BIT;
2539 ci.tiling = VK_IMAGE_TILING_OPTIMAL;
2540 ci.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
2541 ci.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
2542 ci.queueFamilyIndexCount = 0;
2543 ci.pQueueFamilyIndices = NULL;
2544 ci.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
2545
2546 // Create 1D image
2547 VkImageObj image_1D(m_device);
2548 image_1D.init(&ci);
2549 ASSERT_TRUE(image_1D.initialized());
2550
2551 // 2D image
2552 ci.imageType = VK_IMAGE_TYPE_2D;
2553 ci.extent = {32, 32, 1};
2554 VkImageObj image_2D(m_device);
2555 image_2D.init(&ci);
2556 ASSERT_TRUE(image_2D.initialized());
2557
2558 // 3D image
2559 ci.imageType = VK_IMAGE_TYPE_3D;
2560 ci.extent = {32, 32, 8};
2561 VkImageObj image_3D(m_device);
2562 image_3D.init(&ci);
2563 ASSERT_TRUE(image_3D.initialized());
2564
2565 // 2D image array
2566 ci.imageType = VK_IMAGE_TYPE_2D;
2567 ci.extent = {32, 32, 1};
2568 ci.arrayLayers = 8;
2569 VkImageObj image_2D_array(m_device);
2570 image_2D_array.init(&ci);
2571 ASSERT_TRUE(image_2D_array.initialized());
2572
sfricke-samsung211ee9c2020-02-13 23:38:39 -08002573 // second 2D image array
2574 ci.imageType = VK_IMAGE_TYPE_2D;
2575 ci.extent = {32, 32, 1};
2576 ci.arrayLayers = 8;
2577 VkImageObj image_2D_array_2(m_device);
2578 image_2D_array_2.init(&ci);
2579 ASSERT_TRUE(image_2D_array_2.initialized());
2580
unknown088160a2019-05-23 17:43:13 -06002581 m_commandBuffer->begin();
2582
2583 VkImageCopy copy_region;
2584 copy_region.extent = {32, 1, 1};
2585 copy_region.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
2586 copy_region.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
2587 copy_region.srcSubresource.mipLevel = 0;
2588 copy_region.dstSubresource.mipLevel = 0;
2589 copy_region.srcSubresource.baseArrayLayer = 0;
2590 copy_region.dstSubresource.baseArrayLayer = 0;
2591 copy_region.srcSubresource.layerCount = 1;
2592 copy_region.dstSubresource.layerCount = 1;
2593 copy_region.srcOffset = {0, 0, 0};
2594 copy_region.dstOffset = {0, 0, 0};
2595
2596 // Copy from layer not present
2597 copy_region.srcSubresource.baseArrayLayer = 4;
2598 copy_region.srcSubresource.layerCount = 6;
Mark Lobodzinski20310782020-02-28 14:25:17 -07002599 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdCopyImage-srcSubresource-01698");
unknown088160a2019-05-23 17:43:13 -06002600 m_commandBuffer->CopyImage(image_2D_array.image(), VK_IMAGE_LAYOUT_GENERAL, image_3D.image(), VK_IMAGE_LAYOUT_GENERAL, 1,
2601 &copy_region);
2602 m_errorMonitor->VerifyFound();
2603 copy_region.srcSubresource.baseArrayLayer = 0;
2604 copy_region.srcSubresource.layerCount = 1;
2605
2606 // Copy to layer not present
2607 copy_region.dstSubresource.baseArrayLayer = 1;
2608 copy_region.dstSubresource.layerCount = 8;
Mark Lobodzinski20310782020-02-28 14:25:17 -07002609 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdCopyImage-dstSubresource-01699");
unknown088160a2019-05-23 17:43:13 -06002610 m_commandBuffer->CopyImage(image_3D.image(), VK_IMAGE_LAYOUT_GENERAL, image_2D_array.image(), VK_IMAGE_LAYOUT_GENERAL, 1,
2611 &copy_region);
2612 m_errorMonitor->VerifyFound();
sfricke-samsung211ee9c2020-02-13 23:38:39 -08002613 copy_region.dstSubresource.baseArrayLayer = 0;
unknown088160a2019-05-23 17:43:13 -06002614 copy_region.dstSubresource.layerCount = 1;
2615
sfricke-samsung211ee9c2020-02-13 23:38:39 -08002616 // both 2D and extent.depth not 1
2617 // Need two 2D array images to prevent other errors
2618 copy_region.extent = {4, 1, 2};
Mark Lobodzinski20310782020-02-28 14:25:17 -07002619 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkImageCopy-srcImage-01790");
sfricke-samsung211ee9c2020-02-13 23:38:39 -08002620 m_commandBuffer->CopyImage(image_2D_array.image(), VK_IMAGE_LAYOUT_GENERAL, image_2D_array_2.image(), VK_IMAGE_LAYOUT_GENERAL,
2621 1, &copy_region);
2622 m_errorMonitor->VerifyFound();
2623 copy_region.extent = {32, 1, 1};
2624
2625 // 2D src / 3D dst and depth not equal to src layerCount
2626 copy_region.extent = {4, 1, 2};
Mark Lobodzinski20310782020-02-28 14:25:17 -07002627 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkImageCopy-srcImage-01791");
2628 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkImageCopy-extent-00140");
sfricke-samsung211ee9c2020-02-13 23:38:39 -08002629 m_commandBuffer->CopyImage(image_2D_array.image(), VK_IMAGE_LAYOUT_GENERAL, image_3D.image(), VK_IMAGE_LAYOUT_GENERAL, 1,
2630 &copy_region);
2631 m_errorMonitor->VerifyFound();
2632 copy_region.extent = {32, 1, 1};
2633
2634 // 3D src / 2D dst and depth not equal to dst layerCount
2635 copy_region.extent = {4, 1, 2};
Mark Lobodzinski20310782020-02-28 14:25:17 -07002636 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkImageCopy-dstImage-01792");
2637 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkImageCopy-extent-00140");
sfricke-samsung211ee9c2020-02-13 23:38:39 -08002638 m_commandBuffer->CopyImage(image_3D.image(), VK_IMAGE_LAYOUT_GENERAL, image_2D_array.image(), VK_IMAGE_LAYOUT_GENERAL, 1,
2639 &copy_region);
2640 m_errorMonitor->VerifyFound();
2641 copy_region.extent = {32, 1, 1};
2642
unknown088160a2019-05-23 17:43:13 -06002643 m_commandBuffer->end();
2644}
2645
2646TEST_F(VkLayerTest, CopyImageCompressedBlockAlignment) {
2647 // Image copy tests on compressed images with block alignment errors
2648 SetTargetApiVersion(VK_API_VERSION_1_1);
2649 ASSERT_NO_FATAL_FAILURE(Init());
2650
2651 // Select a compressed format and verify support
2652 VkPhysicalDeviceFeatures device_features = {};
2653 ASSERT_NO_FATAL_FAILURE(GetPhysicalDeviceFeatures(&device_features));
2654 VkFormat compressed_format = VK_FORMAT_UNDEFINED;
2655 if (device_features.textureCompressionBC) {
2656 compressed_format = VK_FORMAT_BC3_SRGB_BLOCK;
2657 } else if (device_features.textureCompressionETC2) {
2658 compressed_format = VK_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK;
2659 } else if (device_features.textureCompressionASTC_LDR) {
2660 compressed_format = VK_FORMAT_ASTC_4x4_UNORM_BLOCK;
2661 }
2662
2663 VkImageCreateInfo ci;
2664 ci.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
2665 ci.pNext = NULL;
2666 ci.flags = 0;
2667 ci.imageType = VK_IMAGE_TYPE_2D;
2668 ci.format = compressed_format;
2669 ci.extent = {64, 64, 1};
2670 ci.mipLevels = 1;
2671 ci.arrayLayers = 1;
2672 ci.samples = VK_SAMPLE_COUNT_1_BIT;
2673 ci.tiling = VK_IMAGE_TILING_OPTIMAL;
2674 ci.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
2675 ci.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
2676 ci.queueFamilyIndexCount = 0;
2677 ci.pQueueFamilyIndices = NULL;
2678 ci.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
2679
2680 VkImageFormatProperties img_prop = {};
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06002681 if (VK_SUCCESS != vk::GetPhysicalDeviceImageFormatProperties(m_device->phy().handle(), ci.format, ci.imageType, ci.tiling,
2682 ci.usage, ci.flags, &img_prop)) {
unknown088160a2019-05-23 17:43:13 -06002683 printf("%s No compressed formats supported - CopyImageCompressedBlockAlignment skipped.\n", kSkipPrefix);
2684 return;
2685 }
2686
2687 // Create images
2688 VkImageObj image_1(m_device);
2689 image_1.init(&ci);
2690 ASSERT_TRUE(image_1.initialized());
2691
2692 ci.extent = {62, 62, 1}; // slightly smaller and not divisible by block size
2693 VkImageObj image_2(m_device);
2694 image_2.init(&ci);
2695 ASSERT_TRUE(image_2.initialized());
2696
2697 m_commandBuffer->begin();
2698
2699 VkImageCopy copy_region;
2700 copy_region.extent = {48, 48, 1};
2701 copy_region.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
2702 copy_region.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
2703 copy_region.srcSubresource.mipLevel = 0;
2704 copy_region.dstSubresource.mipLevel = 0;
2705 copy_region.srcSubresource.baseArrayLayer = 0;
2706 copy_region.dstSubresource.baseArrayLayer = 0;
2707 copy_region.srcSubresource.layerCount = 1;
2708 copy_region.dstSubresource.layerCount = 1;
2709 copy_region.srcOffset = {0, 0, 0};
2710 copy_region.dstOffset = {0, 0, 0};
2711
2712 // Sanity check
2713 m_errorMonitor->ExpectSuccess();
2714 m_commandBuffer->CopyImage(image_1.image(), VK_IMAGE_LAYOUT_GENERAL, image_2.image(), VK_IMAGE_LAYOUT_GENERAL, 1, &copy_region);
2715 m_errorMonitor->VerifyNotFound();
2716
2717 std::string vuid;
2718 bool ycbcr = (DeviceExtensionEnabled(VK_KHR_SAMPLER_YCBCR_CONVERSION_EXTENSION_NAME) ||
2719 (DeviceValidationVersion() >= VK_API_VERSION_1_1));
2720
2721 // Src, Dest offsets must be multiples of compressed block sizes {4, 4, 1}
2722 // Image transfer granularity gets set to compressed block size, so an ITG error is also (unavoidably) triggered.
2723 vuid = ycbcr ? "VUID-VkImageCopy-srcImage-01727" : "VUID-VkImageCopy-srcOffset-00157";
2724 copy_region.srcOffset = {2, 4, 0}; // source width
Mark Lobodzinski20310782020-02-28 14:25:17 -07002725 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, vuid);
2726 m_errorMonitor->SetDesiredFailureMsg(kErrorBit,
unknown088160a2019-05-23 17:43:13 -06002727 "VUID-vkCmdCopyImage-srcOffset-01783"); // srcOffset image transfer granularity
2728 m_commandBuffer->CopyImage(image_1.image(), VK_IMAGE_LAYOUT_GENERAL, image_2.image(), VK_IMAGE_LAYOUT_GENERAL, 1, &copy_region);
2729 m_errorMonitor->VerifyFound();
2730 copy_region.srcOffset = {12, 1, 0}; // source height
Mark Lobodzinski20310782020-02-28 14:25:17 -07002731 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, vuid);
2732 m_errorMonitor->SetDesiredFailureMsg(kErrorBit,
unknown088160a2019-05-23 17:43:13 -06002733 "VUID-vkCmdCopyImage-srcOffset-01783"); // srcOffset image transfer granularity
2734 m_commandBuffer->CopyImage(image_1.image(), VK_IMAGE_LAYOUT_GENERAL, image_2.image(), VK_IMAGE_LAYOUT_GENERAL, 1, &copy_region);
2735 m_errorMonitor->VerifyFound();
2736 copy_region.srcOffset = {0, 0, 0};
2737
2738 vuid = ycbcr ? "VUID-VkImageCopy-dstImage-01731" : "VUID-VkImageCopy-dstOffset-00162";
2739 copy_region.dstOffset = {1, 0, 0}; // dest width
Mark Lobodzinski20310782020-02-28 14:25:17 -07002740 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, vuid);
2741 m_errorMonitor->SetDesiredFailureMsg(kErrorBit,
unknown088160a2019-05-23 17:43:13 -06002742 "VUID-vkCmdCopyImage-dstOffset-01784"); // dstOffset image transfer granularity
2743 m_commandBuffer->CopyImage(image_1.image(), VK_IMAGE_LAYOUT_GENERAL, image_2.image(), VK_IMAGE_LAYOUT_GENERAL, 1, &copy_region);
2744 m_errorMonitor->VerifyFound();
2745 copy_region.dstOffset = {4, 1, 0}; // dest height
Mark Lobodzinski20310782020-02-28 14:25:17 -07002746 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, vuid);
2747 m_errorMonitor->SetDesiredFailureMsg(kErrorBit,
unknown088160a2019-05-23 17:43:13 -06002748 "VUID-vkCmdCopyImage-dstOffset-01784"); // dstOffset image transfer granularity
2749 m_commandBuffer->CopyImage(image_1.image(), VK_IMAGE_LAYOUT_GENERAL, image_2.image(), VK_IMAGE_LAYOUT_GENERAL, 1, &copy_region);
2750 m_errorMonitor->VerifyFound();
2751 copy_region.dstOffset = {0, 0, 0};
2752
2753 // Copy extent must be multiples of compressed block sizes {4, 4, 1} if not full width/height
2754 vuid = ycbcr ? "VUID-VkImageCopy-srcImage-01728" : "VUID-VkImageCopy-extent-00158";
2755 copy_region.extent = {62, 60, 1}; // source width
Mark Lobodzinski20310782020-02-28 14:25:17 -07002756 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, vuid);
2757 m_errorMonitor->SetDesiredFailureMsg(kErrorBit,
unknown088160a2019-05-23 17:43:13 -06002758 "VUID-vkCmdCopyImage-srcOffset-01783"); // src extent image transfer granularity
2759 m_commandBuffer->CopyImage(image_1.image(), VK_IMAGE_LAYOUT_GENERAL, image_2.image(), VK_IMAGE_LAYOUT_GENERAL, 1, &copy_region);
2760 m_errorMonitor->VerifyFound();
2761 vuid = ycbcr ? "VUID-VkImageCopy-srcImage-01729" : "VUID-VkImageCopy-extent-00159";
2762 copy_region.extent = {60, 62, 1}; // source height
Mark Lobodzinski20310782020-02-28 14:25:17 -07002763 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, vuid);
2764 m_errorMonitor->SetDesiredFailureMsg(kErrorBit,
unknown088160a2019-05-23 17:43:13 -06002765 "VUID-vkCmdCopyImage-srcOffset-01783"); // src extent image transfer granularity
2766 m_commandBuffer->CopyImage(image_1.image(), VK_IMAGE_LAYOUT_GENERAL, image_2.image(), VK_IMAGE_LAYOUT_GENERAL, 1, &copy_region);
2767 m_errorMonitor->VerifyFound();
2768
2769 vuid = ycbcr ? "VUID-VkImageCopy-dstImage-01732" : "VUID-VkImageCopy-extent-00163";
2770 copy_region.extent = {62, 60, 1}; // dest width
Mark Lobodzinski20310782020-02-28 14:25:17 -07002771 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, vuid);
2772 m_errorMonitor->SetDesiredFailureMsg(kErrorBit,
unknown088160a2019-05-23 17:43:13 -06002773 "VUID-vkCmdCopyImage-dstOffset-01784"); // dst extent image transfer granularity
2774 m_commandBuffer->CopyImage(image_2.image(), VK_IMAGE_LAYOUT_GENERAL, image_1.image(), VK_IMAGE_LAYOUT_GENERAL, 1, &copy_region);
2775 m_errorMonitor->VerifyFound();
2776 vuid = ycbcr ? "VUID-VkImageCopy-dstImage-01733" : "VUID-VkImageCopy-extent-00164";
2777 copy_region.extent = {60, 62, 1}; // dest height
Mark Lobodzinski20310782020-02-28 14:25:17 -07002778 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, vuid);
2779 m_errorMonitor->SetDesiredFailureMsg(kErrorBit,
unknown088160a2019-05-23 17:43:13 -06002780 "VUID-vkCmdCopyImage-dstOffset-01784"); // dst extent image transfer granularity
2781 m_commandBuffer->CopyImage(image_2.image(), VK_IMAGE_LAYOUT_GENERAL, image_1.image(), VK_IMAGE_LAYOUT_GENERAL, 1, &copy_region);
2782 m_errorMonitor->VerifyFound();
2783
2784 // Note: "VUID-VkImageCopy-extent-00160", "VUID-VkImageCopy-extent-00165", "VUID-VkImageCopy-srcImage-01730",
2785 // "VUID-VkImageCopy-dstImage-01734"
2786 // There are currently no supported compressed formats with a block depth other than 1,
2787 // so impossible to create a 'not a multiple' condition for depth.
2788 m_commandBuffer->end();
2789}
2790
2791TEST_F(VkLayerTest, CopyImageSinglePlane422Alignment) {
2792 // Image copy tests on single-plane _422 formats with block alignment errors
2793
2794 // Enable KHR multiplane req'd extensions
2795 bool mp_extensions = InstanceExtensionSupported(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME,
2796 VK_KHR_GET_MEMORY_REQUIREMENTS_2_SPEC_VERSION);
2797 if (mp_extensions) {
2798 m_instance_extension_names.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
2799 }
Mark Lobodzinski09ce9c42020-03-06 10:02:44 -07002800 ASSERT_NO_FATAL_FAILURE(InitFramework(m_errorMonitor));
unknown088160a2019-05-23 17:43:13 -06002801 mp_extensions = mp_extensions && DeviceExtensionSupported(gpu(), nullptr, VK_KHR_MAINTENANCE1_EXTENSION_NAME);
2802 mp_extensions = mp_extensions && DeviceExtensionSupported(gpu(), nullptr, VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME);
2803 mp_extensions = mp_extensions && DeviceExtensionSupported(gpu(), nullptr, VK_KHR_BIND_MEMORY_2_EXTENSION_NAME);
2804 mp_extensions = mp_extensions && DeviceExtensionSupported(gpu(), nullptr, VK_KHR_SAMPLER_YCBCR_CONVERSION_EXTENSION_NAME);
2805 if (mp_extensions) {
2806 m_device_extension_names.push_back(VK_KHR_MAINTENANCE1_EXTENSION_NAME);
2807 m_device_extension_names.push_back(VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME);
2808 m_device_extension_names.push_back(VK_KHR_BIND_MEMORY_2_EXTENSION_NAME);
2809 m_device_extension_names.push_back(VK_KHR_SAMPLER_YCBCR_CONVERSION_EXTENSION_NAME);
2810 } else {
2811 printf("%s test requires KHR multiplane extensions, not available. Skipping.\n", kSkipPrefix);
2812 return;
2813 }
2814 ASSERT_NO_FATAL_FAILURE(InitState());
2815
2816 // Select a _422 format and verify support
2817 VkImageCreateInfo ci = {};
2818 ci.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
2819 ci.pNext = NULL;
2820 ci.flags = 0;
2821 ci.imageType = VK_IMAGE_TYPE_2D;
2822 ci.format = VK_FORMAT_G8B8G8R8_422_UNORM_KHR;
2823 ci.tiling = VK_IMAGE_TILING_OPTIMAL;
2824 ci.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
2825 ci.mipLevels = 1;
2826 ci.arrayLayers = 1;
2827 ci.samples = VK_SAMPLE_COUNT_1_BIT;
2828 ci.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
2829 ci.queueFamilyIndexCount = 0;
2830 ci.pQueueFamilyIndices = NULL;
2831 ci.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
2832
2833 // Verify formats
2834 VkFormatFeatureFlags features = VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT;
2835 bool supported = ImageFormatAndFeaturesSupported(instance(), gpu(), ci, features);
2836 if (!supported) {
2837 printf("%s Single-plane _422 image format not supported. Skipping test.\n", kSkipPrefix);
2838 return; // Assume there's low ROI on searching for different mp formats
2839 }
2840
2841 // Create images
2842 ci.extent = {64, 64, 1};
2843 VkImageObj image_422(m_device);
2844 image_422.init(&ci);
2845 ASSERT_TRUE(image_422.initialized());
2846
2847 ci.extent = {64, 64, 1};
2848 ci.format = VK_FORMAT_R8G8B8A8_UNORM;
2849 VkImageObj image_ucmp(m_device);
2850 image_ucmp.init(&ci);
2851 ASSERT_TRUE(image_ucmp.initialized());
2852
2853 m_commandBuffer->begin();
2854
2855 VkImageCopy copy_region;
2856 copy_region.extent = {48, 48, 1};
2857 copy_region.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
2858 copy_region.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
2859 copy_region.srcSubresource.mipLevel = 0;
2860 copy_region.dstSubresource.mipLevel = 0;
2861 copy_region.srcSubresource.baseArrayLayer = 0;
2862 copy_region.dstSubresource.baseArrayLayer = 0;
2863 copy_region.srcSubresource.layerCount = 1;
2864 copy_region.dstSubresource.layerCount = 1;
2865 copy_region.srcOffset = {0, 0, 0};
2866 copy_region.dstOffset = {0, 0, 0};
2867
2868 // Src offsets must be multiples of compressed block sizes
2869 copy_region.srcOffset = {3, 4, 0}; // source offset x
Mark Lobodzinski20310782020-02-28 14:25:17 -07002870 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkImageCopy-srcImage-01727");
2871 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdCopyImage-srcOffset-01783");
unknown088160a2019-05-23 17:43:13 -06002872 m_commandBuffer->CopyImage(image_422.image(), VK_IMAGE_LAYOUT_GENERAL, image_ucmp.image(), VK_IMAGE_LAYOUT_GENERAL, 1,
2873 &copy_region);
2874 m_errorMonitor->VerifyFound();
2875 copy_region.srcOffset = {0, 0, 0};
2876
2877 // Dst offsets must be multiples of compressed block sizes
2878 copy_region.dstOffset = {1, 0, 0};
Mark Lobodzinski20310782020-02-28 14:25:17 -07002879 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkImageCopy-dstImage-01731");
2880 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdCopyImage-dstOffset-01784");
Mark Lobodzinski20310782020-02-28 14:25:17 -07002881 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkImageCopy-dstOffset-00150");
unknown088160a2019-05-23 17:43:13 -06002882 m_commandBuffer->CopyImage(image_ucmp.image(), VK_IMAGE_LAYOUT_GENERAL, image_422.image(), VK_IMAGE_LAYOUT_GENERAL, 1,
2883 &copy_region);
2884 m_errorMonitor->VerifyFound();
2885 copy_region.dstOffset = {0, 0, 0};
2886
2887 // Copy extent must be multiples of compressed block sizes if not full width/height
2888 copy_region.extent = {31, 60, 1}; // 422 source, extent.x
Mark Lobodzinski20310782020-02-28 14:25:17 -07002889 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkImageCopy-srcImage-01728");
2890 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdCopyImage-srcOffset-01783");
unknown088160a2019-05-23 17:43:13 -06002891 m_commandBuffer->CopyImage(image_422.image(), VK_IMAGE_LAYOUT_GENERAL, image_ucmp.image(), VK_IMAGE_LAYOUT_GENERAL, 1,
2892 &copy_region);
2893 m_errorMonitor->VerifyFound();
2894
unknown357e1782019-09-25 17:57:40 -06002895 // 422 dest
unknown088160a2019-05-23 17:43:13 -06002896 m_commandBuffer->CopyImage(image_ucmp.image(), VK_IMAGE_LAYOUT_GENERAL, image_422.image(), VK_IMAGE_LAYOUT_GENERAL, 1,
2897 &copy_region);
unknown357e1782019-09-25 17:57:40 -06002898 m_errorMonitor->VerifyNotFound();
unknown088160a2019-05-23 17:43:13 -06002899 copy_region.dstOffset = {0, 0, 0};
2900
2901 m_commandBuffer->end();
2902}
2903
2904TEST_F(VkLayerTest, CopyImageMultiplaneAspectBits) {
2905 // Image copy tests on multiplane images with aspect errors
2906
2907 // Enable KHR multiplane req'd extensions
2908 bool mp_extensions = InstanceExtensionSupported(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME,
2909 VK_KHR_GET_MEMORY_REQUIREMENTS_2_SPEC_VERSION);
2910 if (mp_extensions) {
2911 m_instance_extension_names.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
2912 }
Mark Lobodzinski09ce9c42020-03-06 10:02:44 -07002913 ASSERT_NO_FATAL_FAILURE(InitFramework(m_errorMonitor));
unknown088160a2019-05-23 17:43:13 -06002914 mp_extensions = mp_extensions && DeviceExtensionSupported(gpu(), nullptr, VK_KHR_MAINTENANCE1_EXTENSION_NAME);
2915 mp_extensions = mp_extensions && DeviceExtensionSupported(gpu(), nullptr, VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME);
2916 mp_extensions = mp_extensions && DeviceExtensionSupported(gpu(), nullptr, VK_KHR_BIND_MEMORY_2_EXTENSION_NAME);
2917 mp_extensions = mp_extensions && DeviceExtensionSupported(gpu(), nullptr, VK_KHR_SAMPLER_YCBCR_CONVERSION_EXTENSION_NAME);
2918 if (mp_extensions) {
2919 m_device_extension_names.push_back(VK_KHR_MAINTENANCE1_EXTENSION_NAME);
2920 m_device_extension_names.push_back(VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME);
2921 m_device_extension_names.push_back(VK_KHR_BIND_MEMORY_2_EXTENSION_NAME);
2922 m_device_extension_names.push_back(VK_KHR_SAMPLER_YCBCR_CONVERSION_EXTENSION_NAME);
2923 } else {
2924 printf("%s test requires KHR multiplane extensions, not available. Skipping.\n", kSkipPrefix);
2925 return;
2926 }
2927 ASSERT_NO_FATAL_FAILURE(InitState());
2928
2929 // Select multi-plane formats and verify support
2930 VkFormat mp3_format = VK_FORMAT_G8_B8_R8_3PLANE_422_UNORM_KHR;
2931 VkFormat mp2_format = VK_FORMAT_G8_B8R8_2PLANE_422_UNORM_KHR;
2932
2933 VkImageCreateInfo ci = {};
2934 ci.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
2935 ci.pNext = NULL;
2936 ci.flags = 0;
2937 ci.imageType = VK_IMAGE_TYPE_2D;
2938 ci.format = mp2_format;
2939 ci.extent = {256, 256, 1};
2940 ci.tiling = VK_IMAGE_TILING_OPTIMAL;
2941 ci.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
2942 ci.mipLevels = 1;
2943 ci.arrayLayers = 1;
2944 ci.samples = VK_SAMPLE_COUNT_1_BIT;
2945 ci.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
2946 ci.queueFamilyIndexCount = 0;
2947 ci.pQueueFamilyIndices = NULL;
2948 ci.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
2949
2950 // Verify formats
2951 VkFormatFeatureFlags features = VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT;
2952 bool supported = ImageFormatAndFeaturesSupported(instance(), gpu(), ci, features);
2953 ci.format = VK_FORMAT_D24_UNORM_S8_UINT;
2954 supported = supported && ImageFormatAndFeaturesSupported(instance(), gpu(), ci, features);
2955 ci.format = mp3_format;
2956 supported = supported && ImageFormatAndFeaturesSupported(instance(), gpu(), ci, features);
2957 if (!supported) {
2958 printf("%s Multiplane image formats or optimally tiled depth-stencil buffers not supported. Skipping test.\n",
2959 kSkipPrefix);
2960 return; // Assume there's low ROI on searching for different mp formats
2961 }
2962
2963 // Create images
2964 VkImageObj mp3_image(m_device);
2965 mp3_image.init(&ci);
2966 ASSERT_TRUE(mp3_image.initialized());
2967
2968 ci.format = mp2_format;
2969 VkImageObj mp2_image(m_device);
2970 mp2_image.init(&ci);
2971 ASSERT_TRUE(mp2_image.initialized());
2972
2973 ci.format = VK_FORMAT_D24_UNORM_S8_UINT;
2974 VkImageObj sp_image(m_device);
2975 sp_image.init(&ci);
2976 ASSERT_TRUE(sp_image.initialized());
2977
2978 m_commandBuffer->begin();
2979
2980 VkImageCopy copy_region;
2981 copy_region.extent = {128, 128, 1};
2982 copy_region.srcSubresource.aspectMask = VK_IMAGE_ASPECT_PLANE_2_BIT_KHR;
2983 copy_region.dstSubresource.aspectMask = VK_IMAGE_ASPECT_PLANE_2_BIT_KHR;
2984 copy_region.srcSubresource.mipLevel = 0;
2985 copy_region.dstSubresource.mipLevel = 0;
2986 copy_region.srcSubresource.baseArrayLayer = 0;
2987 copy_region.dstSubresource.baseArrayLayer = 0;
2988 copy_region.srcSubresource.layerCount = 1;
2989 copy_region.dstSubresource.layerCount = 1;
2990 copy_region.srcOffset = {0, 0, 0};
2991 copy_region.dstOffset = {0, 0, 0};
2992
Mark Lobodzinski20310782020-02-28 14:25:17 -07002993 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkImageCopy-srcImage-01552");
unknown088160a2019-05-23 17:43:13 -06002994 m_commandBuffer->CopyImage(mp2_image.image(), VK_IMAGE_LAYOUT_GENERAL, mp3_image.image(), VK_IMAGE_LAYOUT_GENERAL, 1,
2995 &copy_region);
2996 m_errorMonitor->VerifyFound();
2997
unknown088160a2019-05-23 17:43:13 -06002998 copy_region.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
2999 copy_region.dstSubresource.aspectMask = VK_IMAGE_ASPECT_PLANE_0_BIT_KHR;
Mark Lobodzinski20310782020-02-28 14:25:17 -07003000 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkImageCopy-srcImage-01553");
unknown088160a2019-05-23 17:43:13 -06003001 m_commandBuffer->CopyImage(mp3_image.image(), VK_IMAGE_LAYOUT_GENERAL, mp2_image.image(), VK_IMAGE_LAYOUT_GENERAL, 1,
3002 &copy_region);
3003 m_errorMonitor->VerifyFound();
3004
3005 copy_region.srcSubresource.aspectMask = VK_IMAGE_ASPECT_PLANE_1_BIT_KHR;
3006 copy_region.dstSubresource.aspectMask = VK_IMAGE_ASPECT_PLANE_2_BIT_KHR;
Mark Lobodzinski20310782020-02-28 14:25:17 -07003007 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkImageCopy-dstImage-01554");
unknown088160a2019-05-23 17:43:13 -06003008 m_commandBuffer->CopyImage(mp3_image.image(), VK_IMAGE_LAYOUT_GENERAL, mp2_image.image(), VK_IMAGE_LAYOUT_GENERAL, 1,
3009 &copy_region);
3010 m_errorMonitor->VerifyFound();
3011
3012 copy_region.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
Mark Lobodzinski20310782020-02-28 14:25:17 -07003013 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkImageCopy-dstImage-01555");
unknown088160a2019-05-23 17:43:13 -06003014 m_commandBuffer->CopyImage(mp2_image.image(), VK_IMAGE_LAYOUT_GENERAL, mp3_image.image(), VK_IMAGE_LAYOUT_GENERAL, 1,
3015 &copy_region);
3016 m_errorMonitor->VerifyFound();
3017
3018 copy_region.dstSubresource.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT;
Mark Lobodzinski20310782020-02-28 14:25:17 -07003019 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkImageCopy-srcImage-01556");
sfricke-samsung99dc12c2020-04-23 01:52:01 -07003020 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdCopyImage-None-01549"); // since also non-compatiable
unknown088160a2019-05-23 17:43:13 -06003021 m_commandBuffer->CopyImage(mp2_image.image(), VK_IMAGE_LAYOUT_GENERAL, sp_image.image(), VK_IMAGE_LAYOUT_GENERAL, 1,
3022 &copy_region);
3023 m_errorMonitor->VerifyFound();
3024
3025 copy_region.srcSubresource.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT;
3026 copy_region.dstSubresource.aspectMask = VK_IMAGE_ASPECT_PLANE_2_BIT_KHR;
Mark Lobodzinski20310782020-02-28 14:25:17 -07003027 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkImageCopy-dstImage-01557");
sfricke-samsung99dc12c2020-04-23 01:52:01 -07003028 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdCopyImage-None-01549"); // since also non-compatiable
unknown088160a2019-05-23 17:43:13 -06003029 m_commandBuffer->CopyImage(sp_image.image(), VK_IMAGE_LAYOUT_GENERAL, mp3_image.image(), VK_IMAGE_LAYOUT_GENERAL, 1,
3030 &copy_region);
3031 m_errorMonitor->VerifyFound();
3032
3033 m_commandBuffer->end();
3034}
3035
3036TEST_F(VkLayerTest, CopyImageSrcSizeExceeded) {
3037 // Image copy with source region specified greater than src image size
3038 ASSERT_NO_FATAL_FAILURE(Init());
3039
3040 // Create images with full mip chain
3041 VkImageCreateInfo ci;
3042 ci.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
3043 ci.pNext = NULL;
3044 ci.flags = 0;
3045 ci.imageType = VK_IMAGE_TYPE_3D;
3046 ci.format = VK_FORMAT_R8G8B8A8_UNORM;
3047 ci.extent = {32, 32, 8};
3048 ci.mipLevels = 6;
3049 ci.arrayLayers = 1;
3050 ci.samples = VK_SAMPLE_COUNT_1_BIT;
3051 ci.tiling = VK_IMAGE_TILING_OPTIMAL;
3052 ci.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
3053 ci.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
3054 ci.queueFamilyIndexCount = 0;
3055 ci.pQueueFamilyIndices = NULL;
3056 ci.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
3057
3058 VkImageObj src_image(m_device);
3059 src_image.init(&ci);
3060 ASSERT_TRUE(src_image.initialized());
3061
3062 // Dest image with one more mip level
3063 ci.extent = {64, 64, 16};
3064 ci.mipLevels = 7;
3065 ci.usage = VK_IMAGE_USAGE_TRANSFER_DST_BIT;
3066 VkImageObj dst_image(m_device);
3067 dst_image.init(&ci);
3068 ASSERT_TRUE(dst_image.initialized());
3069
3070 m_commandBuffer->begin();
3071
3072 VkImageCopy copy_region;
3073 copy_region.extent = {32, 32, 8};
3074 copy_region.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
3075 copy_region.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
3076 copy_region.srcSubresource.mipLevel = 0;
3077 copy_region.dstSubresource.mipLevel = 0;
3078 copy_region.srcSubresource.baseArrayLayer = 0;
3079 copy_region.dstSubresource.baseArrayLayer = 0;
3080 copy_region.srcSubresource.layerCount = 1;
3081 copy_region.dstSubresource.layerCount = 1;
3082 copy_region.srcOffset = {0, 0, 0};
3083 copy_region.dstOffset = {0, 0, 0};
3084
3085 m_errorMonitor->ExpectSuccess();
3086 m_commandBuffer->CopyImage(src_image.image(), VK_IMAGE_LAYOUT_GENERAL, dst_image.image(), VK_IMAGE_LAYOUT_GENERAL, 1,
3087 &copy_region);
3088 m_errorMonitor->VerifyNotFound();
3089
3090 // Source exceeded in x-dim, VU 01202
3091 copy_region.srcOffset.x = 4;
Mark Lobodzinski20310782020-02-28 14:25:17 -07003092 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkImageCopy-srcOffset-00144");
unknown088160a2019-05-23 17:43:13 -06003093 m_commandBuffer->CopyImage(src_image.image(), VK_IMAGE_LAYOUT_GENERAL, dst_image.image(), VK_IMAGE_LAYOUT_GENERAL, 1,
3094 &copy_region);
3095 m_errorMonitor->VerifyFound();
3096
3097 // Source exceeded in y-dim, VU 01203
3098 copy_region.srcOffset.x = 0;
3099 copy_region.extent.height = 48;
Mark Lobodzinski20310782020-02-28 14:25:17 -07003100 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkImageCopy-srcOffset-00145");
unknown088160a2019-05-23 17:43:13 -06003101 m_commandBuffer->CopyImage(src_image.image(), VK_IMAGE_LAYOUT_GENERAL, dst_image.image(), VK_IMAGE_LAYOUT_GENERAL, 1,
3102 &copy_region);
3103 m_errorMonitor->VerifyFound();
3104
3105 // Source exceeded in z-dim, VU 01204
3106 copy_region.extent = {4, 4, 4};
3107 copy_region.srcSubresource.mipLevel = 2;
Mark Lobodzinski20310782020-02-28 14:25:17 -07003108 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkImageCopy-srcOffset-00147");
unknown088160a2019-05-23 17:43:13 -06003109 m_commandBuffer->CopyImage(src_image.image(), VK_IMAGE_LAYOUT_GENERAL, dst_image.image(), VK_IMAGE_LAYOUT_GENERAL, 1,
3110 &copy_region);
3111 m_errorMonitor->VerifyFound();
3112
3113 m_commandBuffer->end();
3114}
3115
3116TEST_F(VkLayerTest, CopyImageDstSizeExceeded) {
3117 // Image copy with dest region specified greater than dest image size
3118 ASSERT_NO_FATAL_FAILURE(Init());
3119
3120 // Create images with full mip chain
3121 VkImageCreateInfo ci;
3122 ci.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
3123 ci.pNext = NULL;
3124 ci.flags = 0;
3125 ci.imageType = VK_IMAGE_TYPE_3D;
3126 ci.format = VK_FORMAT_R8G8B8A8_UNORM;
3127 ci.extent = {32, 32, 8};
3128 ci.mipLevels = 6;
3129 ci.arrayLayers = 1;
3130 ci.samples = VK_SAMPLE_COUNT_1_BIT;
3131 ci.tiling = VK_IMAGE_TILING_OPTIMAL;
3132 ci.usage = VK_IMAGE_USAGE_TRANSFER_DST_BIT;
3133 ci.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
3134 ci.queueFamilyIndexCount = 0;
3135 ci.pQueueFamilyIndices = NULL;
3136 ci.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
3137
3138 VkImageObj dst_image(m_device);
3139 dst_image.init(&ci);
3140 ASSERT_TRUE(dst_image.initialized());
3141
3142 // Src image with one more mip level
3143 ci.extent = {64, 64, 16};
3144 ci.mipLevels = 7;
3145 ci.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
3146 VkImageObj src_image(m_device);
3147 src_image.init(&ci);
3148 ASSERT_TRUE(src_image.initialized());
3149
3150 m_commandBuffer->begin();
3151
3152 VkImageCopy copy_region;
3153 copy_region.extent = {32, 32, 8};
3154 copy_region.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
3155 copy_region.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
3156 copy_region.srcSubresource.mipLevel = 0;
3157 copy_region.dstSubresource.mipLevel = 0;
3158 copy_region.srcSubresource.baseArrayLayer = 0;
3159 copy_region.dstSubresource.baseArrayLayer = 0;
3160 copy_region.srcSubresource.layerCount = 1;
3161 copy_region.dstSubresource.layerCount = 1;
3162 copy_region.srcOffset = {0, 0, 0};
3163 copy_region.dstOffset = {0, 0, 0};
3164
3165 m_errorMonitor->ExpectSuccess();
3166 m_commandBuffer->CopyImage(src_image.image(), VK_IMAGE_LAYOUT_GENERAL, dst_image.image(), VK_IMAGE_LAYOUT_GENERAL, 1,
3167 &copy_region);
3168 m_errorMonitor->VerifyNotFound();
3169
3170 // Dest exceeded in x-dim, VU 01205
3171 copy_region.dstOffset.x = 4;
Mark Lobodzinski20310782020-02-28 14:25:17 -07003172 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkImageCopy-dstOffset-00150");
unknown088160a2019-05-23 17:43:13 -06003173 m_commandBuffer->CopyImage(src_image.image(), VK_IMAGE_LAYOUT_GENERAL, dst_image.image(), VK_IMAGE_LAYOUT_GENERAL, 1,
3174 &copy_region);
3175 m_errorMonitor->VerifyFound();
3176
3177 // Dest exceeded in y-dim, VU 01206
3178 copy_region.dstOffset.x = 0;
3179 copy_region.extent.height = 48;
Mark Lobodzinski20310782020-02-28 14:25:17 -07003180 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkImageCopy-dstOffset-00151");
unknown088160a2019-05-23 17:43:13 -06003181 m_commandBuffer->CopyImage(src_image.image(), VK_IMAGE_LAYOUT_GENERAL, dst_image.image(), VK_IMAGE_LAYOUT_GENERAL, 1,
3182 &copy_region);
3183 m_errorMonitor->VerifyFound();
3184
3185 // Dest exceeded in z-dim, VU 01207
3186 copy_region.extent = {4, 4, 4};
3187 copy_region.dstSubresource.mipLevel = 2;
Mark Lobodzinski20310782020-02-28 14:25:17 -07003188 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkImageCopy-dstOffset-00153");
unknown088160a2019-05-23 17:43:13 -06003189 m_commandBuffer->CopyImage(src_image.image(), VK_IMAGE_LAYOUT_GENERAL, dst_image.image(), VK_IMAGE_LAYOUT_GENERAL, 1,
3190 &copy_region);
3191 m_errorMonitor->VerifyFound();
3192
3193 m_commandBuffer->end();
3194}
3195
sfricke-samsung8ceaaea2020-03-07 14:08:08 -08003196TEST_F(VkLayerTest, CopyImageMultiPlaneSizeExceeded) {
3197 TEST_DESCRIPTION("Image Copy for multi-planar format that exceed size of plane for both src and dst");
3198
3199 // Enable KHR multiplane req'd extensions
3200 bool mp_extensions = InstanceExtensionSupported(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME,
3201 VK_KHR_GET_MEMORY_REQUIREMENTS_2_SPEC_VERSION);
3202 if (mp_extensions == true) {
3203 m_instance_extension_names.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
3204 }
3205 ASSERT_NO_FATAL_FAILURE(InitFramework(m_errorMonitor));
3206 mp_extensions = mp_extensions && DeviceExtensionSupported(gpu(), nullptr, VK_KHR_MAINTENANCE1_EXTENSION_NAME);
3207 mp_extensions = mp_extensions && DeviceExtensionSupported(gpu(), nullptr, VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME);
3208 mp_extensions = mp_extensions && DeviceExtensionSupported(gpu(), nullptr, VK_KHR_BIND_MEMORY_2_EXTENSION_NAME);
3209 mp_extensions = mp_extensions && DeviceExtensionSupported(gpu(), nullptr, VK_KHR_SAMPLER_YCBCR_CONVERSION_EXTENSION_NAME);
3210 if (mp_extensions == true) {
3211 m_device_extension_names.push_back(VK_KHR_MAINTENANCE1_EXTENSION_NAME);
3212 m_device_extension_names.push_back(VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME);
3213 m_device_extension_names.push_back(VK_KHR_BIND_MEMORY_2_EXTENSION_NAME);
3214 m_device_extension_names.push_back(VK_KHR_SAMPLER_YCBCR_CONVERSION_EXTENSION_NAME);
3215 } else {
3216 printf("%s test requires KHR multiplane extensions, not available. Skipping.\n", kSkipPrefix);
3217 return;
3218 }
3219 ASSERT_NO_FATAL_FAILURE(InitState());
3220
sfricke-samsung99dc12c2020-04-23 01:52:01 -07003221 // Try to use VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM because need multi-plane format for some tests and likely supported due to
3222 // copy support being required with samplerYcbcrConversion feature
sfricke-samsung8ceaaea2020-03-07 14:08:08 -08003223 VkFormatProperties props = {0, 0, 0};
3224 bool missing_format_support = false;
sfricke-samsung99dc12c2020-04-23 01:52:01 -07003225 vk::GetPhysicalDeviceFormatProperties(m_device->phy().handle(), VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM, &props);
sfricke-samsung8ceaaea2020-03-07 14:08:08 -08003226 missing_format_support |= (props.bufferFeatures == 0 && props.linearTilingFeatures == 0 && props.optimalTilingFeatures == 0);
3227 missing_format_support |= (props.optimalTilingFeatures & VK_FORMAT_FEATURE_TRANSFER_SRC_BIT) == 0;
3228 missing_format_support |= (props.optimalTilingFeatures & VK_FORMAT_FEATURE_TRANSFER_DST_BIT) == 0;
3229
3230 if (missing_format_support == true) {
sfricke-samsung99dc12c2020-04-23 01:52:01 -07003231 printf("%s VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM transfer not supported; skipped.\n", kSkipPrefix);
sfricke-samsung8ceaaea2020-03-07 14:08:08 -08003232 return;
3233 }
3234
3235 // 128^2 texels in plane_0 and 64^2 texels in plane_1
3236 VkImageObj src_image(m_device);
3237 VkImageObj dst_image(m_device);
sfricke-samsung99dc12c2020-04-23 01:52:01 -07003238 src_image.Init(128, 128, 1, VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM, VK_IMAGE_USAGE_TRANSFER_SRC_BIT, VK_IMAGE_TILING_OPTIMAL, 0);
sfricke-samsung8ceaaea2020-03-07 14:08:08 -08003239 ASSERT_TRUE(src_image.initialized());
sfricke-samsung99dc12c2020-04-23 01:52:01 -07003240 dst_image.Init(128, 128, 1, VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM, VK_IMAGE_USAGE_TRANSFER_DST_BIT, VK_IMAGE_TILING_OPTIMAL, 0);
sfricke-samsung8ceaaea2020-03-07 14:08:08 -08003241 ASSERT_TRUE(dst_image.initialized());
3242
3243 VkImageCopy copy_region = {};
3244 copy_region.extent = {64, 64, 1}; // Size of plane 1
3245 copy_region.srcSubresource.aspectMask = VK_IMAGE_ASPECT_PLANE_1_BIT;
3246 copy_region.dstSubresource.aspectMask = VK_IMAGE_ASPECT_PLANE_1_BIT;
3247 copy_region.srcSubresource.mipLevel = 0;
3248 copy_region.dstSubresource.mipLevel = 0;
3249 copy_region.srcSubresource.baseArrayLayer = 0;
3250 copy_region.dstSubresource.baseArrayLayer = 0;
3251 copy_region.srcSubresource.layerCount = 1;
3252 copy_region.dstSubresource.layerCount = 1;
3253 copy_region.srcOffset = {0, 0, 0};
3254 copy_region.dstOffset = {0, 0, 0};
3255 VkImageCopy original_region = copy_region;
3256
3257 m_commandBuffer->begin();
3258
3259 // Should be able to do a 64x64 copy from plane 1 -> Plane 1
3260 m_errorMonitor->ExpectSuccess();
3261 m_commandBuffer->CopyImage(src_image.image(), VK_IMAGE_LAYOUT_GENERAL, dst_image.image(), VK_IMAGE_LAYOUT_GENERAL, 1,
3262 &copy_region);
3263 m_errorMonitor->VerifyNotFound();
3264
3265 // Should be able to do a 64x64 copy from plane 0 -> Plane 0
3266 copy_region.srcSubresource.aspectMask = VK_IMAGE_ASPECT_PLANE_0_BIT;
3267 copy_region.dstSubresource.aspectMask = VK_IMAGE_ASPECT_PLANE_0_BIT;
3268 m_errorMonitor->ExpectSuccess();
3269 m_commandBuffer->CopyImage(src_image.image(), VK_IMAGE_LAYOUT_GENERAL, dst_image.image(), VK_IMAGE_LAYOUT_GENERAL, 1,
3270 &copy_region);
3271 m_errorMonitor->VerifyNotFound();
3272
locke-lunargdf00db02020-03-04 19:00:57 -07003273 VkMemoryBarrier mem_barrier = lvl_init_struct<VkMemoryBarrier>();
3274 mem_barrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
3275 mem_barrier.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
3276
sfricke-samsung8ceaaea2020-03-07 14:08:08 -08003277 // Should be able to do a 64x64 copy from plane 0 -> Plane 1
3278 copy_region.srcSubresource.aspectMask = VK_IMAGE_ASPECT_PLANE_0_BIT;
3279 copy_region.dstSubresource.aspectMask = VK_IMAGE_ASPECT_PLANE_1_BIT;
3280 m_errorMonitor->ExpectSuccess();
locke-lunargdf00db02020-03-04 19:00:57 -07003281 vk::CmdPipelineBarrier(m_commandBuffer->handle(), VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, 1,
3282 &mem_barrier, 0, nullptr, 0, nullptr);
sfricke-samsung8ceaaea2020-03-07 14:08:08 -08003283 m_commandBuffer->CopyImage(src_image.image(), VK_IMAGE_LAYOUT_GENERAL, dst_image.image(), VK_IMAGE_LAYOUT_GENERAL, 1,
3284 &copy_region);
3285 m_errorMonitor->VerifyNotFound();
3286
3287 // Should be able to do a 64x64 copy from plane 0 -> Plane 1
3288 copy_region.srcSubresource.aspectMask = VK_IMAGE_ASPECT_PLANE_1_BIT;
3289 copy_region.dstSubresource.aspectMask = VK_IMAGE_ASPECT_PLANE_0_BIT;
3290 m_errorMonitor->ExpectSuccess();
locke-lunargdf00db02020-03-04 19:00:57 -07003291 vk::CmdPipelineBarrier(m_commandBuffer->handle(), VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, 1,
3292 &mem_barrier, 0, nullptr, 0, nullptr);
sfricke-samsung8ceaaea2020-03-07 14:08:08 -08003293 m_commandBuffer->CopyImage(src_image.image(), VK_IMAGE_LAYOUT_GENERAL, dst_image.image(), VK_IMAGE_LAYOUT_GENERAL, 1,
3294 &copy_region);
3295 m_errorMonitor->VerifyNotFound();
3296
3297 // Should be able to do a 128x64 copy from plane 0 -> Plane 0
3298 copy_region.extent = {128, 64, 1};
3299 copy_region.srcSubresource.aspectMask = VK_IMAGE_ASPECT_PLANE_0_BIT;
3300 copy_region.dstSubresource.aspectMask = VK_IMAGE_ASPECT_PLANE_0_BIT;
3301 m_errorMonitor->ExpectSuccess();
locke-lunargdf00db02020-03-04 19:00:57 -07003302 vk::CmdPipelineBarrier(m_commandBuffer->handle(), VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, 1,
3303 &mem_barrier, 0, nullptr, 0, nullptr);
sfricke-samsung8ceaaea2020-03-07 14:08:08 -08003304 m_commandBuffer->CopyImage(src_image.image(), VK_IMAGE_LAYOUT_GENERAL, dst_image.image(), VK_IMAGE_LAYOUT_GENERAL, 1,
3305 &copy_region);
3306 m_errorMonitor->VerifyNotFound();
3307
3308 // 128x64 copy from plane 0 -> Plane 1
3309 copy_region.extent = {128, 64, 1};
3310 copy_region.srcSubresource.aspectMask = VK_IMAGE_ASPECT_PLANE_0_BIT;
3311 copy_region.dstSubresource.aspectMask = VK_IMAGE_ASPECT_PLANE_1_BIT;
sfricke-samsung8ceaaea2020-03-07 14:08:08 -08003312 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkImageCopy-dstOffset-00150");
3313 m_commandBuffer->CopyImage(src_image.image(), VK_IMAGE_LAYOUT_GENERAL, dst_image.image(), VK_IMAGE_LAYOUT_GENERAL, 1,
3314 &copy_region);
3315 m_errorMonitor->VerifyFound();
3316
3317 // 128x64 copy from plane 1 -> Plane 0
3318 copy_region.extent = {128, 64, 1};
3319 copy_region.srcSubresource.aspectMask = VK_IMAGE_ASPECT_PLANE_1_BIT;
3320 copy_region.dstSubresource.aspectMask = VK_IMAGE_ASPECT_PLANE_0_BIT;
sfricke-samsung8ceaaea2020-03-07 14:08:08 -08003321 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkImageCopy-srcOffset-00144");
3322 m_commandBuffer->CopyImage(src_image.image(), VK_IMAGE_LAYOUT_GENERAL, dst_image.image(), VK_IMAGE_LAYOUT_GENERAL, 1,
3323 &copy_region);
3324 m_errorMonitor->VerifyFound();
3325
3326 // src exceeded in y-dim from offset
3327 copy_region = original_region;
3328 copy_region.srcOffset.y = 4;
sfricke-samsung8ceaaea2020-03-07 14:08:08 -08003329 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkImageCopy-srcOffset-00145");
3330 m_commandBuffer->CopyImage(src_image.image(), VK_IMAGE_LAYOUT_GENERAL, dst_image.image(), VK_IMAGE_LAYOUT_GENERAL, 1,
3331 &copy_region);
3332 m_errorMonitor->VerifyFound();
3333
3334 // dst exceeded in y-dim from offset
3335 copy_region = original_region;
3336 copy_region.dstOffset.y = 4;
sfricke-samsung8ceaaea2020-03-07 14:08:08 -08003337 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkImageCopy-dstOffset-00151");
3338 m_commandBuffer->CopyImage(src_image.image(), VK_IMAGE_LAYOUT_GENERAL, dst_image.image(), VK_IMAGE_LAYOUT_GENERAL, 1,
3339 &copy_region);
3340 m_errorMonitor->VerifyFound();
3341
3342 m_commandBuffer->end();
3343}
3344
unknown088160a2019-05-23 17:43:13 -06003345TEST_F(VkLayerTest, CopyImageFormatSizeMismatch) {
sfricke-samsung51067b22020-04-30 21:41:17 -07003346 if (!EnableDeviceProfileLayer()) {
3347 printf("%s Failed to enable device profile layer.\n", kSkipPrefix);
3348 return;
3349 }
unknown088160a2019-05-23 17:43:13 -06003350
sfricke-samsung8ceaaea2020-03-07 14:08:08 -08003351 // Enable KHR multiplane req'd extensions
3352 bool mp_extensions = InstanceExtensionSupported(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME,
3353 VK_KHR_GET_MEMORY_REQUIREMENTS_2_SPEC_VERSION);
3354 if (mp_extensions == true) {
3355 m_instance_extension_names.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
3356 }
3357 ASSERT_NO_FATAL_FAILURE(InitFramework(m_errorMonitor));
3358 mp_extensions = mp_extensions && DeviceExtensionSupported(gpu(), nullptr, VK_KHR_MAINTENANCE1_EXTENSION_NAME);
3359 mp_extensions = mp_extensions && DeviceExtensionSupported(gpu(), nullptr, VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME);
3360 mp_extensions = mp_extensions && DeviceExtensionSupported(gpu(), nullptr, VK_KHR_BIND_MEMORY_2_EXTENSION_NAME);
3361 mp_extensions = mp_extensions && DeviceExtensionSupported(gpu(), nullptr, VK_KHR_SAMPLER_YCBCR_CONVERSION_EXTENSION_NAME);
3362 if (mp_extensions == true) {
3363 m_device_extension_names.push_back(VK_KHR_MAINTENANCE1_EXTENSION_NAME);
3364 m_device_extension_names.push_back(VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME);
3365 m_device_extension_names.push_back(VK_KHR_BIND_MEMORY_2_EXTENSION_NAME);
3366 m_device_extension_names.push_back(VK_KHR_SAMPLER_YCBCR_CONVERSION_EXTENSION_NAME);
3367 }
3368 ASSERT_NO_FATAL_FAILURE(InitState());
unknown088160a2019-05-23 17:43:13 -06003369
sfricke-samsung51067b22020-04-30 21:41:17 -07003370 PFN_vkSetPhysicalDeviceFormatPropertiesEXT fpvkSetPhysicalDeviceFormatPropertiesEXT = nullptr;
3371 PFN_vkGetOriginalPhysicalDeviceFormatPropertiesEXT fpvkGetOriginalPhysicalDeviceFormatPropertiesEXT = nullptr;
sfricke-samsungdce5f692020-03-07 13:59:31 -08003372
sfricke-samsung51067b22020-04-30 21:41:17 -07003373 // Load required functions
3374 if (!LoadDeviceProfileLayer(fpvkSetPhysicalDeviceFormatPropertiesEXT, fpvkGetOriginalPhysicalDeviceFormatPropertiesEXT)) {
3375 printf("%s Failed to device profile layer.\n", kSkipPrefix);
3376 return;
3377 }
3378
3379 // Set transfer for all potential used formats
3380 VkFormatProperties format_props;
3381 fpvkGetOriginalPhysicalDeviceFormatPropertiesEXT(gpu(), VK_FORMAT_R8_UNORM, &format_props);
3382 format_props.optimalTilingFeatures |= (VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT);
3383 fpvkSetPhysicalDeviceFormatPropertiesEXT(gpu(), VK_FORMAT_R8_UNORM, format_props);
3384
3385 fpvkGetOriginalPhysicalDeviceFormatPropertiesEXT(gpu(), VK_FORMAT_R8_UINT, &format_props);
3386 format_props.optimalTilingFeatures |= (VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT);
3387 fpvkSetPhysicalDeviceFormatPropertiesEXT(gpu(), VK_FORMAT_R8_UINT, format_props);
unknown088160a2019-05-23 17:43:13 -06003388
3389 VkImageCreateInfo image_create_info = {};
3390 image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
3391 image_create_info.pNext = NULL;
3392 image_create_info.imageType = VK_IMAGE_TYPE_2D;
unknown088160a2019-05-23 17:43:13 -06003393 image_create_info.extent.width = 32;
3394 image_create_info.extent.height = 32;
3395 image_create_info.extent.depth = 1;
3396 image_create_info.mipLevels = 1;
3397 image_create_info.arrayLayers = 1;
3398 image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
sfricke-samsung51067b22020-04-30 21:41:17 -07003399 image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL;
3400 image_create_info.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
unknown088160a2019-05-23 17:43:13 -06003401 image_create_info.flags = 0;
3402
sfricke-samsung51067b22020-04-30 21:41:17 -07003403 image_create_info.format = VK_FORMAT_R8_UNORM;
3404 VkImageObj image_8b_unorm(m_device);
3405 image_8b_unorm.init(&image_create_info);
unknown088160a2019-05-23 17:43:13 -06003406
sfricke-samsung51067b22020-04-30 21:41:17 -07003407 image_create_info.format = VK_FORMAT_R8_UINT;
3408 VkImageObj image_8b_uint(m_device);
3409 image_8b_uint.init(&image_create_info);
3410
3411 // First try to test two single plane mismatch
3412 {
3413 fpvkGetOriginalPhysicalDeviceFormatPropertiesEXT(gpu(), VK_FORMAT_R8G8B8A8_UNORM, &format_props);
3414 format_props.optimalTilingFeatures |= (VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT);
3415 fpvkSetPhysicalDeviceFormatPropertiesEXT(gpu(), VK_FORMAT_R8G8B8A8_UNORM, format_props);
3416
3417 image_create_info.format = VK_FORMAT_R8G8B8A8_UNORM;
3418 VkImageObj image_32b_unorm(m_device);
3419 image_32b_unorm.init(&image_create_info);
3420
3421 m_commandBuffer->begin();
3422 VkImageCopy copyRegion;
3423 copyRegion.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
3424 copyRegion.srcSubresource.mipLevel = 0;
3425 copyRegion.srcSubresource.baseArrayLayer = 0;
3426 copyRegion.srcSubresource.layerCount = 1;
3427 copyRegion.srcOffset.x = 0;
3428 copyRegion.srcOffset.y = 0;
3429 copyRegion.srcOffset.z = 0;
3430 copyRegion.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
3431 copyRegion.dstSubresource.mipLevel = 0;
3432 copyRegion.dstSubresource.baseArrayLayer = 0;
3433 copyRegion.dstSubresource.layerCount = 1;
3434 copyRegion.dstOffset.x = 0;
3435 copyRegion.dstOffset.y = 0;
3436 copyRegion.dstOffset.z = 0;
3437 copyRegion.extent.width = 1;
3438 copyRegion.extent.height = 1;
3439 copyRegion.extent.depth = 1;
3440
3441 // Sanity check between two 8bit formats
3442 m_errorMonitor->ExpectSuccess();
3443 m_commandBuffer->CopyImage(image_8b_unorm.handle(), VK_IMAGE_LAYOUT_GENERAL, image_8b_uint.handle(),
3444 VK_IMAGE_LAYOUT_GENERAL, 1, &copyRegion);
3445 m_errorMonitor->VerifyNotFound();
3446
3447 const char *vuid = (mp_extensions) ? "VUID-vkCmdCopyImage-srcImage-01548" : "VUID-vkCmdCopyImage-srcImage-00135";
3448 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, vuid);
3449 m_commandBuffer->CopyImage(image_8b_unorm.handle(), VK_IMAGE_LAYOUT_GENERAL, image_32b_unorm.handle(),
3450 VK_IMAGE_LAYOUT_GENERAL, 1, &copyRegion);
3451 m_errorMonitor->VerifyFound();
3452
3453 // Swap src and dst
3454 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, vuid);
3455 m_commandBuffer->CopyImage(image_32b_unorm.handle(), VK_IMAGE_LAYOUT_GENERAL, image_8b_unorm.handle(),
3456 VK_IMAGE_LAYOUT_GENERAL, 1, &copyRegion);
3457 m_errorMonitor->VerifyFound();
3458
3459 m_commandBuffer->end();
unknown088160a2019-05-23 17:43:13 -06003460 }
3461
sfricke-samsung51067b22020-04-30 21:41:17 -07003462 // DstImage is a mismatched plane of a multi-planar format
3463 if (mp_extensions == false) {
3464 printf("%s No multi-planar support; section of tests skipped.\n", kSkipPrefix);
3465 } else {
3466 fpvkGetOriginalPhysicalDeviceFormatPropertiesEXT(gpu(), VK_FORMAT_G8_B8R8_2PLANE_420_UNORM, &format_props);
3467 format_props.optimalTilingFeatures |= (VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT);
3468 fpvkSetPhysicalDeviceFormatPropertiesEXT(gpu(), VK_FORMAT_G8_B8R8_2PLANE_420_UNORM, format_props);
unknown088160a2019-05-23 17:43:13 -06003469
sfricke-samsung51067b22020-04-30 21:41:17 -07003470 image_create_info.format = VK_FORMAT_G8_B8R8_2PLANE_420_UNORM;
3471 VkImageObj image_8b_16b_420_unorm(m_device);
3472 image_8b_16b_420_unorm.init(&image_create_info);
unknown088160a2019-05-23 17:43:13 -06003473
sfricke-samsung51067b22020-04-30 21:41:17 -07003474 m_commandBuffer->begin();
3475 VkImageCopy copyRegion;
3476 copyRegion.srcSubresource.mipLevel = 0;
3477 copyRegion.srcSubresource.baseArrayLayer = 0;
3478 copyRegion.srcSubresource.layerCount = 1;
3479 copyRegion.srcOffset.x = 0;
3480 copyRegion.srcOffset.y = 0;
3481 copyRegion.srcOffset.z = 0;
3482 copyRegion.dstSubresource.mipLevel = 0;
3483 copyRegion.dstSubresource.baseArrayLayer = 0;
3484 copyRegion.dstSubresource.layerCount = 1;
3485 copyRegion.dstOffset.x = 0;
3486 copyRegion.dstOffset.y = 0;
3487 copyRegion.dstOffset.z = 0;
3488 copyRegion.extent.width = 1;
3489 copyRegion.extent.height = 1;
3490 copyRegion.extent.depth = 1;
unknown088160a2019-05-23 17:43:13 -06003491
sfricke-samsung51067b22020-04-30 21:41:17 -07003492 // First test single-plane -> multi-plan
3493 copyRegion.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
3494 copyRegion.dstSubresource.aspectMask = VK_IMAGE_ASPECT_PLANE_0_BIT;
unknown088160a2019-05-23 17:43:13 -06003495
sfricke-samsung51067b22020-04-30 21:41:17 -07003496 // Plane 0 is VK_FORMAT_R8_UNORM so this should succeed
3497 m_errorMonitor->ExpectSuccess();
3498 m_commandBuffer->CopyImage(image_8b_unorm.handle(), VK_IMAGE_LAYOUT_GENERAL, image_8b_16b_420_unorm.handle(),
3499 VK_IMAGE_LAYOUT_GENERAL, 1, &copyRegion);
3500 m_errorMonitor->VerifyNotFound();
unknown088160a2019-05-23 17:43:13 -06003501
locke-lunargdf00db02020-03-04 19:00:57 -07003502 image_8b_16b_420_unorm.ImageMemoryBarrier(m_commandBuffer, VK_IMAGE_ASPECT_PLANE_0_BIT, VK_ACCESS_TRANSFER_WRITE_BIT,
3503 VK_ACCESS_TRANSFER_WRITE_BIT, VK_IMAGE_LAYOUT_GENERAL);
3504
sfricke-samsung51067b22020-04-30 21:41:17 -07003505 // Make sure no false postiives if Compatible format
3506 m_errorMonitor->ExpectSuccess();
3507 m_commandBuffer->CopyImage(image_8b_uint.handle(), VK_IMAGE_LAYOUT_GENERAL, image_8b_16b_420_unorm.handle(),
3508 VK_IMAGE_LAYOUT_GENERAL, 1, &copyRegion);
3509 m_errorMonitor->VerifyNotFound();
unknown088160a2019-05-23 17:43:13 -06003510
sfricke-samsung51067b22020-04-30 21:41:17 -07003511 // Plane 1 is VK_FORMAT_R8G8_UNORM so this should fail
3512 copyRegion.dstSubresource.aspectMask = VK_IMAGE_ASPECT_PLANE_1_BIT;
3513 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdCopyImage-None-01549");
3514 m_commandBuffer->CopyImage(image_8b_unorm.handle(), VK_IMAGE_LAYOUT_GENERAL, image_8b_16b_420_unorm.handle(),
3515 VK_IMAGE_LAYOUT_GENERAL, 1, &copyRegion);
3516 m_errorMonitor->VerifyFound();
unknown088160a2019-05-23 17:43:13 -06003517
sfricke-samsung51067b22020-04-30 21:41:17 -07003518 // Same tests but swap src and dst
3519 copyRegion.srcSubresource.aspectMask = VK_IMAGE_ASPECT_PLANE_0_BIT;
3520 copyRegion.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
sfricke-samsungdce5f692020-03-07 13:59:31 -08003521
locke-lunargdf00db02020-03-04 19:00:57 -07003522 image_8b_unorm.ImageMemoryBarrier(m_commandBuffer, VK_IMAGE_ASPECT_COLOR_BIT, VK_ACCESS_TRANSFER_READ_BIT,
3523 VK_ACCESS_TRANSFER_WRITE_BIT, VK_IMAGE_LAYOUT_GENERAL);
3524 image_8b_16b_420_unorm.ImageMemoryBarrier(m_commandBuffer, VK_IMAGE_ASPECT_PLANE_0_BIT, VK_ACCESS_TRANSFER_WRITE_BIT,
3525 VK_ACCESS_TRANSFER_READ_BIT, VK_IMAGE_LAYOUT_GENERAL);
3526
sfricke-samsung51067b22020-04-30 21:41:17 -07003527 m_errorMonitor->ExpectSuccess();
3528 m_commandBuffer->CopyImage(image_8b_16b_420_unorm.handle(), VK_IMAGE_LAYOUT_GENERAL, image_8b_unorm.handle(),
3529 VK_IMAGE_LAYOUT_GENERAL, 1, &copyRegion);
3530 m_errorMonitor->VerifyNotFound();
3531
locke-lunargdf00db02020-03-04 19:00:57 -07003532 image_8b_16b_420_unorm.ImageMemoryBarrier(m_commandBuffer, VK_IMAGE_ASPECT_PLANE_0_BIT, VK_ACCESS_TRANSFER_WRITE_BIT,
3533 VK_ACCESS_TRANSFER_READ_BIT, VK_IMAGE_LAYOUT_GENERAL);
3534
sfricke-samsung51067b22020-04-30 21:41:17 -07003535 m_errorMonitor->ExpectSuccess();
3536 m_commandBuffer->CopyImage(image_8b_16b_420_unorm.handle(), VK_IMAGE_LAYOUT_GENERAL, image_8b_uint.handle(),
3537 VK_IMAGE_LAYOUT_GENERAL, 1, &copyRegion);
3538 m_errorMonitor->VerifyNotFound();
3539
3540 copyRegion.srcSubresource.aspectMask = VK_IMAGE_ASPECT_PLANE_1_BIT;
3541 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdCopyImage-None-01549");
3542 m_commandBuffer->CopyImage(image_8b_16b_420_unorm.handle(), VK_IMAGE_LAYOUT_GENERAL, image_8b_unorm.handle(),
3543 VK_IMAGE_LAYOUT_GENERAL, 1, &copyRegion);
3544 m_errorMonitor->VerifyFound();
3545
3546 m_commandBuffer->end();
3547 }
unknown088160a2019-05-23 17:43:13 -06003548}
3549
3550TEST_F(VkLayerTest, CopyImageDepthStencilFormatMismatch) {
3551 ASSERT_NO_FATAL_FAILURE(Init());
3552 auto depth_format = FindSupportedDepthStencilFormat(gpu());
3553 if (!depth_format) {
3554 printf("%s Couldn't depth stencil image format.\n", kSkipPrefix);
3555 return;
3556 }
3557
3558 VkFormatProperties properties;
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06003559 vk::GetPhysicalDeviceFormatProperties(m_device->phy().handle(), VK_FORMAT_D32_SFLOAT, &properties);
unknown088160a2019-05-23 17:43:13 -06003560 if (properties.optimalTilingFeatures == 0) {
3561 printf("%s Image format not supported; skipped.\n", kSkipPrefix);
3562 return;
3563 }
3564
3565 VkImageObj srcImage(m_device);
3566 srcImage.Init(32, 32, 1, VK_FORMAT_D32_SFLOAT, VK_IMAGE_USAGE_TRANSFER_SRC_BIT, VK_IMAGE_TILING_OPTIMAL);
3567 ASSERT_TRUE(srcImage.initialized());
3568 VkImageObj dstImage(m_device);
3569 dstImage.Init(32, 32, 1, depth_format, VK_IMAGE_USAGE_TRANSFER_DST_BIT, VK_IMAGE_TILING_OPTIMAL);
3570 ASSERT_TRUE(dstImage.initialized());
3571
3572 // Create two images of different types and try to copy between them
3573
3574 m_commandBuffer->begin();
3575 VkImageCopy copyRegion;
3576 copyRegion.srcSubresource.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT;
3577 copyRegion.srcSubresource.mipLevel = 0;
3578 copyRegion.srcSubresource.baseArrayLayer = 0;
3579 copyRegion.srcSubresource.layerCount = 1;
3580 copyRegion.srcOffset.x = 0;
3581 copyRegion.srcOffset.y = 0;
3582 copyRegion.srcOffset.z = 0;
3583 copyRegion.dstSubresource.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT;
3584 copyRegion.dstSubresource.mipLevel = 0;
3585 copyRegion.dstSubresource.baseArrayLayer = 0;
3586 copyRegion.dstSubresource.layerCount = 1;
3587 copyRegion.dstOffset.x = 0;
3588 copyRegion.dstOffset.y = 0;
3589 copyRegion.dstOffset.z = 0;
3590 copyRegion.extent.width = 1;
3591 copyRegion.extent.height = 1;
3592 copyRegion.extent.depth = 1;
3593
sfricke-samsung99dc12c2020-04-23 01:52:01 -07003594 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdCopyImage-srcImage-00135");
unknown088160a2019-05-23 17:43:13 -06003595 m_commandBuffer->CopyImage(srcImage.handle(), VK_IMAGE_LAYOUT_GENERAL, dstImage.handle(), VK_IMAGE_LAYOUT_GENERAL, 1,
3596 &copyRegion);
3597 m_commandBuffer->end();
3598
3599 m_errorMonitor->VerifyFound();
3600}
3601
3602TEST_F(VkLayerTest, CopyImageSampleCountMismatch) {
3603 TEST_DESCRIPTION("Image copies with sample count mis-matches");
3604
3605 ASSERT_NO_FATAL_FAILURE(Init());
3606
3607 VkImageFormatProperties image_format_properties;
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06003608 vk::GetPhysicalDeviceImageFormatProperties(gpu(), VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_TYPE_2D, VK_IMAGE_TILING_OPTIMAL,
3609 VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT, 0,
3610 &image_format_properties);
unknown088160a2019-05-23 17:43:13 -06003611
3612 if ((0 == (VK_SAMPLE_COUNT_2_BIT & image_format_properties.sampleCounts)) ||
3613 (0 == (VK_SAMPLE_COUNT_4_BIT & image_format_properties.sampleCounts))) {
3614 printf("%s Image multi-sample support not found; skipped.\n", kSkipPrefix);
3615 return;
3616 }
3617
3618 VkImageCreateInfo ci;
3619 ci.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
3620 ci.pNext = NULL;
3621 ci.flags = 0;
3622 ci.imageType = VK_IMAGE_TYPE_2D;
3623 ci.format = VK_FORMAT_R8G8B8A8_UNORM;
3624 ci.extent = {128, 128, 1};
3625 ci.mipLevels = 1;
3626 ci.arrayLayers = 1;
3627 ci.samples = VK_SAMPLE_COUNT_1_BIT;
3628 ci.tiling = VK_IMAGE_TILING_OPTIMAL;
3629 ci.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
3630 ci.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
3631 ci.queueFamilyIndexCount = 0;
3632 ci.pQueueFamilyIndices = NULL;
3633 ci.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
3634
3635 VkImageObj image1(m_device);
3636 image1.init(&ci);
3637 ASSERT_TRUE(image1.initialized());
3638
3639 ci.samples = VK_SAMPLE_COUNT_2_BIT;
3640 VkImageObj image2(m_device);
3641 image2.init(&ci);
3642 ASSERT_TRUE(image2.initialized());
3643
3644 ci.samples = VK_SAMPLE_COUNT_4_BIT;
3645 VkImageObj image4(m_device);
3646 image4.init(&ci);
3647 ASSERT_TRUE(image4.initialized());
3648
3649 m_commandBuffer->begin();
3650
3651 VkImageCopy copyRegion;
3652 copyRegion.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
3653 copyRegion.srcSubresource.mipLevel = 0;
3654 copyRegion.srcSubresource.baseArrayLayer = 0;
3655 copyRegion.srcSubresource.layerCount = 1;
3656 copyRegion.srcOffset = {0, 0, 0};
3657 copyRegion.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
3658 copyRegion.dstSubresource.mipLevel = 0;
3659 copyRegion.dstSubresource.baseArrayLayer = 0;
3660 copyRegion.dstSubresource.layerCount = 1;
3661 copyRegion.dstOffset = {0, 0, 0};
3662 copyRegion.extent = {128, 128, 1};
3663
3664 // Copy a single sample image to/from a multi-sample image
Mark Lobodzinski20310782020-02-28 14:25:17 -07003665 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdCopyImage-srcImage-00136");
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06003666 vk::CmdCopyImage(m_commandBuffer->handle(), image1.handle(), VK_IMAGE_LAYOUT_GENERAL, image4.handle(), VK_IMAGE_LAYOUT_GENERAL,
3667 1, &copyRegion);
unknown088160a2019-05-23 17:43:13 -06003668 m_errorMonitor->VerifyFound();
3669
Mark Lobodzinski20310782020-02-28 14:25:17 -07003670 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdCopyImage-srcImage-00136");
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06003671 vk::CmdCopyImage(m_commandBuffer->handle(), image2.handle(), VK_IMAGE_LAYOUT_GENERAL, image1.handle(), VK_IMAGE_LAYOUT_GENERAL,
3672 1, &copyRegion);
unknown088160a2019-05-23 17:43:13 -06003673 m_errorMonitor->VerifyFound();
3674
3675 // Copy between multi-sample images with different sample counts
Mark Lobodzinski20310782020-02-28 14:25:17 -07003676 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdCopyImage-srcImage-00136");
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06003677 vk::CmdCopyImage(m_commandBuffer->handle(), image2.handle(), VK_IMAGE_LAYOUT_GENERAL, image4.handle(), VK_IMAGE_LAYOUT_GENERAL,
3678 1, &copyRegion);
unknown088160a2019-05-23 17:43:13 -06003679 m_errorMonitor->VerifyFound();
3680
Mark Lobodzinski20310782020-02-28 14:25:17 -07003681 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdCopyImage-srcImage-00136");
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06003682 vk::CmdCopyImage(m_commandBuffer->handle(), image4.handle(), VK_IMAGE_LAYOUT_GENERAL, image2.handle(), VK_IMAGE_LAYOUT_GENERAL,
3683 1, &copyRegion);
unknown088160a2019-05-23 17:43:13 -06003684 m_errorMonitor->VerifyFound();
3685
3686 m_commandBuffer->end();
3687}
3688
3689TEST_F(VkLayerTest, CopyImageAspectMismatch) {
3690 TEST_DESCRIPTION("Image copies with aspect mask errors");
sfricke-samsung99dc12c2020-04-23 01:52:01 -07003691
3692 if (!EnableDeviceProfileLayer()) {
3693 printf("%s Failed to enable device profile layer.\n", kSkipPrefix);
3694 return;
3695 }
3696
3697 bool mp_extensions = InstanceExtensionSupported(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME, 1);
3698 if (mp_extensions) {
3699 m_instance_extension_names.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
3700 }
3701
3702 ASSERT_NO_FATAL_FAILURE(InitFramework(m_errorMonitor));
3703 mp_extensions = mp_extensions && DeviceExtensionSupported(gpu(), nullptr, VK_KHR_MAINTENANCE1_EXTENSION_NAME);
3704 mp_extensions = mp_extensions && DeviceExtensionSupported(gpu(), nullptr, VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME);
3705 mp_extensions = mp_extensions && DeviceExtensionSupported(gpu(), nullptr, VK_KHR_BIND_MEMORY_2_EXTENSION_NAME);
3706 mp_extensions = mp_extensions && DeviceExtensionSupported(gpu(), nullptr, VK_KHR_SAMPLER_YCBCR_CONVERSION_EXTENSION_NAME);
3707 if (mp_extensions) {
3708 m_device_extension_names.push_back(VK_KHR_MAINTENANCE1_EXTENSION_NAME);
3709 m_device_extension_names.push_back(VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME);
3710 m_device_extension_names.push_back(VK_KHR_BIND_MEMORY_2_EXTENSION_NAME);
3711 m_device_extension_names.push_back(VK_KHR_SAMPLER_YCBCR_CONVERSION_EXTENSION_NAME);
3712 }
3713 ASSERT_NO_FATAL_FAILURE(InitState());
3714
3715 PFN_vkSetPhysicalDeviceFormatPropertiesEXT fpvkSetPhysicalDeviceFormatPropertiesEXT = nullptr;
3716 PFN_vkGetOriginalPhysicalDeviceFormatPropertiesEXT fpvkGetOriginalPhysicalDeviceFormatPropertiesEXT = nullptr;
3717
3718 if (!LoadDeviceProfileLayer(fpvkSetPhysicalDeviceFormatPropertiesEXT, fpvkGetOriginalPhysicalDeviceFormatPropertiesEXT)) {
3719 printf("%s Required extensions are not avaiable.\n", kSkipPrefix);
3720 return;
3721 }
3722
unknown088160a2019-05-23 17:43:13 -06003723 auto ds_format = FindSupportedDepthStencilFormat(gpu());
3724 if (!ds_format) {
3725 printf("%s Couldn't find depth stencil format.\n", kSkipPrefix);
3726 return;
3727 }
3728
sfricke-samsung99dc12c2020-04-23 01:52:01 -07003729 // Add Transfer support for all used formats
3730 VkFormatProperties formatProps;
3731 fpvkGetOriginalPhysicalDeviceFormatPropertiesEXT(gpu(), VK_FORMAT_R32_SFLOAT, &formatProps);
3732 formatProps.optimalTilingFeatures |= (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT);
3733 fpvkSetPhysicalDeviceFormatPropertiesEXT(gpu(), VK_FORMAT_R32_SFLOAT, formatProps);
3734 fpvkGetOriginalPhysicalDeviceFormatPropertiesEXT(gpu(), VK_FORMAT_D32_SFLOAT, &formatProps);
3735 formatProps.optimalTilingFeatures |= (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT);
3736 fpvkSetPhysicalDeviceFormatPropertiesEXT(gpu(), VK_FORMAT_R32_SFLOAT, formatProps);
3737 fpvkGetOriginalPhysicalDeviceFormatPropertiesEXT(gpu(), ds_format, &formatProps);
3738 formatProps.optimalTilingFeatures |= (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT);
3739 fpvkSetPhysicalDeviceFormatPropertiesEXT(gpu(), ds_format, formatProps);
3740
unknown088160a2019-05-23 17:43:13 -06003741 VkImageObj color_image(m_device), ds_image(m_device), depth_image(m_device);
3742 color_image.Init(128, 128, 1, VK_FORMAT_R32_SFLOAT, VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT);
3743 depth_image.Init(128, 128, 1, VK_FORMAT_D32_SFLOAT, VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT,
3744 VK_IMAGE_TILING_OPTIMAL, 0);
3745 ds_image.Init(128, 128, 1, ds_format, VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT,
3746 VK_IMAGE_TILING_OPTIMAL, 0);
3747 ASSERT_TRUE(color_image.initialized());
3748 ASSERT_TRUE(depth_image.initialized());
3749 ASSERT_TRUE(ds_image.initialized());
3750
3751 VkImageCopy copyRegion;
3752 copyRegion.srcSubresource.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT;
3753 copyRegion.srcSubresource.mipLevel = 0;
3754 copyRegion.srcSubresource.baseArrayLayer = 0;
3755 copyRegion.srcSubresource.layerCount = 1;
3756 copyRegion.srcOffset = {0, 0, 0};
3757 copyRegion.dstSubresource.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT;
3758 copyRegion.dstSubresource.mipLevel = 0;
3759 copyRegion.dstSubresource.baseArrayLayer = 0;
3760 copyRegion.dstSubresource.layerCount = 1;
3761 copyRegion.dstOffset = {64, 0, 0};
3762 copyRegion.extent = {64, 128, 1};
3763
3764 // Submitting command before command buffer is in recording state
Mark Lobodzinski20310782020-02-28 14:25:17 -07003765 m_errorMonitor->SetDesiredFailureMsg(kErrorBit,
unknown088160a2019-05-23 17:43:13 -06003766 "You must call vkBeginCommandBuffer"); // "VUID-vkCmdCopyImage-commandBuffer-recording");
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06003767 vk::CmdCopyImage(m_commandBuffer->handle(), depth_image.handle(), VK_IMAGE_LAYOUT_GENERAL, depth_image.handle(),
3768 VK_IMAGE_LAYOUT_GENERAL, 1, &copyRegion);
unknown088160a2019-05-23 17:43:13 -06003769 m_errorMonitor->VerifyFound();
3770
3771 m_commandBuffer->begin();
3772
3773 // Src and dest aspect masks don't match
3774 copyRegion.dstSubresource.aspectMask = VK_IMAGE_ASPECT_STENCIL_BIT;
sfricke-samsung99dc12c2020-04-23 01:52:01 -07003775 const char *vuid = mp_extensions ? "VUID-VkImageCopy-srcImage-01551" : "VUID-VkImageCopy-aspectMask-00137";
Mark Lobodzinski20310782020-02-28 14:25:17 -07003776 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, vuid);
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06003777 vk::CmdCopyImage(m_commandBuffer->handle(), ds_image.handle(), VK_IMAGE_LAYOUT_GENERAL, ds_image.handle(),
3778 VK_IMAGE_LAYOUT_GENERAL, 1, &copyRegion);
unknown088160a2019-05-23 17:43:13 -06003779 m_errorMonitor->VerifyFound();
3780 copyRegion.dstSubresource.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT;
3781
3782 // Illegal combinations of aspect bits
3783 copyRegion.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT | VK_IMAGE_ASPECT_DEPTH_BIT; // color must be alone
3784 copyRegion.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
Mark Lobodzinski20310782020-02-28 14:25:17 -07003785 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkImageSubresourceLayers-aspectMask-00167");
unknown088160a2019-05-23 17:43:13 -06003786 // These aspect/format mismatches are redundant but unavoidable here
Mark Lobodzinski20310782020-02-28 14:25:17 -07003787 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkImageCopy-aspectMask-00142");
3788 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, vuid);
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06003789 vk::CmdCopyImage(m_commandBuffer->handle(), color_image.handle(), VK_IMAGE_LAYOUT_GENERAL, color_image.handle(),
3790 VK_IMAGE_LAYOUT_GENERAL, 1, &copyRegion);
unknown088160a2019-05-23 17:43:13 -06003791 m_errorMonitor->VerifyFound();
3792 // same test for dstSubresource
3793 copyRegion.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
3794 copyRegion.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT | VK_IMAGE_ASPECT_DEPTH_BIT; // color must be alone
Mark Lobodzinski20310782020-02-28 14:25:17 -07003795 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkImageSubresourceLayers-aspectMask-00167");
unknown088160a2019-05-23 17:43:13 -06003796 // These aspect/format mismatches are redundant but unavoidable here
Mark Lobodzinski20310782020-02-28 14:25:17 -07003797 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkImageCopy-aspectMask-00143");
3798 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, vuid);
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06003799 vk::CmdCopyImage(m_commandBuffer->handle(), color_image.handle(), VK_IMAGE_LAYOUT_GENERAL, color_image.handle(),
3800 VK_IMAGE_LAYOUT_GENERAL, 1, &copyRegion);
unknown088160a2019-05-23 17:43:13 -06003801 m_errorMonitor->VerifyFound();
3802
3803 // Metadata aspect is illegal
3804 copyRegion.srcSubresource.aspectMask = VK_IMAGE_ASPECT_METADATA_BIT;
3805 copyRegion.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
Mark Lobodzinski20310782020-02-28 14:25:17 -07003806 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkImageSubresourceLayers-aspectMask-00168");
unknown088160a2019-05-23 17:43:13 -06003807 // These aspect/format mismatches are redundant but unavoidable here
Mark Lobodzinski20310782020-02-28 14:25:17 -07003808 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, vuid);
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06003809 vk::CmdCopyImage(m_commandBuffer->handle(), color_image.handle(), VK_IMAGE_LAYOUT_GENERAL, color_image.handle(),
3810 VK_IMAGE_LAYOUT_GENERAL, 1, &copyRegion);
unknown088160a2019-05-23 17:43:13 -06003811 m_errorMonitor->VerifyFound();
3812 // same test for dstSubresource
3813 copyRegion.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
3814 copyRegion.dstSubresource.aspectMask = VK_IMAGE_ASPECT_METADATA_BIT;
Mark Lobodzinski20310782020-02-28 14:25:17 -07003815 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkImageSubresourceLayers-aspectMask-00168");
unknown088160a2019-05-23 17:43:13 -06003816 // These aspect/format mismatches are redundant but unavoidable here
Mark Lobodzinski20310782020-02-28 14:25:17 -07003817 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, vuid);
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06003818 vk::CmdCopyImage(m_commandBuffer->handle(), color_image.handle(), VK_IMAGE_LAYOUT_GENERAL, color_image.handle(),
3819 VK_IMAGE_LAYOUT_GENERAL, 1, &copyRegion);
unknown088160a2019-05-23 17:43:13 -06003820 m_errorMonitor->VerifyFound();
3821
3822 copyRegion.srcSubresource.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT;
3823 copyRegion.dstSubresource.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT;
sfricke-samsung99dc12c2020-04-23 01:52:01 -07003824 const char *compatible_vuid = mp_extensions ? "VUID-vkCmdCopyImage-srcImage-01548" : "VUID-vkCmdCopyImage-srcImage-00135";
unknown088160a2019-05-23 17:43:13 -06003825
3826 // Aspect mask doesn't match source image format
Mark Lobodzinski20310782020-02-28 14:25:17 -07003827 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkImageCopy-aspectMask-00142");
unknown088160a2019-05-23 17:43:13 -06003828 // Again redundant but unavoidable
sfricke-samsung99dc12c2020-04-23 01:52:01 -07003829 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, compatible_vuid);
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06003830 vk::CmdCopyImage(m_commandBuffer->handle(), color_image.handle(), VK_IMAGE_LAYOUT_GENERAL, depth_image.handle(),
3831 VK_IMAGE_LAYOUT_GENERAL, 1, &copyRegion);
unknown088160a2019-05-23 17:43:13 -06003832 m_errorMonitor->VerifyFound();
3833
3834 // Aspect mask doesn't match dest image format
3835 copyRegion.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
3836 copyRegion.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
Mark Lobodzinski20310782020-02-28 14:25:17 -07003837 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkImageCopy-aspectMask-00143");
unknown088160a2019-05-23 17:43:13 -06003838 // Again redundant but unavoidable
sfricke-samsung99dc12c2020-04-23 01:52:01 -07003839 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, compatible_vuid);
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06003840 vk::CmdCopyImage(m_commandBuffer->handle(), color_image.handle(), VK_IMAGE_LAYOUT_GENERAL, depth_image.handle(),
3841 VK_IMAGE_LAYOUT_GENERAL, 1, &copyRegion);
unknown088160a2019-05-23 17:43:13 -06003842 m_errorMonitor->VerifyFound();
3843
3844 m_commandBuffer->end();
3845}
3846
3847TEST_F(VkLayerTest, ResolveImageLowSampleCount) {
sfricke-samsungc26350e2020-05-30 12:31:31 -07003848 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdResolveImage-srcImage-00257");
unknown088160a2019-05-23 17:43:13 -06003849
3850 ASSERT_NO_FATAL_FAILURE(Init());
3851
3852 // Create two images of sample count 1 and try to Resolve between them
3853
3854 VkImageCreateInfo image_create_info = {};
3855 image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
3856 image_create_info.pNext = NULL;
3857 image_create_info.imageType = VK_IMAGE_TYPE_2D;
3858 image_create_info.format = VK_FORMAT_B8G8R8A8_UNORM;
3859 image_create_info.extent.width = 32;
3860 image_create_info.extent.height = 1;
3861 image_create_info.extent.depth = 1;
3862 image_create_info.mipLevels = 1;
3863 image_create_info.arrayLayers = 1;
3864 image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
3865 image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL;
3866 image_create_info.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
3867 image_create_info.flags = 0;
3868
3869 VkImageObj srcImage(m_device);
3870 srcImage.init(&image_create_info);
3871 ASSERT_TRUE(srcImage.initialized());
3872
3873 VkImageObj dstImage(m_device);
3874 dstImage.init(&image_create_info);
3875 ASSERT_TRUE(dstImage.initialized());
3876
3877 m_commandBuffer->begin();
3878 VkImageResolve resolveRegion;
3879 resolveRegion.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
3880 resolveRegion.srcSubresource.mipLevel = 0;
3881 resolveRegion.srcSubresource.baseArrayLayer = 0;
3882 resolveRegion.srcSubresource.layerCount = 1;
3883 resolveRegion.srcOffset.x = 0;
3884 resolveRegion.srcOffset.y = 0;
3885 resolveRegion.srcOffset.z = 0;
3886 resolveRegion.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
3887 resolveRegion.dstSubresource.mipLevel = 0;
3888 resolveRegion.dstSubresource.baseArrayLayer = 0;
3889 resolveRegion.dstSubresource.layerCount = 1;
3890 resolveRegion.dstOffset.x = 0;
3891 resolveRegion.dstOffset.y = 0;
3892 resolveRegion.dstOffset.z = 0;
3893 resolveRegion.extent.width = 1;
3894 resolveRegion.extent.height = 1;
3895 resolveRegion.extent.depth = 1;
3896 m_commandBuffer->ResolveImage(srcImage.handle(), VK_IMAGE_LAYOUT_GENERAL, dstImage.handle(), VK_IMAGE_LAYOUT_GENERAL, 1,
3897 &resolveRegion);
3898 m_commandBuffer->end();
3899
3900 m_errorMonitor->VerifyFound();
3901}
3902
3903TEST_F(VkLayerTest, ResolveImageHighSampleCount) {
sfricke-samsungc26350e2020-05-30 12:31:31 -07003904 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdResolveImage-dstImage-00259");
unknown088160a2019-05-23 17:43:13 -06003905
3906 ASSERT_NO_FATAL_FAILURE(Init());
3907
3908 // Create two images of sample count 4 and try to Resolve between them
3909
3910 VkImageCreateInfo image_create_info = {};
3911 image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
3912 image_create_info.pNext = NULL;
3913 image_create_info.imageType = VK_IMAGE_TYPE_2D;
3914 image_create_info.format = VK_FORMAT_B8G8R8A8_UNORM;
3915 image_create_info.extent.width = 32;
3916 image_create_info.extent.height = 1;
3917 image_create_info.extent.depth = 1;
3918 image_create_info.mipLevels = 1;
3919 image_create_info.arrayLayers = 1;
3920 image_create_info.samples = VK_SAMPLE_COUNT_4_BIT;
3921 image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL;
3922 // Note: Some implementations expect color attachment usage for any
3923 // multisample surface
3924 image_create_info.usage =
3925 VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
3926 image_create_info.flags = 0;
3927
3928 VkImageObj srcImage(m_device);
3929 srcImage.init(&image_create_info);
3930 ASSERT_TRUE(srcImage.initialized());
3931
3932 VkImageObj dstImage(m_device);
3933 dstImage.init(&image_create_info);
3934 ASSERT_TRUE(dstImage.initialized());
3935
3936 m_commandBuffer->begin();
3937 // Need memory barrier to VK_IMAGE_LAYOUT_GENERAL for source and dest?
3938 // VK_IMAGE_LAYOUT_UNDEFINED = 0,
3939 // VK_IMAGE_LAYOUT_GENERAL = 1,
3940 VkImageResolve resolveRegion;
3941 resolveRegion.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
3942 resolveRegion.srcSubresource.mipLevel = 0;
3943 resolveRegion.srcSubresource.baseArrayLayer = 0;
3944 resolveRegion.srcSubresource.layerCount = 1;
3945 resolveRegion.srcOffset.x = 0;
3946 resolveRegion.srcOffset.y = 0;
3947 resolveRegion.srcOffset.z = 0;
3948 resolveRegion.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
3949 resolveRegion.dstSubresource.mipLevel = 0;
3950 resolveRegion.dstSubresource.baseArrayLayer = 0;
3951 resolveRegion.dstSubresource.layerCount = 1;
3952 resolveRegion.dstOffset.x = 0;
3953 resolveRegion.dstOffset.y = 0;
3954 resolveRegion.dstOffset.z = 0;
3955 resolveRegion.extent.width = 1;
3956 resolveRegion.extent.height = 1;
3957 resolveRegion.extent.depth = 1;
3958 m_commandBuffer->ResolveImage(srcImage.handle(), VK_IMAGE_LAYOUT_GENERAL, dstImage.handle(), VK_IMAGE_LAYOUT_GENERAL, 1,
3959 &resolveRegion);
3960 m_commandBuffer->end();
3961
3962 m_errorMonitor->VerifyFound();
3963}
3964
3965TEST_F(VkLayerTest, ResolveImageFormatMismatch) {
sfricke-samsungc26350e2020-05-30 12:31:31 -07003966 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdResolveImage-srcImage-01386");
unknown088160a2019-05-23 17:43:13 -06003967
3968 ASSERT_NO_FATAL_FAILURE(Init());
3969
3970 // Create two images of different types and try to copy between them
locke-lunarg8e2c91b2019-06-11 17:53:26 -06003971 VkImageObj srcImage(m_device);
3972 VkImageObj dstImage(m_device);
unknown088160a2019-05-23 17:43:13 -06003973
3974 VkImageCreateInfo image_create_info = {};
3975 image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
3976 image_create_info.pNext = NULL;
3977 image_create_info.imageType = VK_IMAGE_TYPE_2D;
3978 image_create_info.format = VK_FORMAT_B8G8R8A8_UNORM;
3979 image_create_info.extent.width = 32;
3980 image_create_info.extent.height = 1;
3981 image_create_info.extent.depth = 1;
3982 image_create_info.mipLevels = 1;
3983 image_create_info.arrayLayers = 1;
3984 image_create_info.samples = VK_SAMPLE_COUNT_2_BIT;
3985 image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL;
3986 // Note: Some implementations expect color attachment usage for any
3987 // multisample surface
3988 image_create_info.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
3989 image_create_info.flags = 0;
locke-lunarg8e2c91b2019-06-11 17:53:26 -06003990 srcImage.init(&image_create_info);
unknown088160a2019-05-23 17:43:13 -06003991
3992 // Set format to something other than source image
3993 image_create_info.format = VK_FORMAT_R32_SFLOAT;
3994 // Note: Some implementations expect color attachment usage for any
3995 // multisample surface
3996 image_create_info.usage = VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
3997 image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
locke-lunarg8e2c91b2019-06-11 17:53:26 -06003998 dstImage.init(&image_create_info);
unknown088160a2019-05-23 17:43:13 -06003999
4000 m_commandBuffer->begin();
4001 // Need memory barrier to VK_IMAGE_LAYOUT_GENERAL for source and dest?
4002 // VK_IMAGE_LAYOUT_UNDEFINED = 0,
4003 // VK_IMAGE_LAYOUT_GENERAL = 1,
4004 VkImageResolve resolveRegion;
4005 resolveRegion.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
4006 resolveRegion.srcSubresource.mipLevel = 0;
4007 resolveRegion.srcSubresource.baseArrayLayer = 0;
4008 resolveRegion.srcSubresource.layerCount = 1;
4009 resolveRegion.srcOffset.x = 0;
4010 resolveRegion.srcOffset.y = 0;
4011 resolveRegion.srcOffset.z = 0;
4012 resolveRegion.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
4013 resolveRegion.dstSubresource.mipLevel = 0;
4014 resolveRegion.dstSubresource.baseArrayLayer = 0;
4015 resolveRegion.dstSubresource.layerCount = 1;
4016 resolveRegion.dstOffset.x = 0;
4017 resolveRegion.dstOffset.y = 0;
4018 resolveRegion.dstOffset.z = 0;
4019 resolveRegion.extent.width = 1;
4020 resolveRegion.extent.height = 1;
4021 resolveRegion.extent.depth = 1;
locke-lunarg8e2c91b2019-06-11 17:53:26 -06004022 m_commandBuffer->ResolveImage(srcImage.handle(), VK_IMAGE_LAYOUT_GENERAL, dstImage.handle(), VK_IMAGE_LAYOUT_GENERAL, 1,
4023 &resolveRegion);
unknown088160a2019-05-23 17:43:13 -06004024 m_commandBuffer->end();
4025
4026 m_errorMonitor->VerifyFound();
unknown088160a2019-05-23 17:43:13 -06004027}
4028
4029TEST_F(VkLayerTest, ResolveImageTypeMismatch) {
sfricke-samsungc26350e2020-05-30 12:31:31 -07004030 m_errorMonitor->SetDesiredFailureMsg(kWarningBit, "UNASSIGNED-CoreValidation-DrawState-MismatchedImageType");
unknown088160a2019-05-23 17:43:13 -06004031
4032 ASSERT_NO_FATAL_FAILURE(Init());
4033
4034 // Create two images of different types and try to copy between them
locke-lunarg8e2c91b2019-06-11 17:53:26 -06004035 VkImageObj srcImage(m_device);
4036 VkImageObj dstImage(m_device);
unknown088160a2019-05-23 17:43:13 -06004037
4038 VkImageCreateInfo image_create_info = {};
4039 image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
4040 image_create_info.pNext = NULL;
4041 image_create_info.imageType = VK_IMAGE_TYPE_2D;
4042 image_create_info.format = VK_FORMAT_B8G8R8A8_UNORM;
4043 image_create_info.extent.width = 32;
4044 image_create_info.extent.height = 1;
4045 image_create_info.extent.depth = 1;
4046 image_create_info.mipLevels = 1;
4047 image_create_info.arrayLayers = 1;
4048 image_create_info.samples = VK_SAMPLE_COUNT_2_BIT;
4049 image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL;
4050 // Note: Some implementations expect color attachment usage for any
4051 // multisample surface
4052 image_create_info.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
4053 image_create_info.flags = 0;
locke-lunarg8e2c91b2019-06-11 17:53:26 -06004054 srcImage.init(&image_create_info);
unknown088160a2019-05-23 17:43:13 -06004055
4056 image_create_info.imageType = VK_IMAGE_TYPE_1D;
4057 // Note: Some implementations expect color attachment usage for any
4058 // multisample surface
4059 image_create_info.usage = VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
4060 image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
locke-lunarg8e2c91b2019-06-11 17:53:26 -06004061 dstImage.init(&image_create_info);
unknown088160a2019-05-23 17:43:13 -06004062
4063 m_commandBuffer->begin();
4064 // Need memory barrier to VK_IMAGE_LAYOUT_GENERAL for source and dest?
4065 // VK_IMAGE_LAYOUT_UNDEFINED = 0,
4066 // VK_IMAGE_LAYOUT_GENERAL = 1,
4067 VkImageResolve resolveRegion;
4068 resolveRegion.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
4069 resolveRegion.srcSubresource.mipLevel = 0;
4070 resolveRegion.srcSubresource.baseArrayLayer = 0;
4071 resolveRegion.srcSubresource.layerCount = 1;
4072 resolveRegion.srcOffset.x = 0;
4073 resolveRegion.srcOffset.y = 0;
4074 resolveRegion.srcOffset.z = 0;
4075 resolveRegion.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
4076 resolveRegion.dstSubresource.mipLevel = 0;
4077 resolveRegion.dstSubresource.baseArrayLayer = 0;
4078 resolveRegion.dstSubresource.layerCount = 1;
4079 resolveRegion.dstOffset.x = 0;
4080 resolveRegion.dstOffset.y = 0;
4081 resolveRegion.dstOffset.z = 0;
4082 resolveRegion.extent.width = 1;
4083 resolveRegion.extent.height = 1;
4084 resolveRegion.extent.depth = 1;
locke-lunarg8e2c91b2019-06-11 17:53:26 -06004085 m_commandBuffer->ResolveImage(srcImage.handle(), VK_IMAGE_LAYOUT_GENERAL, dstImage.handle(), VK_IMAGE_LAYOUT_GENERAL, 1,
4086 &resolveRegion);
unknown088160a2019-05-23 17:43:13 -06004087 m_commandBuffer->end();
4088
4089 m_errorMonitor->VerifyFound();
unknown088160a2019-05-23 17:43:13 -06004090}
4091
4092TEST_F(VkLayerTest, ResolveImageLayoutMismatch) {
4093 ASSERT_NO_FATAL_FAILURE(Init());
4094
4095 // Create two images of different types and try to copy between them
4096 VkImageObj srcImage(m_device);
4097 VkImageObj dstImage(m_device);
4098
4099 VkImageCreateInfo image_create_info = {};
4100 image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
4101 image_create_info.pNext = NULL;
4102 image_create_info.imageType = VK_IMAGE_TYPE_2D;
4103 image_create_info.format = VK_FORMAT_B8G8R8A8_UNORM;
4104 image_create_info.extent.width = 32;
4105 image_create_info.extent.height = 32;
4106 image_create_info.extent.depth = 1;
4107 image_create_info.mipLevels = 1;
4108 image_create_info.arrayLayers = 1;
4109 image_create_info.samples = VK_SAMPLE_COUNT_2_BIT;
4110 image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL;
4111 image_create_info.usage =
4112 VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
4113 // Note: Some implementations expect color attachment usage for any
4114 // multisample surface
4115 image_create_info.flags = 0;
4116 srcImage.init(&image_create_info);
4117 ASSERT_TRUE(srcImage.initialized());
4118
4119 // Note: Some implementations expect color attachment usage for any
4120 // multisample surface
4121 image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
4122 dstImage.init(&image_create_info);
4123 ASSERT_TRUE(dstImage.initialized());
4124
4125 m_commandBuffer->begin();
4126 // source image must have valid contents before resolve
4127 VkClearColorValue clear_color = {{0, 0, 0, 0}};
4128 VkImageSubresourceRange subresource = {};
4129 subresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
4130 subresource.layerCount = 1;
4131 subresource.levelCount = 1;
4132 srcImage.SetLayout(m_commandBuffer, VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
4133 m_commandBuffer->ClearColorImage(srcImage.image(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &clear_color, 1, &subresource);
4134 srcImage.SetLayout(m_commandBuffer, VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL);
4135 dstImage.SetLayout(m_commandBuffer, VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
4136
4137 VkImageResolve resolveRegion;
4138 resolveRegion.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
4139 resolveRegion.srcSubresource.mipLevel = 0;
4140 resolveRegion.srcSubresource.baseArrayLayer = 0;
4141 resolveRegion.srcSubresource.layerCount = 1;
4142 resolveRegion.srcOffset.x = 0;
4143 resolveRegion.srcOffset.y = 0;
4144 resolveRegion.srcOffset.z = 0;
4145 resolveRegion.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
4146 resolveRegion.dstSubresource.mipLevel = 0;
4147 resolveRegion.dstSubresource.baseArrayLayer = 0;
4148 resolveRegion.dstSubresource.layerCount = 1;
4149 resolveRegion.dstOffset.x = 0;
4150 resolveRegion.dstOffset.y = 0;
4151 resolveRegion.dstOffset.z = 0;
4152 resolveRegion.extent.width = 1;
4153 resolveRegion.extent.height = 1;
4154 resolveRegion.extent.depth = 1;
4155 // source image layout mismatch
Mark Lobodzinski20310782020-02-28 14:25:17 -07004156 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdResolveImage-srcImageLayout-00260");
unknown088160a2019-05-23 17:43:13 -06004157 m_commandBuffer->ResolveImage(srcImage.image(), VK_IMAGE_LAYOUT_GENERAL, dstImage.image(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
4158 1, &resolveRegion);
4159 m_errorMonitor->VerifyFound();
4160 // dst image layout mismatch
Mark Lobodzinski20310782020-02-28 14:25:17 -07004161 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdResolveImage-dstImageLayout-00262");
unknown088160a2019-05-23 17:43:13 -06004162 m_commandBuffer->ResolveImage(srcImage.image(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, dstImage.image(), VK_IMAGE_LAYOUT_GENERAL,
4163 1, &resolveRegion);
4164 m_errorMonitor->VerifyFound();
4165 m_commandBuffer->end();
4166}
4167
4168TEST_F(VkLayerTest, ResolveInvalidSubresource) {
4169 ASSERT_NO_FATAL_FAILURE(Init());
4170
4171 // Create two images of different types and try to copy between them
4172 VkImageObj srcImage(m_device);
4173 VkImageObj dstImage(m_device);
4174
4175 VkImageCreateInfo image_create_info = {};
4176 image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
4177 image_create_info.pNext = NULL;
4178 image_create_info.imageType = VK_IMAGE_TYPE_2D;
4179 image_create_info.format = VK_FORMAT_B8G8R8A8_UNORM;
4180 image_create_info.extent.width = 32;
4181 image_create_info.extent.height = 32;
4182 image_create_info.extent.depth = 1;
4183 image_create_info.mipLevels = 1;
4184 image_create_info.arrayLayers = 1;
4185 image_create_info.samples = VK_SAMPLE_COUNT_2_BIT;
4186 image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL;
4187 image_create_info.usage =
4188 VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
4189 // Note: Some implementations expect color attachment usage for any
4190 // multisample surface
4191 image_create_info.flags = 0;
4192 srcImage.init(&image_create_info);
4193 ASSERT_TRUE(srcImage.initialized());
4194
4195 // Note: Some implementations expect color attachment usage for any
4196 // multisample surface
4197 image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
4198 dstImage.init(&image_create_info);
4199 ASSERT_TRUE(dstImage.initialized());
4200
4201 m_commandBuffer->begin();
4202 // source image must have valid contents before resolve
4203 VkClearColorValue clear_color = {{0, 0, 0, 0}};
4204 VkImageSubresourceRange subresource = {};
4205 subresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
4206 subresource.layerCount = 1;
4207 subresource.levelCount = 1;
4208 srcImage.SetLayout(m_commandBuffer, VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
4209 m_commandBuffer->ClearColorImage(srcImage.image(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &clear_color, 1, &subresource);
4210 srcImage.SetLayout(m_commandBuffer, VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL);
4211 dstImage.SetLayout(m_commandBuffer, VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
4212
4213 VkImageResolve resolveRegion;
4214 resolveRegion.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
4215 resolveRegion.srcSubresource.mipLevel = 0;
4216 resolveRegion.srcSubresource.baseArrayLayer = 0;
4217 resolveRegion.srcSubresource.layerCount = 1;
4218 resolveRegion.srcOffset.x = 0;
4219 resolveRegion.srcOffset.y = 0;
4220 resolveRegion.srcOffset.z = 0;
4221 resolveRegion.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
4222 resolveRegion.dstSubresource.mipLevel = 0;
4223 resolveRegion.dstSubresource.baseArrayLayer = 0;
4224 resolveRegion.dstSubresource.layerCount = 1;
4225 resolveRegion.dstOffset.x = 0;
4226 resolveRegion.dstOffset.y = 0;
4227 resolveRegion.dstOffset.z = 0;
4228 resolveRegion.extent.width = 1;
4229 resolveRegion.extent.height = 1;
4230 resolveRegion.extent.depth = 1;
4231 // invalid source mip level
4232 resolveRegion.srcSubresource.mipLevel = image_create_info.mipLevels;
Mark Lobodzinski20310782020-02-28 14:25:17 -07004233 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdResolveImage-srcSubresource-01709");
unknown088160a2019-05-23 17:43:13 -06004234 m_commandBuffer->ResolveImage(srcImage.image(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, dstImage.image(),
4235 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &resolveRegion);
4236 m_errorMonitor->VerifyFound();
4237 resolveRegion.srcSubresource.mipLevel = 0;
4238 // invalid dest mip level
4239 resolveRegion.dstSubresource.mipLevel = image_create_info.mipLevels;
Mark Lobodzinski20310782020-02-28 14:25:17 -07004240 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdResolveImage-dstSubresource-01710");
unknown088160a2019-05-23 17:43:13 -06004241 m_commandBuffer->ResolveImage(srcImage.image(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, dstImage.image(),
4242 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &resolveRegion);
4243 m_errorMonitor->VerifyFound();
4244 resolveRegion.dstSubresource.mipLevel = 0;
4245 // invalid source array layer range
4246 resolveRegion.srcSubresource.baseArrayLayer = image_create_info.arrayLayers;
Mark Lobodzinski20310782020-02-28 14:25:17 -07004247 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdResolveImage-srcSubresource-01711");
unknown088160a2019-05-23 17:43:13 -06004248 m_commandBuffer->ResolveImage(srcImage.image(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, dstImage.image(),
4249 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &resolveRegion);
4250 m_errorMonitor->VerifyFound();
4251 resolveRegion.srcSubresource.baseArrayLayer = 0;
4252 // invalid dest array layer range
4253 resolveRegion.dstSubresource.baseArrayLayer = image_create_info.arrayLayers;
Mark Lobodzinski20310782020-02-28 14:25:17 -07004254 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdResolveImage-dstSubresource-01712");
unknown088160a2019-05-23 17:43:13 -06004255 m_commandBuffer->ResolveImage(srcImage.image(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, dstImage.image(),
4256 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &resolveRegion);
4257 m_errorMonitor->VerifyFound();
4258 resolveRegion.dstSubresource.baseArrayLayer = 0;
4259
4260 m_commandBuffer->end();
4261}
4262
sfricke-samsungf78d0592020-06-11 21:34:44 -07004263TEST_F(VkLayerTest, ResolveImageImageType) {
4264 ASSERT_NO_FATAL_FAILURE(Init());
4265 // Create images of different types and try to resolve between them
4266 VkImageObj srcImage2D(m_device);
4267 VkImageObj dstImage1D(m_device);
4268 VkImageObj dstImage3D(m_device);
4269
4270 VkImageCreateInfo image_create_info = {};
4271 image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
4272 image_create_info.pNext = NULL;
4273 image_create_info.format = VK_FORMAT_R8G8B8A8_UNORM;
4274 image_create_info.extent.width = 32;
4275 image_create_info.extent.height = 1;
4276 image_create_info.extent.depth = 1;
4277 image_create_info.mipLevels = 1;
4278 image_create_info.arrayLayers = 4; // more than 1 to not trip other validation
4279 image_create_info.samples = VK_SAMPLE_COUNT_2_BIT;
4280 image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL;
4281 image_create_info.usage =
4282 VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
4283 // Note: Some implementations expect color attachment usage for any
4284 // multisample surface
4285 image_create_info.flags = 0;
4286
4287 image_create_info.imageType = VK_IMAGE_TYPE_2D;
4288 srcImage2D.init(&image_create_info);
4289 ASSERT_TRUE(srcImage2D.initialized());
4290
4291 image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
4292 image_create_info.imageType = VK_IMAGE_TYPE_1D;
4293 dstImage1D.init(&image_create_info);
4294 ASSERT_TRUE(dstImage1D.initialized());
4295
4296 image_create_info.imageType = VK_IMAGE_TYPE_3D;
4297 image_create_info.extent.height = 16;
4298 image_create_info.extent.depth = 16;
4299 image_create_info.arrayLayers = 1;
4300 dstImage3D.init(&image_create_info);
4301 ASSERT_TRUE(dstImage3D.initialized());
4302
4303 m_commandBuffer->begin();
4304
4305 VkImageResolve resolveRegion;
4306 resolveRegion.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
4307 resolveRegion.srcSubresource.mipLevel = 0;
4308 resolveRegion.srcSubresource.baseArrayLayer = 0;
4309 resolveRegion.srcSubresource.layerCount = 1;
4310 resolveRegion.srcOffset.x = 0;
4311 resolveRegion.srcOffset.y = 0;
4312 resolveRegion.srcOffset.z = 0;
4313 resolveRegion.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
4314 resolveRegion.dstSubresource.mipLevel = 0;
4315 resolveRegion.dstSubresource.baseArrayLayer = 0;
4316 resolveRegion.dstSubresource.layerCount = 1;
4317 resolveRegion.dstOffset.x = 0;
4318 resolveRegion.dstOffset.y = 0;
4319 resolveRegion.dstOffset.z = 0;
4320 resolveRegion.extent.width = 1;
4321 resolveRegion.extent.height = 1;
4322 resolveRegion.extent.depth = 1;
4323
4324 // non-zero value baseArrayLayer
4325 resolveRegion.srcSubresource.baseArrayLayer = 2;
4326 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkImageResolve-srcImage-00268");
4327 m_commandBuffer->ResolveImage(srcImage2D.image(), VK_IMAGE_LAYOUT_GENERAL, dstImage3D.image(), VK_IMAGE_LAYOUT_GENERAL, 1,
4328 &resolveRegion);
4329 m_errorMonitor->VerifyFound();
4330 resolveRegion.srcSubresource.baseArrayLayer = 0;
4331
4332 // Set height with 1D dstImage
4333 resolveRegion.extent.height = 2;
4334 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkImageResolve-dstImage-00276");
4335 m_commandBuffer->ResolveImage(srcImage2D.image(), VK_IMAGE_LAYOUT_GENERAL, dstImage1D.image(), VK_IMAGE_LAYOUT_GENERAL, 1,
4336 &resolveRegion);
4337 m_errorMonitor->VerifyFound();
4338 resolveRegion.extent.height = 1;
4339
4340 // Set depth with 1D dstImage and 2D srcImage
4341 resolveRegion.extent.depth = 2;
4342 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkImageResolve-dstImage-00278");
4343 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkImageResolve-srcImage-00273");
4344 m_commandBuffer->ResolveImage(srcImage2D.image(), VK_IMAGE_LAYOUT_GENERAL, dstImage1D.image(), VK_IMAGE_LAYOUT_GENERAL, 1,
4345 &resolveRegion);
4346 m_errorMonitor->VerifyFound();
4347 resolveRegion.extent.depth = 1;
4348
4349 m_commandBuffer->end();
4350}
4351
unknown088160a2019-05-23 17:43:13 -06004352TEST_F(VkLayerTest, ClearImageErrors) {
4353 TEST_DESCRIPTION("Call ClearColorImage w/ a depth|stencil image and ClearDepthStencilImage with a color image.");
4354
4355 ASSERT_NO_FATAL_FAILURE(Init());
4356 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
4357
4358 m_commandBuffer->begin();
4359
4360 // Color image
4361 VkClearColorValue clear_color;
4362 memset(clear_color.uint32, 0, sizeof(uint32_t) * 4);
4363 const VkFormat color_format = VK_FORMAT_B8G8R8A8_UNORM;
4364 const int32_t img_width = 32;
4365 const int32_t img_height = 32;
4366 VkImageCreateInfo image_create_info = {};
4367 image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
4368 image_create_info.pNext = NULL;
4369 image_create_info.imageType = VK_IMAGE_TYPE_2D;
4370 image_create_info.format = color_format;
4371 image_create_info.extent.width = img_width;
4372 image_create_info.extent.height = img_height;
4373 image_create_info.extent.depth = 1;
4374 image_create_info.mipLevels = 1;
4375 image_create_info.arrayLayers = 1;
4376 image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
4377 image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL;
4378
4379 image_create_info.usage = VK_IMAGE_USAGE_SAMPLED_BIT;
4380 vk_testing::Image color_image_no_transfer;
4381 color_image_no_transfer.init(*m_device, image_create_info);
4382
4383 image_create_info.usage = VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
4384 vk_testing::Image color_image;
4385 color_image.init(*m_device, image_create_info);
4386
4387 const VkImageSubresourceRange color_range = vk_testing::Image::subresource_range(image_create_info, VK_IMAGE_ASPECT_COLOR_BIT);
4388
4389 // Depth/Stencil image
4390 VkClearDepthStencilValue clear_value = {0};
4391 VkImageCreateInfo ds_image_create_info = vk_testing::Image::create_info();
4392 ds_image_create_info.imageType = VK_IMAGE_TYPE_2D;
4393 ds_image_create_info.format = VK_FORMAT_D16_UNORM;
4394 ds_image_create_info.extent.width = 64;
4395 ds_image_create_info.extent.height = 64;
4396 ds_image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL;
4397 ds_image_create_info.usage = VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
4398
4399 vk_testing::Image ds_image;
4400 ds_image.init(*m_device, ds_image_create_info);
4401
4402 const VkImageSubresourceRange ds_range = vk_testing::Image::subresource_range(ds_image_create_info, VK_IMAGE_ASPECT_DEPTH_BIT);
4403
sfricke-samsungcd924d92020-05-20 23:51:17 -07004404 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdClearColorImage-image-00007");
unknown088160a2019-05-23 17:43:13 -06004405
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06004406 vk::CmdClearColorImage(m_commandBuffer->handle(), ds_image.handle(), VK_IMAGE_LAYOUT_GENERAL, &clear_color, 1, &color_range);
unknown088160a2019-05-23 17:43:13 -06004407
4408 m_errorMonitor->VerifyFound();
4409
sfricke-samsungcd924d92020-05-20 23:51:17 -07004410 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdClearColorImage-image-00002");
unknown088160a2019-05-23 17:43:13 -06004411
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06004412 vk::CmdClearColorImage(m_commandBuffer->handle(), color_image_no_transfer.handle(), VK_IMAGE_LAYOUT_GENERAL, &clear_color, 1,
4413 &color_range);
unknown088160a2019-05-23 17:43:13 -06004414
4415 m_errorMonitor->VerifyFound();
4416
4417 // Call CmdClearDepthStencilImage with color image
sfricke-samsungcd924d92020-05-20 23:51:17 -07004418 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdClearDepthStencilImage-image-00014");
unknown088160a2019-05-23 17:43:13 -06004419
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06004420 vk::CmdClearDepthStencilImage(m_commandBuffer->handle(), color_image.handle(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
4421 &clear_value, 1, &ds_range);
unknown088160a2019-05-23 17:43:13 -06004422
4423 m_errorMonitor->VerifyFound();
4424}
4425
4426TEST_F(VkLayerTest, CommandQueueFlags) {
4427 TEST_DESCRIPTION(
4428 "Allocate a command buffer on a queue that does not support graphics and try to issue a graphics-only command");
4429
4430 ASSERT_NO_FATAL_FAILURE(Init());
4431
4432 uint32_t queueFamilyIndex = m_device->QueueFamilyWithoutCapabilities(VK_QUEUE_GRAPHICS_BIT);
4433 if (queueFamilyIndex == UINT32_MAX) {
4434 printf("%s Non-graphics queue family not found; skipped.\n", kSkipPrefix);
4435 return;
4436 } else {
4437 // Create command pool on a non-graphics queue
4438 VkCommandPoolObj command_pool(m_device, queueFamilyIndex);
4439
4440 // Setup command buffer on pool
4441 VkCommandBufferObj command_buffer(m_device, &command_pool);
4442 command_buffer.begin();
4443
4444 // Issue a graphics only command
Mark Lobodzinski20310782020-02-28 14:25:17 -07004445 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdSetViewport-commandBuffer-cmdpool");
unknown088160a2019-05-23 17:43:13 -06004446 VkViewport viewport = {0, 0, 16, 16, 0, 1};
4447 command_buffer.SetViewport(0, 1, &viewport);
4448 m_errorMonitor->VerifyFound();
4449 }
4450}
4451
4452TEST_F(VkLayerTest, ExecuteUnrecordedSecondaryCB) {
4453 TEST_DESCRIPTION("Attempt vkCmdExecuteCommands with a CB in the initial state");
4454 ASSERT_NO_FATAL_FAILURE(Init());
4455 VkCommandBufferObj secondary(m_device, m_commandPool, VK_COMMAND_BUFFER_LEVEL_SECONDARY);
4456 // never record secondary
4457
Mark Lobodzinski20310782020-02-28 14:25:17 -07004458 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdExecuteCommands-pCommandBuffers-00089");
unknown088160a2019-05-23 17:43:13 -06004459 m_commandBuffer->begin();
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06004460 vk::CmdExecuteCommands(m_commandBuffer->handle(), 1, &secondary.handle());
unknown088160a2019-05-23 17:43:13 -06004461 m_errorMonitor->VerifyFound();
4462 m_commandBuffer->end();
4463}
4464
4465TEST_F(VkLayerTest, ExecuteSecondaryCBWithLayoutMismatch) {
4466 TEST_DESCRIPTION("Attempt vkCmdExecuteCommands with a CB with incorrect initial layout.");
4467
Mark Lobodzinski09ce9c42020-03-06 10:02:44 -07004468 ASSERT_NO_FATAL_FAILURE(InitFramework(m_errorMonitor));
unknown088160a2019-05-23 17:43:13 -06004469 ASSERT_NO_FATAL_FAILURE(InitState(nullptr, nullptr, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT));
4470
4471 VkImageCreateInfo image_create_info = {};
4472 image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
4473 image_create_info.pNext = NULL;
4474 image_create_info.imageType = VK_IMAGE_TYPE_2D;
4475 image_create_info.format = VK_FORMAT_B8G8R8A8_UNORM;
4476 image_create_info.extent.width = 32;
4477 image_create_info.extent.height = 1;
4478 image_create_info.extent.depth = 1;
4479 image_create_info.mipLevels = 1;
4480 image_create_info.arrayLayers = 1;
4481 image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
4482 image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL;
4483 image_create_info.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
4484 image_create_info.flags = 0;
4485
4486 VkImageSubresource image_sub = VkImageObj::subresource(VK_IMAGE_ASPECT_COLOR_BIT, 0, 0);
4487 VkImageSubresourceRange image_sub_range = VkImageObj::subresource_range(image_sub);
4488
4489 VkImageObj image(m_device);
4490 image.init(&image_create_info);
4491 ASSERT_TRUE(image.initialized());
4492 VkImageMemoryBarrier image_barrier =
4493 image.image_memory_barrier(0, 0, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_GENERAL, image_sub_range);
4494
4495 auto pipeline = [&image_barrier](const VkCommandBufferObj &cb, VkImageLayout old_layout, VkImageLayout new_layout) {
4496 image_barrier.oldLayout = old_layout;
4497 image_barrier.newLayout = new_layout;
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06004498 vk::CmdPipelineBarrier(cb.handle(), VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, 0, nullptr,
4499 0, nullptr, 1, &image_barrier);
unknown088160a2019-05-23 17:43:13 -06004500 };
4501
4502 // Validate that mismatched use of image layout in secondary command buffer is caught at record time
4503 VkCommandBufferObj secondary(m_device, m_commandPool, VK_COMMAND_BUFFER_LEVEL_SECONDARY);
4504 secondary.begin();
4505 pipeline(secondary, VK_IMAGE_LAYOUT_GENERAL, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
4506 secondary.end();
4507
Mark Lobodzinski20310782020-02-28 14:25:17 -07004508 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "UNASSIGNED-vkCmdExecuteCommands-commandBuffer-00001");
unknown088160a2019-05-23 17:43:13 -06004509 m_commandBuffer->begin();
4510 pipeline(*m_commandBuffer, VK_IMAGE_LAYOUT_GENERAL, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL);
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06004511 vk::CmdExecuteCommands(m_commandBuffer->handle(), 1, &secondary.handle());
unknown088160a2019-05-23 17:43:13 -06004512 m_errorMonitor->VerifyFound();
4513
unknown088160a2019-05-23 17:43:13 -06004514 m_commandBuffer->reset();
4515 secondary.reset();
4516
4517 // Validate that UNDEFINED doesn't false positive on us
4518 secondary.begin();
4519 pipeline(secondary, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
4520 secondary.end();
4521 m_commandBuffer->begin();
4522 pipeline(*m_commandBuffer, VK_IMAGE_LAYOUT_GENERAL, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
4523 m_errorMonitor->ExpectSuccess();
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06004524 vk::CmdExecuteCommands(m_commandBuffer->handle(), 1, &secondary.handle());
unknown088160a2019-05-23 17:43:13 -06004525 m_errorMonitor->VerifyNotFound();
4526 m_commandBuffer->end();
4527}
4528
4529TEST_F(VkLayerTest, SetDynViewportParamTests) {
4530 TEST_DESCRIPTION("Test parameters of vkCmdSetViewport without multiViewport feature");
4531
4532 SetTargetApiVersion(VK_API_VERSION_1_1);
4533 VkPhysicalDeviceFeatures features{};
4534 ASSERT_NO_FATAL_FAILURE(Init(&features));
4535
4536 const VkViewport vp = {0.0, 0.0, 64.0, 64.0, 0.0, 1.0};
4537 const VkViewport viewports[] = {vp, vp};
4538
4539 m_commandBuffer->begin();
4540
4541 // array tests
Mark Lobodzinski20310782020-02-28 14:25:17 -07004542 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdSetViewport-firstViewport-01224");
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06004543 vk::CmdSetViewport(m_commandBuffer->handle(), 1, 1, viewports);
unknown088160a2019-05-23 17:43:13 -06004544 m_errorMonitor->VerifyFound();
4545
Mark Lobodzinski20310782020-02-28 14:25:17 -07004546 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdSetViewport-viewportCount-arraylength");
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06004547 vk::CmdSetViewport(m_commandBuffer->handle(), 0, 0, nullptr);
unknown088160a2019-05-23 17:43:13 -06004548 m_errorMonitor->VerifyFound();
4549
Mark Lobodzinski20310782020-02-28 14:25:17 -07004550 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdSetViewport-viewportCount-01225");
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06004551 vk::CmdSetViewport(m_commandBuffer->handle(), 0, 2, viewports);
unknown088160a2019-05-23 17:43:13 -06004552 m_errorMonitor->VerifyFound();
4553
Mark Lobodzinski20310782020-02-28 14:25:17 -07004554 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdSetViewport-firstViewport-01224");
4555 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdSetViewport-viewportCount-01225");
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06004556 vk::CmdSetViewport(m_commandBuffer->handle(), 1, 2, viewports);
unknown088160a2019-05-23 17:43:13 -06004557 m_errorMonitor->VerifyFound();
4558
Mark Lobodzinski20310782020-02-28 14:25:17 -07004559 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdSetViewport-pViewports-parameter");
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06004560 vk::CmdSetViewport(m_commandBuffer->handle(), 0, 1, nullptr);
unknown088160a2019-05-23 17:43:13 -06004561 m_errorMonitor->VerifyFound();
4562
4563 // core viewport tests
4564 using std::vector;
4565 struct TestCase {
4566 VkViewport vp;
4567 std::string veid;
4568 };
4569
4570 // not necessarily boundary values (unspecified cast rounding), but guaranteed to be over limit
4571 const auto one_past_max_w = NearestGreater(static_cast<float>(m_device->props.limits.maxViewportDimensions[0]));
4572 const auto one_past_max_h = NearestGreater(static_cast<float>(m_device->props.limits.maxViewportDimensions[1]));
4573
4574 const auto min_bound = m_device->props.limits.viewportBoundsRange[0];
4575 const auto max_bound = m_device->props.limits.viewportBoundsRange[1];
4576 const auto one_before_min_bounds = NearestSmaller(min_bound);
4577 const auto one_past_max_bounds = NearestGreater(max_bound);
4578
4579 const auto below_zero = NearestSmaller(0.0f);
4580 const auto past_one = NearestGreater(1.0f);
4581
4582 vector<TestCase> test_cases = {
4583 {{0.0, 0.0, 0.0, 64.0, 0.0, 1.0}, "VUID-VkViewport-width-01770"},
4584 {{0.0, 0.0, one_past_max_w, 64.0, 0.0, 1.0}, "VUID-VkViewport-width-01771"},
4585 {{0.0, 0.0, NAN, 64.0, 0.0, 1.0}, "VUID-VkViewport-width-01770"},
4586 {{0.0, 0.0, 64.0, one_past_max_h, 0.0, 1.0}, "VUID-VkViewport-height-01773"},
4587 {{one_before_min_bounds, 0.0, 64.0, 64.0, 0.0, 1.0}, "VUID-VkViewport-x-01774"},
4588 {{one_past_max_bounds, 0.0, 64.0, 64.0, 0.0, 1.0}, "VUID-VkViewport-x-01232"},
4589 {{NAN, 0.0, 64.0, 64.0, 0.0, 1.0}, "VUID-VkViewport-x-01774"},
4590 {{0.0, one_before_min_bounds, 64.0, 64.0, 0.0, 1.0}, "VUID-VkViewport-y-01775"},
4591 {{0.0, NAN, 64.0, 64.0, 0.0, 1.0}, "VUID-VkViewport-y-01775"},
4592 {{max_bound, 0.0, 1.0, 64.0, 0.0, 1.0}, "VUID-VkViewport-x-01232"},
4593 {{0.0, max_bound, 64.0, 1.0, 0.0, 1.0}, "VUID-VkViewport-y-01233"},
4594 {{0.0, 0.0, 64.0, 64.0, below_zero, 1.0}, "VUID-VkViewport-minDepth-01234"},
4595 {{0.0, 0.0, 64.0, 64.0, past_one, 1.0}, "VUID-VkViewport-minDepth-01234"},
4596 {{0.0, 0.0, 64.0, 64.0, NAN, 1.0}, "VUID-VkViewport-minDepth-01234"},
4597 {{0.0, 0.0, 64.0, 64.0, 0.0, below_zero}, "VUID-VkViewport-maxDepth-01235"},
4598 {{0.0, 0.0, 64.0, 64.0, 0.0, past_one}, "VUID-VkViewport-maxDepth-01235"},
4599 {{0.0, 0.0, 64.0, 64.0, 0.0, NAN}, "VUID-VkViewport-maxDepth-01235"},
4600 };
4601
4602 if (DeviceValidationVersion() < VK_API_VERSION_1_1) {
4603 test_cases.push_back({{0.0, 0.0, 64.0, 0.0, 0.0, 1.0}, "VUID-VkViewport-height-01772"});
4604 test_cases.push_back({{0.0, 0.0, 64.0, NAN, 0.0, 1.0}, "VUID-VkViewport-height-01772"});
4605 } else {
4606 test_cases.push_back({{0.0, 0.0, 64.0, NAN, 0.0, 1.0}, "VUID-VkViewport-height-01773"});
4607 }
4608
4609 for (const auto &test_case : test_cases) {
Mark Lobodzinski20310782020-02-28 14:25:17 -07004610 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, test_case.veid);
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06004611 vk::CmdSetViewport(m_commandBuffer->handle(), 0, 1, &test_case.vp);
unknown088160a2019-05-23 17:43:13 -06004612 m_errorMonitor->VerifyFound();
4613 }
4614}
4615
4616TEST_F(VkLayerTest, SetDynViewportParamMaintenance1Tests) {
4617 TEST_DESCRIPTION("Verify errors are detected on misuse of SetViewport with a negative viewport extension enabled.");
4618
Mark Lobodzinski09ce9c42020-03-06 10:02:44 -07004619 ASSERT_NO_FATAL_FAILURE(InitFramework(m_errorMonitor));
unknown088160a2019-05-23 17:43:13 -06004620
4621 if (DeviceExtensionSupported(gpu(), nullptr, VK_KHR_MAINTENANCE1_EXTENSION_NAME)) {
4622 m_device_extension_names.push_back(VK_KHR_MAINTENANCE1_EXTENSION_NAME);
4623 } else {
4624 printf("%s VK_KHR_maintenance1 extension not supported -- skipping test\n", kSkipPrefix);
4625 return;
4626 }
4627 ASSERT_NO_FATAL_FAILURE(InitState());
4628
4629 NegHeightViewportTests(m_device, m_commandBuffer, m_errorMonitor);
4630}
4631
4632TEST_F(VkLayerTest, SetDynViewportParamMultiviewportTests) {
4633 TEST_DESCRIPTION("Test parameters of vkCmdSetViewport with multiViewport feature enabled");
4634
4635 ASSERT_NO_FATAL_FAILURE(Init());
4636
4637 if (!m_device->phy().features().multiViewport) {
4638 printf("%s VkPhysicalDeviceFeatures::multiViewport is not supported -- skipping test.\n", kSkipPrefix);
4639 return;
4640 }
4641
unknown088160a2019-05-23 17:43:13 -06004642 m_commandBuffer->begin();
4643
Mark Lobodzinski20310782020-02-28 14:25:17 -07004644 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdSetViewport-viewportCount-arraylength");
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06004645 vk::CmdSetViewport(m_commandBuffer->handle(), 0, 0, nullptr);
unknown088160a2019-05-23 17:43:13 -06004646 m_errorMonitor->VerifyFound();
4647
Petr Kraus14e49492019-09-09 20:13:29 +02004648 const auto max_viewports = m_device->props.limits.maxViewports;
4649
Mark Lobodzinski20310782020-02-28 14:25:17 -07004650 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdSetViewport-pViewports-parameter");
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06004651 vk::CmdSetViewport(m_commandBuffer->handle(), 0, max_viewports, nullptr);
unknown088160a2019-05-23 17:43:13 -06004652 m_errorMonitor->VerifyFound();
4653
Petr Kraus14e49492019-09-09 20:13:29 +02004654 const uint32_t too_big_max_viewports = 65536 + 1; // let's say this is too much to allocate
4655 if (max_viewports >= too_big_max_viewports) {
4656 printf("%s VkPhysicalDeviceLimits::maxViewports is too large to practically test against -- skipping part of test.\n",
4657 kSkipPrefix);
4658 } else {
4659 const VkViewport vp = {0.0, 0.0, 64.0, 64.0, 0.0, 1.0};
4660 const std::vector<VkViewport> viewports(max_viewports + 1, vp);
4661
Mark Lobodzinski20310782020-02-28 14:25:17 -07004662 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdSetViewport-firstViewport-01223");
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06004663 vk::CmdSetViewport(m_commandBuffer->handle(), 0, max_viewports + 1, viewports.data());
Petr Kraus14e49492019-09-09 20:13:29 +02004664 m_errorMonitor->VerifyFound();
4665
Mark Lobodzinski20310782020-02-28 14:25:17 -07004666 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdSetViewport-firstViewport-01223");
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06004667 vk::CmdSetViewport(m_commandBuffer->handle(), max_viewports, 1, viewports.data());
Petr Kraus14e49492019-09-09 20:13:29 +02004668 m_errorMonitor->VerifyFound();
4669
Mark Lobodzinski20310782020-02-28 14:25:17 -07004670 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdSetViewport-firstViewport-01223");
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06004671 vk::CmdSetViewport(m_commandBuffer->handle(), 1, max_viewports, viewports.data());
Petr Kraus14e49492019-09-09 20:13:29 +02004672 m_errorMonitor->VerifyFound();
4673
Mark Lobodzinski20310782020-02-28 14:25:17 -07004674 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdSetViewport-viewportCount-arraylength");
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06004675 vk::CmdSetViewport(m_commandBuffer->handle(), 1, 0, viewports.data());
Petr Kraus14e49492019-09-09 20:13:29 +02004676 m_errorMonitor->VerifyFound();
unknown088160a2019-05-23 17:43:13 -06004677 }
unknown088160a2019-05-23 17:43:13 -06004678}
4679
4680TEST_F(VkLayerTest, BadRenderPassScopeSecondaryCmdBuffer) {
4681 TEST_DESCRIPTION(
4682 "Test secondary buffers executed in wrong render pass scope wrt VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT");
4683
4684 ASSERT_NO_FATAL_FAILURE(Init());
4685 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
4686
4687 VkCommandBufferObj sec_cmdbuff_inside_rp(m_device, m_commandPool, VK_COMMAND_BUFFER_LEVEL_SECONDARY);
4688 VkCommandBufferObj sec_cmdbuff_outside_rp(m_device, m_commandPool, VK_COMMAND_BUFFER_LEVEL_SECONDARY);
4689
4690 const VkCommandBufferInheritanceInfo cmdbuff_ii = {
4691 VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO,
4692 nullptr, // pNext
4693 m_renderPass,
4694 0, // subpass
4695 m_framebuffer,
4696 };
4697 const VkCommandBufferBeginInfo cmdbuff_bi_tmpl = {VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,
4698 nullptr, // pNext
4699 VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT, &cmdbuff_ii};
4700
4701 VkCommandBufferBeginInfo cmdbuff_inside_rp_bi = cmdbuff_bi_tmpl;
4702 cmdbuff_inside_rp_bi.flags |= VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT;
4703 sec_cmdbuff_inside_rp.begin(&cmdbuff_inside_rp_bi);
4704 sec_cmdbuff_inside_rp.end();
4705
4706 VkCommandBufferBeginInfo cmdbuff_outside_rp_bi = cmdbuff_bi_tmpl;
4707 cmdbuff_outside_rp_bi.flags &= ~VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT;
4708 sec_cmdbuff_outside_rp.begin(&cmdbuff_outside_rp_bi);
4709 sec_cmdbuff_outside_rp.end();
4710
4711 m_commandBuffer->begin();
4712
Mark Lobodzinski20310782020-02-28 14:25:17 -07004713 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdExecuteCommands-pCommandBuffers-00100");
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06004714 vk::CmdExecuteCommands(m_commandBuffer->handle(), 1, &sec_cmdbuff_inside_rp.handle());
unknown088160a2019-05-23 17:43:13 -06004715 m_errorMonitor->VerifyFound();
4716
4717 const VkRenderPassBeginInfo rp_bi{VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,
4718 nullptr, // pNext
4719 m_renderPass,
4720 m_framebuffer,
4721 {{0, 0}, {32, 32}},
4722 static_cast<uint32_t>(m_renderPassClearValues.size()),
4723 m_renderPassClearValues.data()};
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06004724 vk::CmdBeginRenderPass(m_commandBuffer->handle(), &rp_bi, VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS);
unknown088160a2019-05-23 17:43:13 -06004725
Mark Lobodzinski20310782020-02-28 14:25:17 -07004726 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdExecuteCommands-pCommandBuffers-00096");
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06004727 vk::CmdExecuteCommands(m_commandBuffer->handle(), 1, &sec_cmdbuff_outside_rp.handle());
unknown088160a2019-05-23 17:43:13 -06004728 m_errorMonitor->VerifyFound();
4729}
4730
4731TEST_F(VkLayerTest, SecondaryCommandBufferClearColorAttachmentsRenderArea) {
4732 TEST_DESCRIPTION(
4733 "Create a secondary command buffer with CmdClearAttachments call that has a rect outside of renderPass renderArea");
4734 ASSERT_NO_FATAL_FAILURE(Init());
4735 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
4736
4737 VkCommandBufferAllocateInfo command_buffer_allocate_info = {};
4738 command_buffer_allocate_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
4739 command_buffer_allocate_info.commandPool = m_commandPool->handle();
4740 command_buffer_allocate_info.level = VK_COMMAND_BUFFER_LEVEL_SECONDARY;
4741 command_buffer_allocate_info.commandBufferCount = 1;
4742
4743 VkCommandBuffer secondary_command_buffer;
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06004744 ASSERT_VK_SUCCESS(vk::AllocateCommandBuffers(m_device->device(), &command_buffer_allocate_info, &secondary_command_buffer));
unknown088160a2019-05-23 17:43:13 -06004745 VkCommandBufferBeginInfo command_buffer_begin_info = {};
4746 VkCommandBufferInheritanceInfo command_buffer_inheritance_info = {};
4747 command_buffer_inheritance_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO;
4748 command_buffer_inheritance_info.renderPass = m_renderPass;
4749 command_buffer_inheritance_info.framebuffer = m_framebuffer;
4750
4751 command_buffer_begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
4752 command_buffer_begin_info.flags =
4753 VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT | VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT;
4754 command_buffer_begin_info.pInheritanceInfo = &command_buffer_inheritance_info;
4755
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06004756 vk::BeginCommandBuffer(secondary_command_buffer, &command_buffer_begin_info);
unknown088160a2019-05-23 17:43:13 -06004757 VkClearAttachment color_attachment;
4758 color_attachment.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
4759 color_attachment.clearValue.color.float32[0] = 0;
4760 color_attachment.clearValue.color.float32[1] = 0;
4761 color_attachment.clearValue.color.float32[2] = 0;
4762 color_attachment.clearValue.color.float32[3] = 0;
4763 color_attachment.colorAttachment = 0;
4764 // x extent of 257 exceeds render area of 256
Mark Lobodzinski62490892019-06-28 09:58:27 -06004765 VkClearRect clear_rect = {{{0, 0}, {257, 32}}, 0, 1};
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06004766 vk::CmdClearAttachments(secondary_command_buffer, 1, &color_attachment, 1, &clear_rect);
4767 vk::EndCommandBuffer(secondary_command_buffer);
unknown088160a2019-05-23 17:43:13 -06004768 m_commandBuffer->begin();
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06004769 vk::CmdBeginRenderPass(m_commandBuffer->handle(), &m_renderPassBeginInfo, VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS);
unknown088160a2019-05-23 17:43:13 -06004770
Mark Lobodzinski20310782020-02-28 14:25:17 -07004771 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdClearAttachments-pRects-00016");
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06004772 vk::CmdExecuteCommands(m_commandBuffer->handle(), 1, &secondary_command_buffer);
unknown088160a2019-05-23 17:43:13 -06004773 m_errorMonitor->VerifyFound();
4774
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06004775 vk::CmdEndRenderPass(m_commandBuffer->handle());
unknown088160a2019-05-23 17:43:13 -06004776 m_commandBuffer->end();
4777}
4778
4779TEST_F(VkLayerTest, PushDescriptorSetCmdPushBadArgs) {
4780 TEST_DESCRIPTION("Attempt to push a push descriptor set with incorrect arguments.");
4781 if (InstanceExtensionSupported(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME)) {
4782 m_instance_extension_names.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
4783 } else {
4784 printf("%s %s Extension not supported, skipping tests\n", kSkipPrefix,
4785 VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
4786 return;
4787 }
4788
Mark Lobodzinski09ce9c42020-03-06 10:02:44 -07004789 ASSERT_NO_FATAL_FAILURE(InitFramework(m_errorMonitor));
unknown088160a2019-05-23 17:43:13 -06004790 if (DeviceExtensionSupported(gpu(), nullptr, VK_KHR_PUSH_DESCRIPTOR_EXTENSION_NAME)) {
4791 m_device_extension_names.push_back(VK_KHR_PUSH_DESCRIPTOR_EXTENSION_NAME);
4792 } else {
4793 printf("%s %s Extension not supported, skipping tests\n", kSkipPrefix, VK_KHR_PUSH_DESCRIPTOR_EXTENSION_NAME);
4794 return;
4795 }
4796 ASSERT_NO_FATAL_FAILURE(InitState());
4797
4798 auto push_descriptor_prop = GetPushDescriptorProperties(instance(), gpu());
4799 if (push_descriptor_prop.maxPushDescriptors < 1) {
4800 // Some implementations report an invalid maxPushDescriptors of 0
4801 printf("%s maxPushDescriptors is zero, skipping tests\n", kSkipPrefix);
4802 return;
4803 }
4804
4805 // Create ordinary and push descriptor set layout
4806 VkDescriptorSetLayoutBinding binding = {0, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1, VK_SHADER_STAGE_FRAGMENT_BIT, nullptr};
4807 const VkDescriptorSetLayoutObj ds_layout(m_device, {binding});
4808 ASSERT_TRUE(ds_layout.initialized());
4809 const VkDescriptorSetLayoutObj push_ds_layout(m_device, {binding}, VK_DESCRIPTOR_SET_LAYOUT_CREATE_PUSH_DESCRIPTOR_BIT_KHR);
4810 ASSERT_TRUE(push_ds_layout.initialized());
4811
4812 // Now use the descriptor set layouts to create a pipeline layout
4813 const VkPipelineLayoutObj pipeline_layout(m_device, {&push_ds_layout, &ds_layout});
4814 ASSERT_TRUE(pipeline_layout.initialized());
4815
4816 // Create a descriptor to push
4817 const uint32_t buffer_data[4] = {4, 5, 6, 7};
4818 VkConstantBufferObj buffer_obj(m_device, sizeof(buffer_data), &buffer_data);
4819 ASSERT_TRUE(buffer_obj.initialized());
4820
4821 // Create a "write" struct, noting that the buffer_info cannot be a temporary arg (the return from write_descriptor_set
4822 // references its data), and the DescriptorSet() can be temporary, because the value is ignored
4823 VkDescriptorBufferInfo buffer_info = {buffer_obj.handle(), 0, VK_WHOLE_SIZE};
4824
4825 VkWriteDescriptorSet descriptor_write = vk_testing::Device::write_descriptor_set(
4826 vk_testing::DescriptorSet(), 0, 0, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1, &buffer_info);
4827
4828 // Find address of extension call and make the call
4829 PFN_vkCmdPushDescriptorSetKHR vkCmdPushDescriptorSetKHR =
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06004830 (PFN_vkCmdPushDescriptorSetKHR)vk::GetDeviceProcAddr(m_device->device(), "vkCmdPushDescriptorSetKHR");
unknown088160a2019-05-23 17:43:13 -06004831 ASSERT_TRUE(vkCmdPushDescriptorSetKHR != nullptr);
4832
4833 // Section 1: Queue family matching/capabilities.
4834 // Create command pool on a non-graphics queue
4835 const uint32_t no_gfx_qfi = m_device->QueueFamilyMatching(VK_QUEUE_COMPUTE_BIT, VK_QUEUE_GRAPHICS_BIT);
4836 const uint32_t transfer_only_qfi =
4837 m_device->QueueFamilyMatching(VK_QUEUE_TRANSFER_BIT, (VK_QUEUE_COMPUTE_BIT | VK_QUEUE_GRAPHICS_BIT));
4838 if ((UINT32_MAX == transfer_only_qfi) && (UINT32_MAX == no_gfx_qfi)) {
unknownc3033e52019-06-21 16:56:20 -06004839 printf("%s No compute or transfer only queue family, skipping bindpoint and queue tests.\n", kSkipPrefix);
unknown088160a2019-05-23 17:43:13 -06004840 } else {
4841 const uint32_t err_qfi = (UINT32_MAX == no_gfx_qfi) ? transfer_only_qfi : no_gfx_qfi;
4842
4843 VkCommandPoolObj command_pool(m_device, err_qfi);
4844 ASSERT_TRUE(command_pool.initialized());
4845 VkCommandBufferObj command_buffer(m_device, &command_pool);
4846 ASSERT_TRUE(command_buffer.initialized());
4847 command_buffer.begin();
4848
Mark Lobodzinski20310782020-02-28 14:25:17 -07004849 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdPushDescriptorSetKHR-pipelineBindPoint-00363");
4850 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkWriteDescriptorSet-descriptorType-00330");
unknown088160a2019-05-23 17:43:13 -06004851 if (err_qfi == transfer_only_qfi) {
4852 // This as this queue neither supports the gfx or compute bindpoints, we'll get two errors
Mark Lobodzinski20310782020-02-28 14:25:17 -07004853 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdPushDescriptorSetKHR-commandBuffer-cmdpool");
unknown088160a2019-05-23 17:43:13 -06004854 }
4855 vkCmdPushDescriptorSetKHR(command_buffer.handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_layout.handle(), 0, 1,
4856 &descriptor_write);
4857 m_errorMonitor->VerifyFound();
4858 command_buffer.end();
4859
4860 // If we succeed in testing only one condition above, we need to test the other below.
4861 if ((UINT32_MAX != transfer_only_qfi) && (err_qfi != transfer_only_qfi)) {
4862 // Need to test the neither compute/gfx supported case separately.
4863 VkCommandPoolObj tran_command_pool(m_device, transfer_only_qfi);
4864 ASSERT_TRUE(tran_command_pool.initialized());
4865 VkCommandBufferObj tran_command_buffer(m_device, &tran_command_pool);
4866 ASSERT_TRUE(tran_command_buffer.initialized());
4867 tran_command_buffer.begin();
4868
4869 // We can't avoid getting *both* errors in this case
Mark Lobodzinski20310782020-02-28 14:25:17 -07004870 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdPushDescriptorSetKHR-pipelineBindPoint-00363");
4871 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkWriteDescriptorSet-descriptorType-00330");
4872 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdPushDescriptorSetKHR-commandBuffer-cmdpool");
unknown088160a2019-05-23 17:43:13 -06004873 vkCmdPushDescriptorSetKHR(tran_command_buffer.handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_layout.handle(), 0, 1,
4874 &descriptor_write);
4875 m_errorMonitor->VerifyFound();
4876 tran_command_buffer.end();
4877 }
4878 }
4879
4880 // Push to the non-push binding
4881 m_commandBuffer->begin();
Mark Lobodzinski20310782020-02-28 14:25:17 -07004882 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdPushDescriptorSetKHR-set-00365");
unknown088160a2019-05-23 17:43:13 -06004883 vkCmdPushDescriptorSetKHR(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_layout.handle(), 1, 1,
4884 &descriptor_write);
4885 m_errorMonitor->VerifyFound();
4886
4887 // Specify set out of bounds
Mark Lobodzinski20310782020-02-28 14:25:17 -07004888 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdPushDescriptorSetKHR-set-00364");
unknown088160a2019-05-23 17:43:13 -06004889 vkCmdPushDescriptorSetKHR(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_layout.handle(), 2, 1,
4890 &descriptor_write);
4891 m_errorMonitor->VerifyFound();
4892 m_commandBuffer->end();
4893
4894 // This is a test for VUID-vkCmdPushDescriptorSetKHR-commandBuffer-recording
4895 // TODO: Add VALIDATION_ERROR_ code support to core_validation::ValidateCmd
Mark Lobodzinski20310782020-02-28 14:25:17 -07004896 m_errorMonitor->SetDesiredFailureMsg(kErrorBit,
unknown088160a2019-05-23 17:43:13 -06004897 "You must call vkBeginCommandBuffer() before this call to vkCmdPushDescriptorSetKHR()");
Mark Lobodzinski20310782020-02-28 14:25:17 -07004898 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkWriteDescriptorSet-descriptorType-00330");
unknown088160a2019-05-23 17:43:13 -06004899 vkCmdPushDescriptorSetKHR(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_layout.handle(), 0, 1,
4900 &descriptor_write);
4901 m_errorMonitor->VerifyFound();
4902}
4903
Jeremy Hayesf96a5162020-02-10 13:49:31 -07004904TEST_F(VkLayerTest, PushDescriptorSetCmdBufferOffsetUnaligned) {
4905 TEST_DESCRIPTION("Attempt to push a push descriptor set buffer with unaligned offset.");
4906 if (InstanceExtensionSupported(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME)) {
4907 m_instance_extension_names.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
4908 } else {
4909 printf("%s %s Extension not supported, skipping tests\n", kSkipPrefix,
4910 VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
4911 return;
4912 }
4913
Mark Lobodzinski09ce9c42020-03-06 10:02:44 -07004914 ASSERT_NO_FATAL_FAILURE(InitFramework(m_errorMonitor));
Jeremy Hayesf96a5162020-02-10 13:49:31 -07004915 if (DeviceExtensionSupported(gpu(), nullptr, VK_KHR_PUSH_DESCRIPTOR_EXTENSION_NAME)) {
4916 m_device_extension_names.push_back(VK_KHR_PUSH_DESCRIPTOR_EXTENSION_NAME);
4917 } else {
4918 printf("%s %s Extension not supported, skipping tests\n", kSkipPrefix, VK_KHR_PUSH_DESCRIPTOR_EXTENSION_NAME);
4919 return;
4920 }
4921 ASSERT_NO_FATAL_FAILURE(InitState());
4922
4923 auto const push_descriptor_prop = GetPushDescriptorProperties(instance(), gpu());
4924 if (push_descriptor_prop.maxPushDescriptors < 1) {
4925 // Some implementations report an invalid maxPushDescriptors of 0.
4926 printf("%s maxPushDescriptors is zero, skipping test\n", kSkipPrefix);
4927 return;
4928 }
4929
4930 auto const min_alignment = m_device->props.limits.minUniformBufferOffsetAlignment;
4931 if (min_alignment == 0) {
4932 printf("%s minUniformBufferOffsetAlignment is zero, skipping test\n", kSkipPrefix);
4933 return;
4934 }
4935
4936 VkDescriptorSetLayoutBinding binding = {0, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1, VK_SHADER_STAGE_FRAGMENT_BIT, nullptr};
4937 const VkDescriptorSetLayoutObj push_ds_layout(m_device, {binding}, VK_DESCRIPTOR_SET_LAYOUT_CREATE_PUSH_DESCRIPTOR_BIT_KHR);
4938 ASSERT_TRUE(push_ds_layout.initialized());
4939
4940 const VkPipelineLayoutObj pipeline_layout(m_device, {&push_ds_layout});
4941 ASSERT_TRUE(pipeline_layout.initialized());
4942
4943 const uint32_t buffer_data[4] = {4, 5, 6, 7};
4944 VkConstantBufferObj buffer_obj(m_device, sizeof(buffer_data), &buffer_data, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT);
4945 ASSERT_TRUE(buffer_obj.initialized());
4946
4947 // Use an invalid alignment.
4948 VkDescriptorBufferInfo buffer_info = {buffer_obj.handle(), min_alignment - 1, VK_WHOLE_SIZE};
4949 VkWriteDescriptorSet descriptor_write = vk_testing::Device::write_descriptor_set(
4950 vk_testing::DescriptorSet(), 0, 0, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1, &buffer_info);
4951
4952 PFN_vkCmdPushDescriptorSetKHR vkCmdPushDescriptorSetKHR =
4953 (PFN_vkCmdPushDescriptorSetKHR)vk::GetDeviceProcAddr(m_device->device(), "vkCmdPushDescriptorSetKHR");
4954 ASSERT_TRUE(vkCmdPushDescriptorSetKHR != nullptr);
4955
4956 m_commandBuffer->begin();
Mark Lobodzinski20310782020-02-28 14:25:17 -07004957 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkWriteDescriptorSet-descriptorType-00327");
Jeremy Hayesf96a5162020-02-10 13:49:31 -07004958 vkCmdPushDescriptorSetKHR(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_layout.handle(), 0, 1,
4959 &descriptor_write);
4960 m_errorMonitor->VerifyFound();
4961
4962 m_commandBuffer->end();
4963}
4964
unknown088160a2019-05-23 17:43:13 -06004965TEST_F(VkLayerTest, SetDynScissorParamTests) {
4966 TEST_DESCRIPTION("Test parameters of vkCmdSetScissor without multiViewport feature");
4967
4968 VkPhysicalDeviceFeatures features{};
4969 ASSERT_NO_FATAL_FAILURE(Init(&features));
4970
4971 const VkRect2D scissor = {{0, 0}, {16, 16}};
4972 const VkRect2D scissors[] = {scissor, scissor};
4973
4974 m_commandBuffer->begin();
4975
4976 // array tests
Mark Lobodzinski20310782020-02-28 14:25:17 -07004977 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdSetScissor-firstScissor-00593");
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06004978 vk::CmdSetScissor(m_commandBuffer->handle(), 1, 1, scissors);
unknown088160a2019-05-23 17:43:13 -06004979 m_errorMonitor->VerifyFound();
4980
Mark Lobodzinski20310782020-02-28 14:25:17 -07004981 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdSetScissor-scissorCount-arraylength");
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06004982 vk::CmdSetScissor(m_commandBuffer->handle(), 0, 0, nullptr);
unknown088160a2019-05-23 17:43:13 -06004983 m_errorMonitor->VerifyFound();
4984
Mark Lobodzinski20310782020-02-28 14:25:17 -07004985 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdSetScissor-scissorCount-00594");
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06004986 vk::CmdSetScissor(m_commandBuffer->handle(), 0, 2, scissors);
unknown088160a2019-05-23 17:43:13 -06004987 m_errorMonitor->VerifyFound();
4988
Mark Lobodzinski20310782020-02-28 14:25:17 -07004989 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdSetScissor-firstScissor-00593");
4990 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdSetScissor-scissorCount-00594");
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06004991 vk::CmdSetScissor(m_commandBuffer->handle(), 1, 2, scissors);
unknown088160a2019-05-23 17:43:13 -06004992 m_errorMonitor->VerifyFound();
4993
Mark Lobodzinski20310782020-02-28 14:25:17 -07004994 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdSetScissor-pScissors-parameter");
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06004995 vk::CmdSetScissor(m_commandBuffer->handle(), 0, 1, nullptr);
unknown088160a2019-05-23 17:43:13 -06004996 m_errorMonitor->VerifyFound();
4997
4998 struct TestCase {
4999 VkRect2D scissor;
5000 std::string vuid;
5001 };
5002
5003 std::vector<TestCase> test_cases = {{{{-1, 0}, {16, 16}}, "VUID-vkCmdSetScissor-x-00595"},
5004 {{{0, -1}, {16, 16}}, "VUID-vkCmdSetScissor-x-00595"},
5005 {{{1, 0}, {INT32_MAX, 16}}, "VUID-vkCmdSetScissor-offset-00596"},
5006 {{{INT32_MAX, 0}, {1, 16}}, "VUID-vkCmdSetScissor-offset-00596"},
5007 {{{0, 0}, {uint32_t{INT32_MAX} + 1, 16}}, "VUID-vkCmdSetScissor-offset-00596"},
5008 {{{0, 1}, {16, INT32_MAX}}, "VUID-vkCmdSetScissor-offset-00597"},
5009 {{{0, INT32_MAX}, {16, 1}}, "VUID-vkCmdSetScissor-offset-00597"},
5010 {{{0, 0}, {16, uint32_t{INT32_MAX} + 1}}, "VUID-vkCmdSetScissor-offset-00597"}};
5011
5012 for (const auto &test_case : test_cases) {
Mark Lobodzinski20310782020-02-28 14:25:17 -07005013 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, test_case.vuid);
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06005014 vk::CmdSetScissor(m_commandBuffer->handle(), 0, 1, &test_case.scissor);
unknown088160a2019-05-23 17:43:13 -06005015 m_errorMonitor->VerifyFound();
5016 }
5017
5018 m_commandBuffer->end();
5019}
5020
5021TEST_F(VkLayerTest, SetDynScissorParamMultiviewportTests) {
5022 TEST_DESCRIPTION("Test parameters of vkCmdSetScissor with multiViewport feature enabled");
5023
5024 ASSERT_NO_FATAL_FAILURE(Init());
5025
5026 if (!m_device->phy().features().multiViewport) {
5027 printf("%s VkPhysicalDeviceFeatures::multiViewport is not supported -- skipping test.\n", kSkipPrefix);
5028 return;
5029 }
5030
unknown088160a2019-05-23 17:43:13 -06005031 m_commandBuffer->begin();
5032
Mark Lobodzinski20310782020-02-28 14:25:17 -07005033 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdSetScissor-scissorCount-arraylength");
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06005034 vk::CmdSetScissor(m_commandBuffer->handle(), 0, 0, nullptr);
unknown088160a2019-05-23 17:43:13 -06005035 m_errorMonitor->VerifyFound();
5036
Petr Kraus14e49492019-09-09 20:13:29 +02005037 const auto max_scissors = m_device->props.limits.maxViewports;
5038
Mark Lobodzinski20310782020-02-28 14:25:17 -07005039 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdSetScissor-pScissors-parameter");
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06005040 vk::CmdSetScissor(m_commandBuffer->handle(), 0, max_scissors, nullptr);
unknown088160a2019-05-23 17:43:13 -06005041 m_errorMonitor->VerifyFound();
5042
Petr Kraus14e49492019-09-09 20:13:29 +02005043 const uint32_t too_big_max_scissors = 65536 + 1; // let's say this is too much to allocate
5044 if (max_scissors >= too_big_max_scissors) {
5045 printf("%s VkPhysicalDeviceLimits::maxViewports is too large to practically test against -- skipping part of test.\n",
5046 kSkipPrefix);
5047 } else {
5048 const VkRect2D scissor = {{0, 0}, {16, 16}};
5049 const std::vector<VkRect2D> scissors(max_scissors + 1, scissor);
5050
Mark Lobodzinski20310782020-02-28 14:25:17 -07005051 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdSetScissor-firstScissor-00592");
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06005052 vk::CmdSetScissor(m_commandBuffer->handle(), 0, max_scissors + 1, scissors.data());
Petr Kraus14e49492019-09-09 20:13:29 +02005053 m_errorMonitor->VerifyFound();
5054
Mark Lobodzinski20310782020-02-28 14:25:17 -07005055 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdSetScissor-firstScissor-00592");
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06005056 vk::CmdSetScissor(m_commandBuffer->handle(), max_scissors, 1, scissors.data());
Petr Kraus14e49492019-09-09 20:13:29 +02005057 m_errorMonitor->VerifyFound();
5058
Mark Lobodzinski20310782020-02-28 14:25:17 -07005059 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdSetScissor-firstScissor-00592");
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06005060 vk::CmdSetScissor(m_commandBuffer->handle(), 1, max_scissors, scissors.data());
Petr Kraus14e49492019-09-09 20:13:29 +02005061 m_errorMonitor->VerifyFound();
5062
Mark Lobodzinski20310782020-02-28 14:25:17 -07005063 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdSetScissor-scissorCount-arraylength");
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06005064 vk::CmdSetScissor(m_commandBuffer->handle(), 1, 0, scissors.data());
Petr Kraus14e49492019-09-09 20:13:29 +02005065 m_errorMonitor->VerifyFound();
unknown088160a2019-05-23 17:43:13 -06005066 }
unknown088160a2019-05-23 17:43:13 -06005067}
5068
5069TEST_F(VkLayerTest, DrawIndirect) {
5070 TEST_DESCRIPTION("Test covered valid usage for vkCmdDrawIndirect");
5071
5072 ASSERT_NO_FATAL_FAILURE(Init());
5073 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
5074
locke-lunarg8e2c91b2019-06-11 17:53:26 -06005075 CreatePipelineHelper pipe(*this);
5076 pipe.InitInfo();
5077 const VkDynamicState dyn_states[] = {VK_DYNAMIC_STATE_VIEWPORT, VK_DYNAMIC_STATE_SCISSOR};
5078 VkPipelineDynamicStateCreateInfo dyn_state_ci = {};
5079 dyn_state_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO;
5080 dyn_state_ci.dynamicStateCount = size(dyn_states);
5081 dyn_state_ci.pDynamicStates = dyn_states;
5082 pipe.dyn_state_ci_ = dyn_state_ci;
5083 pipe.InitState();
5084 pipe.CreateGraphicsPipeline();
unknown088160a2019-05-23 17:43:13 -06005085
5086 m_commandBuffer->begin();
5087 m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
5088
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06005089 vk::CmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.pipeline_);
5090 vk::CmdBindDescriptorSets(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.pipeline_layout_.handle(), 0, 1,
5091 &pipe.descriptor_set_->set_, 0, NULL);
unknown088160a2019-05-23 17:43:13 -06005092
5093 VkViewport viewport = {0, 0, 16, 16, 0, 1};
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06005094 vk::CmdSetViewport(m_commandBuffer->handle(), 0, 1, &viewport);
unknown088160a2019-05-23 17:43:13 -06005095 VkRect2D scissor = {{0, 0}, {16, 16}};
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06005096 vk::CmdSetScissor(m_commandBuffer->handle(), 0, 1, &scissor);
unknown088160a2019-05-23 17:43:13 -06005097
5098 VkBufferCreateInfo buffer_create_info = {VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO};
5099 buffer_create_info.usage = VK_BUFFER_USAGE_VERTEX_BUFFER_BIT;
5100 buffer_create_info.size = sizeof(VkDrawIndirectCommand);
locke-lunarg8e2c91b2019-06-11 17:53:26 -06005101 VkBufferObj draw_buffer;
5102 draw_buffer.init(*m_device, buffer_create_info);
unknown088160a2019-05-23 17:43:13 -06005103
5104 // VUID-vkCmdDrawIndirect-buffer-02709
Mark Lobodzinski20310782020-02-28 14:25:17 -07005105 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdDrawIndirect-buffer-02709");
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06005106 vk::CmdDrawIndirect(m_commandBuffer->handle(), draw_buffer.handle(), 0, 1, sizeof(VkDrawIndirectCommand));
unknown088160a2019-05-23 17:43:13 -06005107 m_errorMonitor->VerifyFound();
5108
5109 m_commandBuffer->EndRenderPass();
5110 m_commandBuffer->end();
unknown088160a2019-05-23 17:43:13 -06005111}
5112
Mark Lobodzinski977f0342019-12-19 14:24:09 -07005113TEST_F(VkLayerTest, DrawIndirectByteCountEXT) {
5114 TEST_DESCRIPTION("Test covered valid usage for vkCmdDrawIndirectByteCountEXT");
5115
5116 if (InstanceExtensionSupported(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME)) {
5117 m_instance_extension_names.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
5118 } else {
5119 printf("%s Did not find required instance extension %s; skipped.\n", kSkipPrefix,
5120 VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
5121 return;
5122 }
Mark Lobodzinski09ce9c42020-03-06 10:02:44 -07005123 ASSERT_NO_FATAL_FAILURE(InitFramework(m_errorMonitor));
Mark Lobodzinski977f0342019-12-19 14:24:09 -07005124
5125 if (DeviceExtensionSupported(gpu(), nullptr, VK_EXT_TRANSFORM_FEEDBACK_EXTENSION_NAME)) {
5126 m_device_extension_names.push_back(VK_EXT_TRANSFORM_FEEDBACK_EXTENSION_NAME);
5127 } else {
5128 printf("%s VK_EXT_transform_feedback extension not supported, skipping test\n", kSkipPrefix);
Mark Lobodzinskid01b2bc2019-12-20 10:19:36 -07005129 return;
Mark Lobodzinski977f0342019-12-19 14:24:09 -07005130 }
5131
5132 ASSERT_NO_FATAL_FAILURE(InitState());
5133 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
5134
5135 PFN_vkCmdDrawIndirectByteCountEXT fpvkCmdDrawIndirectByteCountEXT =
5136 (PFN_vkCmdDrawIndirectByteCountEXT)vk::GetDeviceProcAddr(device(), "vkCmdDrawIndirectByteCountEXT");
5137
5138 m_commandBuffer->begin();
5139 m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
5140 VkBufferCreateInfo buffer_create_info = {VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO};
5141 buffer_create_info.usage = VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT;
5142 buffer_create_info.size = 1024;
5143 VkBufferObj counter_buffer;
5144 counter_buffer.init(*m_device, buffer_create_info);
5145
5146 // VUID-vkCmdDrawIndirectByteCountEXT-vertexStride-02289
Mark Lobodzinski20310782020-02-28 14:25:17 -07005147 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdDrawIndirectByteCountEXT-vertexStride-02289");
Mark Lobodzinski977f0342019-12-19 14:24:09 -07005148 fpvkCmdDrawIndirectByteCountEXT(m_commandBuffer->handle(), 1, 0, counter_buffer.handle(), 0, 1, 0xCADECADE);
5149 m_errorMonitor->VerifyFound();
5150
5151 m_commandBuffer->EndRenderPass();
5152 m_commandBuffer->end();
5153}
5154
unknown088160a2019-05-23 17:43:13 -06005155TEST_F(VkLayerTest, DrawIndirectCountKHR) {
5156 TEST_DESCRIPTION("Test covered valid usage for vkCmdDrawIndirectCountKHR");
5157
Mark Lobodzinski09ce9c42020-03-06 10:02:44 -07005158 ASSERT_NO_FATAL_FAILURE(InitFramework(m_errorMonitor));
unknown088160a2019-05-23 17:43:13 -06005159 if (DeviceExtensionSupported(gpu(), nullptr, VK_KHR_DRAW_INDIRECT_COUNT_EXTENSION_NAME)) {
5160 m_device_extension_names.push_back(VK_KHR_DRAW_INDIRECT_COUNT_EXTENSION_NAME);
5161 } else {
5162 printf(" VK_KHR_draw_indirect_count Extension not supported, skipping test\n");
5163 return;
5164 }
5165 ASSERT_NO_FATAL_FAILURE(InitState());
5166 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
5167
5168 VkMemoryRequirements memory_requirements;
5169 VkMemoryAllocateInfo memory_allocate_info = {VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO};
5170
5171 auto vkCmdDrawIndirectCountKHR =
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06005172 (PFN_vkCmdDrawIndirectCountKHR)vk::GetDeviceProcAddr(m_device->device(), "vkCmdDrawIndirectCountKHR");
unknown088160a2019-05-23 17:43:13 -06005173
locke-lunarg8e2c91b2019-06-11 17:53:26 -06005174 CreatePipelineHelper pipe(*this);
5175 pipe.InitInfo();
5176 const VkDynamicState dyn_states[] = {VK_DYNAMIC_STATE_VIEWPORT, VK_DYNAMIC_STATE_SCISSOR};
5177 VkPipelineDynamicStateCreateInfo dyn_state_ci = {};
5178 dyn_state_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO;
5179 dyn_state_ci.dynamicStateCount = size(dyn_states);
5180 dyn_state_ci.pDynamicStates = dyn_states;
5181 pipe.dyn_state_ci_ = dyn_state_ci;
5182 pipe.InitState();
5183 pipe.CreateGraphicsPipeline();
unknown088160a2019-05-23 17:43:13 -06005184
5185 m_commandBuffer->begin();
5186 m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
5187
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06005188 vk::CmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.pipeline_);
5189 vk::CmdBindDescriptorSets(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.pipeline_layout_.handle(), 0, 1,
5190 &pipe.descriptor_set_->set_, 0, NULL);
unknown088160a2019-05-23 17:43:13 -06005191
5192 VkViewport viewport = {0, 0, 16, 16, 0, 1};
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06005193 vk::CmdSetViewport(m_commandBuffer->handle(), 0, 1, &viewport);
unknown088160a2019-05-23 17:43:13 -06005194 VkRect2D scissor = {{0, 0}, {16, 16}};
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06005195 vk::CmdSetScissor(m_commandBuffer->handle(), 0, 1, &scissor);
unknown088160a2019-05-23 17:43:13 -06005196
5197 VkBufferCreateInfo buffer_create_info = {VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO};
5198 buffer_create_info.size = sizeof(VkDrawIndirectCommand);
5199 buffer_create_info.usage = VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT;
5200 VkBuffer draw_buffer;
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06005201 vk::CreateBuffer(m_device->device(), &buffer_create_info, nullptr, &draw_buffer);
unknown088160a2019-05-23 17:43:13 -06005202
5203 VkBufferCreateInfo count_buffer_create_info = {VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO};
5204 count_buffer_create_info.size = sizeof(uint32_t);
5205 count_buffer_create_info.usage = VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT;
locke-lunarg8e2c91b2019-06-11 17:53:26 -06005206 VkBufferObj count_buffer;
5207 count_buffer.init(*m_device, count_buffer_create_info);
unknown088160a2019-05-23 17:43:13 -06005208
Mike Schuchardt65847d92019-12-20 13:50:47 -08005209 // VUID-vkCmdDrawIndirectCount-buffer-02708
Mark Lobodzinski20310782020-02-28 14:25:17 -07005210 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdDrawIndirectCount-buffer-02708");
locke-lunarg8e2c91b2019-06-11 17:53:26 -06005211 vkCmdDrawIndirectCountKHR(m_commandBuffer->handle(), draw_buffer, 0, count_buffer.handle(), 0, 1,
5212 sizeof(VkDrawIndirectCommand));
unknown088160a2019-05-23 17:43:13 -06005213 m_errorMonitor->VerifyFound();
5214
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06005215 vk::GetBufferMemoryRequirements(m_device->device(), draw_buffer, &memory_requirements);
unknown088160a2019-05-23 17:43:13 -06005216 memory_allocate_info.allocationSize = memory_requirements.size;
5217 m_device->phy().set_memory_type(memory_requirements.memoryTypeBits, &memory_allocate_info, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT);
5218 VkDeviceMemory draw_buffer_memory;
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06005219 vk::AllocateMemory(m_device->device(), &memory_allocate_info, NULL, &draw_buffer_memory);
5220 vk::BindBufferMemory(m_device->device(), draw_buffer, draw_buffer_memory, 0);
unknown088160a2019-05-23 17:43:13 -06005221
5222 VkBuffer count_buffer_unbound;
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06005223 vk::CreateBuffer(m_device->device(), &count_buffer_create_info, nullptr, &count_buffer_unbound);
unknown088160a2019-05-23 17:43:13 -06005224
Mike Schuchardt65847d92019-12-20 13:50:47 -08005225 // VUID-vkCmdDrawIndirectCount-countBuffer-02714
Mark Lobodzinski20310782020-02-28 14:25:17 -07005226 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdDrawIndirectCount-countBuffer-02714");
unknown088160a2019-05-23 17:43:13 -06005227 vkCmdDrawIndirectCountKHR(m_commandBuffer->handle(), draw_buffer, 0, count_buffer_unbound, 0, 1, sizeof(VkDrawIndirectCommand));
5228 m_errorMonitor->VerifyFound();
5229
Mike Schuchardt65847d92019-12-20 13:50:47 -08005230 // VUID-vkCmdDrawIndirectCount-offset-02710
Mark Lobodzinski20310782020-02-28 14:25:17 -07005231 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdDrawIndirectCount-offset-02710");
locke-lunarg8e2c91b2019-06-11 17:53:26 -06005232 vkCmdDrawIndirectCountKHR(m_commandBuffer->handle(), draw_buffer, 1, count_buffer.handle(), 0, 1,
5233 sizeof(VkDrawIndirectCommand));
unknown088160a2019-05-23 17:43:13 -06005234 m_errorMonitor->VerifyFound();
5235
Mike Schuchardt65847d92019-12-20 13:50:47 -08005236 // VUID-vkCmdDrawIndirectCount-countBufferOffset-02716
Mark Lobodzinski20310782020-02-28 14:25:17 -07005237 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdDrawIndirectCount-countBufferOffset-02716");
locke-lunarg8e2c91b2019-06-11 17:53:26 -06005238 vkCmdDrawIndirectCountKHR(m_commandBuffer->handle(), draw_buffer, 0, count_buffer.handle(), 1, 1,
5239 sizeof(VkDrawIndirectCommand));
unknown088160a2019-05-23 17:43:13 -06005240 m_errorMonitor->VerifyFound();
5241
Mike Schuchardt65847d92019-12-20 13:50:47 -08005242 // VUID-vkCmdDrawIndirectCount-stride-03110
Mark Lobodzinski20310782020-02-28 14:25:17 -07005243 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdDrawIndirectCount-stride-03110");
locke-lunarg8e2c91b2019-06-11 17:53:26 -06005244 vkCmdDrawIndirectCountKHR(m_commandBuffer->handle(), draw_buffer, 0, count_buffer.handle(), 0, 1, 1);
unknown088160a2019-05-23 17:43:13 -06005245 m_errorMonitor->VerifyFound();
5246
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06005247 // TODO: These covered VUIDs aren't tested. There is also no test coverage for the core Vulkan 1.0 vk::CmdDraw* equivalent of
unknown088160a2019-05-23 17:43:13 -06005248 // these:
Mike Schuchardt65847d92019-12-20 13:50:47 -08005249 // VUID-vkCmdDrawIndirectCount-renderPass-02684
5250 // VUID-vkCmdDrawIndirectCount-subpass-02685
5251 // VUID-vkCmdDrawIndirectCount-commandBuffer-02701
unknown088160a2019-05-23 17:43:13 -06005252
5253 m_commandBuffer->EndRenderPass();
5254 m_commandBuffer->end();
5255
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06005256 vk::DestroyBuffer(m_device->device(), draw_buffer, 0);
5257 vk::DestroyBuffer(m_device->device(), count_buffer_unbound, 0);
unknown088160a2019-05-23 17:43:13 -06005258
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06005259 vk::FreeMemory(m_device->device(), draw_buffer_memory, 0);
unknown088160a2019-05-23 17:43:13 -06005260}
5261
5262TEST_F(VkLayerTest, DrawIndexedIndirectCountKHR) {
5263 TEST_DESCRIPTION("Test covered valid usage for vkCmdDrawIndexedIndirectCountKHR");
5264
Mark Lobodzinski09ce9c42020-03-06 10:02:44 -07005265 ASSERT_NO_FATAL_FAILURE(InitFramework(m_errorMonitor));
unknown088160a2019-05-23 17:43:13 -06005266 if (DeviceExtensionSupported(gpu(), nullptr, VK_KHR_DRAW_INDIRECT_COUNT_EXTENSION_NAME)) {
5267 m_device_extension_names.push_back(VK_KHR_DRAW_INDIRECT_COUNT_EXTENSION_NAME);
5268 } else {
5269 printf(" VK_KHR_draw_indirect_count Extension not supported, skipping test\n");
5270 return;
5271 }
5272 ASSERT_NO_FATAL_FAILURE(InitState());
5273 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
5274
unknown088160a2019-05-23 17:43:13 -06005275 auto vkCmdDrawIndexedIndirectCountKHR =
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06005276 (PFN_vkCmdDrawIndexedIndirectCountKHR)vk::GetDeviceProcAddr(m_device->device(), "vkCmdDrawIndexedIndirectCountKHR");
unknown088160a2019-05-23 17:43:13 -06005277
locke-lunarg8e2c91b2019-06-11 17:53:26 -06005278 CreatePipelineHelper pipe(*this);
5279 pipe.InitInfo();
5280 const VkDynamicState dyn_states[] = {VK_DYNAMIC_STATE_VIEWPORT, VK_DYNAMIC_STATE_SCISSOR};
5281 VkPipelineDynamicStateCreateInfo dyn_state_ci = {};
5282 dyn_state_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO;
5283 dyn_state_ci.dynamicStateCount = size(dyn_states);
5284 dyn_state_ci.pDynamicStates = dyn_states;
5285 pipe.dyn_state_ci_ = dyn_state_ci;
5286 pipe.InitState();
5287 pipe.CreateGraphicsPipeline();
unknown088160a2019-05-23 17:43:13 -06005288
5289 m_commandBuffer->begin();
5290 m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
5291
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06005292 vk::CmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.pipeline_);
5293 vk::CmdBindDescriptorSets(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.pipeline_layout_.handle(), 0, 1,
5294 &pipe.descriptor_set_->set_, 0, NULL);
unknown088160a2019-05-23 17:43:13 -06005295
5296 VkViewport viewport = {0, 0, 16, 16, 0, 1};
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06005297 vk::CmdSetViewport(m_commandBuffer->handle(), 0, 1, &viewport);
unknown088160a2019-05-23 17:43:13 -06005298 VkRect2D scissor = {{0, 0}, {16, 16}};
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06005299 vk::CmdSetScissor(m_commandBuffer->handle(), 0, 1, &scissor);
unknown088160a2019-05-23 17:43:13 -06005300
5301 VkBufferCreateInfo buffer_create_info = {VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO};
5302 buffer_create_info.size = sizeof(VkDrawIndexedIndirectCommand);
5303 buffer_create_info.usage = VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT;
locke-lunarg8e2c91b2019-06-11 17:53:26 -06005304 VkBufferObj draw_buffer;
5305 draw_buffer.init(*m_device, buffer_create_info);
unknown088160a2019-05-23 17:43:13 -06005306
5307 VkBufferCreateInfo count_buffer_create_info = {VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO};
5308 count_buffer_create_info.size = sizeof(uint32_t);
5309 count_buffer_create_info.usage = VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT;
locke-lunarg8e2c91b2019-06-11 17:53:26 -06005310 VkBufferObj count_buffer;
5311 count_buffer.init(*m_device, count_buffer_create_info);
unknown088160a2019-05-23 17:43:13 -06005312
5313 VkBufferCreateInfo index_buffer_create_info = {VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO};
5314 index_buffer_create_info.size = sizeof(uint32_t);
5315 index_buffer_create_info.usage = VK_BUFFER_USAGE_INDEX_BUFFER_BIT;
locke-lunarg8e2c91b2019-06-11 17:53:26 -06005316 VkBufferObj index_buffer;
5317 index_buffer.init(*m_device, index_buffer_create_info);
unknown088160a2019-05-23 17:43:13 -06005318
Mike Schuchardt65847d92019-12-20 13:50:47 -08005319 // VUID-vkCmdDrawIndexedIndirectCount-commandBuffer-02701 (partial - only tests whether the index buffer is bound)
Mark Lobodzinski20310782020-02-28 14:25:17 -07005320 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdDrawIndexedIndirectCount-commandBuffer-02701");
locke-lunarg8e2c91b2019-06-11 17:53:26 -06005321 vkCmdDrawIndexedIndirectCountKHR(m_commandBuffer->handle(), draw_buffer.handle(), 0, count_buffer.handle(), 0, 1,
unknown088160a2019-05-23 17:43:13 -06005322 sizeof(VkDrawIndexedIndirectCommand));
5323 m_errorMonitor->VerifyFound();
5324
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06005325 vk::CmdBindIndexBuffer(m_commandBuffer->handle(), index_buffer.handle(), 0, VK_INDEX_TYPE_UINT32);
unknown088160a2019-05-23 17:43:13 -06005326
5327 VkBuffer draw_buffer_unbound;
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06005328 vk::CreateBuffer(m_device->device(), &count_buffer_create_info, nullptr, &draw_buffer_unbound);
unknown088160a2019-05-23 17:43:13 -06005329
Mike Schuchardt65847d92019-12-20 13:50:47 -08005330 // VUID-vkCmdDrawIndexedIndirectCount-buffer-02708
Mark Lobodzinski20310782020-02-28 14:25:17 -07005331 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdDrawIndexedIndirectCount-buffer-02708");
locke-lunarg8e2c91b2019-06-11 17:53:26 -06005332 vkCmdDrawIndexedIndirectCountKHR(m_commandBuffer->handle(), draw_buffer_unbound, 0, count_buffer.handle(), 0, 1,
unknown088160a2019-05-23 17:43:13 -06005333 sizeof(VkDrawIndexedIndirectCommand));
5334 m_errorMonitor->VerifyFound();
5335
5336 VkBuffer count_buffer_unbound;
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06005337 vk::CreateBuffer(m_device->device(), &count_buffer_create_info, nullptr, &count_buffer_unbound);
unknown088160a2019-05-23 17:43:13 -06005338
Mike Schuchardt65847d92019-12-20 13:50:47 -08005339 // VUID-vkCmdDrawIndexedIndirectCount-countBuffer-02714
Mark Lobodzinski20310782020-02-28 14:25:17 -07005340 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdDrawIndexedIndirectCount-countBuffer-02714");
locke-lunarg8e2c91b2019-06-11 17:53:26 -06005341 vkCmdDrawIndexedIndirectCountKHR(m_commandBuffer->handle(), draw_buffer.handle(), 0, count_buffer_unbound, 0, 1,
unknown088160a2019-05-23 17:43:13 -06005342 sizeof(VkDrawIndexedIndirectCommand));
5343 m_errorMonitor->VerifyFound();
5344
Mike Schuchardt65847d92019-12-20 13:50:47 -08005345 // VUID-vkCmdDrawIndexedIndirectCount-offset-02710
Mark Lobodzinski20310782020-02-28 14:25:17 -07005346 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdDrawIndexedIndirectCount-offset-02710");
locke-lunarg8e2c91b2019-06-11 17:53:26 -06005347 vkCmdDrawIndexedIndirectCountKHR(m_commandBuffer->handle(), draw_buffer.handle(), 1, count_buffer.handle(), 0, 1,
unknown088160a2019-05-23 17:43:13 -06005348 sizeof(VkDrawIndexedIndirectCommand));
5349 m_errorMonitor->VerifyFound();
5350
Mike Schuchardt65847d92019-12-20 13:50:47 -08005351 // VUID-vkCmdDrawIndexedIndirectCount-countBufferOffset-02716
Mark Lobodzinski20310782020-02-28 14:25:17 -07005352 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdDrawIndexedIndirectCount-countBufferOffset-02716");
locke-lunarg8e2c91b2019-06-11 17:53:26 -06005353 vkCmdDrawIndexedIndirectCountKHR(m_commandBuffer->handle(), draw_buffer.handle(), 0, count_buffer.handle(), 1, 1,
unknown088160a2019-05-23 17:43:13 -06005354 sizeof(VkDrawIndexedIndirectCommand));
5355 m_errorMonitor->VerifyFound();
5356
Mike Schuchardt65847d92019-12-20 13:50:47 -08005357 // VUID-vkCmdDrawIndexedIndirectCount-stride-03142
Mark Lobodzinski20310782020-02-28 14:25:17 -07005358 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdDrawIndexedIndirectCount-stride-03142");
locke-lunarg8e2c91b2019-06-11 17:53:26 -06005359 vkCmdDrawIndexedIndirectCountKHR(m_commandBuffer->handle(), draw_buffer.handle(), 0, count_buffer.handle(), 0, 1, 1);
unknown088160a2019-05-23 17:43:13 -06005360 m_errorMonitor->VerifyFound();
5361
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06005362 // TODO: These covered VUIDs aren't tested. There is also no test coverage for the core Vulkan 1.0 vk::CmdDraw* equivalent of
unknown088160a2019-05-23 17:43:13 -06005363 // these:
Mike Schuchardt65847d92019-12-20 13:50:47 -08005364 // VUID-vkCmdDrawIndexedIndirectCount-renderPass-02684
5365 // VUID-vkCmdDrawIndexedIndirectCount-subpass-02685
5366 // VUID-vkCmdDrawIndexedIndirectCount-commandBuffer-02701 (partial)
unknown088160a2019-05-23 17:43:13 -06005367
5368 m_commandBuffer->EndRenderPass();
5369 m_commandBuffer->end();
5370
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06005371 vk::DestroyBuffer(m_device->device(), draw_buffer_unbound, 0);
5372 vk::DestroyBuffer(m_device->device(), count_buffer_unbound, 0);
unknown088160a2019-05-23 17:43:13 -06005373}
5374
sfricke-samsung860d3b22020-05-04 21:08:29 -07005375TEST_F(VkLayerTest, DrawIndirectCountFeature) {
5376 TEST_DESCRIPTION("Test covered valid usage for the 1.2 drawIndirectCount feature");
5377
5378 SetTargetApiVersion(VK_API_VERSION_1_2);
5379 ASSERT_NO_FATAL_FAILURE(Init());
5380 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
5381 if (DeviceValidationVersion() < VK_API_VERSION_1_2) {
5382 printf("%s Tests requires Vulkan 1.2+, skipping test\n", kSkipPrefix);
5383 return;
5384 }
5385
5386 VkBufferObj indirect_buffer;
5387 indirect_buffer.init(*m_device, sizeof(VkDrawIndirectCommand), VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT,
5388 VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT);
5389
5390 VkBufferObj indexed_indirect_buffer;
5391 indexed_indirect_buffer.init(*m_device, sizeof(VkDrawIndexedIndirectCommand), VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT,
5392 VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT);
5393
5394 VkBufferObj count_buffer;
5395 count_buffer.init(*m_device, sizeof(uint32_t), VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT);
5396
5397 VkBufferObj index_buffer;
5398 index_buffer.init(*m_device, sizeof(uint32_t), VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, VK_BUFFER_USAGE_INDEX_BUFFER_BIT);
5399
5400 CreatePipelineHelper pipe(*this);
5401 pipe.InitInfo();
5402 pipe.InitState();
5403 pipe.CreateGraphicsPipeline();
5404
5405 // Make calls to valid commands but without the drawIndirectCount feature set
5406 m_commandBuffer->begin();
5407 m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
5408
5409 vk::CmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.pipeline_);
5410
5411 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdDrawIndirectCount-None-02836");
5412 vk::CmdDrawIndirectCount(m_commandBuffer->handle(), indirect_buffer.handle(), 0, count_buffer.handle(), 0, 1,
5413 sizeof(VkDrawIndirectCommand));
5414 m_errorMonitor->VerifyFound();
5415
5416 vk::CmdBindIndexBuffer(m_commandBuffer->handle(), index_buffer.handle(), 0, VK_INDEX_TYPE_UINT32);
5417
5418 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdDrawIndexedIndirect-None-02837");
5419 vk::CmdDrawIndexedIndirectCount(m_commandBuffer->handle(), indexed_indirect_buffer.handle(), 0, count_buffer.handle(), 0, 1,
5420 sizeof(VkDrawIndexedIndirectCommand));
5421 m_errorMonitor->VerifyFound();
5422
5423 m_commandBuffer->EndRenderPass();
5424 m_commandBuffer->end();
5425}
5426
unknown088160a2019-05-23 17:43:13 -06005427TEST_F(VkLayerTest, ExclusiveScissorNV) {
5428 TEST_DESCRIPTION("Test VK_NV_scissor_exclusive with multiViewport disabled.");
5429
5430 if (InstanceExtensionSupported(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME)) {
5431 m_instance_extension_names.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
5432 } else {
5433 printf("%s Did not find required instance extension %s; skipped.\n", kSkipPrefix,
5434 VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
5435 return;
5436 }
Mark Lobodzinski09ce9c42020-03-06 10:02:44 -07005437 ASSERT_NO_FATAL_FAILURE(InitFramework(m_errorMonitor));
unknown088160a2019-05-23 17:43:13 -06005438 std::array<const char *, 1> required_device_extensions = {{VK_NV_SCISSOR_EXCLUSIVE_EXTENSION_NAME}};
5439 for (auto device_extension : required_device_extensions) {
5440 if (DeviceExtensionSupported(gpu(), nullptr, device_extension)) {
5441 m_device_extension_names.push_back(device_extension);
5442 } else {
5443 printf("%s %s Extension not supported, skipping tests\n", kSkipPrefix, device_extension);
5444 return;
5445 }
5446 }
5447
5448 PFN_vkGetPhysicalDeviceFeatures2KHR vkGetPhysicalDeviceFeatures2KHR =
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06005449 (PFN_vkGetPhysicalDeviceFeatures2KHR)vk::GetInstanceProcAddr(instance(), "vkGetPhysicalDeviceFeatures2KHR");
unknown088160a2019-05-23 17:43:13 -06005450 ASSERT_TRUE(vkGetPhysicalDeviceFeatures2KHR != nullptr);
5451
5452 // Create a device that enables exclusive scissor but disables multiViewport
5453 auto exclusive_scissor_features = lvl_init_struct<VkPhysicalDeviceExclusiveScissorFeaturesNV>();
5454 auto features2 = lvl_init_struct<VkPhysicalDeviceFeatures2KHR>(&exclusive_scissor_features);
5455 vkGetPhysicalDeviceFeatures2KHR(gpu(), &features2);
5456
5457 features2.features.multiViewport = VK_FALSE;
5458
5459 ASSERT_NO_FATAL_FAILURE(InitState(nullptr, &features2));
5460 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
5461
5462 if (m_device->phy().properties().limits.maxViewports) {
5463 printf("%s Device doesn't support the necessary number of viewports, skipping test.\n", kSkipPrefix);
5464 return;
5465 }
5466
5467 // Based on PSOViewportStateTests
5468 {
5469 VkViewport viewport = {0.0f, 0.0f, 64.0f, 64.0f, 0.0f, 1.0f};
5470 VkViewport viewports[] = {viewport, viewport};
5471 VkRect2D scissor = {{0, 0}, {64, 64}};
5472 VkRect2D scissors[100] = {scissor, scissor};
5473
5474 using std::vector;
5475 struct TestCase {
5476 uint32_t viewport_count;
5477 VkViewport *viewports;
5478 uint32_t scissor_count;
5479 VkRect2D *scissors;
5480 uint32_t exclusive_scissor_count;
5481 VkRect2D *exclusive_scissors;
5482
5483 vector<std::string> vuids;
5484 };
5485
5486 vector<TestCase> test_cases = {
5487 {1,
5488 viewports,
5489 1,
5490 scissors,
5491 2,
5492 scissors,
5493 {"VUID-VkPipelineViewportExclusiveScissorStateCreateInfoNV-exclusiveScissorCount-02027",
5494 "VUID-VkPipelineViewportExclusiveScissorStateCreateInfoNV-exclusiveScissorCount-02029"}},
5495 {1,
5496 viewports,
5497 1,
5498 scissors,
5499 100,
5500 scissors,
5501 {"VUID-VkPipelineViewportExclusiveScissorStateCreateInfoNV-exclusiveScissorCount-02027",
5502 "VUID-VkPipelineViewportExclusiveScissorStateCreateInfoNV-exclusiveScissorCount-02028",
5503 "VUID-VkPipelineViewportExclusiveScissorStateCreateInfoNV-exclusiveScissorCount-02029"}},
Shannon McPherson24c13d12020-06-18 15:51:41 -06005504 {1, viewports, 1, scissors, 1, nullptr, {"VUID-VkGraphicsPipelineCreateInfo-pDynamicStates-04056"}},
unknown088160a2019-05-23 17:43:13 -06005505 };
5506
5507 for (const auto &test_case : test_cases) {
5508 VkPipelineViewportExclusiveScissorStateCreateInfoNV exc = {
5509 VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_EXCLUSIVE_SCISSOR_STATE_CREATE_INFO_NV};
5510
5511 const auto break_vp = [&test_case, &exc](CreatePipelineHelper &helper) {
5512 helper.vp_state_ci_.viewportCount = test_case.viewport_count;
5513 helper.vp_state_ci_.pViewports = test_case.viewports;
5514 helper.vp_state_ci_.scissorCount = test_case.scissor_count;
5515 helper.vp_state_ci_.pScissors = test_case.scissors;
5516 helper.vp_state_ci_.pNext = &exc;
5517
5518 exc.exclusiveScissorCount = test_case.exclusive_scissor_count;
5519 exc.pExclusiveScissors = test_case.exclusive_scissors;
5520 };
Mark Lobodzinski20310782020-02-28 14:25:17 -07005521 CreatePipelineHelper::OneshotTest(*this, break_vp, kErrorBit, test_case.vuids);
unknown088160a2019-05-23 17:43:13 -06005522 }
5523 }
5524
5525 // Based on SetDynScissorParamTests
5526 {
5527 auto vkCmdSetExclusiveScissorNV =
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06005528 (PFN_vkCmdSetExclusiveScissorNV)vk::GetDeviceProcAddr(m_device->device(), "vkCmdSetExclusiveScissorNV");
unknown088160a2019-05-23 17:43:13 -06005529
5530 const VkRect2D scissor = {{0, 0}, {16, 16}};
5531 const VkRect2D scissors[] = {scissor, scissor};
5532
5533 m_commandBuffer->begin();
5534
Mark Lobodzinski20310782020-02-28 14:25:17 -07005535 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdSetExclusiveScissorNV-firstExclusiveScissor-02035");
unknown088160a2019-05-23 17:43:13 -06005536 vkCmdSetExclusiveScissorNV(m_commandBuffer->handle(), 1, 1, scissors);
5537 m_errorMonitor->VerifyFound();
5538
Mark Lobodzinski20310782020-02-28 14:25:17 -07005539 m_errorMonitor->SetDesiredFailureMsg(kErrorBit,
unknown088160a2019-05-23 17:43:13 -06005540 "vkCmdSetExclusiveScissorNV: parameter exclusiveScissorCount must be greater than 0");
5541 vkCmdSetExclusiveScissorNV(m_commandBuffer->handle(), 0, 0, nullptr);
5542 m_errorMonitor->VerifyFound();
5543
Mark Lobodzinski20310782020-02-28 14:25:17 -07005544 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdSetExclusiveScissorNV-exclusiveScissorCount-02036");
unknown088160a2019-05-23 17:43:13 -06005545 vkCmdSetExclusiveScissorNV(m_commandBuffer->handle(), 0, 2, scissors);
5546 m_errorMonitor->VerifyFound();
5547
Mark Lobodzinski20310782020-02-28 14:25:17 -07005548 m_errorMonitor->SetDesiredFailureMsg(kErrorBit,
unknown088160a2019-05-23 17:43:13 -06005549 "vkCmdSetExclusiveScissorNV: parameter exclusiveScissorCount must be greater than 0");
Mark Lobodzinski20310782020-02-28 14:25:17 -07005550 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdSetExclusiveScissorNV-firstExclusiveScissor-02035");
unknown088160a2019-05-23 17:43:13 -06005551 vkCmdSetExclusiveScissorNV(m_commandBuffer->handle(), 1, 0, scissors);
5552 m_errorMonitor->VerifyFound();
5553
Mark Lobodzinski20310782020-02-28 14:25:17 -07005554 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdSetExclusiveScissorNV-firstExclusiveScissor-02035");
5555 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdSetExclusiveScissorNV-exclusiveScissorCount-02036");
unknown088160a2019-05-23 17:43:13 -06005556 vkCmdSetExclusiveScissorNV(m_commandBuffer->handle(), 1, 2, scissors);
5557 m_errorMonitor->VerifyFound();
5558
Mark Lobodzinski20310782020-02-28 14:25:17 -07005559 m_errorMonitor->SetDesiredFailureMsg(kErrorBit,
unknown088160a2019-05-23 17:43:13 -06005560 "vkCmdSetExclusiveScissorNV: required parameter pExclusiveScissors specified as NULL");
5561 vkCmdSetExclusiveScissorNV(m_commandBuffer->handle(), 0, 1, nullptr);
5562 m_errorMonitor->VerifyFound();
5563
5564 struct TestCase {
5565 VkRect2D scissor;
5566 std::string vuid;
5567 };
5568
5569 std::vector<TestCase> test_cases = {
5570 {{{-1, 0}, {16, 16}}, "VUID-vkCmdSetExclusiveScissorNV-x-02037"},
5571 {{{0, -1}, {16, 16}}, "VUID-vkCmdSetExclusiveScissorNV-x-02037"},
5572 {{{1, 0}, {INT32_MAX, 16}}, "VUID-vkCmdSetExclusiveScissorNV-offset-02038"},
5573 {{{INT32_MAX, 0}, {1, 16}}, "VUID-vkCmdSetExclusiveScissorNV-offset-02038"},
5574 {{{0, 0}, {uint32_t{INT32_MAX} + 1, 16}}, "VUID-vkCmdSetExclusiveScissorNV-offset-02038"},
5575 {{{0, 1}, {16, INT32_MAX}}, "VUID-vkCmdSetExclusiveScissorNV-offset-02039"},
5576 {{{0, INT32_MAX}, {16, 1}}, "VUID-vkCmdSetExclusiveScissorNV-offset-02039"},
5577 {{{0, 0}, {16, uint32_t{INT32_MAX} + 1}}, "VUID-vkCmdSetExclusiveScissorNV-offset-02039"}};
5578
5579 for (const auto &test_case : test_cases) {
Mark Lobodzinski20310782020-02-28 14:25:17 -07005580 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, test_case.vuid);
unknown088160a2019-05-23 17:43:13 -06005581 vkCmdSetExclusiveScissorNV(m_commandBuffer->handle(), 0, 1, &test_case.scissor);
5582 m_errorMonitor->VerifyFound();
5583 }
5584
5585 m_commandBuffer->end();
5586 }
5587}
5588
5589TEST_F(VkLayerTest, MeshShaderNV) {
5590 TEST_DESCRIPTION("Test VK_NV_mesh_shader.");
5591
5592 if (InstanceExtensionSupported(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME)) {
5593 m_instance_extension_names.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
5594 } else {
5595 printf("%s Did not find required instance extension %s; skipped.\n", kSkipPrefix,
5596 VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
5597 return;
5598 }
Mark Lobodzinski09ce9c42020-03-06 10:02:44 -07005599 ASSERT_NO_FATAL_FAILURE(InitFramework(m_errorMonitor));
unknown088160a2019-05-23 17:43:13 -06005600 std::array<const char *, 1> required_device_extensions = {{VK_NV_MESH_SHADER_EXTENSION_NAME}};
5601 for (auto device_extension : required_device_extensions) {
5602 if (DeviceExtensionSupported(gpu(), nullptr, device_extension)) {
5603 m_device_extension_names.push_back(device_extension);
5604 } else {
5605 printf("%s %s Extension not supported, skipping tests\n", kSkipPrefix, device_extension);
5606 return;
5607 }
5608 }
5609
Tony-LunarG048f5012020-04-29 16:55:11 -06005610 if (IsPlatform(kMockICD) || DeviceSimulation()) {
unknown088160a2019-05-23 17:43:13 -06005611 printf("%sNot suppored by MockICD, skipping tests\n", kSkipPrefix);
5612 return;
5613 }
5614
5615 PFN_vkGetPhysicalDeviceFeatures2KHR vkGetPhysicalDeviceFeatures2KHR =
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06005616 (PFN_vkGetPhysicalDeviceFeatures2KHR)vk::GetInstanceProcAddr(instance(), "vkGetPhysicalDeviceFeatures2KHR");
unknown088160a2019-05-23 17:43:13 -06005617 ASSERT_TRUE(vkGetPhysicalDeviceFeatures2KHR != nullptr);
5618
5619 // Create a device that enables mesh_shader
5620 auto mesh_shader_features = lvl_init_struct<VkPhysicalDeviceMeshShaderFeaturesNV>();
5621 auto features2 = lvl_init_struct<VkPhysicalDeviceFeatures2KHR>(&mesh_shader_features);
5622 vkGetPhysicalDeviceFeatures2KHR(gpu(), &features2);
5623 features2.features.multiDrawIndirect = VK_FALSE;
5624
5625 ASSERT_NO_FATAL_FAILURE(InitState(nullptr, &features2));
5626 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
5627
5628 static const char vertShaderText[] =
5629 "#version 450\n"
5630 "vec2 vertices[3];\n"
5631 "void main() {\n"
5632 " vertices[0] = vec2(-1.0, -1.0);\n"
5633 " vertices[1] = vec2( 1.0, -1.0);\n"
5634 " vertices[2] = vec2( 0.0, 1.0);\n"
5635 " gl_Position = vec4(vertices[gl_VertexIndex % 3], 0.0, 1.0);\n"
5636 " gl_PointSize = 1.0f;\n"
5637 "}\n";
5638
5639 static const char meshShaderText[] =
5640 "#version 450\n"
5641 "#extension GL_NV_mesh_shader : require\n"
5642 "layout(local_size_x = 1) in;\n"
5643 "layout(max_vertices = 3) out;\n"
5644 "layout(max_primitives = 1) out;\n"
5645 "layout(triangles) out;\n"
5646 "void main() {\n"
5647 " gl_MeshVerticesNV[0].gl_Position = vec4(-1.0, -1.0, 0, 1);\n"
5648 " gl_MeshVerticesNV[1].gl_Position = vec4( 1.0, -1.0, 0, 1);\n"
5649 " gl_MeshVerticesNV[2].gl_Position = vec4( 0.0, 1.0, 0, 1);\n"
5650 " gl_PrimitiveIndicesNV[0] = 0;\n"
5651 " gl_PrimitiveIndicesNV[1] = 1;\n"
5652 " gl_PrimitiveIndicesNV[2] = 2;\n"
5653 " gl_PrimitiveCountNV = 1;\n"
5654 "}\n";
5655
5656 VkShaderObj vs(m_device, vertShaderText, VK_SHADER_STAGE_VERTEX_BIT, this);
5657 VkShaderObj ms(m_device, meshShaderText, VK_SHADER_STAGE_MESH_BIT_NV, this);
5658 VkShaderObj fs(m_device, bindStateFragShaderText, VK_SHADER_STAGE_FRAGMENT_BIT, this);
5659
5660 // Test pipeline creation
5661 {
5662 // can't mix mesh with vertex
5663 const auto break_vp = [&](CreatePipelineHelper &helper) {
5664 helper.shader_stages_ = {vs.GetStageCreateInfo(), fs.GetStageCreateInfo(), ms.GetStageCreateInfo()};
5665 };
Mark Lobodzinski20310782020-02-28 14:25:17 -07005666 CreatePipelineHelper::OneshotTest(*this, break_vp, kErrorBit,
unknown088160a2019-05-23 17:43:13 -06005667 vector<std::string>({"VUID-VkGraphicsPipelineCreateInfo-pStages-02095"}));
5668
5669 // vertex or mesh must be present
5670 const auto break_vp2 = [&](CreatePipelineHelper &helper) { helper.shader_stages_ = {fs.GetStageCreateInfo()}; };
Mark Lobodzinski20310782020-02-28 14:25:17 -07005671 CreatePipelineHelper::OneshotTest(*this, break_vp2, kErrorBit,
unknown088160a2019-05-23 17:43:13 -06005672 vector<std::string>({"VUID-VkGraphicsPipelineCreateInfo-stage-02096"}));
5673
5674 // vertexinput and inputassembly must be valid when vertex stage is present
5675 const auto break_vp3 = [&](CreatePipelineHelper &helper) {
5676 helper.shader_stages_ = {vs.GetStageCreateInfo(), fs.GetStageCreateInfo()};
5677 helper.gp_ci_.pVertexInputState = nullptr;
5678 helper.gp_ci_.pInputAssemblyState = nullptr;
5679 };
Mark Lobodzinski20310782020-02-28 14:25:17 -07005680 CreatePipelineHelper::OneshotTest(*this, break_vp3, kErrorBit,
unknown088160a2019-05-23 17:43:13 -06005681 vector<std::string>({"VUID-VkGraphicsPipelineCreateInfo-pStages-02097",
5682 "VUID-VkGraphicsPipelineCreateInfo-pStages-02098"}));
5683 }
5684
5685 PFN_vkCmdDrawMeshTasksIndirectNV vkCmdDrawMeshTasksIndirectNV =
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06005686 (PFN_vkCmdDrawMeshTasksIndirectNV)vk::GetInstanceProcAddr(instance(), "vkCmdDrawMeshTasksIndirectNV");
unknown088160a2019-05-23 17:43:13 -06005687
5688 VkBufferCreateInfo buffer_create_info = {VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO};
5689 buffer_create_info.size = sizeof(uint32_t);
5690 buffer_create_info.usage = VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT;
5691 VkBuffer buffer;
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06005692 VkResult result = vk::CreateBuffer(m_device->device(), &buffer_create_info, nullptr, &buffer);
unknown088160a2019-05-23 17:43:13 -06005693 ASSERT_VK_SUCCESS(result);
5694
5695 m_commandBuffer->begin();
5696
Mark Lobodzinski20310782020-02-28 14:25:17 -07005697 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdDrawMeshTasksIndirectNV-drawCount-02146");
5698 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdDrawMeshTasksIndirectNV-drawCount-02718");
unknown088160a2019-05-23 17:43:13 -06005699 vkCmdDrawMeshTasksIndirectNV(m_commandBuffer->handle(), buffer, 0, 2, 0);
5700 m_errorMonitor->VerifyFound();
5701
5702 m_commandBuffer->end();
5703
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06005704 vk::DestroyBuffer(m_device->device(), buffer, 0);
unknown088160a2019-05-23 17:43:13 -06005705}
5706
5707TEST_F(VkLayerTest, MeshShaderDisabledNV) {
5708 TEST_DESCRIPTION("Test VK_NV_mesh_shader VUs with NV_mesh_shader disabled.");
5709 ASSERT_NO_FATAL_FAILURE(Init());
5710 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
5711
5712 VkEvent event;
5713 VkEventCreateInfo event_create_info{};
5714 event_create_info.sType = VK_STRUCTURE_TYPE_EVENT_CREATE_INFO;
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06005715 vk::CreateEvent(m_device->device(), &event_create_info, nullptr, &event);
unknown088160a2019-05-23 17:43:13 -06005716
5717 m_commandBuffer->begin();
5718
Shannon McPherson93970b12020-06-12 14:34:35 -06005719 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdSetEvent-stageMask-04095");
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06005720 vk::CmdSetEvent(m_commandBuffer->handle(), event, VK_PIPELINE_STAGE_MESH_SHADER_BIT_NV);
unknown088160a2019-05-23 17:43:13 -06005721 m_errorMonitor->VerifyFound();
5722
Shannon McPherson93970b12020-06-12 14:34:35 -06005723 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdSetEvent-stageMask-04096");
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06005724 vk::CmdSetEvent(m_commandBuffer->handle(), event, VK_PIPELINE_STAGE_TASK_SHADER_BIT_NV);
unknown088160a2019-05-23 17:43:13 -06005725 m_errorMonitor->VerifyFound();
5726
Shannon McPherson93970b12020-06-12 14:34:35 -06005727 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdResetEvent-stageMask-04095");
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06005728 vk::CmdResetEvent(m_commandBuffer->handle(), event, VK_PIPELINE_STAGE_MESH_SHADER_BIT_NV);
unknown088160a2019-05-23 17:43:13 -06005729 m_errorMonitor->VerifyFound();
5730
Shannon McPherson93970b12020-06-12 14:34:35 -06005731 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdResetEvent-stageMask-04096");
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06005732 vk::CmdResetEvent(m_commandBuffer->handle(), event, VK_PIPELINE_STAGE_TASK_SHADER_BIT_NV);
unknown088160a2019-05-23 17:43:13 -06005733 m_errorMonitor->VerifyFound();
5734
Shannon McPherson93970b12020-06-12 14:34:35 -06005735 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdWaitEvents-srcStageMask-04095");
5736 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdWaitEvents-dstStageMask-04095");
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06005737 vk::CmdWaitEvents(m_commandBuffer->handle(), 1, &event, VK_PIPELINE_STAGE_MESH_SHADER_BIT_NV,
5738 VK_PIPELINE_STAGE_MESH_SHADER_BIT_NV, 0, nullptr, 0, nullptr, 0, nullptr);
unknown088160a2019-05-23 17:43:13 -06005739 m_errorMonitor->VerifyFound();
5740
Shannon McPherson93970b12020-06-12 14:34:35 -06005741 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdWaitEvents-srcStageMask-04096");
5742 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdWaitEvents-dstStageMask-04096");
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06005743 vk::CmdWaitEvents(m_commandBuffer->handle(), 1, &event, VK_PIPELINE_STAGE_TASK_SHADER_BIT_NV,
5744 VK_PIPELINE_STAGE_TASK_SHADER_BIT_NV, 0, nullptr, 0, nullptr, 0, nullptr);
unknown088160a2019-05-23 17:43:13 -06005745 m_errorMonitor->VerifyFound();
5746
Shannon McPherson93970b12020-06-12 14:34:35 -06005747 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdPipelineBarrier-srcStageMask-04095");
5748 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdPipelineBarrier-dstStageMask-04095");
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06005749 vk::CmdPipelineBarrier(m_commandBuffer->handle(), VK_PIPELINE_STAGE_MESH_SHADER_BIT_NV, VK_PIPELINE_STAGE_MESH_SHADER_BIT_NV, 0,
5750 0, nullptr, 0, nullptr, 0, nullptr);
unknown088160a2019-05-23 17:43:13 -06005751 m_errorMonitor->VerifyFound();
5752
Shannon McPherson93970b12020-06-12 14:34:35 -06005753 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdPipelineBarrier-srcStageMask-04096");
5754 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdPipelineBarrier-dstStageMask-04096");
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06005755 vk::CmdPipelineBarrier(m_commandBuffer->handle(), VK_PIPELINE_STAGE_TASK_SHADER_BIT_NV, VK_PIPELINE_STAGE_TASK_SHADER_BIT_NV, 0,
5756 0, nullptr, 0, nullptr, 0, nullptr);
unknown088160a2019-05-23 17:43:13 -06005757 m_errorMonitor->VerifyFound();
5758
5759 m_commandBuffer->end();
5760
5761 VkSemaphoreCreateInfo semaphore_create_info = {};
5762 semaphore_create_info.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO;
5763 VkSemaphore semaphore;
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06005764 ASSERT_VK_SUCCESS(vk::CreateSemaphore(m_device->device(), &semaphore_create_info, nullptr, &semaphore));
unknown088160a2019-05-23 17:43:13 -06005765
5766 VkPipelineStageFlags stage_flags = VK_PIPELINE_STAGE_MESH_SHADER_BIT_NV | VK_PIPELINE_STAGE_TASK_SHADER_BIT_NV;
5767 VkSubmitInfo submit_info = {};
5768
5769 // Signal the semaphore so the next test can wait on it.
5770 submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
5771 submit_info.signalSemaphoreCount = 1;
5772 submit_info.pSignalSemaphores = &semaphore;
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06005773 vk::QueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
unknown088160a2019-05-23 17:43:13 -06005774 m_errorMonitor->VerifyNotFound();
5775
5776 submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
5777 submit_info.signalSemaphoreCount = 0;
5778 submit_info.pSignalSemaphores = nullptr;
5779 submit_info.waitSemaphoreCount = 1;
5780 submit_info.pWaitSemaphores = &semaphore;
5781 submit_info.pWaitDstStageMask = &stage_flags;
5782
Mark Lobodzinski20310782020-02-28 14:25:17 -07005783 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkSubmitInfo-pWaitDstStageMask-02089");
5784 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkSubmitInfo-pWaitDstStageMask-02090");
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06005785 vk::QueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
unknown088160a2019-05-23 17:43:13 -06005786 m_errorMonitor->VerifyFound();
5787
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06005788 vk::QueueWaitIdle(m_device->m_queue);
unknown088160a2019-05-23 17:43:13 -06005789
5790 VkShaderObj vs(m_device, bindStateVertShaderText, VK_SHADER_STAGE_VERTEX_BIT, this);
5791 VkPipelineShaderStageCreateInfo meshStage = {VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO};
5792 meshStage = vs.GetStageCreateInfo();
5793 meshStage.stage = VK_SHADER_STAGE_MESH_BIT_NV;
5794 VkPipelineShaderStageCreateInfo taskStage = {VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO};
5795 taskStage = vs.GetStageCreateInfo();
5796 taskStage.stage = VK_SHADER_STAGE_TASK_BIT_NV;
5797
5798 // mesh and task shaders not supported
5799 const auto break_vp = [&](CreatePipelineHelper &helper) {
5800 helper.shader_stages_ = {meshStage, taskStage, vs.GetStageCreateInfo()};
5801 };
5802 CreatePipelineHelper::OneshotTest(
Mark Lobodzinski20310782020-02-28 14:25:17 -07005803 *this, break_vp, kErrorBit,
unknown088160a2019-05-23 17:43:13 -06005804 vector<std::string>({"VUID-VkPipelineShaderStageCreateInfo-pName-00707", "VUID-VkPipelineShaderStageCreateInfo-pName-00707",
5805 "VUID-VkPipelineShaderStageCreateInfo-stage-02091",
5806 "VUID-VkPipelineShaderStageCreateInfo-stage-02092"}));
5807
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06005808 vk::DestroyEvent(m_device->device(), event, nullptr);
5809 vk::DestroySemaphore(m_device->device(), semaphore, nullptr);
unknown088160a2019-05-23 17:43:13 -06005810}
Chris Mayerc93536f2019-09-19 16:34:49 +02005811
5812TEST_F(VkLayerTest, ViewportWScalingNV) {
5813 TEST_DESCRIPTION("Verify VK_NV_clip_space_w_scaling");
5814
Mark Lobodzinski09ce9c42020-03-06 10:02:44 -07005815 ASSERT_NO_FATAL_FAILURE(InitFramework(m_errorMonitor));
Chris Mayerc93536f2019-09-19 16:34:49 +02005816
5817 VkPhysicalDeviceFeatures device_features = {};
5818 ASSERT_NO_FATAL_FAILURE(GetPhysicalDeviceFeatures(&device_features));
5819
5820 if (!device_features.multiViewport) {
5821 printf("%s VkPhysicalDeviceFeatures::multiViewport is not supported, skipping tests\n", kSkipPrefix);
5822 return;
5823 }
5824
5825 if (DeviceExtensionSupported(gpu(), nullptr, VK_NV_CLIP_SPACE_W_SCALING_EXTENSION_NAME)) {
5826 m_device_extension_names.push_back(VK_NV_CLIP_SPACE_W_SCALING_EXTENSION_NAME);
5827 } else {
5828 printf("%s %s Extension not supported, skipping tests\n", kSkipPrefix, VK_NV_CLIP_SPACE_W_SCALING_EXTENSION_NAME);
5829 return;
5830 }
5831
5832 ASSERT_NO_FATAL_FAILURE(InitState(&device_features));
5833 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
5834
5835 auto vkCmdSetViewportWScalingNV =
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06005836 reinterpret_cast<PFN_vkCmdSetViewportWScalingNV>(vk::GetDeviceProcAddr(m_device->device(), "vkCmdSetViewportWScalingNV"));
Chris Mayerc93536f2019-09-19 16:34:49 +02005837
5838 const char vs_src[] = R"(
5839 #version 450
5840 const vec2 positions[] = { vec2(-1.0f, 1.0f),
5841 vec2( 1.0f, 1.0f),
5842 vec2(-1.0f, -1.0f),
5843 vec2( 1.0f, -1.0f) };
5844 out gl_PerVertex {
5845 vec4 gl_Position;
5846 };
5847
5848 void main() {
5849 gl_Position = vec4(positions[gl_VertexIndex % 4], 0.0f, 1.0f);
5850 })";
5851
5852 const char fs_src[] = R"(
5853 #version 450
5854 layout(location = 0) out vec4 outColor;
5855
5856 void main() {
5857 outColor = vec4(0.0f, 1.0f, 0.0f, 1.0f);
5858 })";
5859
5860 const std::vector<VkViewport> vp = {
5861 {0.0f, 0.0f, 64.0f, 64.0f}, {0.0f, 0.0f, 64.0f, 64.0f}, {0.0f, 0.0f, 64.0f, 64.0f}, {0.0f, 0.0f, 64.0f, 64.0f}};
5862 const std::vector<VkRect2D> sc = {{{0, 0}, {32, 32}}, {{32, 0}, {32, 32}}, {{0, 32}, {32, 32}}, {{32, 32}, {32, 32}}};
5863 const std::vector<VkViewportWScalingNV> scale = {{-0.2f, -0.2f}, {0.2f, -0.2f}, {-0.2f, 0.2f}, {0.2f, 0.2f}};
5864
5865 const uint32_t vp_count = static_cast<uint32_t>(vp.size());
5866
5867 VkPipelineViewportWScalingStateCreateInfoNV vpsi = {VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_W_SCALING_STATE_CREATE_INFO_NV};
5868 vpsi.viewportWScalingEnable = VK_TRUE;
5869 vpsi.viewportCount = vp_count;
5870 vpsi.pViewportWScalings = scale.data();
5871
5872 VkPipelineViewportStateCreateInfo vpci = {VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO};
5873 vpci.viewportCount = vp_count;
5874 vpci.pViewports = vp.data();
5875 vpci.scissorCount = vp_count;
5876 vpci.pScissors = sc.data();
5877 vpci.pNext = &vpsi;
5878
5879 const auto set_vpci = [&vpci](CreatePipelineHelper &helper) { helper.vp_state_ci_ = vpci; };
5880
5881 // Make sure no errors show up when creating the pipeline with w-scaling enabled
Mark Lobodzinski20310782020-02-28 14:25:17 -07005882 CreatePipelineHelper::OneshotTest(*this, set_vpci, kErrorBit, vector<std::string>(), true);
Chris Mayerc93536f2019-09-19 16:34:49 +02005883
5884 // Create pipeline with w-scaling enabled but without a valid scaling array
5885 vpsi.pViewportWScalings = nullptr;
Mark Lobodzinski20310782020-02-28 14:25:17 -07005886 CreatePipelineHelper::OneshotTest(*this, set_vpci, kErrorBit,
Chris Mayerc93536f2019-09-19 16:34:49 +02005887 vector<std::string>({"VUID-VkGraphicsPipelineCreateInfo-pDynamicStates-01715"}));
5888
5889 vpsi.pViewportWScalings = scale.data();
5890
5891 // Create pipeline with w-scaling enabled but without matching viewport counts
5892 vpsi.viewportCount = 1;
Mark Lobodzinski20310782020-02-28 14:25:17 -07005893 CreatePipelineHelper::OneshotTest(*this, set_vpci, kErrorBit,
Chris Mayerc93536f2019-09-19 16:34:49 +02005894 vector<std::string>({"VUID-VkPipelineViewportStateCreateInfo-viewportWScalingEnable-01726"}));
5895
5896 const VkPipelineLayoutObj pl(m_device);
5897
5898 VkShaderObj vs(m_device, vs_src, VK_SHADER_STAGE_VERTEX_BIT, this);
5899 VkShaderObj fs(m_device, fs_src, VK_SHADER_STAGE_FRAGMENT_BIT, this);
5900
5901 VkPipelineObj pipe(m_device);
5902 pipe.AddDefaultColorAttachment();
5903 pipe.AddShader(&vs);
5904 pipe.AddShader(&fs);
5905 pipe.SetViewport(vp);
5906 pipe.SetScissor(sc);
5907 pipe.CreateVKPipeline(pl.handle(), renderPass());
5908
5909 VkPipelineObj pipeDynWScale(m_device);
5910 pipeDynWScale.AddDefaultColorAttachment();
5911 pipeDynWScale.AddShader(&vs);
5912 pipeDynWScale.AddShader(&fs);
5913 pipeDynWScale.SetViewport(vp);
5914 pipeDynWScale.SetScissor(sc);
5915 pipeDynWScale.MakeDynamic(VK_DYNAMIC_STATE_VIEWPORT_W_SCALING_NV);
5916 pipeDynWScale.CreateVKPipeline(pl.handle(), renderPass());
5917
5918 m_commandBuffer->begin();
5919
5920 // Bind pipeline without dynamic w scaling enabled
5921 m_errorMonitor->ExpectSuccess();
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06005922 vk::CmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.handle());
Chris Mayerc93536f2019-09-19 16:34:49 +02005923 m_errorMonitor->VerifyNotFound();
5924
Chris Mayerc93536f2019-09-19 16:34:49 +02005925 // Bind pipeline that has dynamic w-scaling enabled
5926 m_errorMonitor->ExpectSuccess();
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06005927 vk::CmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeDynWScale.handle());
Chris Mayerc93536f2019-09-19 16:34:49 +02005928 m_errorMonitor->VerifyNotFound();
5929
5930 const auto max_vps = m_device->props.limits.maxViewports;
5931
Mark Lobodzinski20310782020-02-28 14:25:17 -07005932 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdSetViewportWScalingNV-firstViewport-01323");
Chris Mayerc93536f2019-09-19 16:34:49 +02005933 vkCmdSetViewportWScalingNV(m_commandBuffer->handle(), max_vps, vp_count, scale.data());
5934 m_errorMonitor->VerifyFound();
5935
Mark Lobodzinski20310782020-02-28 14:25:17 -07005936 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdSetViewportWScalingNV-firstViewport-01324");
Chris Mayerc93536f2019-09-19 16:34:49 +02005937 vkCmdSetViewportWScalingNV(m_commandBuffer->handle(), 1, max_vps, scale.data());
5938 m_errorMonitor->VerifyFound();
5939
5940 m_errorMonitor->ExpectSuccess();
5941 vkCmdSetViewportWScalingNV(m_commandBuffer->handle(), 0, vp_count, scale.data());
5942 m_errorMonitor->VerifyNotFound();
5943
5944 m_commandBuffer->end();
5945}
sfricke-samsung914e8002020-01-07 22:26:18 -08005946
5947TEST_F(VkLayerTest, CreateSamplerYcbcrConversionEnable) {
5948 TEST_DESCRIPTION("Checks samplerYcbcrConversion is enabled before calling vkCreateSamplerYcbcrConversion");
5949
5950 // Enable Sampler YCbCr Conversion req'd extensions
5951 // Only need revision 1 of vkGetPhysicalDeviceProperties2 and this allows more device capable for testing
5952 bool mp_extensions = InstanceExtensionSupported(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME, 1);
5953 if (mp_extensions) {
5954 m_instance_extension_names.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
5955 }
5956 SetTargetApiVersion(VK_API_VERSION_1_1);
Mark Lobodzinski09ce9c42020-03-06 10:02:44 -07005957 ASSERT_NO_FATAL_FAILURE(InitFramework(m_errorMonitor));
sfricke-samsung914e8002020-01-07 22:26:18 -08005958 mp_extensions = mp_extensions && DeviceExtensionSupported(gpu(), nullptr, VK_KHR_MAINTENANCE1_EXTENSION_NAME);
5959 mp_extensions = mp_extensions && DeviceExtensionSupported(gpu(), nullptr, VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME);
5960 mp_extensions = mp_extensions && DeviceExtensionSupported(gpu(), nullptr, VK_KHR_BIND_MEMORY_2_EXTENSION_NAME);
5961 mp_extensions = mp_extensions && DeviceExtensionSupported(gpu(), nullptr, VK_KHR_SAMPLER_YCBCR_CONVERSION_EXTENSION_NAME);
5962 if (mp_extensions) {
5963 m_device_extension_names.push_back(VK_KHR_MAINTENANCE1_EXTENSION_NAME);
5964 m_device_extension_names.push_back(VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME);
5965 m_device_extension_names.push_back(VK_KHR_BIND_MEMORY_2_EXTENSION_NAME);
5966 m_device_extension_names.push_back(VK_KHR_SAMPLER_YCBCR_CONVERSION_EXTENSION_NAME);
5967 } else {
5968 printf("%s test requires Sampler YCbCr Conversion extensions, not available. Skipping.\n", kSkipPrefix);
5969 return;
5970 }
5971
5972 // Explictly not enable Ycbcr Conversion Features
5973 VkPhysicalDeviceSamplerYcbcrConversionFeatures ycbcr_features = {};
5974 ycbcr_features.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SAMPLER_YCBCR_CONVERSION_FEATURES;
5975 ycbcr_features.samplerYcbcrConversion = VK_FALSE;
5976 ASSERT_NO_FATAL_FAILURE(InitState(nullptr, &ycbcr_features));
5977
5978 PFN_vkCreateSamplerYcbcrConversionKHR vkCreateSamplerYcbcrConversionFunction =
5979 (PFN_vkCreateSamplerYcbcrConversionKHR)vk::GetDeviceProcAddr(m_device->handle(), "vkCreateSamplerYcbcrConversionKHR");
5980 if (vkCreateSamplerYcbcrConversionFunction == nullptr) {
5981 printf("%s did not find vkCreateSamplerYcbcrConversionKHR function pointer; Skipping.\n", kSkipPrefix);
5982 return;
5983 }
5984
5985 // Create Ycbcr conversion
5986 VkSamplerYcbcrConversion conversions;
5987 VkSamplerYcbcrConversionCreateInfo ycbcr_create_info = {VK_STRUCTURE_TYPE_SAMPLER_YCBCR_CONVERSION_CREATE_INFO,
5988 NULL,
5989 VK_FORMAT_G8_B8R8_2PLANE_420_UNORM_KHR,
5990 VK_SAMPLER_YCBCR_MODEL_CONVERSION_RGB_IDENTITY,
5991 VK_SAMPLER_YCBCR_RANGE_ITU_FULL,
5992 {VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY,
5993 VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY},
5994 VK_CHROMA_LOCATION_COSITED_EVEN,
5995 VK_CHROMA_LOCATION_COSITED_EVEN,
5996 VK_FILTER_NEAREST,
5997 false};
5998
Mark Lobodzinski20310782020-02-28 14:25:17 -07005999 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCreateSamplerYcbcrConversion-None-01648");
sfricke-samsung914e8002020-01-07 22:26:18 -08006000 vkCreateSamplerYcbcrConversionFunction(m_device->handle(), &ycbcr_create_info, nullptr, &conversions);
6001 m_errorMonitor->VerifyFound();
Shannon McPherson50421602020-01-28 15:18:46 -07006002}
Jeremy Hayescd7df2c2020-05-21 16:36:47 -06006003
6004TEST_F(VkLayerTest, TransformFeedbackFeatureEnabled) {
6005 TEST_DESCRIPTION("VkPhysicalDeviceTransformFeedbackFeaturesEXT::transformFeedback must be enabled");
6006
6007 if (!InstanceExtensionSupported(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME)) {
6008 printf("%s Did not find required instance extension %s; skipped.\n", kSkipPrefix,
6009 VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
6010 return;
6011 }
6012 m_instance_extension_names.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
6013
6014 ASSERT_NO_FATAL_FAILURE(InitFramework(m_errorMonitor));
6015
6016 if (!DeviceExtensionSupported(gpu(), nullptr, VK_EXT_TRANSFORM_FEEDBACK_EXTENSION_NAME)) {
6017 printf("%s %s Extension not supported, skipping tests\n", kSkipPrefix, VK_EXT_TRANSFORM_FEEDBACK_EXTENSION_NAME);
6018 return;
6019 }
6020 m_device_extension_names.push_back(VK_EXT_TRANSFORM_FEEDBACK_EXTENSION_NAME);
6021
6022 {
6023 PFN_vkGetPhysicalDeviceFeatures2KHR vkGetPhysicalDeviceFeatures2KHR =
6024 (PFN_vkGetPhysicalDeviceFeatures2KHR)vk::GetInstanceProcAddr(instance(), "vkGetPhysicalDeviceFeatures2KHR");
6025 ASSERT_TRUE(vkGetPhysicalDeviceFeatures2KHR != nullptr);
6026
6027 auto tf_features = lvl_init_struct<VkPhysicalDeviceTransformFeedbackFeaturesEXT>();
6028 auto pd_features = lvl_init_struct<VkPhysicalDeviceFeatures2>(&tf_features);
6029 vkGetPhysicalDeviceFeatures2KHR(gpu(), &pd_features);
6030
6031 if (!tf_features.transformFeedback) {
6032 printf("%s transformFeedback not supported; skipped.\n", kSkipPrefix);
6033 return;
6034 }
6035 }
6036
6037 ASSERT_NO_FATAL_FAILURE(InitState());
6038 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
6039
6040 {
6041 auto vkCmdBindTransformFeedbackBuffersEXT = (PFN_vkCmdBindTransformFeedbackBuffersEXT)vk::GetDeviceProcAddr(
6042 m_device->device(), "vkCmdBindTransformFeedbackBuffersEXT");
6043 ASSERT_TRUE(vkCmdBindTransformFeedbackBuffersEXT != nullptr);
6044
6045 auto info = lvl_init_struct<VkBufferCreateInfo>();
6046 info.usage = VK_BUFFER_USAGE_TRANSFORM_FEEDBACK_BUFFER_BIT_EXT;
6047 info.size = 4;
6048 VkBufferObj buffer;
6049 buffer.init(*m_device, info);
6050 VkDeviceSize offsets[1]{};
6051
6052 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdBindTransformFeedbackBuffersEXT-transformFeedback-02355");
6053 vkCmdBindTransformFeedbackBuffersEXT(m_commandBuffer->handle(), 0, 1, &buffer.handle(), offsets, nullptr);
6054 m_errorMonitor->VerifyFound();
6055 }
6056
6057 {
6058 auto vkCmdBeginTransformFeedbackEXT =
6059 (PFN_vkCmdBeginTransformFeedbackEXT)vk::GetDeviceProcAddr(m_device->device(), "vkCmdBeginTransformFeedbackEXT");
6060 ASSERT_TRUE(vkCmdBeginTransformFeedbackEXT != nullptr);
6061
6062 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdBeginTransformFeedbackEXT-transformFeedback-02366");
6063 vkCmdBeginTransformFeedbackEXT(m_commandBuffer->handle(), 0, 1, nullptr, nullptr);
6064 m_errorMonitor->VerifyFound();
6065 }
6066
6067 {
6068 auto vkCmdEndTransformFeedbackEXT =
6069 (PFN_vkCmdEndTransformFeedbackEXT)vk::GetDeviceProcAddr(m_device->device(), "vkCmdEndTransformFeedbackEXT");
6070 ASSERT_TRUE(vkCmdEndTransformFeedbackEXT != nullptr);
6071
6072 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdEndTransformFeedbackEXT-transformFeedback-02374");
6073 m_errorMonitor->SetUnexpectedError("VUID-vkCmdEndTransformFeedbackEXT-None-02375");
6074 vkCmdEndTransformFeedbackEXT(m_commandBuffer->handle(), 0, 1, nullptr, nullptr);
6075 m_errorMonitor->VerifyFound();
6076 }
6077}
6078
6079TEST_F(VkLayerTest, TransformFeedbackCmdBindTransformFeedbackBuffersEXT) {
6080 TEST_DESCRIPTION("Submit invalid arguments to vkCmdBindTransformFeedbackBuffersEXT");
6081
6082 if (!InstanceExtensionSupported(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME)) {
6083 printf("%s Did not find required instance extension %s; skipped.\n", kSkipPrefix,
6084 VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
6085 return;
6086 }
6087 m_instance_extension_names.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
6088
6089 ASSERT_NO_FATAL_FAILURE(InitFramework(m_errorMonitor));
6090
6091 if (!DeviceExtensionSupported(gpu(), nullptr, VK_EXT_TRANSFORM_FEEDBACK_EXTENSION_NAME)) {
6092 printf("%s %s Extension not supported, skipping tests\n", kSkipPrefix, VK_EXT_TRANSFORM_FEEDBACK_EXTENSION_NAME);
6093 return;
6094 }
6095 m_device_extension_names.push_back(VK_EXT_TRANSFORM_FEEDBACK_EXTENSION_NAME);
6096
6097 {
6098 PFN_vkGetPhysicalDeviceFeatures2KHR vkGetPhysicalDeviceFeatures2KHR =
6099 (PFN_vkGetPhysicalDeviceFeatures2KHR)vk::GetInstanceProcAddr(instance(), "vkGetPhysicalDeviceFeatures2KHR");
6100 ASSERT_TRUE(vkGetPhysicalDeviceFeatures2KHR != nullptr);
6101
6102 auto tf_features = lvl_init_struct<VkPhysicalDeviceTransformFeedbackFeaturesEXT>();
6103 auto pd_features = lvl_init_struct<VkPhysicalDeviceFeatures2>(&tf_features);
6104 vkGetPhysicalDeviceFeatures2KHR(gpu(), &pd_features);
6105
6106 if (!tf_features.transformFeedback) {
6107 printf("%s transformFeedback not supported; skipped.\n", kSkipPrefix);
6108 return;
6109 }
6110
6111 ASSERT_NO_FATAL_FAILURE(InitState(nullptr, &pd_features));
6112 }
6113
6114 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
6115
6116 auto vkCmdBindTransformFeedbackBuffersEXT =
6117 (PFN_vkCmdBindTransformFeedbackBuffersEXT)vk::GetDeviceProcAddr(m_device->device(), "vkCmdBindTransformFeedbackBuffersEXT");
6118 ASSERT_TRUE(vkCmdBindTransformFeedbackBuffersEXT != nullptr);
6119
6120 {
6121 auto tf_properties = lvl_init_struct<VkPhysicalDeviceTransformFeedbackPropertiesEXT>();
6122 auto pd_properties = lvl_init_struct<VkPhysicalDeviceProperties2>(&tf_properties);
6123 vk::GetPhysicalDeviceProperties2(gpu(), &pd_properties);
6124
6125 auto info = lvl_init_struct<VkBufferCreateInfo>();
6126 info.usage = VK_BUFFER_USAGE_TRANSFORM_FEEDBACK_BUFFER_BIT_EXT;
6127 info.size = 8;
6128 VkBufferObj const buffer_obj(*m_device, info);
6129
6130 // Request a firstBinding that is too large.
6131 {
6132 auto const firstBinding = tf_properties.maxTransformFeedbackBuffers;
6133 VkDeviceSize const offsets[1]{};
6134
6135 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdBindTransformFeedbackBuffersEXT-firstBinding-02356");
6136 m_errorMonitor->SetUnexpectedError("VUID-vkCmdBindTransformFeedbackBuffersEXT-firstBinding-02357");
6137 vkCmdBindTransformFeedbackBuffersEXT(m_commandBuffer->handle(), firstBinding, 1, &buffer_obj.handle(), offsets,
6138 nullptr);
6139 m_errorMonitor->VerifyFound();
6140 }
6141
6142 // Request too many bindings.
6143 if (tf_properties.maxTransformFeedbackBuffers < std::numeric_limits<uint32_t>::max()) {
6144 auto const bindingCount = tf_properties.maxTransformFeedbackBuffers + 1;
6145 std::vector<VkBuffer> buffers(bindingCount, buffer_obj.handle());
6146
6147 std::vector<VkDeviceSize> offsets(bindingCount);
6148
6149 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdBindTransformFeedbackBuffersEXT-firstBinding-02357");
6150 vkCmdBindTransformFeedbackBuffersEXT(m_commandBuffer->handle(), 0, bindingCount, buffers.data(), offsets.data(),
6151 nullptr);
6152 m_errorMonitor->VerifyFound();
6153 }
6154
6155 // Request a size that is larger than the maximum size.
6156 if (tf_properties.maxTransformFeedbackBufferSize < std::numeric_limits<VkDeviceSize>::max()) {
6157 VkDeviceSize const offsets[1]{};
6158 VkDeviceSize const sizes[1]{tf_properties.maxTransformFeedbackBufferSize + 1};
6159
6160 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdBindTransformFeedbackBuffersEXT-pSize-02361");
6161 vkCmdBindTransformFeedbackBuffersEXT(m_commandBuffer->handle(), 0, 1, &buffer_obj.handle(), offsets, sizes);
6162 m_errorMonitor->VerifyFound();
6163 }
6164 }
6165
6166 {
6167 auto info = lvl_init_struct<VkBufferCreateInfo>();
6168 info.usage = VK_BUFFER_USAGE_TRANSFORM_FEEDBACK_BUFFER_BIT_EXT;
6169 info.size = 8;
6170 VkBufferObj const buffer_obj(*m_device, info);
6171
6172 // Request an offset that is too large.
6173 {
6174 VkDeviceSize const offsets[1]{info.size + 4};
6175
6176 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdBindTransformFeedbackBuffersEXT-pOffsets-02358");
6177 vkCmdBindTransformFeedbackBuffersEXT(m_commandBuffer->handle(), 0, 1, &buffer_obj.handle(), offsets, nullptr);
6178 m_errorMonitor->VerifyFound();
6179 }
6180
6181 // Request an offset that is not a multiple of 4.
6182 {
6183 VkDeviceSize const offsets[1]{1};
6184
6185 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdBindTransformFeedbackBuffersEXT-pOffsets-02359");
6186 vkCmdBindTransformFeedbackBuffersEXT(m_commandBuffer->handle(), 0, 1, &buffer_obj.handle(), offsets, nullptr);
6187 m_errorMonitor->VerifyFound();
6188 }
6189
6190 // Request a size that is larger than the buffer's size.
6191 {
6192 VkDeviceSize const offsets[1]{};
6193 VkDeviceSize const sizes[1]{info.size + 1};
6194
6195 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdBindTransformFeedbackBuffersEXT-pSizes-02362");
6196 m_errorMonitor->SetUnexpectedError("VUID-vkCmdBindTransformFeedbackBuffersEXT-pOffsets-02363");
6197 vkCmdBindTransformFeedbackBuffersEXT(m_commandBuffer->handle(), 0, 1, &buffer_obj.handle(), offsets, sizes);
6198 m_errorMonitor->VerifyFound();
6199 }
6200
6201 // Request an offset and size whose sum is larger than the buffer's size.
6202 {
6203 VkDeviceSize const offsets[1]{4};
6204 VkDeviceSize const sizes[1]{info.size - 3};
6205
6206 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdBindTransformFeedbackBuffersEXT-pOffsets-02363");
6207 vkCmdBindTransformFeedbackBuffersEXT(m_commandBuffer->handle(), 0, 1, &buffer_obj.handle(), offsets, sizes);
6208 m_errorMonitor->VerifyFound();
6209 }
6210
6211 // Bind while transform feedback is active.
6212 {
6213 auto vkCmdBeginTransformFeedbackEXT =
6214 (PFN_vkCmdBeginTransformFeedbackEXT)vk::GetDeviceProcAddr(m_device->device(), "vkCmdBeginTransformFeedbackEXT");
6215 ASSERT_TRUE(vkCmdBeginTransformFeedbackEXT != nullptr);
6216 vkCmdBeginTransformFeedbackEXT(m_commandBuffer->handle(), 0, 1, nullptr, nullptr);
6217
6218 VkDeviceSize const offsets[1]{};
6219
6220 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdBindTransformFeedbackBuffersEXT-None-02365");
6221 vkCmdBindTransformFeedbackBuffersEXT(m_commandBuffer->handle(), 0, 1, &buffer_obj.handle(), offsets, nullptr);
6222 m_errorMonitor->VerifyFound();
6223
6224 auto vkCmdEndTransformFeedbackEXT =
6225 (PFN_vkCmdEndTransformFeedbackEXT)vk::GetDeviceProcAddr(m_device->device(), "vkCmdEndTransformFeedbackEXT");
6226 ASSERT_TRUE(vkCmdEndTransformFeedbackEXT != nullptr);
6227 vkCmdEndTransformFeedbackEXT(m_commandBuffer->handle(), 0, 1, nullptr, nullptr);
6228 }
6229 }
6230
6231 // Don't set VK_BUFFER_USAGE_TRANSFORM_FEEDBACK_BUFFER_BIT_EXT.
6232 {
6233 auto info = lvl_init_struct<VkBufferCreateInfo>();
6234 // info.usage = VK_BUFFER_USAGE_TRANSFORM_FEEDBACK_BUFFER_BIT_EXT;
6235 info.size = 4;
6236 VkBufferObj const buffer_obj(*m_device, info);
6237
6238 VkDeviceSize const offsets[1]{};
6239
6240 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdBindTransformFeedbackBuffersEXT-pBuffers-02360");
6241 vkCmdBindTransformFeedbackBuffersEXT(m_commandBuffer->handle(), 0, 1, &buffer_obj.handle(), offsets, nullptr);
6242 m_errorMonitor->VerifyFound();
6243 }
6244
6245 // Don't bind memory.
6246 {
6247 VkBuffer buffer{};
6248 {
6249 auto vkCreateBuffer = (PFN_vkCreateBuffer)vk::GetDeviceProcAddr(m_device->device(), "vkCreateBuffer");
6250 ASSERT_TRUE(vkCreateBuffer != nullptr);
6251
6252 auto info = lvl_init_struct<VkBufferCreateInfo>();
6253 info.usage = VK_BUFFER_USAGE_TRANSFORM_FEEDBACK_BUFFER_BIT_EXT;
6254 info.size = 4;
6255 vkCreateBuffer(m_device->device(), &info, nullptr, &buffer);
6256 }
6257
6258 VkDeviceSize const offsets[1]{};
6259
6260 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdBindTransformFeedbackBuffersEXT-pBuffers-02364");
6261 vkCmdBindTransformFeedbackBuffersEXT(m_commandBuffer->handle(), 0, 1, &buffer, offsets, nullptr);
6262 m_errorMonitor->VerifyFound();
6263 }
6264}
6265
6266TEST_F(VkLayerTest, TransformFeedbackCmdBeginTransformFeedbackEXT) {
6267 TEST_DESCRIPTION("Submit invalid arguments to vkCmdBeginTransformFeedbackEXT");
6268
6269 if (!InstanceExtensionSupported(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME)) {
6270 printf("%s Did not find required instance extension %s; skipped.\n", kSkipPrefix,
6271 VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
6272 return;
6273 }
6274 m_instance_extension_names.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
6275
6276 ASSERT_NO_FATAL_FAILURE(InitFramework(m_errorMonitor));
6277
6278 if (!DeviceExtensionSupported(gpu(), nullptr, VK_EXT_TRANSFORM_FEEDBACK_EXTENSION_NAME)) {
6279 printf("%s %s Extension not supported, skipping tests\n", kSkipPrefix, VK_EXT_TRANSFORM_FEEDBACK_EXTENSION_NAME);
6280 return;
6281 }
6282 m_device_extension_names.push_back(VK_EXT_TRANSFORM_FEEDBACK_EXTENSION_NAME);
6283
6284 {
6285 PFN_vkGetPhysicalDeviceFeatures2KHR vkGetPhysicalDeviceFeatures2KHR =
6286 (PFN_vkGetPhysicalDeviceFeatures2KHR)vk::GetInstanceProcAddr(instance(), "vkGetPhysicalDeviceFeatures2KHR");
6287 ASSERT_TRUE(vkGetPhysicalDeviceFeatures2KHR != nullptr);
6288
6289 auto tf_features = lvl_init_struct<VkPhysicalDeviceTransformFeedbackFeaturesEXT>();
6290 auto pd_features = lvl_init_struct<VkPhysicalDeviceFeatures2>(&tf_features);
6291 vkGetPhysicalDeviceFeatures2KHR(gpu(), &pd_features);
6292
6293 if (!tf_features.transformFeedback) {
6294 printf("%s transformFeedback not supported; skipped.\n", kSkipPrefix);
6295 return;
6296 }
6297
6298 ASSERT_NO_FATAL_FAILURE(InitState(nullptr, &pd_features));
6299 }
6300
6301 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
6302
6303 auto vkCmdBeginTransformFeedbackEXT =
6304 (PFN_vkCmdBeginTransformFeedbackEXT)vk::GetDeviceProcAddr(m_device->device(), "vkCmdBeginTransformFeedbackEXT");
6305 ASSERT_TRUE(vkCmdBeginTransformFeedbackEXT != nullptr);
6306
6307 {
6308 auto tf_properties = lvl_init_struct<VkPhysicalDeviceTransformFeedbackPropertiesEXT>();
6309 auto pd_properties = lvl_init_struct<VkPhysicalDeviceProperties2>(&tf_properties);
6310 vk::GetPhysicalDeviceProperties2(gpu(), &pd_properties);
6311
6312 // Request a firstCounterBuffer that is too large.
6313 {
6314 auto const firstCounterBuffer = tf_properties.maxTransformFeedbackBuffers;
6315
6316 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdBeginTransformFeedbackEXT-firstCounterBuffer-02368");
6317 m_errorMonitor->SetUnexpectedError("VUID-vkCmdBeginTransformFeedbackEXT-firstCounterBuffer-02369");
6318 vkCmdBeginTransformFeedbackEXT(m_commandBuffer->handle(), firstCounterBuffer, 1, nullptr, nullptr);
6319 m_errorMonitor->VerifyFound();
6320 }
6321
6322 // Request too many buffers.
6323 if (tf_properties.maxTransformFeedbackBuffers < std::numeric_limits<uint32_t>::max()) {
6324 auto const counterBufferCount = tf_properties.maxTransformFeedbackBuffers + 1;
6325
6326 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdBeginTransformFeedbackEXT-firstCounterBuffer-02369");
6327 vkCmdBeginTransformFeedbackEXT(m_commandBuffer->handle(), 0, counterBufferCount, nullptr, nullptr);
6328 m_errorMonitor->VerifyFound();
6329 }
6330 }
6331
6332 // Request an out-of-bounds location.
6333 {
6334 auto info = lvl_init_struct<VkBufferCreateInfo>();
6335 info.usage = VK_BUFFER_USAGE_TRANSFORM_FEEDBACK_COUNTER_BUFFER_BIT_EXT;
6336 info.size = 4;
6337 VkBufferObj const buffer_obj(*m_device, info);
6338
6339 VkDeviceSize const offsets[1]{1};
6340
6341 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdBeginTransformFeedbackEXT-pCounterBufferOffsets-02370");
6342 vkCmdBeginTransformFeedbackEXT(m_commandBuffer->handle(), 0, 1, &buffer_obj.handle(), offsets);
6343 m_errorMonitor->VerifyFound();
6344 }
6345
6346 // Request specific offsets without specifying buffers.
6347 {
6348 VkDeviceSize const offsets[1]{};
6349
6350 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdBeginTransformFeedbackEXT-pCounterBuffer-02371");
6351 vkCmdBeginTransformFeedbackEXT(m_commandBuffer->handle(), 0, 1, nullptr, offsets);
6352 m_errorMonitor->VerifyFound();
6353 }
6354
6355 // Don't set VK_BUFFER_USAGE_TRANSFORM_FEEDBACK_COUNTER_BUFFER_BIT_EXT.
6356 {
6357 auto info = lvl_init_struct<VkBufferCreateInfo>();
6358 // info.usage = VK_BUFFER_USAGE_TRANSFORM_FEEDBACK_COUNTER_BUFFER_BIT_EXT;
6359 info.size = 4;
6360 VkBufferObj const buffer_obj(*m_device, info);
6361
6362 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdBeginTransformFeedbackEXT-pCounterBuffers-02372");
6363 vkCmdBeginTransformFeedbackEXT(m_commandBuffer->handle(), 0, 1, &buffer_obj.handle(), nullptr);
6364 m_errorMonitor->VerifyFound();
6365 }
6366
6367 // Begin while transform feedback is active.
6368 {
6369 vkCmdBeginTransformFeedbackEXT(m_commandBuffer->handle(), 0, 1, nullptr, nullptr);
6370
6371 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdBeginTransformFeedbackEXT-None-02367");
6372 vkCmdBeginTransformFeedbackEXT(m_commandBuffer->handle(), 0, 1, nullptr, nullptr);
6373 m_errorMonitor->VerifyFound();
6374
6375 auto vkCmdEndTransformFeedbackEXT =
6376 (PFN_vkCmdEndTransformFeedbackEXT)vk::GetDeviceProcAddr(m_device->device(), "vkCmdEndTransformFeedbackEXT");
6377 ASSERT_TRUE(vkCmdEndTransformFeedbackEXT != nullptr);
6378
6379 vkCmdEndTransformFeedbackEXT(m_commandBuffer->handle(), 0, 1, nullptr, nullptr);
6380 }
6381}
6382
6383TEST_F(VkLayerTest, TransformFeedbackCmdEndTransformFeedbackEXT) {
6384 TEST_DESCRIPTION("Submit invalid arguments to vkCmdEndTransformFeedbackEXT");
6385
6386 if (!InstanceExtensionSupported(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME)) {
6387 printf("%s Did not find required instance extension %s; skipped.\n", kSkipPrefix,
6388 VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
6389 return;
6390 }
6391 m_instance_extension_names.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
6392
6393 ASSERT_NO_FATAL_FAILURE(InitFramework(m_errorMonitor));
6394
6395 if (!DeviceExtensionSupported(gpu(), nullptr, VK_EXT_TRANSFORM_FEEDBACK_EXTENSION_NAME)) {
6396 printf("%s %s Extension not supported, skipping tests\n", kSkipPrefix, VK_EXT_TRANSFORM_FEEDBACK_EXTENSION_NAME);
6397 return;
6398 }
6399 m_device_extension_names.push_back(VK_EXT_TRANSFORM_FEEDBACK_EXTENSION_NAME);
6400
6401 {
6402 PFN_vkGetPhysicalDeviceFeatures2KHR vkGetPhysicalDeviceFeatures2KHR =
6403 (PFN_vkGetPhysicalDeviceFeatures2KHR)vk::GetInstanceProcAddr(instance(), "vkGetPhysicalDeviceFeatures2KHR");
6404 ASSERT_TRUE(vkGetPhysicalDeviceFeatures2KHR != nullptr);
6405
6406 auto tf_features = lvl_init_struct<VkPhysicalDeviceTransformFeedbackFeaturesEXT>();
6407 auto pd_features = lvl_init_struct<VkPhysicalDeviceFeatures2>(&tf_features);
6408 vkGetPhysicalDeviceFeatures2KHR(gpu(), &pd_features);
6409
6410 if (!tf_features.transformFeedback) {
6411 printf("%s transformFeedback not supported; skipped.\n", kSkipPrefix);
6412 return;
6413 }
6414
6415 ASSERT_NO_FATAL_FAILURE(InitState(nullptr, &pd_features));
6416 }
6417
6418 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
6419
6420 auto vkCmdEndTransformFeedbackEXT =
6421 (PFN_vkCmdEndTransformFeedbackEXT)vk::GetDeviceProcAddr(m_device->device(), "vkCmdEndTransformFeedbackEXT");
6422 ASSERT_TRUE(vkCmdEndTransformFeedbackEXT != nullptr);
6423
6424 {
6425 // Activate transform feedback.
6426 auto vkCmdBeginTransformFeedbackEXT =
6427 (PFN_vkCmdBeginTransformFeedbackEXT)vk::GetDeviceProcAddr(m_device->device(), "vkCmdBeginTransformFeedbackEXT");
6428 ASSERT_TRUE(vkCmdBeginTransformFeedbackEXT != nullptr);
6429 vkCmdBeginTransformFeedbackEXT(m_commandBuffer->handle(), 0, 1, nullptr, nullptr);
6430
6431 {
6432 auto tf_properties = lvl_init_struct<VkPhysicalDeviceTransformFeedbackPropertiesEXT>();
6433 auto pd_properties = lvl_init_struct<VkPhysicalDeviceProperties2>(&tf_properties);
6434 vk::GetPhysicalDeviceProperties2(gpu(), &pd_properties);
6435
6436 // Request a firstCounterBuffer that is too large.
6437 {
6438 auto const firstCounterBuffer = tf_properties.maxTransformFeedbackBuffers;
6439
6440 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdEndTransformFeedbackEXT-firstCounterBuffer-02376");
6441 m_errorMonitor->SetUnexpectedError("VUID-vkCmdEndTransformFeedbackEXT-firstCounterBuffer-02377");
6442 vkCmdEndTransformFeedbackEXT(m_commandBuffer->handle(), firstCounterBuffer, 1, nullptr, nullptr);
6443 m_errorMonitor->VerifyFound();
6444 }
6445
6446 // Request too many buffers.
6447 if (tf_properties.maxTransformFeedbackBuffers < std::numeric_limits<uint32_t>::max()) {
6448 auto const counterBufferCount = tf_properties.maxTransformFeedbackBuffers + 1;
6449
6450 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdEndTransformFeedbackEXT-firstCounterBuffer-02377");
6451 vkCmdEndTransformFeedbackEXT(m_commandBuffer->handle(), 0, counterBufferCount, nullptr, nullptr);
6452 m_errorMonitor->VerifyFound();
6453 }
6454 }
6455
6456 // Request an out-of-bounds location.
6457 {
6458 auto info = lvl_init_struct<VkBufferCreateInfo>();
6459 info.usage = VK_BUFFER_USAGE_TRANSFORM_FEEDBACK_COUNTER_BUFFER_BIT_EXT;
6460 info.size = 4;
6461 VkBufferObj const buffer_obj(*m_device, info);
6462
6463 VkDeviceSize const offsets[1]{1};
6464
6465 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdEndTransformFeedbackEXT-pCounterBufferOffsets-02378");
6466 vkCmdEndTransformFeedbackEXT(m_commandBuffer->handle(), 0, 1, &buffer_obj.handle(), offsets);
6467 m_errorMonitor->VerifyFound();
6468 }
6469
6470 // Request specific offsets without specifying buffers.
6471 {
6472 VkDeviceSize const offsets[1]{};
6473
6474 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdEndTransformFeedbackEXT-pCounterBuffer-02379");
6475 vkCmdEndTransformFeedbackEXT(m_commandBuffer->handle(), 0, 1, nullptr, offsets);
6476 m_errorMonitor->VerifyFound();
6477 }
6478
6479 // Don't set VK_BUFFER_USAGE_TRANSFORM_FEEDBACK_COUNTER_BUFFER_BIT_EXT.
6480 {
6481 auto info = lvl_init_struct<VkBufferCreateInfo>();
6482 // info.usage = VK_BUFFER_USAGE_TRANSFORM_FEEDBACK_COUNTER_BUFFER_BIT_EXT;
6483 info.size = 4;
6484 VkBufferObj const buffer_obj(*m_device, info);
6485
6486 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdEndTransformFeedbackEXT-pCounterBuffers-02380");
6487 vkCmdEndTransformFeedbackEXT(m_commandBuffer->handle(), 0, 1, &buffer_obj.handle(), nullptr);
6488 m_errorMonitor->VerifyFound();
6489 }
6490 }
6491
6492 // End while transform feedback is inactive.
6493 {
6494 vkCmdEndTransformFeedbackEXT(m_commandBuffer->handle(), 0, 1, nullptr, nullptr);
6495
6496 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdEndTransformFeedbackEXT-None-02375");
6497 vkCmdEndTransformFeedbackEXT(m_commandBuffer->handle(), 0, 1, nullptr, nullptr);
6498 m_errorMonitor->VerifyFound();
6499 }
6500}
sfricke-samsung071af2d2020-07-02 10:37:22 -07006501
6502TEST_F(VkLayerTest, UnprotectedIndirectCommands) {
6503 TEST_DESCRIPTION("Test making indirect commands in unprotected command buffers");
6504
6505 // protect memory added in VK 1.1
6506 SetTargetApiVersion(VK_API_VERSION_1_1);
6507
6508 if (InstanceExtensionSupported(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME)) {
6509 m_instance_extension_names.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
6510 } else {
6511 printf("%s Did not find required instance extension %s; skipped.\n", kSkipPrefix,
6512 VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
6513 return;
6514 }
6515 ASSERT_NO_FATAL_FAILURE(InitFramework(m_errorMonitor));
6516
6517 PFN_vkGetPhysicalDeviceFeatures2KHR vkGetPhysicalDeviceFeatures2KHR =
6518 (PFN_vkGetPhysicalDeviceFeatures2KHR)vk::GetInstanceProcAddr(instance(), "vkGetPhysicalDeviceFeatures2KHR");
6519 ASSERT_TRUE(vkGetPhysicalDeviceFeatures2KHR != nullptr);
6520
6521 auto protected_memory_features = lvl_init_struct<VkPhysicalDeviceProtectedMemoryFeatures>();
6522 auto features2 = lvl_init_struct<VkPhysicalDeviceFeatures2KHR>(&protected_memory_features);
6523 vkGetPhysicalDeviceFeatures2KHR(gpu(), &features2);
6524
6525 if (protected_memory_features.protectedMemory == VK_FALSE) {
6526 printf("%s protectedMemory feature not supported, skipped.\n", kSkipPrefix);
6527 return;
6528 };
6529
6530 // Turns m_commandBuffer into a protected command buffer
6531 ASSERT_NO_FATAL_FAILURE(InitState(nullptr, &features2, VK_COMMAND_POOL_CREATE_PROTECTED_BIT));
6532
6533 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
6534 if (DeviceValidationVersion() < VK_API_VERSION_1_1) {
6535 printf("%s Tests requires Vulkan 1.1+, skipping test\n", kSkipPrefix);
6536 return;
6537 }
6538
6539 VkBufferObj indirect_buffer;
6540 indirect_buffer.init(*m_device, sizeof(VkDrawIndirectCommand), VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT,
6541 VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT);
6542
6543 VkBufferObj indexed_indirect_buffer;
6544 indexed_indirect_buffer.init(*m_device, sizeof(VkDrawIndexedIndirectCommand), VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT,
6545 VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT);
6546
6547 VkBufferObj index_buffer;
6548 index_buffer.init(*m_device, sizeof(uint32_t), VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, VK_BUFFER_USAGE_INDEX_BUFFER_BIT);
6549
6550 CreatePipelineHelper pipe(*this);
6551 pipe.InitInfo();
6552 pipe.InitState();
6553 pipe.CreateGraphicsPipeline();
6554
6555 m_commandBuffer->begin();
6556 m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
6557
6558 vk::CmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.pipeline_);
6559
6560 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdDrawIndirect-commandBuffer-02711");
6561 vk::CmdDrawIndirect(m_commandBuffer->handle(), indirect_buffer.handle(), 0, 1, sizeof(VkDrawIndirectCommand));
6562 m_errorMonitor->VerifyFound();
6563
6564 vk::CmdBindIndexBuffer(m_commandBuffer->handle(), index_buffer.handle(), 0, VK_INDEX_TYPE_UINT32);
6565
6566 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdDrawIndexedIndirect-commandBuffer-02711");
6567 vk::CmdDrawIndexedIndirect(m_commandBuffer->handle(), indexed_indirect_buffer.handle(), 0, 1,
6568 sizeof(VkDrawIndexedIndirectCommand));
6569 m_errorMonitor->VerifyFound();
6570
6571 m_commandBuffer->EndRenderPass();
6572 m_commandBuffer->end();
6573}