blob: bd47ee9a41a9b3ea59b522d82569035e896b277a [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
Mark Lobodzinski20310782020-02-28 14:25:17 -0700152 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdPipelineBarrier-image-02635");
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
742TEST_F(VkLayerTest, ClearColorAttachmentsOutsideRenderPass) {
743 // Call CmdClearAttachmentss outside of an active RenderPass
744
Mark Lobodzinski20310782020-02-28 14:25:17 -0700745 m_errorMonitor->SetDesiredFailureMsg(kErrorBit,
unknown088160a2019-05-23 17:43:13 -0600746 "vkCmdClearAttachments(): This call must be issued inside an active render pass");
747
748 ASSERT_NO_FATAL_FAILURE(Init());
749 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
750
751 // Start no RenderPass
752 m_commandBuffer->begin();
753
754 VkClearAttachment color_attachment;
755 color_attachment.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
756 color_attachment.clearValue.color.float32[0] = 0;
757 color_attachment.clearValue.color.float32[1] = 0;
758 color_attachment.clearValue.color.float32[2] = 0;
759 color_attachment.clearValue.color.float32[3] = 0;
760 color_attachment.colorAttachment = 0;
Mark Lobodzinskid5447512019-06-28 09:56:36 -0600761 VkClearRect clear_rect = {{{0, 0}, {32, 32}}, 0, 1};
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -0600762 vk::CmdClearAttachments(m_commandBuffer->handle(), 1, &color_attachment, 1, &clear_rect);
unknown088160a2019-05-23 17:43:13 -0600763
764 m_errorMonitor->VerifyFound();
765}
766
Mark Lobodzinski7d7da062019-06-27 16:01:39 -0600767TEST_F(VkLayerTest, ClearColorAttachmentsZeroLayercount) {
768 TEST_DESCRIPTION("Call CmdClearAttachments with a pRect having a layerCount of zero.");
769
Mark Lobodzinski20310782020-02-28 14:25:17 -0700770 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdClearAttachments-layerCount-01934");
Mark Lobodzinski7d7da062019-06-27 16:01:39 -0600771
772 ASSERT_NO_FATAL_FAILURE(Init());
773 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
774
775 m_commandBuffer->begin();
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -0600776 vk::CmdBeginRenderPass(m_commandBuffer->handle(), &renderPassBeginInfo(), VK_SUBPASS_CONTENTS_INLINE);
Mark Lobodzinski7d7da062019-06-27 16:01:39 -0600777
778 VkClearAttachment color_attachment;
779 color_attachment.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
780 color_attachment.clearValue.color.float32[0] = 0;
781 color_attachment.clearValue.color.float32[1] = 0;
782 color_attachment.clearValue.color.float32[2] = 0;
783 color_attachment.clearValue.color.float32[3] = 0;
784 color_attachment.colorAttachment = 0;
785 VkClearRect clear_rect = {{{0, 0}, {32, 32}}};
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -0600786 vk::CmdClearAttachments(m_commandBuffer->handle(), 1, &color_attachment, 1, &clear_rect);
Mark Lobodzinski7d7da062019-06-27 16:01:39 -0600787
788 m_errorMonitor->VerifyFound();
789}
790
sfricke-samsungf0f3d8b2020-04-25 02:20:47 -0700791TEST_F(VkLayerTest, ClearColorAttachmentsZeroExtent) {
792 TEST_DESCRIPTION("Call CmdClearAttachments with a pRect having a rect2D extent of zero.");
793
794 ASSERT_NO_FATAL_FAILURE(Init());
795 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
796
797 m_commandBuffer->begin();
798 vk::CmdBeginRenderPass(m_commandBuffer->handle(), &renderPassBeginInfo(), VK_SUBPASS_CONTENTS_INLINE);
799
800 VkClearAttachment color_attachment;
801 color_attachment.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
802 color_attachment.clearValue.color.float32[0] = 0;
803 color_attachment.clearValue.color.float32[1] = 0;
804 color_attachment.clearValue.color.float32[2] = 0;
805 color_attachment.clearValue.color.float32[3] = 0;
806 color_attachment.colorAttachment = 0;
807 VkClearRect clear_rect = {};
808 clear_rect.rect.offset = {0, 0};
809 clear_rect.baseArrayLayer = 0;
810 clear_rect.layerCount = 1;
811
812 clear_rect.rect.extent = {0, 1};
813 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdClearAttachments-rect-02682");
814 vk::CmdClearAttachments(m_commandBuffer->handle(), 1, &color_attachment, 1, &clear_rect);
815 m_errorMonitor->VerifyFound();
816
817 clear_rect.rect.extent = {1, 0};
818 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdClearAttachments-rect-02683");
819 vk::CmdClearAttachments(m_commandBuffer->handle(), 1, &color_attachment, 1, &clear_rect);
820 m_errorMonitor->VerifyFound();
821}
822
unknown088160a2019-05-23 17:43:13 -0600823TEST_F(VkLayerTest, ExecuteCommandsPrimaryCB) {
824 TEST_DESCRIPTION("Attempt vkCmdExecuteCommands with a primary command buffer (should only be secondary)");
825
826 ASSERT_NO_FATAL_FAILURE(Init());
827 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
828
829 // An empty primary command buffer
830 VkCommandBufferObj cb(m_device, m_commandPool);
831 cb.begin();
832 cb.end();
833
834 m_commandBuffer->begin();
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -0600835 vk::CmdBeginRenderPass(m_commandBuffer->handle(), &renderPassBeginInfo(), VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS);
unknown088160a2019-05-23 17:43:13 -0600836 VkCommandBuffer handle = cb.handle();
837
Mark Lobodzinski20310782020-02-28 14:25:17 -0700838 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdExecuteCommands-pCommandBuffers-00088");
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -0600839 vk::CmdExecuteCommands(m_commandBuffer->handle(), 1, &handle);
unknown088160a2019-05-23 17:43:13 -0600840 m_errorMonitor->VerifyFound();
841
842 m_errorMonitor->SetUnexpectedError("All elements of pCommandBuffers must not be in the pending state");
843
844 m_commandBuffer->EndRenderPass();
845 m_commandBuffer->end();
846}
847
Petr Kraus8e53cf02020-01-03 05:30:04 +0100848TEST_F(VkLayerTest, ExecuteCommandsToSecondaryCB) {
849 TEST_DESCRIPTION("Attempt vkCmdExecuteCommands to a Secondary command buffer");
850
851 ASSERT_NO_FATAL_FAILURE(Init());
852
853 VkCommandBufferObj main_cb(m_device, m_commandPool, VK_COMMAND_BUFFER_LEVEL_SECONDARY);
854 VkCommandBufferObj secondary_cb(m_device, m_commandPool, VK_COMMAND_BUFFER_LEVEL_SECONDARY);
855 secondary_cb.begin();
856 secondary_cb.end();
857
858 main_cb.begin();
Mark Lobodzinski20310782020-02-28 14:25:17 -0700859 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdExecuteCommands-bufferlevel");
Petr Kraus8e53cf02020-01-03 05:30:04 +0100860 vk::CmdExecuteCommands(main_cb.handle(), 1, &secondary_cb.handle());
861 m_errorMonitor->VerifyFound();
862}
863
unknown088160a2019-05-23 17:43:13 -0600864TEST_F(VkLayerTest, InvalidVertexAttributeAlignment) {
865 TEST_DESCRIPTION("Check for proper aligment of attribAddress which depends on a bound pipeline and on a bound vertex buffer");
866
867 ASSERT_NO_FATAL_FAILURE(Init());
868 ASSERT_NO_FATAL_FAILURE(InitViewport());
869 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
870
871 const VkPipelineLayoutObj pipeline_layout(m_device);
872
873 struct VboEntry {
874 uint16_t input0[2];
875 uint32_t input1;
876 float input2[4];
877 };
878
879 const unsigned vbo_entry_count = 3;
880 const VboEntry vbo_data[vbo_entry_count] = {};
881
882 VkConstantBufferObj vbo(m_device, static_cast<int>(sizeof(VboEntry) * vbo_entry_count),
883 reinterpret_cast<const void *>(vbo_data), VK_BUFFER_USAGE_VERTEX_BUFFER_BIT);
884
885 VkVertexInputBindingDescription input_binding;
886 input_binding.binding = 0;
887 input_binding.stride = sizeof(VboEntry);
888 input_binding.inputRate = VK_VERTEX_INPUT_RATE_VERTEX;
889
890 VkVertexInputAttributeDescription input_attribs[3];
891
892 input_attribs[0].binding = 0;
893 // Location switch between attrib[0] and attrib[1] is intentional
894 input_attribs[0].location = 1;
895 input_attribs[0].format = VK_FORMAT_A8B8G8R8_UNORM_PACK32;
896 input_attribs[0].offset = offsetof(VboEntry, input1);
897
898 input_attribs[1].binding = 0;
899 input_attribs[1].location = 0;
900 input_attribs[1].format = VK_FORMAT_R16G16_UNORM;
901 input_attribs[1].offset = offsetof(VboEntry, input0);
902
903 input_attribs[2].binding = 0;
904 input_attribs[2].location = 2;
905 input_attribs[2].format = VK_FORMAT_R32G32B32A32_SFLOAT;
906 input_attribs[2].offset = offsetof(VboEntry, input2);
907
908 char const *vsSource =
909 "#version 450\n"
910 "\n"
911 "layout(location = 0) in vec2 input0;"
912 "layout(location = 1) in vec4 input1;"
913 "layout(location = 2) in vec4 input2;"
914 "\n"
915 "void main(){\n"
916 " gl_Position = input1 + input2;\n"
917 " gl_Position.xy += input0;\n"
918 "}\n";
unknown088160a2019-05-23 17:43:13 -0600919
920 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
locke-lunarg8e2c91b2019-06-11 17:53:26 -0600921 VkShaderObj fs(m_device, bindStateFragShaderText, VK_SHADER_STAGE_FRAGMENT_BIT, this);
unknown088160a2019-05-23 17:43:13 -0600922
923 VkPipelineObj pipe1(m_device);
924 pipe1.AddDefaultColorAttachment();
925 pipe1.AddShader(&vs);
926 pipe1.AddShader(&fs);
927 pipe1.AddVertexInputBindings(&input_binding, 1);
928 pipe1.AddVertexInputAttribs(&input_attribs[0], 3);
929 pipe1.SetViewport(m_viewports);
930 pipe1.SetScissor(m_scissors);
931 pipe1.CreateVKPipeline(pipeline_layout.handle(), renderPass());
932
933 input_binding.stride = 6;
934
935 VkPipelineObj pipe2(m_device);
936 pipe2.AddDefaultColorAttachment();
937 pipe2.AddShader(&vs);
938 pipe2.AddShader(&fs);
939 pipe2.AddVertexInputBindings(&input_binding, 1);
940 pipe2.AddVertexInputAttribs(&input_attribs[0], 3);
941 pipe2.SetViewport(m_viewports);
942 pipe2.SetScissor(m_scissors);
943 pipe2.CreateVKPipeline(pipeline_layout.handle(), renderPass());
944
945 m_commandBuffer->begin();
946 m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
947
948 // Test with invalid buffer offset
949 VkDeviceSize offset = 1;
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -0600950 vk::CmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe1.handle());
951 vk::CmdBindVertexBuffers(m_commandBuffer->handle(), 0, 1, &vbo.handle(), &offset);
Mark Lobodzinski20310782020-02-28 14:25:17 -0700952 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "Invalid attribAddress alignment for vertex attribute 0");
953 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "Invalid attribAddress alignment for vertex attribute 1");
954 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "Invalid attribAddress alignment for vertex attribute 2");
unknown088160a2019-05-23 17:43:13 -0600955 m_commandBuffer->Draw(1, 0, 0, 0);
956 m_errorMonitor->VerifyFound();
957
958 // Test with invalid buffer stride
959 offset = 0;
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -0600960 vk::CmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe2.handle());
961 vk::CmdBindVertexBuffers(m_commandBuffer->handle(), 0, 1, &vbo.handle(), &offset);
Mark Lobodzinski20310782020-02-28 14:25:17 -0700962 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "Invalid attribAddress alignment for vertex attribute 0");
unknown088160a2019-05-23 17:43:13 -0600963 // Attribute[1] is aligned properly even with a wrong stride
Mark Lobodzinski20310782020-02-28 14:25:17 -0700964 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "Invalid attribAddress alignment for vertex attribute 2");
unknown088160a2019-05-23 17:43:13 -0600965 m_commandBuffer->Draw(1, 0, 0, 0);
966 m_errorMonitor->VerifyFound();
967
968 m_commandBuffer->EndRenderPass();
969 m_commandBuffer->end();
970}
971
972TEST_F(VkLayerTest, NonSimultaneousSecondaryMarksPrimary) {
973 ASSERT_NO_FATAL_FAILURE(Init());
locke-lunarg77b9f7c2019-06-18 00:06:03 -0600974 const char *simultaneous_use_message = "UNASSIGNED-CoreValidation-DrawState-InvalidCommandBufferSimultaneousUse";
unknown088160a2019-05-23 17:43:13 -0600975
976 VkCommandBufferObj secondary(m_device, m_commandPool, VK_COMMAND_BUFFER_LEVEL_SECONDARY);
977
978 secondary.begin();
979 secondary.end();
980
981 VkCommandBufferBeginInfo cbbi = {
982 VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,
983 nullptr,
984 VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT,
985 nullptr,
986 };
987
988 m_commandBuffer->begin(&cbbi);
Mark Lobodzinski20310782020-02-28 14:25:17 -0700989 m_errorMonitor->SetDesiredFailureMsg(kWarningBit, simultaneous_use_message);
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -0600990 vk::CmdExecuteCommands(m_commandBuffer->handle(), 1, &secondary.handle());
unknown088160a2019-05-23 17:43:13 -0600991 m_errorMonitor->VerifyFound();
992 m_commandBuffer->end();
993}
994
995TEST_F(VkLayerTest, SimultaneousUseSecondaryTwoExecutes) {
996 ASSERT_NO_FATAL_FAILURE(Init());
997
John Zulauff1640d12019-08-13 15:39:58 -0600998 const char *simultaneous_use_message = "VUID-vkCmdExecuteCommands-pCommandBuffers-00092";
unknown088160a2019-05-23 17:43:13 -0600999
1000 VkCommandBufferObj secondary(m_device, m_commandPool, VK_COMMAND_BUFFER_LEVEL_SECONDARY);
1001
1002 VkCommandBufferInheritanceInfo inh = {
1003 VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO,
1004 nullptr,
1005 };
1006 VkCommandBufferBeginInfo cbbi = {VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, nullptr, 0, &inh};
1007
1008 secondary.begin(&cbbi);
1009 secondary.end();
1010
1011 m_commandBuffer->begin();
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06001012 vk::CmdExecuteCommands(m_commandBuffer->handle(), 1, &secondary.handle());
Mark Lobodzinski20310782020-02-28 14:25:17 -07001013 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, simultaneous_use_message);
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06001014 vk::CmdExecuteCommands(m_commandBuffer->handle(), 1, &secondary.handle());
unknown088160a2019-05-23 17:43:13 -06001015 m_errorMonitor->VerifyFound();
1016 m_commandBuffer->end();
1017}
1018
1019TEST_F(VkLayerTest, SimultaneousUseSecondarySingleExecute) {
1020 ASSERT_NO_FATAL_FAILURE(Init());
1021
1022 // variation on previous test executing the same CB twice in the same
1023 // CmdExecuteCommands call
1024
John Zulauff1640d12019-08-13 15:39:58 -06001025 const char *simultaneous_use_message = "VUID-vkCmdExecuteCommands-pCommandBuffers-00093";
unknown088160a2019-05-23 17:43:13 -06001026
1027 VkCommandBufferObj secondary(m_device, m_commandPool, VK_COMMAND_BUFFER_LEVEL_SECONDARY);
1028
1029 VkCommandBufferInheritanceInfo inh = {
1030 VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO,
1031 nullptr,
1032 };
1033 VkCommandBufferBeginInfo cbbi = {VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, nullptr, 0, &inh};
1034
1035 secondary.begin(&cbbi);
1036 secondary.end();
1037
1038 m_commandBuffer->begin();
1039 VkCommandBuffer cbs[] = {secondary.handle(), secondary.handle()};
Mark Lobodzinski20310782020-02-28 14:25:17 -07001040 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, simultaneous_use_message);
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06001041 vk::CmdExecuteCommands(m_commandBuffer->handle(), 2, cbs);
unknown088160a2019-05-23 17:43:13 -06001042 m_errorMonitor->VerifyFound();
1043 m_commandBuffer->end();
1044}
1045
1046TEST_F(VkLayerTest, SimultaneousUseOneShot) {
1047 TEST_DESCRIPTION("Submit the same command buffer twice in one submit looking for simultaneous use and one time submit errors");
1048 const char *simultaneous_use_message = "is already in use and is not marked for simultaneous use";
1049 const char *one_shot_message = "VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT set, but has been submitted";
1050 ASSERT_NO_FATAL_FAILURE(Init());
1051
1052 VkCommandBuffer cmd_bufs[2];
1053 VkCommandBufferAllocateInfo alloc_info;
1054 alloc_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
1055 alloc_info.pNext = NULL;
1056 alloc_info.commandBufferCount = 2;
1057 alloc_info.commandPool = m_commandPool->handle();
1058 alloc_info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06001059 vk::AllocateCommandBuffers(m_device->device(), &alloc_info, cmd_bufs);
unknown088160a2019-05-23 17:43:13 -06001060
1061 VkCommandBufferBeginInfo cb_binfo;
1062 cb_binfo.pNext = NULL;
1063 cb_binfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
1064 cb_binfo.pInheritanceInfo = VK_NULL_HANDLE;
1065 cb_binfo.flags = 0;
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06001066 vk::BeginCommandBuffer(cmd_bufs[0], &cb_binfo);
unknown088160a2019-05-23 17:43:13 -06001067 VkViewport viewport = {0, 0, 16, 16, 0, 1};
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06001068 vk::CmdSetViewport(cmd_bufs[0], 0, 1, &viewport);
1069 vk::EndCommandBuffer(cmd_bufs[0]);
unknown088160a2019-05-23 17:43:13 -06001070 VkCommandBuffer duplicates[2] = {cmd_bufs[0], cmd_bufs[0]};
1071
1072 VkSubmitInfo submit_info = {};
1073 submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
1074 submit_info.commandBufferCount = 2;
1075 submit_info.pCommandBuffers = duplicates;
Mark Lobodzinski20310782020-02-28 14:25:17 -07001076 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, simultaneous_use_message);
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06001077 vk::QueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
unknown088160a2019-05-23 17:43:13 -06001078 m_errorMonitor->VerifyFound();
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06001079 vk::QueueWaitIdle(m_device->m_queue);
unknown088160a2019-05-23 17:43:13 -06001080
1081 // Set one time use and now look for one time submit
1082 duplicates[0] = duplicates[1] = cmd_bufs[1];
1083 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 -06001084 vk::BeginCommandBuffer(cmd_bufs[1], &cb_binfo);
1085 vk::CmdSetViewport(cmd_bufs[1], 0, 1, &viewport);
1086 vk::EndCommandBuffer(cmd_bufs[1]);
Mark Lobodzinski20310782020-02-28 14:25:17 -07001087 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, one_shot_message);
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06001088 vk::QueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
unknown088160a2019-05-23 17:43:13 -06001089 m_errorMonitor->VerifyFound();
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06001090 vk::QueueWaitIdle(m_device->m_queue);
unknown088160a2019-05-23 17:43:13 -06001091}
1092
1093TEST_F(VkLayerTest, DrawTimeImageViewTypeMismatchWithPipeline) {
1094 TEST_DESCRIPTION(
1095 "Test that an error is produced when an image view type does not match the dimensionality declared in the shader");
1096
Mark Lobodzinski20310782020-02-28 14:25:17 -07001097 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "requires an image view of type VK_IMAGE_VIEW_TYPE_3D");
unknown088160a2019-05-23 17:43:13 -06001098
1099 ASSERT_NO_FATAL_FAILURE(Init());
1100 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
1101
unknown088160a2019-05-23 17:43:13 -06001102 char const *fsSource =
1103 "#version 450\n"
1104 "\n"
1105 "layout(set=0, binding=0) uniform sampler3D s;\n"
1106 "layout(location=0) out vec4 color;\n"
1107 "void main() {\n"
1108 " color = texture(s, vec3(0));\n"
1109 "}\n";
locke-lunarg8e2c91b2019-06-11 17:53:26 -06001110 VkShaderObj vs(m_device, bindStateVertShaderText, VK_SHADER_STAGE_VERTEX_BIT, this);
unknown088160a2019-05-23 17:43:13 -06001111 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
1112
1113 VkPipelineObj pipe(m_device);
1114 pipe.AddShader(&vs);
1115 pipe.AddShader(&fs);
1116 pipe.AddDefaultColorAttachment();
1117
1118 VkTextureObj texture(m_device, nullptr);
1119 VkSamplerObj sampler(m_device);
1120
1121 VkDescriptorSetObj descriptorSet(m_device);
1122 descriptorSet.AppendSamplerTexture(&sampler, &texture);
1123 descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
1124
1125 VkResult err = pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass());
1126 ASSERT_VK_SUCCESS(err);
1127
1128 m_commandBuffer->begin();
1129 m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
1130
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06001131 vk::CmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.handle());
unknown088160a2019-05-23 17:43:13 -06001132 m_commandBuffer->BindDescriptorSet(descriptorSet);
1133
1134 VkViewport viewport = {0, 0, 16, 16, 0, 1};
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06001135 vk::CmdSetViewport(m_commandBuffer->handle(), 0, 1, &viewport);
unknown088160a2019-05-23 17:43:13 -06001136 VkRect2D scissor = {{0, 0}, {16, 16}};
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06001137 vk::CmdSetScissor(m_commandBuffer->handle(), 0, 1, &scissor);
unknown088160a2019-05-23 17:43:13 -06001138
1139 // error produced here.
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06001140 vk::CmdDraw(m_commandBuffer->handle(), 3, 1, 0, 0);
unknown088160a2019-05-23 17:43:13 -06001141
1142 m_errorMonitor->VerifyFound();
1143
1144 m_commandBuffer->EndRenderPass();
1145 m_commandBuffer->end();
1146}
1147
1148TEST_F(VkLayerTest, DrawTimeImageMultisampleMismatchWithPipeline) {
1149 TEST_DESCRIPTION(
1150 "Test that an error is produced when a multisampled images are consumed via singlesample images types in the shader, or "
1151 "vice versa.");
1152
Mark Lobodzinski20310782020-02-28 14:25:17 -07001153 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "requires bound image to have multiple samples");
unknown088160a2019-05-23 17:43:13 -06001154
1155 ASSERT_NO_FATAL_FAILURE(Init());
1156 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
1157
unknown088160a2019-05-23 17:43:13 -06001158 char const *fsSource =
1159 "#version 450\n"
1160 "\n"
1161 "layout(set=0, binding=0) uniform sampler2DMS s;\n"
1162 "layout(location=0) out vec4 color;\n"
1163 "void main() {\n"
1164 " color = texelFetch(s, ivec2(0), 0);\n"
1165 "}\n";
locke-lunarg8e2c91b2019-06-11 17:53:26 -06001166 VkShaderObj vs(m_device, bindStateVertShaderText, VK_SHADER_STAGE_VERTEX_BIT, this);
unknown088160a2019-05-23 17:43:13 -06001167 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
1168
1169 VkPipelineObj pipe(m_device);
1170 pipe.AddShader(&vs);
1171 pipe.AddShader(&fs);
1172 pipe.AddDefaultColorAttachment();
1173
1174 VkTextureObj texture(m_device, nullptr); // THIS LINE CAUSES CRASH ON MALI
1175 VkSamplerObj sampler(m_device);
1176
1177 VkDescriptorSetObj descriptorSet(m_device);
1178 descriptorSet.AppendSamplerTexture(&sampler, &texture);
1179 descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
1180
1181 VkResult err = pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass());
1182 ASSERT_VK_SUCCESS(err);
1183
1184 m_commandBuffer->begin();
1185 m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
1186
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06001187 vk::CmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.handle());
unknown088160a2019-05-23 17:43:13 -06001188 m_commandBuffer->BindDescriptorSet(descriptorSet);
1189
1190 VkViewport viewport = {0, 0, 16, 16, 0, 1};
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06001191 vk::CmdSetViewport(m_commandBuffer->handle(), 0, 1, &viewport);
unknown088160a2019-05-23 17:43:13 -06001192 VkRect2D scissor = {{0, 0}, {16, 16}};
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06001193 vk::CmdSetScissor(m_commandBuffer->handle(), 0, 1, &scissor);
unknown088160a2019-05-23 17:43:13 -06001194
1195 // error produced here.
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06001196 vk::CmdDraw(m_commandBuffer->handle(), 3, 1, 0, 0);
unknown088160a2019-05-23 17:43:13 -06001197
1198 m_errorMonitor->VerifyFound();
1199
1200 m_commandBuffer->EndRenderPass();
1201 m_commandBuffer->end();
1202}
1203
1204TEST_F(VkLayerTest, DrawTimeImageComponentTypeMismatchWithPipeline) {
1205 TEST_DESCRIPTION(
1206 "Test that an error is produced when the component type of an imageview disagrees with the type in the shader.");
1207
Mark Lobodzinski20310782020-02-28 14:25:17 -07001208 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "SINT component type, but bound descriptor");
unknown088160a2019-05-23 17:43:13 -06001209
1210 ASSERT_NO_FATAL_FAILURE(Init());
1211 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
1212
unknown088160a2019-05-23 17:43:13 -06001213 char const *fsSource =
1214 "#version 450\n"
1215 "\n"
1216 "layout(set=0, binding=0) uniform isampler2D s;\n"
1217 "layout(location=0) out vec4 color;\n"
1218 "void main() {\n"
1219 " color = texelFetch(s, ivec2(0), 0);\n"
1220 "}\n";
locke-lunarg8e2c91b2019-06-11 17:53:26 -06001221 VkShaderObj vs(m_device, bindStateVertShaderText, VK_SHADER_STAGE_VERTEX_BIT, this);
unknown088160a2019-05-23 17:43:13 -06001222 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
1223
1224 VkPipelineObj pipe(m_device);
1225 pipe.AddShader(&vs);
1226 pipe.AddShader(&fs);
1227 pipe.AddDefaultColorAttachment();
1228
1229 VkTextureObj texture(m_device, nullptr); // UNORM texture by default, incompatible with isampler2D
1230 VkSamplerObj sampler(m_device);
1231
1232 VkDescriptorSetObj descriptorSet(m_device);
1233 descriptorSet.AppendSamplerTexture(&sampler, &texture);
1234 descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
1235
1236 VkResult err = pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass());
1237 ASSERT_VK_SUCCESS(err);
1238
1239 m_commandBuffer->begin();
1240 m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
1241
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06001242 vk::CmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.handle());
unknown088160a2019-05-23 17:43:13 -06001243 m_commandBuffer->BindDescriptorSet(descriptorSet);
1244
1245 VkViewport viewport = {0, 0, 16, 16, 0, 1};
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06001246 vk::CmdSetViewport(m_commandBuffer->handle(), 0, 1, &viewport);
unknown088160a2019-05-23 17:43:13 -06001247 VkRect2D scissor = {{0, 0}, {16, 16}};
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06001248 vk::CmdSetScissor(m_commandBuffer->handle(), 0, 1, &scissor);
unknown088160a2019-05-23 17:43:13 -06001249
1250 // error produced here.
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06001251 vk::CmdDraw(m_commandBuffer->handle(), 3, 1, 0, 0);
unknown088160a2019-05-23 17:43:13 -06001252
1253 m_errorMonitor->VerifyFound();
1254
1255 m_commandBuffer->EndRenderPass();
1256 m_commandBuffer->end();
1257}
1258
unknown088160a2019-05-23 17:43:13 -06001259TEST_F(VkLayerTest, CopyImageLayerCountMismatch) {
1260 TEST_DESCRIPTION(
1261 "Try to copy between images with the source subresource having a different layerCount than the destination subresource");
1262 ASSERT_NO_FATAL_FAILURE(Init());
1263
1264 // Create two images to copy between
1265 VkImageObj src_image_obj(m_device);
1266 VkImageObj dst_image_obj(m_device);
1267
1268 VkImageCreateInfo image_create_info = {};
1269 image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
1270 image_create_info.pNext = NULL;
1271 image_create_info.imageType = VK_IMAGE_TYPE_2D;
1272 image_create_info.format = VK_FORMAT_B8G8R8A8_UNORM;
1273 image_create_info.extent.width = 32;
1274 image_create_info.extent.height = 32;
1275 image_create_info.extent.depth = 1;
1276 image_create_info.mipLevels = 1;
1277 image_create_info.arrayLayers = 4;
1278 image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
1279 image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL;
1280 image_create_info.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
1281 image_create_info.flags = 0;
1282
1283 src_image_obj.init(&image_create_info);
1284 ASSERT_TRUE(src_image_obj.initialized());
1285
1286 image_create_info.usage = VK_IMAGE_USAGE_TRANSFER_DST_BIT;
1287 dst_image_obj.init(&image_create_info);
1288 ASSERT_TRUE(dst_image_obj.initialized());
1289
1290 m_commandBuffer->begin();
1291 VkImageCopy copyRegion;
1292 copyRegion.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
1293 copyRegion.srcSubresource.mipLevel = 0;
1294 copyRegion.srcSubresource.baseArrayLayer = 0;
1295 copyRegion.srcSubresource.layerCount = 1;
1296 copyRegion.srcOffset.x = 0;
1297 copyRegion.srcOffset.y = 0;
1298 copyRegion.srcOffset.z = 0;
1299 copyRegion.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
1300 copyRegion.dstSubresource.mipLevel = 0;
1301 copyRegion.dstSubresource.baseArrayLayer = 0;
1302 // Introduce failure by forcing the dst layerCount to differ from src
1303 copyRegion.dstSubresource.layerCount = 3;
1304 copyRegion.dstOffset.x = 0;
1305 copyRegion.dstOffset.y = 0;
1306 copyRegion.dstOffset.z = 0;
1307 copyRegion.extent.width = 1;
1308 copyRegion.extent.height = 1;
1309 copyRegion.extent.depth = 1;
1310
Mark Lobodzinski20310782020-02-28 14:25:17 -07001311 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkImageCopy-extent-00140");
unknown088160a2019-05-23 17:43:13 -06001312 m_commandBuffer->CopyImage(src_image_obj.image(), VK_IMAGE_LAYOUT_GENERAL, dst_image_obj.image(), VK_IMAGE_LAYOUT_GENERAL, 1,
1313 &copyRegion);
1314 m_errorMonitor->VerifyFound();
1315}
1316
1317TEST_F(VkLayerTest, CompressedImageMipCopyTests) {
1318 TEST_DESCRIPTION("Image/Buffer copies for higher mip levels");
1319
1320 ASSERT_NO_FATAL_FAILURE(Init());
1321
1322 VkPhysicalDeviceFeatures device_features = {};
1323 ASSERT_NO_FATAL_FAILURE(GetPhysicalDeviceFeatures(&device_features));
1324 VkFormat compressed_format = VK_FORMAT_UNDEFINED;
1325 if (device_features.textureCompressionBC) {
1326 compressed_format = VK_FORMAT_BC3_SRGB_BLOCK;
1327 } else if (device_features.textureCompressionETC2) {
1328 compressed_format = VK_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK;
1329 } else if (device_features.textureCompressionASTC_LDR) {
1330 compressed_format = VK_FORMAT_ASTC_4x4_UNORM_BLOCK;
1331 } else {
1332 printf("%s No compressed formats supported - CompressedImageMipCopyTests skipped.\n", kSkipPrefix);
1333 return;
1334 }
1335
1336 VkImageCreateInfo ci;
1337 ci.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
1338 ci.pNext = NULL;
1339 ci.flags = 0;
1340 ci.imageType = VK_IMAGE_TYPE_2D;
1341 ci.format = compressed_format;
1342 ci.extent = {32, 32, 1};
1343 ci.mipLevels = 6;
1344 ci.arrayLayers = 1;
1345 ci.samples = VK_SAMPLE_COUNT_1_BIT;
1346 ci.tiling = VK_IMAGE_TILING_OPTIMAL;
1347 ci.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
1348 ci.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
1349 ci.queueFamilyIndexCount = 0;
1350 ci.pQueueFamilyIndices = NULL;
1351 ci.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
1352
1353 VkImageObj image(m_device);
1354 image.init(&ci);
1355 ASSERT_TRUE(image.initialized());
1356
1357 VkImageObj odd_image(m_device);
1358 ci.extent = {31, 32, 1}; // Mips are [31,32] [15,16] [7,8] [3,4], [1,2] [1,1]
1359 odd_image.init(&ci);
1360 ASSERT_TRUE(odd_image.initialized());
1361
1362 // Allocate buffers
1363 VkMemoryPropertyFlags reqs = 0;
1364 VkBufferObj buffer_1024, buffer_64, buffer_16, buffer_8;
1365 buffer_1024.init_as_src_and_dst(*m_device, 1024, reqs);
1366 buffer_64.init_as_src_and_dst(*m_device, 64, reqs);
1367 buffer_16.init_as_src_and_dst(*m_device, 16, reqs);
1368 buffer_8.init_as_src_and_dst(*m_device, 8, reqs);
1369
1370 VkBufferImageCopy region = {};
1371 region.bufferRowLength = 0;
1372 region.bufferImageHeight = 0;
1373 region.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
1374 region.imageSubresource.layerCount = 1;
1375 region.imageOffset = {0, 0, 0};
1376 region.bufferOffset = 0;
1377
1378 // start recording
1379 m_commandBuffer->begin();
1380
1381 // Mip level copies that work - 5 levels
1382 m_errorMonitor->ExpectSuccess();
1383
1384 // Mip 0 should fit in 1k buffer - 1k texels @ 1b each
1385 region.imageExtent = {32, 32, 1};
1386 region.imageSubresource.mipLevel = 0;
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06001387 vk::CmdCopyImageToBuffer(m_commandBuffer->handle(), image.handle(), VK_IMAGE_LAYOUT_GENERAL, buffer_1024.handle(), 1, &region);
1388 vk::CmdCopyBufferToImage(m_commandBuffer->handle(), buffer_1024.handle(), image.handle(), VK_IMAGE_LAYOUT_GENERAL, 1, &region);
unknown088160a2019-05-23 17:43:13 -06001389
1390 // Mip 2 should fit in 64b buffer - 64 texels @ 1b each
1391 region.imageExtent = {8, 8, 1};
1392 region.imageSubresource.mipLevel = 2;
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06001393 vk::CmdCopyImageToBuffer(m_commandBuffer->handle(), image.handle(), VK_IMAGE_LAYOUT_GENERAL, buffer_64.handle(), 1, &region);
1394 vk::CmdCopyBufferToImage(m_commandBuffer->handle(), buffer_64.handle(), image.handle(), VK_IMAGE_LAYOUT_GENERAL, 1, &region);
unknown088160a2019-05-23 17:43:13 -06001395
1396 // Mip 3 should fit in 16b buffer - 16 texels @ 1b each
1397 region.imageExtent = {4, 4, 1};
1398 region.imageSubresource.mipLevel = 3;
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06001399 vk::CmdCopyImageToBuffer(m_commandBuffer->handle(), image.handle(), VK_IMAGE_LAYOUT_GENERAL, buffer_16.handle(), 1, &region);
1400 vk::CmdCopyBufferToImage(m_commandBuffer->handle(), buffer_16.handle(), image.handle(), VK_IMAGE_LAYOUT_GENERAL, 1, &region);
unknown088160a2019-05-23 17:43:13 -06001401
1402 // Mip 4&5 should fit in 16b buffer with no complaint - 4 & 1 texels @ 1b each
1403 region.imageExtent = {2, 2, 1};
1404 region.imageSubresource.mipLevel = 4;
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06001405 vk::CmdCopyImageToBuffer(m_commandBuffer->handle(), image.handle(), VK_IMAGE_LAYOUT_GENERAL, buffer_16.handle(), 1, &region);
1406 vk::CmdCopyBufferToImage(m_commandBuffer->handle(), buffer_16.handle(), image.handle(), VK_IMAGE_LAYOUT_GENERAL, 1, &region);
unknown088160a2019-05-23 17:43:13 -06001407
1408 region.imageExtent = {1, 1, 1};
1409 region.imageSubresource.mipLevel = 5;
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06001410 vk::CmdCopyImageToBuffer(m_commandBuffer->handle(), image.handle(), VK_IMAGE_LAYOUT_GENERAL, buffer_16.handle(), 1, &region);
1411 vk::CmdCopyBufferToImage(m_commandBuffer->handle(), buffer_16.handle(), image.handle(), VK_IMAGE_LAYOUT_GENERAL, 1, &region);
unknown088160a2019-05-23 17:43:13 -06001412 m_errorMonitor->VerifyNotFound();
1413
1414 // Buffer must accommodate a full compressed block, regardless of texel count
Mark Lobodzinski20310782020-02-28 14:25:17 -07001415 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdCopyImageToBuffer-pRegions-00183");
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06001416 vk::CmdCopyImageToBuffer(m_commandBuffer->handle(), image.handle(), VK_IMAGE_LAYOUT_GENERAL, buffer_8.handle(), 1, &region);
unknown088160a2019-05-23 17:43:13 -06001417 m_errorMonitor->VerifyFound();
Mark Lobodzinski20310782020-02-28 14:25:17 -07001418 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdCopyBufferToImage-pRegions-00171");
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06001419 vk::CmdCopyBufferToImage(m_commandBuffer->handle(), buffer_8.handle(), image.handle(), VK_IMAGE_LAYOUT_GENERAL, 1, &region);
unknown088160a2019-05-23 17:43:13 -06001420 m_errorMonitor->VerifyFound();
1421
sfricke-samsung3a10b922020-05-13 23:23:16 -07001422 std::string vuid;
1423 bool ycbcr = (DeviceExtensionEnabled(VK_KHR_SAMPLER_YCBCR_CONVERSION_EXTENSION_NAME) ||
1424 (DeviceValidationVersion() >= VK_API_VERSION_1_1));
1425
unknown088160a2019-05-23 17:43:13 -06001426 // Copy width < compressed block size, but not the full mip width
1427 region.imageExtent = {1, 2, 1};
1428 region.imageSubresource.mipLevel = 4;
sfricke-samsung3a10b922020-05-13 23:23:16 -07001429 vuid = ycbcr ? "VUID-VkBufferImageCopy-None-01739" : "VUID-VkBufferImageCopy-imageExtent-00207";
1430 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, vuid); // width not a multiple of compressed block width
Mark Lobodzinski20310782020-02-28 14:25:17 -07001431 m_errorMonitor->SetDesiredFailureMsg(kErrorBit,
unknown088160a2019-05-23 17:43:13 -06001432 "VUID-vkCmdCopyImageToBuffer-imageOffset-01794"); // image transfer granularity
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06001433 vk::CmdCopyImageToBuffer(m_commandBuffer->handle(), image.handle(), VK_IMAGE_LAYOUT_GENERAL, buffer_16.handle(), 1, &region);
unknown088160a2019-05-23 17:43:13 -06001434 m_errorMonitor->VerifyFound();
sfricke-samsung3a10b922020-05-13 23:23:16 -07001435 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, vuid); // width not a multiple of compressed block width
Mark Lobodzinski20310782020-02-28 14:25:17 -07001436 m_errorMonitor->SetDesiredFailureMsg(kErrorBit,
unknown088160a2019-05-23 17:43:13 -06001437 "VUID-vkCmdCopyBufferToImage-imageOffset-01793"); // image transfer granularity
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06001438 vk::CmdCopyBufferToImage(m_commandBuffer->handle(), buffer_16.handle(), image.handle(), VK_IMAGE_LAYOUT_GENERAL, 1, &region);
unknown088160a2019-05-23 17:43:13 -06001439 m_errorMonitor->VerifyFound();
1440
1441 // Copy height < compressed block size but not the full mip height
1442 region.imageExtent = {2, 1, 1};
sfricke-samsung3a10b922020-05-13 23:23:16 -07001443 vuid = ycbcr ? "VUID-VkBufferImageCopy-None-01740" : "VUID-VkBufferImageCopy-imageExtent-00208";
1444 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, vuid); // height not a multiple of compressed block width
Mark Lobodzinski20310782020-02-28 14:25:17 -07001445 m_errorMonitor->SetDesiredFailureMsg(kErrorBit,
unknown088160a2019-05-23 17:43:13 -06001446 "VUID-vkCmdCopyImageToBuffer-imageOffset-01794"); // image transfer granularity
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06001447 vk::CmdCopyImageToBuffer(m_commandBuffer->handle(), image.handle(), VK_IMAGE_LAYOUT_GENERAL, buffer_16.handle(), 1, &region);
unknown088160a2019-05-23 17:43:13 -06001448 m_errorMonitor->VerifyFound();
sfricke-samsung3a10b922020-05-13 23:23:16 -07001449 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, vuid); // height not a multiple of compressed block width
Mark Lobodzinski20310782020-02-28 14:25:17 -07001450 m_errorMonitor->SetDesiredFailureMsg(kErrorBit,
unknown088160a2019-05-23 17:43:13 -06001451 "VUID-vkCmdCopyBufferToImage-imageOffset-01793"); // image transfer granularity
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06001452 vk::CmdCopyBufferToImage(m_commandBuffer->handle(), buffer_16.handle(), image.handle(), VK_IMAGE_LAYOUT_GENERAL, 1, &region);
unknown088160a2019-05-23 17:43:13 -06001453 m_errorMonitor->VerifyFound();
1454
1455 // Offsets must be multiple of compressed block size
1456 region.imageOffset = {1, 1, 0};
1457 region.imageExtent = {1, 1, 1};
sfricke-samsung3a10b922020-05-13 23:23:16 -07001458 vuid = ycbcr ? "VUID-VkBufferImageCopy-None-01737" : "VUID-VkBufferImageCopy-imageOffset-00205";
1459 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, vuid); // imageOffset not a multiple of block size
Mark Lobodzinski20310782020-02-28 14:25:17 -07001460 m_errorMonitor->SetDesiredFailureMsg(kErrorBit,
unknown088160a2019-05-23 17:43:13 -06001461 "VUID-vkCmdCopyImageToBuffer-imageOffset-01794"); // image transfer granularity
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06001462 vk::CmdCopyImageToBuffer(m_commandBuffer->handle(), image.handle(), VK_IMAGE_LAYOUT_GENERAL, buffer_16.handle(), 1, &region);
unknown088160a2019-05-23 17:43:13 -06001463 m_errorMonitor->VerifyFound();
sfricke-samsung3a10b922020-05-13 23:23:16 -07001464 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, vuid); // imageOffset not a multiple of block size
Mark Lobodzinski20310782020-02-28 14:25:17 -07001465 m_errorMonitor->SetDesiredFailureMsg(kErrorBit,
unknown088160a2019-05-23 17:43:13 -06001466 "VUID-vkCmdCopyBufferToImage-imageOffset-01793"); // image transfer granularity
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06001467 vk::CmdCopyBufferToImage(m_commandBuffer->handle(), buffer_16.handle(), image.handle(), VK_IMAGE_LAYOUT_GENERAL, 1, &region);
unknown088160a2019-05-23 17:43:13 -06001468 m_errorMonitor->VerifyFound();
1469
1470 // Offset + extent width = mip width - should succeed
1471 region.imageOffset = {4, 4, 0};
1472 region.imageExtent = {3, 4, 1};
1473 region.imageSubresource.mipLevel = 2;
1474 m_errorMonitor->ExpectSuccess();
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06001475 vk::CmdCopyImageToBuffer(m_commandBuffer->handle(), odd_image.handle(), VK_IMAGE_LAYOUT_GENERAL, buffer_16.handle(), 1,
1476 &region);
1477 vk::CmdCopyBufferToImage(m_commandBuffer->handle(), buffer_16.handle(), odd_image.handle(), VK_IMAGE_LAYOUT_GENERAL, 1,
1478 &region);
unknown088160a2019-05-23 17:43:13 -06001479 m_errorMonitor->VerifyNotFound();
1480
unknown088160a2019-05-23 17:43:13 -06001481 // Offset + extent width < mip width and not a multiple of block width - should fail
1482 region.imageExtent = {3, 3, 1};
sfricke-samsung3a10b922020-05-13 23:23:16 -07001483 vuid = ycbcr ? "VUID-VkBufferImageCopy-None-01740" : "VUID-VkBufferImageCopy-imageExtent-00208";
1484 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, vuid); // offset+extent not a multiple of block width
Mark Lobodzinski20310782020-02-28 14:25:17 -07001485 m_errorMonitor->SetDesiredFailureMsg(kErrorBit,
unknown088160a2019-05-23 17:43:13 -06001486 "VUID-vkCmdCopyImageToBuffer-imageOffset-01794"); // image transfer granularity
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06001487 vk::CmdCopyImageToBuffer(m_commandBuffer->handle(), odd_image.handle(), VK_IMAGE_LAYOUT_GENERAL, buffer_16.handle(), 1,
1488 &region);
unknown088160a2019-05-23 17:43:13 -06001489 m_errorMonitor->VerifyFound();
sfricke-samsung3a10b922020-05-13 23:23:16 -07001490 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, vuid); // offset+extent not a multiple of block width
Mark Lobodzinski20310782020-02-28 14:25:17 -07001491 m_errorMonitor->SetDesiredFailureMsg(kErrorBit,
unknown088160a2019-05-23 17:43:13 -06001492 "VUID-vkCmdCopyBufferToImage-imageOffset-01793"); // image transfer granularity
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06001493 vk::CmdCopyBufferToImage(m_commandBuffer->handle(), buffer_16.handle(), odd_image.handle(), VK_IMAGE_LAYOUT_GENERAL, 1,
1494 &region);
unknown088160a2019-05-23 17:43:13 -06001495 m_errorMonitor->VerifyFound();
1496}
1497
1498TEST_F(VkLayerTest, ImageBufferCopyTests) {
1499 TEST_DESCRIPTION("Image to buffer and buffer to image tests");
sfricke-samsung6d97e562020-01-07 22:01:00 -08001500
1501 // Enable KHR multiplane req'd extensions for multi-planar copy tests
1502 bool mp_extensions = InstanceExtensionSupported(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME,
1503 VK_KHR_GET_MEMORY_REQUIREMENTS_2_SPEC_VERSION);
1504 if (mp_extensions) {
1505 m_instance_extension_names.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
1506 }
Mark Lobodzinski09ce9c42020-03-06 10:02:44 -07001507 ASSERT_NO_FATAL_FAILURE(InitFramework(m_errorMonitor, nullptr));
sfricke-samsung6d97e562020-01-07 22:01:00 -08001508 mp_extensions = mp_extensions && DeviceExtensionSupported(gpu(), nullptr, VK_KHR_MAINTENANCE1_EXTENSION_NAME);
1509 mp_extensions = mp_extensions && DeviceExtensionSupported(gpu(), nullptr, VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME);
1510 mp_extensions = mp_extensions && DeviceExtensionSupported(gpu(), nullptr, VK_KHR_BIND_MEMORY_2_EXTENSION_NAME);
1511 mp_extensions = mp_extensions && DeviceExtensionSupported(gpu(), nullptr, VK_KHR_SAMPLER_YCBCR_CONVERSION_EXTENSION_NAME);
1512 if (mp_extensions) {
1513 m_device_extension_names.push_back(VK_KHR_MAINTENANCE1_EXTENSION_NAME);
1514 m_device_extension_names.push_back(VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME);
1515 m_device_extension_names.push_back(VK_KHR_BIND_MEMORY_2_EXTENSION_NAME);
1516 m_device_extension_names.push_back(VK_KHR_SAMPLER_YCBCR_CONVERSION_EXTENSION_NAME);
1517 }
1518 ASSERT_NO_FATAL_FAILURE(InitState());
unknown088160a2019-05-23 17:43:13 -06001519
1520 // Bail if any dimension of transfer granularity is 0.
1521 auto index = m_device->graphics_queue_node_index_;
1522 auto queue_family_properties = m_device->phy().queue_properties();
1523 if ((queue_family_properties[index].minImageTransferGranularity.depth == 0) ||
1524 (queue_family_properties[index].minImageTransferGranularity.width == 0) ||
1525 (queue_family_properties[index].minImageTransferGranularity.height == 0)) {
1526 printf("%s Subresource copies are disallowed when xfer granularity (x|y|z) is 0. Skipped.\n", kSkipPrefix);
1527 return;
1528 }
1529
sfricke-samsung6d97e562020-01-07 22:01:00 -08001530 // All VkImageObj must be defined here as if defined inside below scopes will cause image memory to be deleted when out of scope
1531 // 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 -07001532 VkImageObj image_64k(m_device); // 128^2 texels, 64k
1533 VkImageObj image_16k(m_device); // 64^2 texels, 16k
sfricke-samsung6d97e562020-01-07 22:01:00 -08001534 // depth stencil
unknown088160a2019-05-23 17:43:13 -06001535 VkImageObj image_16k_depth(m_device); // 64^2 texels, depth, 16k
1536 VkImageObj ds_image_4D_1S(m_device); // 256^2 texels, 512kb (256k depth, 64k stencil, 192k pack)
1537 VkImageObj ds_image_3D_1S(m_device); // 256^2 texels, 256kb (192k depth, 64k stencil)
1538 VkImageObj ds_image_2D(m_device); // 256^2 texels, 128k (128k depth)
1539 VkImageObj ds_image_1S(m_device); // 256^2 texels, 64k (64k stencil)
sfricke-samsung6d97e562020-01-07 22:01:00 -08001540 // compression
1541 VkImageObj image_16k_4x4comp(m_device); // 128^2 texels as 32^2 compressed (4x4) blocks, 16k
1542 VkImageObj image_NPOT_4x4comp(m_device); // 130^2 texels as 33^2 compressed (4x4) blocks
1543 // multi-planar
1544 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 -06001545
sfricke-samsung6d97e562020-01-07 22:01:00 -08001546 // Verify R8G8B8A8_UINT format is supported for transfer
1547 bool missing_rgba_support = false;
1548 VkFormatProperties props = {0, 0, 0};
1549 vk::GetPhysicalDeviceFormatProperties(m_device->phy().handle(), VK_FORMAT_R8G8B8A8_UINT, &props);
1550 missing_rgba_support |= (props.bufferFeatures == 0 && props.linearTilingFeatures == 0 && props.optimalTilingFeatures == 0);
1551 missing_rgba_support |= (props.optimalTilingFeatures & VK_FORMAT_FEATURE_TRANSFER_SRC_BIT) == 0;
1552 missing_rgba_support |= (props.optimalTilingFeatures & VK_FORMAT_FEATURE_TRANSFER_DST_BIT) == 0;
1553
1554 if (!missing_rgba_support) {
1555 image_64k.Init(128, 128, 1, VK_FORMAT_R8G8B8A8_UINT,
1556 VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT,
1557 VK_IMAGE_TILING_OPTIMAL, 0);
1558 ASSERT_TRUE(image_64k.initialized());
1559
1560 image_16k.Init(64, 64, 1, VK_FORMAT_R8G8B8A8_UINT,
1561 VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT,
1562 VK_IMAGE_TILING_OPTIMAL, 0);
1563 ASSERT_TRUE(image_16k.initialized());
1564 }
unknown088160a2019-05-23 17:43:13 -06001565
1566 // Verify all needed Depth/Stencil formats are supported
1567 bool missing_ds_support = false;
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06001568 vk::GetPhysicalDeviceFormatProperties(m_device->phy().handle(), VK_FORMAT_D32_SFLOAT_S8_UINT, &props);
unknown088160a2019-05-23 17:43:13 -06001569 missing_ds_support |= (props.bufferFeatures == 0 && props.linearTilingFeatures == 0 && props.optimalTilingFeatures == 0);
1570 missing_ds_support |= (props.optimalTilingFeatures & VK_FORMAT_FEATURE_TRANSFER_SRC_BIT) == 0;
1571 missing_ds_support |= (props.optimalTilingFeatures & VK_FORMAT_FEATURE_TRANSFER_DST_BIT) == 0;
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06001572 vk::GetPhysicalDeviceFormatProperties(m_device->phy().handle(), VK_FORMAT_D24_UNORM_S8_UINT, &props);
unknown088160a2019-05-23 17:43:13 -06001573 missing_ds_support |= (props.bufferFeatures == 0 && props.linearTilingFeatures == 0 && props.optimalTilingFeatures == 0);
1574 missing_ds_support |= (props.optimalTilingFeatures & VK_FORMAT_FEATURE_TRANSFER_SRC_BIT) == 0;
1575 missing_ds_support |= (props.optimalTilingFeatures & VK_FORMAT_FEATURE_TRANSFER_DST_BIT) == 0;
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06001576 vk::GetPhysicalDeviceFormatProperties(m_device->phy().handle(), VK_FORMAT_D16_UNORM, &props);
unknown088160a2019-05-23 17:43:13 -06001577 missing_ds_support |= (props.bufferFeatures == 0 && props.linearTilingFeatures == 0 && props.optimalTilingFeatures == 0);
1578 missing_ds_support |= (props.optimalTilingFeatures & VK_FORMAT_FEATURE_TRANSFER_SRC_BIT) == 0;
1579 missing_ds_support |= (props.optimalTilingFeatures & VK_FORMAT_FEATURE_TRANSFER_DST_BIT) == 0;
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06001580 vk::GetPhysicalDeviceFormatProperties(m_device->phy().handle(), VK_FORMAT_S8_UINT, &props);
unknown088160a2019-05-23 17:43:13 -06001581 missing_ds_support |= (props.bufferFeatures == 0 && props.linearTilingFeatures == 0 && props.optimalTilingFeatures == 0);
1582 missing_ds_support |= (props.optimalTilingFeatures & VK_FORMAT_FEATURE_TRANSFER_SRC_BIT) == 0;
1583 missing_ds_support |= (props.optimalTilingFeatures & VK_FORMAT_FEATURE_TRANSFER_DST_BIT) == 0;
1584
1585 if (!missing_ds_support) {
1586 image_16k_depth.Init(64, 64, 1, VK_FORMAT_D24_UNORM_S8_UINT,
1587 VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT, VK_IMAGE_TILING_OPTIMAL, 0);
1588 ASSERT_TRUE(image_16k_depth.initialized());
1589
1590 ds_image_4D_1S.Init(
1591 256, 256, 1, VK_FORMAT_D32_SFLOAT_S8_UINT,
1592 VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT,
1593 VK_IMAGE_TILING_OPTIMAL, 0);
1594 ASSERT_TRUE(ds_image_4D_1S.initialized());
1595
1596 ds_image_3D_1S.Init(
1597 256, 256, 1, VK_FORMAT_D24_UNORM_S8_UINT,
1598 VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT,
1599 VK_IMAGE_TILING_OPTIMAL, 0);
1600 ASSERT_TRUE(ds_image_3D_1S.initialized());
1601
1602 ds_image_2D.Init(
1603 256, 256, 1, VK_FORMAT_D16_UNORM,
1604 VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT,
1605 VK_IMAGE_TILING_OPTIMAL, 0);
1606 ASSERT_TRUE(ds_image_2D.initialized());
1607
1608 ds_image_1S.Init(
1609 256, 256, 1, VK_FORMAT_S8_UINT,
1610 VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT,
1611 VK_IMAGE_TILING_OPTIMAL, 0);
1612 ASSERT_TRUE(ds_image_1S.initialized());
1613 }
1614
1615 // Allocate buffers
1616 VkBufferObj buffer_256k, buffer_128k, buffer_64k, buffer_16k;
1617 VkMemoryPropertyFlags reqs = 0;
1618 buffer_256k.init_as_src_and_dst(*m_device, 262144, reqs); // 256k
1619 buffer_128k.init_as_src_and_dst(*m_device, 131072, reqs); // 128k
1620 buffer_64k.init_as_src_and_dst(*m_device, 65536, reqs); // 64k
1621 buffer_16k.init_as_src_and_dst(*m_device, 16384, reqs); // 16k
1622
1623 VkBufferImageCopy region = {};
1624 region.bufferRowLength = 0;
1625 region.bufferImageHeight = 0;
1626 region.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
1627 region.imageSubresource.layerCount = 1;
1628 region.imageOffset = {0, 0, 0};
1629 region.imageExtent = {64, 64, 1};
1630 region.bufferOffset = 0;
1631
sfricke-samsung6d97e562020-01-07 22:01:00 -08001632 if (missing_rgba_support) {
1633 printf("%s R8G8B8A8_UINT transfer unsupported - skipping RGBA tests.\n", kSkipPrefix);
unknown088160a2019-05-23 17:43:13 -06001634
sfricke-samsung6d97e562020-01-07 22:01:00 -08001635 // start recording for future tests
1636 m_commandBuffer->begin();
1637 } else {
1638 // attempt copies before putting command buffer in recording state
Mark Lobodzinski20310782020-02-28 14:25:17 -07001639 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdCopyBufferToImage-commandBuffer-recording");
sfricke-samsung6d97e562020-01-07 22:01:00 -08001640 vk::CmdCopyBufferToImage(m_commandBuffer->handle(), buffer_64k.handle(), image_64k.handle(), VK_IMAGE_LAYOUT_GENERAL, 1,
1641 &region);
unknown088160a2019-05-23 17:43:13 -06001642 m_errorMonitor->VerifyFound();
1643
Mark Lobodzinski20310782020-02-28 14:25:17 -07001644 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdCopyImageToBuffer-commandBuffer-recording");
sfricke-samsung6d97e562020-01-07 22:01:00 -08001645 vk::CmdCopyImageToBuffer(m_commandBuffer->handle(), image_64k.handle(), VK_IMAGE_LAYOUT_GENERAL, buffer_64k.handle(), 1,
1646 &region);
1647 m_errorMonitor->VerifyFound();
1648
1649 // start recording
1650 m_commandBuffer->begin();
1651
1652 // successful copies
1653 m_errorMonitor->ExpectSuccess();
1654 vk::CmdCopyImageToBuffer(m_commandBuffer->handle(), image_16k.handle(), VK_IMAGE_LAYOUT_GENERAL, buffer_16k.handle(), 1,
1655 &region);
1656 vk::CmdCopyBufferToImage(m_commandBuffer->handle(), buffer_16k.handle(), image_16k.handle(), VK_IMAGE_LAYOUT_GENERAL, 1,
1657 &region);
1658 region.imageOffset.x = 16; // 16k copy, offset requires larger image
1659 vk::CmdCopyImageToBuffer(m_commandBuffer->handle(), image_64k.handle(), VK_IMAGE_LAYOUT_GENERAL, buffer_16k.handle(), 1,
1660 &region);
1661 region.imageExtent.height = 78; // > 16k copy requires larger buffer & image
1662 vk::CmdCopyBufferToImage(m_commandBuffer->handle(), buffer_64k.handle(), image_64k.handle(), VK_IMAGE_LAYOUT_GENERAL, 1,
1663 &region);
1664 region.imageOffset.x = 0;
1665 region.imageExtent.height = 64;
1666 region.bufferOffset = 256; // 16k copy with buffer offset, requires larger buffer
1667 vk::CmdCopyImageToBuffer(m_commandBuffer->handle(), image_16k.handle(), VK_IMAGE_LAYOUT_GENERAL, buffer_64k.handle(), 1,
1668 &region);
1669 m_errorMonitor->VerifyNotFound();
1670
1671 // image/buffer too small (extent too large) on copy to image
1672 region.imageExtent = {65, 64, 1};
Mark Lobodzinski20310782020-02-28 14:25:17 -07001673 m_errorMonitor->SetDesiredFailureMsg(kErrorBit,
sfricke-samsung6d97e562020-01-07 22:01:00 -08001674 "VUID-vkCmdCopyBufferToImage-pRegions-00171"); // buffer too small
1675 vk::CmdCopyBufferToImage(m_commandBuffer->handle(), buffer_16k.handle(), image_64k.handle(), VK_IMAGE_LAYOUT_GENERAL, 1,
1676 &region);
1677 m_errorMonitor->VerifyFound();
1678
1679 m_errorMonitor->SetUnexpectedError("VUID-VkBufferImageCopy-imageOffset-00197");
Mark Lobodzinski20310782020-02-28 14:25:17 -07001680 m_errorMonitor->SetDesiredFailureMsg(kErrorBit,
sfricke-samsung6d97e562020-01-07 22:01:00 -08001681 "VUID-vkCmdCopyBufferToImage-pRegions-00172"); // image too small
1682 vk::CmdCopyBufferToImage(m_commandBuffer->handle(), buffer_64k.handle(), image_16k.handle(), VK_IMAGE_LAYOUT_GENERAL, 1,
1683 &region);
1684 m_errorMonitor->VerifyFound();
1685
1686 // image/buffer too small (offset) on copy to image
1687 region.imageExtent = {64, 64, 1};
1688 region.imageOffset = {0, 4, 0};
Mark Lobodzinski20310782020-02-28 14:25:17 -07001689 m_errorMonitor->SetDesiredFailureMsg(kErrorBit,
sfricke-samsung6d97e562020-01-07 22:01:00 -08001690 "VUID-vkCmdCopyBufferToImage-pRegions-00171"); // buffer too small
1691 vk::CmdCopyBufferToImage(m_commandBuffer->handle(), buffer_16k.handle(), image_64k.handle(), VK_IMAGE_LAYOUT_GENERAL, 1,
1692 &region);
1693 m_errorMonitor->VerifyFound();
1694
1695 m_errorMonitor->SetUnexpectedError("VUID-VkBufferImageCopy-imageOffset-00197");
1696 m_errorMonitor->SetUnexpectedError("VUID-VkBufferImageCopy-imageOffset-00198");
Mark Lobodzinski20310782020-02-28 14:25:17 -07001697 m_errorMonitor->SetDesiredFailureMsg(kErrorBit,
sfricke-samsung6d97e562020-01-07 22:01:00 -08001698 "VUID-vkCmdCopyBufferToImage-pRegions-00172"); // image too small
1699 vk::CmdCopyBufferToImage(m_commandBuffer->handle(), buffer_64k.handle(), image_16k.handle(), VK_IMAGE_LAYOUT_GENERAL, 1,
1700 &region);
1701 m_errorMonitor->VerifyFound();
1702
1703 // image/buffer too small on copy to buffer
1704 region.imageExtent = {64, 64, 1};
1705 region.imageOffset = {0, 0, 0};
1706 region.bufferOffset = 4;
Mark Lobodzinski20310782020-02-28 14:25:17 -07001707 m_errorMonitor->SetDesiredFailureMsg(kErrorBit,
sfricke-samsung6d97e562020-01-07 22:01:00 -08001708 "VUID-vkCmdCopyImageToBuffer-pRegions-00183"); // buffer too small
1709 vk::CmdCopyImageToBuffer(m_commandBuffer->handle(), image_64k.handle(), VK_IMAGE_LAYOUT_GENERAL, buffer_16k.handle(), 1,
1710 &region);
1711 m_errorMonitor->VerifyFound();
1712
1713 region.imageExtent = {64, 65, 1};
1714 region.bufferOffset = 0;
1715 m_errorMonitor->SetUnexpectedError("VUID-VkBufferImageCopy-imageOffset-00198");
Mark Lobodzinski20310782020-02-28 14:25:17 -07001716 m_errorMonitor->SetDesiredFailureMsg(kErrorBit,
sfricke-samsung6d97e562020-01-07 22:01:00 -08001717 "VUID-vkCmdCopyImageToBuffer-pRegions-00182"); // image too small
1718 vk::CmdCopyImageToBuffer(m_commandBuffer->handle(), image_16k.handle(), VK_IMAGE_LAYOUT_GENERAL, buffer_64k.handle(), 1,
1719 &region);
1720 m_errorMonitor->VerifyFound();
1721
1722 // buffer size OK but rowlength causes loose packing
Mark Lobodzinski20310782020-02-28 14:25:17 -07001723 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdCopyImageToBuffer-pRegions-00183");
sfricke-samsung6d97e562020-01-07 22:01:00 -08001724 region.imageExtent = {64, 64, 1};
1725 region.bufferRowLength = 68;
1726 vk::CmdCopyImageToBuffer(m_commandBuffer->handle(), image_16k.handle(), VK_IMAGE_LAYOUT_GENERAL, buffer_16k.handle(), 1,
1727 &region);
1728 m_errorMonitor->VerifyFound();
1729
1730 // An extent with zero area should produce a warning, but no error
Mark Lobodzinski20310782020-02-28 14:25:17 -07001731 m_errorMonitor->SetDesiredFailureMsg(kWarningBit | kErrorBit, "} has zero area");
sfricke-samsung6d97e562020-01-07 22:01:00 -08001732 region.imageExtent.width = 0;
1733 vk::CmdCopyImageToBuffer(m_commandBuffer->handle(), image_16k.handle(), VK_IMAGE_LAYOUT_GENERAL, buffer_16k.handle(), 1,
1734 &region);
1735 m_errorMonitor->VerifyFound();
1736
1737 // aspect bits
1738 region.imageExtent = {64, 64, 1};
1739 region.bufferRowLength = 0;
1740 region.bufferImageHeight = 0;
1741 if (!missing_ds_support) {
Mark Lobodzinski20310782020-02-28 14:25:17 -07001742 m_errorMonitor->SetDesiredFailureMsg(kErrorBit,
sfricke-samsung6d97e562020-01-07 22:01:00 -08001743 "VUID-VkBufferImageCopy-aspectMask-00212"); // more than 1 aspect bit set
1744 region.imageSubresource.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT;
1745 vk::CmdCopyImageToBuffer(m_commandBuffer->handle(), image_16k_depth.handle(), VK_IMAGE_LAYOUT_GENERAL,
1746 buffer_16k.handle(), 1, &region);
1747 m_errorMonitor->VerifyFound();
1748
Mark Lobodzinski20310782020-02-28 14:25:17 -07001749 m_errorMonitor->SetDesiredFailureMsg(kErrorBit,
sfricke-samsung6d97e562020-01-07 22:01:00 -08001750 "VUID-VkBufferImageCopy-aspectMask-00211"); // different mis-matched aspect
1751 region.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
1752 vk::CmdCopyImageToBuffer(m_commandBuffer->handle(), image_16k_depth.handle(), VK_IMAGE_LAYOUT_GENERAL,
1753 buffer_16k.handle(), 1, &region);
1754 m_errorMonitor->VerifyFound();
1755 }
1756
Mark Lobodzinski20310782020-02-28 14:25:17 -07001757 m_errorMonitor->SetDesiredFailureMsg(kErrorBit,
sfricke-samsung6d97e562020-01-07 22:01:00 -08001758 "VUID-VkBufferImageCopy-aspectMask-00211"); // mis-matched aspect
1759 region.imageSubresource.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT;
1760 vk::CmdCopyImageToBuffer(m_commandBuffer->handle(), image_16k.handle(), VK_IMAGE_LAYOUT_GENERAL, buffer_16k.handle(), 1,
1761 &region);
1762 m_errorMonitor->VerifyFound();
unknown088160a2019-05-23 17:43:13 -06001763 region.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
sfricke-samsung6d97e562020-01-07 22:01:00 -08001764
1765 // Out-of-range mip levels should fail
1766 region.imageSubresource.mipLevel = image_16k.create_info().mipLevels + 1;
Mark Lobodzinski20310782020-02-28 14:25:17 -07001767 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdCopyImageToBuffer-imageSubresource-01703");
sfricke-samsung6d97e562020-01-07 22:01:00 -08001768 m_errorMonitor->SetUnexpectedError("VUID-VkBufferImageCopy-imageOffset-00197");
1769 m_errorMonitor->SetUnexpectedError("VUID-VkBufferImageCopy-imageOffset-00198");
1770 m_errorMonitor->SetUnexpectedError("VUID-VkBufferImageCopy-imageOffset-00200");
1771 m_errorMonitor->SetDesiredFailureMsg(
Mark Lobodzinski20310782020-02-28 14:25:17 -07001772 kErrorBit,
sfricke-samsung6d97e562020-01-07 22:01:00 -08001773 "VUID-vkCmdCopyImageToBuffer-pRegions-00182"); // unavoidable "region exceeds image bounds" for non-existent mip
1774 vk::CmdCopyImageToBuffer(m_commandBuffer->handle(), image_16k.handle(), VK_IMAGE_LAYOUT_GENERAL, buffer_16k.handle(), 1,
1775 &region);
1776 m_errorMonitor->VerifyFound();
Mark Lobodzinski20310782020-02-28 14:25:17 -07001777 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdCopyBufferToImage-imageSubresource-01701");
sfricke-samsung6d97e562020-01-07 22:01:00 -08001778 m_errorMonitor->SetUnexpectedError("VUID-VkBufferImageCopy-imageOffset-00197");
1779 m_errorMonitor->SetUnexpectedError("VUID-VkBufferImageCopy-imageOffset-00198");
1780 m_errorMonitor->SetUnexpectedError("VUID-VkBufferImageCopy-imageOffset-00200");
1781 m_errorMonitor->SetDesiredFailureMsg(
Mark Lobodzinski20310782020-02-28 14:25:17 -07001782 kErrorBit,
sfricke-samsung6d97e562020-01-07 22:01:00 -08001783 "VUID-vkCmdCopyBufferToImage-pRegions-00172"); // unavoidable "region exceeds image bounds" for non-existent mip
1784 vk::CmdCopyBufferToImage(m_commandBuffer->handle(), buffer_16k.handle(), image_16k.handle(), VK_IMAGE_LAYOUT_GENERAL, 1,
1785 &region);
1786 m_errorMonitor->VerifyFound();
1787 region.imageSubresource.mipLevel = 0;
1788
1789 // Out-of-range array layers should fail
1790 region.imageSubresource.baseArrayLayer = image_16k.create_info().arrayLayers;
1791 region.imageSubresource.layerCount = 1;
Mark Lobodzinski20310782020-02-28 14:25:17 -07001792 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdCopyImageToBuffer-imageSubresource-01704");
sfricke-samsung6d97e562020-01-07 22:01:00 -08001793 vk::CmdCopyImageToBuffer(m_commandBuffer->handle(), image_16k.handle(), VK_IMAGE_LAYOUT_GENERAL, buffer_16k.handle(), 1,
1794 &region);
1795 m_errorMonitor->VerifyFound();
Mark Lobodzinski20310782020-02-28 14:25:17 -07001796 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdCopyBufferToImage-imageSubresource-01702");
sfricke-samsung6d97e562020-01-07 22:01:00 -08001797 vk::CmdCopyBufferToImage(m_commandBuffer->handle(), buffer_16k.handle(), image_16k.handle(), VK_IMAGE_LAYOUT_GENERAL, 1,
1798 &region);
1799 m_errorMonitor->VerifyFound();
1800 region.imageSubresource.baseArrayLayer = 0;
1801
1802 // Layout mismatch should fail
Mark Lobodzinski20310782020-02-28 14:25:17 -07001803 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdCopyImageToBuffer-srcImageLayout-00189");
sfricke-samsung6d97e562020-01-07 22:01:00 -08001804 vk::CmdCopyImageToBuffer(m_commandBuffer->handle(), image_16k.handle(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
1805 buffer_16k.handle(), 1, &region);
1806 m_errorMonitor->VerifyFound();
Mark Lobodzinski20310782020-02-28 14:25:17 -07001807 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdCopyBufferToImage-dstImageLayout-00180");
sfricke-samsung6d97e562020-01-07 22:01:00 -08001808 vk::CmdCopyBufferToImage(m_commandBuffer->handle(), buffer_16k.handle(), image_16k.handle(),
1809 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &region);
unknown088160a2019-05-23 17:43:13 -06001810 m_errorMonitor->VerifyFound();
1811 }
1812
unknown088160a2019-05-23 17:43:13 -06001813 // Test Depth/Stencil copies
1814 if (missing_ds_support) {
1815 printf("%s Depth / Stencil formats unsupported - skipping D/S tests.\n", kSkipPrefix);
1816 } else {
1817 VkBufferImageCopy ds_region = {};
1818 ds_region.bufferOffset = 0;
1819 ds_region.bufferRowLength = 0;
1820 ds_region.bufferImageHeight = 0;
1821 ds_region.imageSubresource.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT;
1822 ds_region.imageSubresource.mipLevel = 0;
1823 ds_region.imageSubresource.baseArrayLayer = 0;
1824 ds_region.imageSubresource.layerCount = 1;
1825 ds_region.imageOffset = {0, 0, 0};
1826 ds_region.imageExtent = {256, 256, 1};
1827
1828 // Depth copies that should succeed
1829 m_errorMonitor->ExpectSuccess(); // Extract 4b depth per texel, pack into 256k buffer
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06001830 vk::CmdCopyImageToBuffer(m_commandBuffer->handle(), ds_image_4D_1S.handle(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
1831 buffer_256k.handle(), 1, &ds_region);
unknown088160a2019-05-23 17:43:13 -06001832 m_errorMonitor->VerifyNotFound();
1833
1834 m_errorMonitor->ExpectSuccess(); // Extract 3b depth per texel, pack (loose) into 256k buffer
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06001835 vk::CmdCopyImageToBuffer(m_commandBuffer->handle(), ds_image_3D_1S.handle(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
1836 buffer_256k.handle(), 1, &ds_region);
unknown088160a2019-05-23 17:43:13 -06001837 m_errorMonitor->VerifyNotFound();
1838
1839 m_errorMonitor->ExpectSuccess(); // Copy 2b depth per texel, into 128k buffer
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06001840 vk::CmdCopyImageToBuffer(m_commandBuffer->handle(), ds_image_2D.handle(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
1841 buffer_128k.handle(), 1, &ds_region);
unknown088160a2019-05-23 17:43:13 -06001842 m_errorMonitor->VerifyNotFound();
1843
1844 // Depth copies that should fail
1845 ds_region.bufferOffset = 4;
1846 m_errorMonitor->SetDesiredFailureMsg(
Mark Lobodzinski20310782020-02-28 14:25:17 -07001847 kErrorBit,
unknown088160a2019-05-23 17:43:13 -06001848 "VUID-vkCmdCopyImageToBuffer-pRegions-00183"); // Extract 4b depth per texel, pack into 256k buffer
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06001849 vk::CmdCopyImageToBuffer(m_commandBuffer->handle(), ds_image_4D_1S.handle(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
1850 buffer_256k.handle(), 1, &ds_region);
unknown088160a2019-05-23 17:43:13 -06001851 m_errorMonitor->VerifyFound();
1852
1853 m_errorMonitor->SetDesiredFailureMsg(
Mark Lobodzinski20310782020-02-28 14:25:17 -07001854 kErrorBit,
unknown088160a2019-05-23 17:43:13 -06001855 "VUID-vkCmdCopyImageToBuffer-pRegions-00183"); // Extract 3b depth per texel, pack (loose) into 256k buffer
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06001856 vk::CmdCopyImageToBuffer(m_commandBuffer->handle(), ds_image_3D_1S.handle(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
1857 buffer_256k.handle(), 1, &ds_region);
unknown088160a2019-05-23 17:43:13 -06001858 m_errorMonitor->VerifyFound();
1859
1860 m_errorMonitor->SetDesiredFailureMsg(
Mark Lobodzinski20310782020-02-28 14:25:17 -07001861 kErrorBit,
unknown088160a2019-05-23 17:43:13 -06001862 "VUID-vkCmdCopyImageToBuffer-pRegions-00183"); // Copy 2b depth per texel, into 128k buffer
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06001863 vk::CmdCopyImageToBuffer(m_commandBuffer->handle(), ds_image_2D.handle(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
1864 buffer_128k.handle(), 1, &ds_region);
unknown088160a2019-05-23 17:43:13 -06001865 m_errorMonitor->VerifyFound();
1866
1867 // Stencil copies that should succeed
1868 ds_region.bufferOffset = 0;
1869 ds_region.imageSubresource.aspectMask = VK_IMAGE_ASPECT_STENCIL_BIT;
1870 m_errorMonitor->ExpectSuccess(); // Extract 1b stencil per texel, pack into 64k buffer
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06001871 vk::CmdCopyImageToBuffer(m_commandBuffer->handle(), ds_image_4D_1S.handle(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
1872 buffer_64k.handle(), 1, &ds_region);
unknown088160a2019-05-23 17:43:13 -06001873 m_errorMonitor->VerifyNotFound();
1874
1875 m_errorMonitor->ExpectSuccess(); // Extract 1b stencil per texel, pack into 64k buffer
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06001876 vk::CmdCopyImageToBuffer(m_commandBuffer->handle(), ds_image_3D_1S.handle(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
1877 buffer_64k.handle(), 1, &ds_region);
unknown088160a2019-05-23 17:43:13 -06001878 m_errorMonitor->VerifyNotFound();
1879
1880 m_errorMonitor->ExpectSuccess(); // Copy 1b depth per texel, into 64k buffer
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06001881 vk::CmdCopyImageToBuffer(m_commandBuffer->handle(), ds_image_1S.handle(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
1882 buffer_64k.handle(), 1, &ds_region);
unknown088160a2019-05-23 17:43:13 -06001883 m_errorMonitor->VerifyNotFound();
1884
1885 // Stencil copies that should fail
1886 m_errorMonitor->SetDesiredFailureMsg(
Mark Lobodzinski20310782020-02-28 14:25:17 -07001887 kErrorBit,
unknown088160a2019-05-23 17:43:13 -06001888 "VUID-vkCmdCopyImageToBuffer-pRegions-00183"); // Extract 1b stencil per texel, pack into 64k buffer
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06001889 vk::CmdCopyImageToBuffer(m_commandBuffer->handle(), ds_image_4D_1S.handle(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
1890 buffer_16k.handle(), 1, &ds_region);
unknown088160a2019-05-23 17:43:13 -06001891 m_errorMonitor->VerifyFound();
1892
1893 m_errorMonitor->SetDesiredFailureMsg(
Mark Lobodzinski20310782020-02-28 14:25:17 -07001894 kErrorBit,
unknown088160a2019-05-23 17:43:13 -06001895 "VUID-vkCmdCopyImageToBuffer-pRegions-00183"); // Extract 1b stencil per texel, pack into 64k buffer
1896 ds_region.bufferRowLength = 260;
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06001897 vk::CmdCopyImageToBuffer(m_commandBuffer->handle(), ds_image_3D_1S.handle(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
1898 buffer_64k.handle(), 1, &ds_region);
unknown088160a2019-05-23 17:43:13 -06001899 m_errorMonitor->VerifyFound();
1900
1901 ds_region.bufferRowLength = 0;
1902 ds_region.bufferOffset = 4;
1903 m_errorMonitor->SetDesiredFailureMsg(
Mark Lobodzinski20310782020-02-28 14:25:17 -07001904 kErrorBit,
unknown088160a2019-05-23 17:43:13 -06001905 "VUID-vkCmdCopyImageToBuffer-pRegions-00183"); // Copy 1b depth per texel, into 64k buffer
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06001906 vk::CmdCopyImageToBuffer(m_commandBuffer->handle(), ds_image_1S.handle(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
1907 buffer_64k.handle(), 1, &ds_region);
unknown088160a2019-05-23 17:43:13 -06001908 m_errorMonitor->VerifyFound();
1909 }
1910
1911 // Test compressed formats, if supported
sfricke-samsung6d97e562020-01-07 22:01:00 -08001912 // Support here requires both feature bit for compression and picked format supports transfer feature bits
unknown088160a2019-05-23 17:43:13 -06001913 VkPhysicalDeviceFeatures device_features = {};
1914 ASSERT_NO_FATAL_FAILURE(GetPhysicalDeviceFeatures(&device_features));
1915 if (!(device_features.textureCompressionBC || device_features.textureCompressionETC2 ||
1916 device_features.textureCompressionASTC_LDR)) {
1917 printf("%s No compressed formats supported - block compression tests skipped.\n", kSkipPrefix);
1918 } else {
sfricke-samsung6d97e562020-01-07 22:01:00 -08001919 // Verify transfer support for each compression format used blow
1920 bool missing_bc_support = false;
1921 bool missing_etc_support = false;
1922 bool missing_astc_support = false;
1923 bool missing_compression_support = false;
1924
1925 vk::GetPhysicalDeviceFormatProperties(m_device->phy().handle(), VK_FORMAT_BC3_SRGB_BLOCK, &props);
1926 missing_bc_support |= (props.bufferFeatures == 0 && props.linearTilingFeatures == 0 && props.optimalTilingFeatures == 0);
1927 missing_bc_support |= (props.optimalTilingFeatures & VK_FORMAT_FEATURE_TRANSFER_SRC_BIT) == 0;
1928 missing_bc_support |= (props.optimalTilingFeatures & VK_FORMAT_FEATURE_TRANSFER_DST_BIT) == 0;
1929
1930 vk::GetPhysicalDeviceFormatProperties(m_device->phy().handle(), VK_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK, &props);
1931 missing_etc_support |= (props.bufferFeatures == 0 && props.linearTilingFeatures == 0 && props.optimalTilingFeatures == 0);
1932 missing_etc_support |= (props.optimalTilingFeatures & VK_FORMAT_FEATURE_TRANSFER_SRC_BIT) == 0;
1933 missing_etc_support |= (props.optimalTilingFeatures & VK_FORMAT_FEATURE_TRANSFER_DST_BIT) == 0;
1934
1935 vk::GetPhysicalDeviceFormatProperties(m_device->phy().handle(), VK_FORMAT_ASTC_4x4_UNORM_BLOCK, &props);
1936 missing_astc_support |= (props.bufferFeatures == 0 && props.linearTilingFeatures == 0 && props.optimalTilingFeatures == 0);
1937 missing_astc_support |= (props.optimalTilingFeatures & VK_FORMAT_FEATURE_TRANSFER_SRC_BIT) == 0;
1938 missing_astc_support |= (props.optimalTilingFeatures & VK_FORMAT_FEATURE_TRANSFER_DST_BIT) == 0;
1939
1940 if (device_features.textureCompressionBC && (!missing_bc_support)) {
unknown088160a2019-05-23 17:43:13 -06001941 image_16k_4x4comp.Init(128, 128, 1, VK_FORMAT_BC3_SRGB_BLOCK, VK_IMAGE_USAGE_TRANSFER_SRC_BIT, VK_IMAGE_TILING_OPTIMAL,
1942 0);
1943 image_NPOT_4x4comp.Init(130, 130, 1, VK_FORMAT_BC3_SRGB_BLOCK, VK_IMAGE_USAGE_TRANSFER_SRC_BIT, VK_IMAGE_TILING_OPTIMAL,
1944 0);
sfricke-samsung6d97e562020-01-07 22:01:00 -08001945 } else if (device_features.textureCompressionETC2 && (!missing_etc_support)) {
unknown088160a2019-05-23 17:43:13 -06001946 image_16k_4x4comp.Init(128, 128, 1, VK_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK, VK_IMAGE_USAGE_TRANSFER_SRC_BIT,
1947 VK_IMAGE_TILING_OPTIMAL, 0);
1948 image_NPOT_4x4comp.Init(130, 130, 1, VK_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK, VK_IMAGE_USAGE_TRANSFER_SRC_BIT,
1949 VK_IMAGE_TILING_OPTIMAL, 0);
sfricke-samsung6d97e562020-01-07 22:01:00 -08001950 } else if (device_features.textureCompressionASTC_LDR && (!missing_astc_support)) {
unknown088160a2019-05-23 17:43:13 -06001951 image_16k_4x4comp.Init(128, 128, 1, VK_FORMAT_ASTC_4x4_UNORM_BLOCK, VK_IMAGE_USAGE_TRANSFER_SRC_BIT,
1952 VK_IMAGE_TILING_OPTIMAL, 0);
1953 image_NPOT_4x4comp.Init(130, 130, 1, VK_FORMAT_ASTC_4x4_UNORM_BLOCK, VK_IMAGE_USAGE_TRANSFER_SRC_BIT,
1954 VK_IMAGE_TILING_OPTIMAL, 0);
sfricke-samsung6d97e562020-01-07 22:01:00 -08001955 } else {
1956 missing_compression_support = true;
unknown088160a2019-05-23 17:43:13 -06001957 }
unknown088160a2019-05-23 17:43:13 -06001958
sfricke-samsung6d97e562020-01-07 22:01:00 -08001959 if (missing_compression_support) {
1960 printf("%s No compressed formats transfers bits are supported - block compression tests skipped.\n", kSkipPrefix);
1961 } else {
1962 ASSERT_TRUE(image_16k_4x4comp.initialized());
sfricke-samsung3a10b922020-05-13 23:23:16 -07001963 std::string vuid;
sfricke-samsung6d97e562020-01-07 22:01:00 -08001964 // Just fits
1965 m_errorMonitor->ExpectSuccess();
1966 region.imageExtent = {128, 128, 1};
1967 vk::CmdCopyImageToBuffer(m_commandBuffer->handle(), image_16k_4x4comp.handle(), VK_IMAGE_LAYOUT_GENERAL,
1968 buffer_16k.handle(), 1, &region);
1969 m_errorMonitor->VerifyNotFound();
unknown088160a2019-05-23 17:43:13 -06001970
sfricke-samsung6d97e562020-01-07 22:01:00 -08001971 // with offset, too big for buffer
Mark Lobodzinski20310782020-02-28 14:25:17 -07001972 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdCopyImageToBuffer-pRegions-00183");
sfricke-samsung6d97e562020-01-07 22:01:00 -08001973 region.bufferOffset = 16;
1974 vk::CmdCopyImageToBuffer(m_commandBuffer->handle(), image_16k_4x4comp.handle(), VK_IMAGE_LAYOUT_GENERAL,
1975 buffer_16k.handle(), 1, &region);
1976 m_errorMonitor->VerifyFound();
1977 region.bufferOffset = 0;
unknown088160a2019-05-23 17:43:13 -06001978
sfricke-samsung6d97e562020-01-07 22:01:00 -08001979 // extents that are not a multiple of compressed block size
sfricke-samsung3a10b922020-05-13 23:23:16 -07001980 vuid = mp_extensions ? "VUID-VkBufferImageCopy-None-01739" : "VUID-VkBufferImageCopy-imageExtent-00207";
1981 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, vuid); // extent width not a multiple of block size
Mark Lobodzinski20310782020-02-28 14:25:17 -07001982 m_errorMonitor->SetDesiredFailureMsg(kErrorBit,
sfricke-samsung6d97e562020-01-07 22:01:00 -08001983 "VUID-vkCmdCopyImageToBuffer-imageOffset-01794"); // image transfer granularity
1984 region.imageExtent.width = 66;
1985 vk::CmdCopyImageToBuffer(m_commandBuffer->handle(), image_NPOT_4x4comp.handle(), VK_IMAGE_LAYOUT_GENERAL,
1986 buffer_16k.handle(), 1, &region);
1987 m_errorMonitor->VerifyFound();
1988 region.imageExtent.width = 128;
unknown088160a2019-05-23 17:43:13 -06001989
sfricke-samsung3a10b922020-05-13 23:23:16 -07001990 vuid = mp_extensions ? "VUID-VkBufferImageCopy-None-01740" : "VUID-VkBufferImageCopy-imageExtent-00208";
1991 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, vuid); // extent height not a multiple of block size
Mark Lobodzinski20310782020-02-28 14:25:17 -07001992 m_errorMonitor->SetDesiredFailureMsg(kErrorBit,
sfricke-samsung6d97e562020-01-07 22:01:00 -08001993 "VUID-vkCmdCopyImageToBuffer-imageOffset-01794"); // image transfer granularity
1994 region.imageExtent.height = 2;
1995 vk::CmdCopyImageToBuffer(m_commandBuffer->handle(), image_NPOT_4x4comp.handle(), VK_IMAGE_LAYOUT_GENERAL,
1996 buffer_16k.handle(), 1, &region);
1997 m_errorMonitor->VerifyFound();
1998 region.imageExtent.height = 128;
unknown088160a2019-05-23 17:43:13 -06001999
sfricke-samsung6d97e562020-01-07 22:01:00 -08002000 // TODO: All available compressed formats are 2D, with block depth of 1. Unable to provoke VU_01277.
unknown088160a2019-05-23 17:43:13 -06002001
sfricke-samsung6d97e562020-01-07 22:01:00 -08002002 // non-multiple extents are allowed if at the far edge of a non-block-multiple image - these should pass
2003 m_errorMonitor->ExpectSuccess();
2004 region.imageExtent.width = 66;
2005 region.imageOffset.x = 64;
2006 vk::CmdCopyImageToBuffer(m_commandBuffer->handle(), image_NPOT_4x4comp.handle(), VK_IMAGE_LAYOUT_GENERAL,
2007 buffer_16k.handle(), 1, &region);
2008 region.imageExtent.width = 16;
2009 region.imageOffset.x = 0;
2010 region.imageExtent.height = 2;
2011 region.imageOffset.y = 128;
2012 vk::CmdCopyImageToBuffer(m_commandBuffer->handle(), image_NPOT_4x4comp.handle(), VK_IMAGE_LAYOUT_GENERAL,
2013 buffer_16k.handle(), 1, &region);
2014 m_errorMonitor->VerifyNotFound();
2015 region.imageOffset = {0, 0, 0};
unknown088160a2019-05-23 17:43:13 -06002016
sfricke-samsung6d97e562020-01-07 22:01:00 -08002017 // buffer offset must be a multiple of texel block size (16)
sfricke-samsung3a10b922020-05-13 23:23:16 -07002018 vuid = mp_extensions ? "VUID-VkBufferImageCopy-None-01738" : "VUID-VkBufferImageCopy-bufferOffset-00206";
2019 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, vuid);
Mark Lobodzinski20310782020-02-28 14:25:17 -07002020 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkBufferImageCopy-bufferOffset-00193");
sfricke-samsung6d97e562020-01-07 22:01:00 -08002021 region.imageExtent = {64, 64, 1};
2022 region.bufferOffset = 24;
2023 vk::CmdCopyImageToBuffer(m_commandBuffer->handle(), image_16k_4x4comp.handle(), VK_IMAGE_LAYOUT_GENERAL,
2024 buffer_16k.handle(), 1, &region);
2025 m_errorMonitor->VerifyFound();
unknown088160a2019-05-23 17:43:13 -06002026
sfricke-samsung6d97e562020-01-07 22:01:00 -08002027 // rowlength not a multiple of block width (4)
sfricke-samsung3a10b922020-05-13 23:23:16 -07002028 vuid = mp_extensions ? "VUID-VkBufferImageCopy-None-01735" : "VUID-VkBufferImageCopy-bufferRowLength-00203";
2029 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, vuid);
sfricke-samsung6d97e562020-01-07 22:01:00 -08002030 region.bufferOffset = 0;
2031 region.bufferRowLength = 130;
2032 region.bufferImageHeight = 0;
2033 vk::CmdCopyImageToBuffer(m_commandBuffer->handle(), image_16k_4x4comp.handle(), VK_IMAGE_LAYOUT_GENERAL,
2034 buffer_64k.handle(), 1, &region);
2035 m_errorMonitor->VerifyFound();
2036
2037 // imageheight not a multiple of block height (4)
sfricke-samsung3a10b922020-05-13 23:23:16 -07002038 vuid = mp_extensions ? "VUID-VkBufferImageCopy-None-01736" : "VUID-VkBufferImageCopy-bufferImageHeight-00204";
2039 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, vuid);
sfricke-samsung6d97e562020-01-07 22:01:00 -08002040 region.bufferRowLength = 0;
2041 region.bufferImageHeight = 130;
2042 vk::CmdCopyImageToBuffer(m_commandBuffer->handle(), image_16k_4x4comp.handle(), VK_IMAGE_LAYOUT_GENERAL,
2043 buffer_64k.handle(), 1, &region);
2044 m_errorMonitor->VerifyFound();
2045 }
2046 }
2047
2048 // Test multi-planar formats, if supported
2049 if (!mp_extensions) {
2050 printf("%s multi-planar extensions not supported; skipped.\n", kSkipPrefix);
2051 } else {
2052 // Try to use G8_B8R8_2PLANE_420_UNORM because need 2-plane format for some tests and likely supported due to copy support
2053 // being required with samplerYcbcrConversion feature
2054 bool missing_mp_support = false;
2055 vk::GetPhysicalDeviceFormatProperties(m_device->phy().handle(), VK_FORMAT_G8_B8R8_2PLANE_420_UNORM, &props);
2056 missing_mp_support |= (props.bufferFeatures == 0 && props.linearTilingFeatures == 0 && props.optimalTilingFeatures == 0);
2057 missing_mp_support |= (props.optimalTilingFeatures & VK_FORMAT_FEATURE_TRANSFER_SRC_BIT) == 0;
2058 missing_mp_support |= (props.optimalTilingFeatures & VK_FORMAT_FEATURE_TRANSFER_DST_BIT) == 0;
2059
2060 if (missing_mp_support) {
2061 printf("%s VK_FORMAT_G8_B8R8_2PLANE_420_UNORM transfer not supported; skipped.\n", kSkipPrefix);
2062 } else {
2063 VkBufferImageCopy mp_region = {};
2064 mp_region.bufferOffset = 0;
2065 mp_region.bufferRowLength = 0;
2066 mp_region.bufferImageHeight = 0;
2067 mp_region.imageSubresource.mipLevel = 0;
2068 mp_region.imageSubresource.baseArrayLayer = 0;
2069 mp_region.imageSubresource.layerCount = 1;
2070 mp_region.imageOffset = {0, 0, 0};
2071 mp_region.imageExtent = {128, 128, 1};
2072
2073 // YUV420 means 1/2 width and height so plane_0 is 128x128 and plane_1 is 64x64 here
2074 image_multi_planar.Init(128, 128, 1, VK_FORMAT_G8_B8R8_2PLANE_420_UNORM, VK_IMAGE_USAGE_TRANSFER_DST_BIT,
2075 VK_IMAGE_TILING_OPTIMAL, 0);
2076 ASSERT_TRUE(image_multi_planar.initialized());
2077
2078 // Copies into a mutli-planar image aspect properly
2079 m_errorMonitor->ExpectSuccess();
2080 mp_region.imageSubresource.aspectMask = VK_IMAGE_ASPECT_PLANE_0_BIT;
2081 vk::CmdCopyBufferToImage(m_commandBuffer->handle(), buffer_16k.handle(), image_multi_planar.handle(),
2082 VK_IMAGE_LAYOUT_GENERAL, 1, &mp_region);
2083 m_errorMonitor->VerifyNotFound();
2084
2085 // uses plane_2 without being 3 planar format
Mark Lobodzinski20310782020-02-28 14:25:17 -07002086 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkBufferImageCopy-aspectMask-01560");
sfricke-samsung6d97e562020-01-07 22:01:00 -08002087 mp_region.imageSubresource.aspectMask = VK_IMAGE_ASPECT_PLANE_2_BIT;
2088 vk::CmdCopyBufferToImage(m_commandBuffer->handle(), buffer_16k.handle(), image_multi_planar.handle(),
2089 VK_IMAGE_LAYOUT_GENERAL, 1, &mp_region);
2090 m_errorMonitor->VerifyFound();
2091
2092 // uses single-plane aspect mask
Mark Lobodzinski20310782020-02-28 14:25:17 -07002093 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkBufferImageCopy-aspectMask-01560");
sfricke-samsung6d97e562020-01-07 22:01:00 -08002094 mp_region.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
2095 vk::CmdCopyBufferToImage(m_commandBuffer->handle(), buffer_16k.handle(), image_multi_planar.handle(),
2096 VK_IMAGE_LAYOUT_GENERAL, 1, &mp_region);
2097 m_errorMonitor->VerifyFound();
2098 }
unknown088160a2019-05-23 17:43:13 -06002099 }
2100}
2101
2102TEST_F(VkLayerTest, MiscImageLayerTests) {
2103 TEST_DESCRIPTION("Image-related tests that don't belong elsewhere");
2104
2105 ASSERT_NO_FATAL_FAILURE(Init());
2106
2107 // TODO: Ideally we should check if a format is supported, before using it.
2108 VkImageObj image(m_device);
2109 image.Init(128, 128, 1, VK_FORMAT_R16G16B16A16_UINT, VK_IMAGE_USAGE_TRANSFER_DST_BIT, VK_IMAGE_TILING_OPTIMAL, 0); // 64bpp
2110 ASSERT_TRUE(image.initialized());
2111 VkBufferObj buffer;
2112 VkMemoryPropertyFlags reqs = 0;
2113 buffer.init_as_src(*m_device, 128 * 128 * 8, reqs);
2114 VkBufferImageCopy region = {};
2115 region.bufferRowLength = 128;
2116 region.bufferImageHeight = 128;
2117 region.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
2118 // layerCount can't be 0 - Expect MISMATCHED_IMAGE_ASPECT
2119 region.imageSubresource.layerCount = 1;
2120 region.imageExtent.height = 4;
2121 region.imageExtent.width = 4;
2122 region.imageExtent.depth = 1;
2123
2124 VkImageObj image2(m_device);
2125 image2.Init(128, 128, 1, VK_FORMAT_R8G8_UNORM, VK_IMAGE_USAGE_TRANSFER_DST_BIT, VK_IMAGE_TILING_OPTIMAL, 0); // 16bpp
2126 ASSERT_TRUE(image2.initialized());
2127 VkBufferObj buffer2;
2128 VkMemoryPropertyFlags reqs2 = 0;
2129 buffer2.init_as_src(*m_device, 128 * 128 * 2, reqs2);
2130 VkBufferImageCopy region2 = {};
2131 region2.bufferRowLength = 128;
2132 region2.bufferImageHeight = 128;
2133 region2.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
2134 // layerCount can't be 0 - Expect MISMATCHED_IMAGE_ASPECT
2135 region2.imageSubresource.layerCount = 1;
2136 region2.imageExtent.height = 4;
2137 region2.imageExtent.width = 4;
2138 region2.imageExtent.depth = 1;
2139 m_commandBuffer->begin();
2140
2141 // Image must have offset.z of 0 and extent.depth of 1
2142 // Introduce failure by setting imageExtent.depth to 0
2143 region.imageExtent.depth = 0;
Mark Lobodzinski20310782020-02-28 14:25:17 -07002144 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkBufferImageCopy-srcImage-00201");
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06002145 vk::CmdCopyBufferToImage(m_commandBuffer->handle(), buffer.handle(), image.handle(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1,
2146 &region);
unknown088160a2019-05-23 17:43:13 -06002147 m_errorMonitor->VerifyFound();
2148
2149 region.imageExtent.depth = 1;
2150
2151 // Image must have offset.z of 0 and extent.depth of 1
2152 // Introduce failure by setting imageOffset.z to 4
2153 // Note: Also (unavoidably) triggers 'region exceeds image' #1228
2154 region.imageOffset.z = 4;
Mark Lobodzinski20310782020-02-28 14:25:17 -07002155 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkBufferImageCopy-srcImage-00201");
2156 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkBufferImageCopy-imageOffset-00200");
2157 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdCopyBufferToImage-pRegions-00172");
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06002158 vk::CmdCopyBufferToImage(m_commandBuffer->handle(), buffer.handle(), image.handle(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1,
2159 &region);
unknown088160a2019-05-23 17:43:13 -06002160 m_errorMonitor->VerifyFound();
2161
2162 region.imageOffset.z = 0;
2163 // BufferOffset must be a multiple of the calling command's VkImage parameter's texel size
2164 // Introduce failure by setting bufferOffset to 1 and 1/2 texels
2165 region.bufferOffset = 4;
Mark Lobodzinski20310782020-02-28 14:25:17 -07002166 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkBufferImageCopy-bufferOffset-00193");
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06002167 vk::CmdCopyBufferToImage(m_commandBuffer->handle(), buffer.handle(), image.handle(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1,
2168 &region);
unknown088160a2019-05-23 17:43:13 -06002169 m_errorMonitor->VerifyFound();
2170
2171 // BufferOffset must be a multiple of 4
2172 // Introduce failure by setting bufferOffset to a value not divisible by 4
2173 region2.bufferOffset = 6;
Mark Lobodzinski20310782020-02-28 14:25:17 -07002174 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkBufferImageCopy-bufferOffset-00194");
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06002175 vk::CmdCopyBufferToImage(m_commandBuffer->handle(), buffer2.handle(), image2.handle(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1,
2176 &region2);
unknown088160a2019-05-23 17:43:13 -06002177 m_errorMonitor->VerifyFound();
2178
2179 // BufferRowLength must be 0, or greater than or equal to the width member of imageExtent
2180 region.bufferOffset = 0;
2181 region.imageExtent.height = 128;
2182 region.imageExtent.width = 128;
2183 // Introduce failure by setting bufferRowLength > 0 but less than width
2184 region.bufferRowLength = 64;
Mark Lobodzinski20310782020-02-28 14:25:17 -07002185 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkBufferImageCopy-bufferRowLength-00195");
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06002186 vk::CmdCopyBufferToImage(m_commandBuffer->handle(), buffer.handle(), image.handle(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1,
2187 &region);
unknown088160a2019-05-23 17:43:13 -06002188 m_errorMonitor->VerifyFound();
2189
2190 // BufferImageHeight must be 0, or greater than or equal to the height member of imageExtent
2191 region.bufferRowLength = 128;
2192 // Introduce failure by setting bufferRowHeight > 0 but less than height
2193 region.bufferImageHeight = 64;
Mark Lobodzinski20310782020-02-28 14:25:17 -07002194 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkBufferImageCopy-bufferImageHeight-00196");
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06002195 vk::CmdCopyBufferToImage(m_commandBuffer->handle(), buffer.handle(), image.handle(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1,
2196 &region);
unknown088160a2019-05-23 17:43:13 -06002197 m_errorMonitor->VerifyFound();
2198
2199 region.bufferImageHeight = 128;
2200 VkImageObj intImage1(m_device);
2201 intImage1.Init(128, 128, 1, VK_FORMAT_R8_UNORM, VK_IMAGE_USAGE_TRANSFER_SRC_BIT, VK_IMAGE_TILING_OPTIMAL, 0);
2202 intImage1.SetLayout(VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_GENERAL);
2203 VkImageObj intImage2(m_device);
2204 intImage2.Init(128, 128, 1, VK_FORMAT_R8_UNORM, VK_IMAGE_USAGE_TRANSFER_DST_BIT, VK_IMAGE_TILING_OPTIMAL, 0);
2205 intImage2.SetLayout(VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_GENERAL);
2206 VkImageBlit blitRegion = {};
2207 blitRegion.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
2208 blitRegion.srcSubresource.baseArrayLayer = 0;
2209 blitRegion.srcSubresource.layerCount = 1;
2210 blitRegion.srcSubresource.mipLevel = 0;
2211 blitRegion.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
2212 blitRegion.dstSubresource.baseArrayLayer = 0;
2213 blitRegion.dstSubresource.layerCount = 1;
2214 blitRegion.dstSubresource.mipLevel = 0;
2215 blitRegion.srcOffsets[0] = {128, 0, 0};
2216 blitRegion.srcOffsets[1] = {128, 128, 1};
2217 blitRegion.dstOffsets[0] = {0, 128, 0};
2218 blitRegion.dstOffsets[1] = {128, 128, 1};
2219
2220 // Look for NULL-blit warning
Mark Lobodzinski20310782020-02-28 14:25:17 -07002221 m_errorMonitor->SetDesiredFailureMsg(kWarningBit, "vkCmdBlitImage(): pRegions[0].srcOffsets specify a zero-volume area.");
2222 m_errorMonitor->SetDesiredFailureMsg(kWarningBit, "vkCmdBlitImage(): pRegions[0].dstOffsets specify a zero-volume area.");
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06002223 vk::CmdBlitImage(m_commandBuffer->handle(), intImage1.handle(), intImage1.Layout(), intImage2.handle(), intImage2.Layout(), 1,
2224 &blitRegion, VK_FILTER_LINEAR);
unknown088160a2019-05-23 17:43:13 -06002225 m_errorMonitor->VerifyFound();
2226}
2227
2228TEST_F(VkLayerTest, CopyImageTypeExtentMismatch) {
2229 // Image copy tests where format type and extents don't match
2230 ASSERT_NO_FATAL_FAILURE(Init());
2231
2232 VkImageCreateInfo ci;
2233 ci.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
2234 ci.pNext = NULL;
2235 ci.flags = 0;
2236 ci.imageType = VK_IMAGE_TYPE_1D;
2237 ci.format = VK_FORMAT_R8G8B8A8_UNORM;
2238 ci.extent = {32, 1, 1};
2239 ci.mipLevels = 1;
2240 ci.arrayLayers = 1;
2241 ci.samples = VK_SAMPLE_COUNT_1_BIT;
2242 ci.tiling = VK_IMAGE_TILING_OPTIMAL;
2243 ci.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
2244 ci.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
2245 ci.queueFamilyIndexCount = 0;
2246 ci.pQueueFamilyIndices = NULL;
2247 ci.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
2248
2249 // Create 1D image
2250 VkImageObj image_1D(m_device);
2251 image_1D.init(&ci);
2252 ASSERT_TRUE(image_1D.initialized());
2253
2254 // 2D image
2255 ci.imageType = VK_IMAGE_TYPE_2D;
2256 ci.extent = {32, 32, 1};
2257 VkImageObj image_2D(m_device);
2258 image_2D.init(&ci);
2259 ASSERT_TRUE(image_2D.initialized());
2260
2261 // 3D image
2262 ci.imageType = VK_IMAGE_TYPE_3D;
2263 ci.extent = {32, 32, 8};
2264 VkImageObj image_3D(m_device);
2265 image_3D.init(&ci);
2266 ASSERT_TRUE(image_3D.initialized());
2267
2268 // 2D image array
2269 ci.imageType = VK_IMAGE_TYPE_2D;
2270 ci.extent = {32, 32, 1};
2271 ci.arrayLayers = 8;
2272 VkImageObj image_2D_array(m_device);
2273 image_2D_array.init(&ci);
2274 ASSERT_TRUE(image_2D_array.initialized());
2275
2276 m_commandBuffer->begin();
2277
2278 VkImageCopy copy_region;
2279 copy_region.extent = {32, 1, 1};
2280 copy_region.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
2281 copy_region.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
2282 copy_region.srcSubresource.mipLevel = 0;
2283 copy_region.dstSubresource.mipLevel = 0;
2284 copy_region.srcSubresource.baseArrayLayer = 0;
2285 copy_region.dstSubresource.baseArrayLayer = 0;
2286 copy_region.srcSubresource.layerCount = 1;
2287 copy_region.dstSubresource.layerCount = 1;
2288 copy_region.srcOffset = {0, 0, 0};
2289 copy_region.dstOffset = {0, 0, 0};
2290
2291 // Sanity check
2292 m_errorMonitor->ExpectSuccess();
2293 m_commandBuffer->CopyImage(image_1D.image(), VK_IMAGE_LAYOUT_GENERAL, image_2D.image(), VK_IMAGE_LAYOUT_GENERAL, 1,
2294 &copy_region);
2295 m_errorMonitor->VerifyNotFound();
2296
2297 // 1D texture w/ offset.y > 0. Source = VU 09c00124, dest = 09c00130
2298 copy_region.srcOffset.y = 1;
Mark Lobodzinski20310782020-02-28 14:25:17 -07002299 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkImageCopy-srcImage-00146");
2300 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkImageCopy-srcOffset-00145"); // also y-dim overrun
unknown088160a2019-05-23 17:43:13 -06002301 m_commandBuffer->CopyImage(image_1D.image(), VK_IMAGE_LAYOUT_GENERAL, image_2D.image(), VK_IMAGE_LAYOUT_GENERAL, 1,
2302 &copy_region);
2303 m_errorMonitor->VerifyFound();
2304 copy_region.srcOffset.y = 0;
2305 copy_region.dstOffset.y = 1;
Mark Lobodzinski20310782020-02-28 14:25:17 -07002306 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkImageCopy-dstImage-00152");
2307 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkImageCopy-dstOffset-00151"); // also y-dim overrun
unknown088160a2019-05-23 17:43:13 -06002308 m_commandBuffer->CopyImage(image_2D.image(), VK_IMAGE_LAYOUT_GENERAL, image_1D.image(), VK_IMAGE_LAYOUT_GENERAL, 1,
2309 &copy_region);
2310 m_errorMonitor->VerifyFound();
2311 copy_region.dstOffset.y = 0;
2312
2313 // 1D texture w/ extent.height > 1. Source = VU 09c00124, dest = 09c00130
2314 copy_region.extent.height = 2;
Mark Lobodzinski20310782020-02-28 14:25:17 -07002315 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkImageCopy-srcImage-00146");
2316 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkImageCopy-srcOffset-00145"); // also y-dim overrun
unknown088160a2019-05-23 17:43:13 -06002317 m_commandBuffer->CopyImage(image_1D.image(), VK_IMAGE_LAYOUT_GENERAL, image_2D.image(), VK_IMAGE_LAYOUT_GENERAL, 1,
2318 &copy_region);
2319 m_errorMonitor->VerifyFound();
Mark Lobodzinski20310782020-02-28 14:25:17 -07002320 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkImageCopy-dstImage-00152");
2321 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkImageCopy-dstOffset-00151"); // also y-dim overrun
unknown088160a2019-05-23 17:43:13 -06002322 m_commandBuffer->CopyImage(image_2D.image(), VK_IMAGE_LAYOUT_GENERAL, image_1D.image(), VK_IMAGE_LAYOUT_GENERAL, 1,
2323 &copy_region);
2324 m_errorMonitor->VerifyFound();
2325 copy_region.extent.height = 1;
2326
2327 // 1D texture w/ offset.z > 0. Source = VU 09c00df2, dest = 09c00df4
2328 copy_region.srcOffset.z = 1;
Mark Lobodzinski20310782020-02-28 14:25:17 -07002329 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkImageCopy-srcImage-01785");
2330 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkImageCopy-srcOffset-00147"); // also z-dim overrun
unknown088160a2019-05-23 17:43:13 -06002331 m_commandBuffer->CopyImage(image_1D.image(), VK_IMAGE_LAYOUT_GENERAL, image_2D.image(), VK_IMAGE_LAYOUT_GENERAL, 1,
2332 &copy_region);
2333 m_errorMonitor->VerifyFound();
2334 copy_region.srcOffset.z = 0;
2335 copy_region.dstOffset.z = 1;
Mark Lobodzinski20310782020-02-28 14:25:17 -07002336 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkImageCopy-dstImage-01786");
2337 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkImageCopy-dstOffset-00153"); // also z-dim overrun
unknown088160a2019-05-23 17:43:13 -06002338 m_commandBuffer->CopyImage(image_2D.image(), VK_IMAGE_LAYOUT_GENERAL, image_1D.image(), VK_IMAGE_LAYOUT_GENERAL, 1,
2339 &copy_region);
2340 m_errorMonitor->VerifyFound();
2341 copy_region.dstOffset.z = 0;
2342
2343 // 1D texture w/ extent.depth > 1. Source = VU 09c00df2, dest = 09c00df4
2344 copy_region.extent.depth = 2;
Mark Lobodzinski20310782020-02-28 14:25:17 -07002345 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkImageCopy-srcImage-01785");
2346 m_errorMonitor->SetDesiredFailureMsg(kErrorBit,
unknown088160a2019-05-23 17:43:13 -06002347 "VUID-VkImageCopy-srcOffset-00147"); // also z-dim overrun (src)
Mark Lobodzinski20310782020-02-28 14:25:17 -07002348 m_errorMonitor->SetDesiredFailureMsg(kErrorBit,
unknown088160a2019-05-23 17:43:13 -06002349 "VUID-VkImageCopy-dstOffset-00153"); // also z-dim overrun (dst)
Mark Lobodzinski20310782020-02-28 14:25:17 -07002350 m_errorMonitor->SetDesiredFailureMsg(kErrorBit,
sfricke-samsung211ee9c2020-02-13 23:38:39 -08002351 "VUID-VkImageCopy-srcImage-01789"); // 2D needs to be 1 pre-Vulkan 1.1
unknown088160a2019-05-23 17:43:13 -06002352 m_commandBuffer->CopyImage(image_1D.image(), VK_IMAGE_LAYOUT_GENERAL, image_2D.image(), VK_IMAGE_LAYOUT_GENERAL, 1,
2353 &copy_region);
2354 m_errorMonitor->VerifyFound();
Mark Lobodzinski20310782020-02-28 14:25:17 -07002355 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkImageCopy-dstImage-01786");
2356 m_errorMonitor->SetDesiredFailureMsg(kErrorBit,
unknown088160a2019-05-23 17:43:13 -06002357 "VUID-VkImageCopy-srcOffset-00147"); // also z-dim overrun (src)
Mark Lobodzinski20310782020-02-28 14:25:17 -07002358 m_errorMonitor->SetDesiredFailureMsg(kErrorBit,
unknown088160a2019-05-23 17:43:13 -06002359 "VUID-VkImageCopy-dstOffset-00153"); // also z-dim overrun (dst)
Mark Lobodzinski20310782020-02-28 14:25:17 -07002360 m_errorMonitor->SetDesiredFailureMsg(kErrorBit,
sfricke-samsung211ee9c2020-02-13 23:38:39 -08002361 "VUID-VkImageCopy-srcImage-01789"); // 2D needs to be 1 pre-Vulkan 1.1
unknown088160a2019-05-23 17:43:13 -06002362 m_commandBuffer->CopyImage(image_2D.image(), VK_IMAGE_LAYOUT_GENERAL, image_1D.image(), VK_IMAGE_LAYOUT_GENERAL, 1,
2363 &copy_region);
2364 m_errorMonitor->VerifyFound();
2365 copy_region.extent.depth = 1;
2366
2367 // 2D texture w/ offset.z > 0. Source = VU 09c00df6, dest = 09c00df8
2368 copy_region.extent = {16, 16, 1};
2369 copy_region.srcOffset.z = 4;
Mark Lobodzinski20310782020-02-28 14:25:17 -07002370 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkImageCopy-srcImage-01787");
2371 m_errorMonitor->SetDesiredFailureMsg(kErrorBit,
unknown088160a2019-05-23 17:43:13 -06002372 "VUID-VkImageCopy-srcOffset-00147"); // also z-dim overrun (src)
2373 m_commandBuffer->CopyImage(image_2D.image(), VK_IMAGE_LAYOUT_GENERAL, image_3D.image(), VK_IMAGE_LAYOUT_GENERAL, 1,
2374 &copy_region);
2375 m_errorMonitor->VerifyFound();
2376 copy_region.srcOffset.z = 0;
2377 copy_region.dstOffset.z = 1;
Mark Lobodzinski20310782020-02-28 14:25:17 -07002378 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkImageCopy-dstImage-01788");
2379 m_errorMonitor->SetDesiredFailureMsg(kErrorBit,
unknown088160a2019-05-23 17:43:13 -06002380 "VUID-VkImageCopy-dstOffset-00153"); // also z-dim overrun (dst)
2381 m_commandBuffer->CopyImage(image_3D.image(), VK_IMAGE_LAYOUT_GENERAL, image_2D.image(), VK_IMAGE_LAYOUT_GENERAL, 1,
2382 &copy_region);
2383 m_errorMonitor->VerifyFound();
2384 copy_region.dstOffset.z = 0;
2385
2386 // 3D texture accessing an array layer other than 0. VU 09c0011a
2387 copy_region.extent = {4, 4, 1};
2388 copy_region.srcSubresource.baseArrayLayer = 1;
Mark Lobodzinski20310782020-02-28 14:25:17 -07002389 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkImageCopy-srcImage-00141");
2390 m_errorMonitor->SetDesiredFailureMsg(kErrorBit,
unknown088160a2019-05-23 17:43:13 -06002391 "VUID-vkCmdCopyImage-srcSubresource-01698"); // also 'too many layers'
2392 m_commandBuffer->CopyImage(image_3D.image(), VK_IMAGE_LAYOUT_GENERAL, image_2D.image(), VK_IMAGE_LAYOUT_GENERAL, 1,
2393 &copy_region);
2394 m_errorMonitor->VerifyFound();
sfricke-samsung211ee9c2020-02-13 23:38:39 -08002395 copy_region.srcSubresource.baseArrayLayer = 0;
2396
unknown088160a2019-05-23 17:43:13 -06002397 m_commandBuffer->end();
2398}
2399
2400TEST_F(VkLayerTest, CopyImageTypeExtentMismatchMaintenance1) {
2401 // Image copy tests where format type and extents don't match and the Maintenance1 extension is enabled
Mark Lobodzinski09ce9c42020-03-06 10:02:44 -07002402 ASSERT_NO_FATAL_FAILURE(InitFramework(m_errorMonitor));
unknown088160a2019-05-23 17:43:13 -06002403 if (DeviceExtensionSupported(gpu(), nullptr, VK_KHR_MAINTENANCE1_EXTENSION_NAME)) {
2404 m_device_extension_names.push_back(VK_KHR_MAINTENANCE1_EXTENSION_NAME);
2405 } else {
2406 printf("%s Maintenance1 extension cannot be enabled, test skipped.\n", kSkipPrefix);
2407 return;
2408 }
2409 ASSERT_NO_FATAL_FAILURE(InitState());
2410
2411 VkFormat image_format = VK_FORMAT_R8G8B8A8_UNORM;
2412 VkFormatProperties format_props;
2413 // TODO: Remove this check if or when devsim handles extensions.
2414 // The chosen format has mandatory support the transfer src and dst format features when Maitenance1 is enabled. However, our
2415 // use of devsim and the mock ICD violate this guarantee.
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06002416 vk::GetPhysicalDeviceFormatProperties(m_device->phy().handle(), image_format, &format_props);
unknown088160a2019-05-23 17:43:13 -06002417 if (!(format_props.optimalTilingFeatures & VK_FORMAT_FEATURE_TRANSFER_SRC_BIT)) {
2418 printf("%s Maintenance1 extension is not supported.\n", kSkipPrefix);
2419 return;
2420 }
2421
2422 VkImageCreateInfo ci;
2423 ci.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
2424 ci.pNext = NULL;
2425 ci.flags = 0;
2426 ci.imageType = VK_IMAGE_TYPE_1D;
2427 ci.format = image_format;
2428 ci.extent = {32, 1, 1};
2429 ci.mipLevels = 1;
2430 ci.arrayLayers = 1;
2431 ci.samples = VK_SAMPLE_COUNT_1_BIT;
2432 ci.tiling = VK_IMAGE_TILING_OPTIMAL;
2433 ci.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
2434 ci.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
2435 ci.queueFamilyIndexCount = 0;
2436 ci.pQueueFamilyIndices = NULL;
2437 ci.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
2438
2439 // Create 1D image
2440 VkImageObj image_1D(m_device);
2441 image_1D.init(&ci);
2442 ASSERT_TRUE(image_1D.initialized());
2443
2444 // 2D image
2445 ci.imageType = VK_IMAGE_TYPE_2D;
2446 ci.extent = {32, 32, 1};
2447 VkImageObj image_2D(m_device);
2448 image_2D.init(&ci);
2449 ASSERT_TRUE(image_2D.initialized());
2450
2451 // 3D image
2452 ci.imageType = VK_IMAGE_TYPE_3D;
2453 ci.extent = {32, 32, 8};
2454 VkImageObj image_3D(m_device);
2455 image_3D.init(&ci);
2456 ASSERT_TRUE(image_3D.initialized());
2457
2458 // 2D image array
2459 ci.imageType = VK_IMAGE_TYPE_2D;
2460 ci.extent = {32, 32, 1};
2461 ci.arrayLayers = 8;
2462 VkImageObj image_2D_array(m_device);
2463 image_2D_array.init(&ci);
2464 ASSERT_TRUE(image_2D_array.initialized());
2465
sfricke-samsung211ee9c2020-02-13 23:38:39 -08002466 // second 2D image array
2467 ci.imageType = VK_IMAGE_TYPE_2D;
2468 ci.extent = {32, 32, 1};
2469 ci.arrayLayers = 8;
2470 VkImageObj image_2D_array_2(m_device);
2471 image_2D_array_2.init(&ci);
2472 ASSERT_TRUE(image_2D_array_2.initialized());
2473
unknown088160a2019-05-23 17:43:13 -06002474 m_commandBuffer->begin();
2475
2476 VkImageCopy copy_region;
2477 copy_region.extent = {32, 1, 1};
2478 copy_region.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
2479 copy_region.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
2480 copy_region.srcSubresource.mipLevel = 0;
2481 copy_region.dstSubresource.mipLevel = 0;
2482 copy_region.srcSubresource.baseArrayLayer = 0;
2483 copy_region.dstSubresource.baseArrayLayer = 0;
2484 copy_region.srcSubresource.layerCount = 1;
2485 copy_region.dstSubresource.layerCount = 1;
2486 copy_region.srcOffset = {0, 0, 0};
2487 copy_region.dstOffset = {0, 0, 0};
2488
2489 // Copy from layer not present
2490 copy_region.srcSubresource.baseArrayLayer = 4;
2491 copy_region.srcSubresource.layerCount = 6;
Mark Lobodzinski20310782020-02-28 14:25:17 -07002492 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdCopyImage-srcSubresource-01698");
unknown088160a2019-05-23 17:43:13 -06002493 m_commandBuffer->CopyImage(image_2D_array.image(), VK_IMAGE_LAYOUT_GENERAL, image_3D.image(), VK_IMAGE_LAYOUT_GENERAL, 1,
2494 &copy_region);
2495 m_errorMonitor->VerifyFound();
2496 copy_region.srcSubresource.baseArrayLayer = 0;
2497 copy_region.srcSubresource.layerCount = 1;
2498
2499 // Copy to layer not present
2500 copy_region.dstSubresource.baseArrayLayer = 1;
2501 copy_region.dstSubresource.layerCount = 8;
Mark Lobodzinski20310782020-02-28 14:25:17 -07002502 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdCopyImage-dstSubresource-01699");
unknown088160a2019-05-23 17:43:13 -06002503 m_commandBuffer->CopyImage(image_3D.image(), VK_IMAGE_LAYOUT_GENERAL, image_2D_array.image(), VK_IMAGE_LAYOUT_GENERAL, 1,
2504 &copy_region);
2505 m_errorMonitor->VerifyFound();
sfricke-samsung211ee9c2020-02-13 23:38:39 -08002506 copy_region.dstSubresource.baseArrayLayer = 0;
unknown088160a2019-05-23 17:43:13 -06002507 copy_region.dstSubresource.layerCount = 1;
2508
sfricke-samsung211ee9c2020-02-13 23:38:39 -08002509 // both 2D and extent.depth not 1
2510 // Need two 2D array images to prevent other errors
2511 copy_region.extent = {4, 1, 2};
Mark Lobodzinski20310782020-02-28 14:25:17 -07002512 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkImageCopy-srcImage-01790");
sfricke-samsung211ee9c2020-02-13 23:38:39 -08002513 m_commandBuffer->CopyImage(image_2D_array.image(), VK_IMAGE_LAYOUT_GENERAL, image_2D_array_2.image(), VK_IMAGE_LAYOUT_GENERAL,
2514 1, &copy_region);
2515 m_errorMonitor->VerifyFound();
2516 copy_region.extent = {32, 1, 1};
2517
2518 // 2D src / 3D dst and depth not equal to src layerCount
2519 copy_region.extent = {4, 1, 2};
Mark Lobodzinski20310782020-02-28 14:25:17 -07002520 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkImageCopy-srcImage-01791");
2521 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkImageCopy-extent-00140");
sfricke-samsung211ee9c2020-02-13 23:38:39 -08002522 m_commandBuffer->CopyImage(image_2D_array.image(), VK_IMAGE_LAYOUT_GENERAL, image_3D.image(), VK_IMAGE_LAYOUT_GENERAL, 1,
2523 &copy_region);
2524 m_errorMonitor->VerifyFound();
2525 copy_region.extent = {32, 1, 1};
2526
2527 // 3D src / 2D dst and depth not equal to dst layerCount
2528 copy_region.extent = {4, 1, 2};
Mark Lobodzinski20310782020-02-28 14:25:17 -07002529 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkImageCopy-dstImage-01792");
2530 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkImageCopy-extent-00140");
sfricke-samsung211ee9c2020-02-13 23:38:39 -08002531 m_commandBuffer->CopyImage(image_3D.image(), VK_IMAGE_LAYOUT_GENERAL, image_2D_array.image(), VK_IMAGE_LAYOUT_GENERAL, 1,
2532 &copy_region);
2533 m_errorMonitor->VerifyFound();
2534 copy_region.extent = {32, 1, 1};
2535
unknown088160a2019-05-23 17:43:13 -06002536 m_commandBuffer->end();
2537}
2538
2539TEST_F(VkLayerTest, CopyImageCompressedBlockAlignment) {
2540 // Image copy tests on compressed images with block alignment errors
2541 SetTargetApiVersion(VK_API_VERSION_1_1);
2542 ASSERT_NO_FATAL_FAILURE(Init());
2543
2544 // Select a compressed format and verify support
2545 VkPhysicalDeviceFeatures device_features = {};
2546 ASSERT_NO_FATAL_FAILURE(GetPhysicalDeviceFeatures(&device_features));
2547 VkFormat compressed_format = VK_FORMAT_UNDEFINED;
2548 if (device_features.textureCompressionBC) {
2549 compressed_format = VK_FORMAT_BC3_SRGB_BLOCK;
2550 } else if (device_features.textureCompressionETC2) {
2551 compressed_format = VK_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK;
2552 } else if (device_features.textureCompressionASTC_LDR) {
2553 compressed_format = VK_FORMAT_ASTC_4x4_UNORM_BLOCK;
2554 }
2555
2556 VkImageCreateInfo ci;
2557 ci.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
2558 ci.pNext = NULL;
2559 ci.flags = 0;
2560 ci.imageType = VK_IMAGE_TYPE_2D;
2561 ci.format = compressed_format;
2562 ci.extent = {64, 64, 1};
2563 ci.mipLevels = 1;
2564 ci.arrayLayers = 1;
2565 ci.samples = VK_SAMPLE_COUNT_1_BIT;
2566 ci.tiling = VK_IMAGE_TILING_OPTIMAL;
2567 ci.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
2568 ci.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
2569 ci.queueFamilyIndexCount = 0;
2570 ci.pQueueFamilyIndices = NULL;
2571 ci.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
2572
2573 VkImageFormatProperties img_prop = {};
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06002574 if (VK_SUCCESS != vk::GetPhysicalDeviceImageFormatProperties(m_device->phy().handle(), ci.format, ci.imageType, ci.tiling,
2575 ci.usage, ci.flags, &img_prop)) {
unknown088160a2019-05-23 17:43:13 -06002576 printf("%s No compressed formats supported - CopyImageCompressedBlockAlignment skipped.\n", kSkipPrefix);
2577 return;
2578 }
2579
2580 // Create images
2581 VkImageObj image_1(m_device);
2582 image_1.init(&ci);
2583 ASSERT_TRUE(image_1.initialized());
2584
2585 ci.extent = {62, 62, 1}; // slightly smaller and not divisible by block size
2586 VkImageObj image_2(m_device);
2587 image_2.init(&ci);
2588 ASSERT_TRUE(image_2.initialized());
2589
2590 m_commandBuffer->begin();
2591
2592 VkImageCopy copy_region;
2593 copy_region.extent = {48, 48, 1};
2594 copy_region.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
2595 copy_region.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
2596 copy_region.srcSubresource.mipLevel = 0;
2597 copy_region.dstSubresource.mipLevel = 0;
2598 copy_region.srcSubresource.baseArrayLayer = 0;
2599 copy_region.dstSubresource.baseArrayLayer = 0;
2600 copy_region.srcSubresource.layerCount = 1;
2601 copy_region.dstSubresource.layerCount = 1;
2602 copy_region.srcOffset = {0, 0, 0};
2603 copy_region.dstOffset = {0, 0, 0};
2604
2605 // Sanity check
2606 m_errorMonitor->ExpectSuccess();
2607 m_commandBuffer->CopyImage(image_1.image(), VK_IMAGE_LAYOUT_GENERAL, image_2.image(), VK_IMAGE_LAYOUT_GENERAL, 1, &copy_region);
2608 m_errorMonitor->VerifyNotFound();
2609
2610 std::string vuid;
2611 bool ycbcr = (DeviceExtensionEnabled(VK_KHR_SAMPLER_YCBCR_CONVERSION_EXTENSION_NAME) ||
2612 (DeviceValidationVersion() >= VK_API_VERSION_1_1));
2613
2614 // Src, Dest offsets must be multiples of compressed block sizes {4, 4, 1}
2615 // Image transfer granularity gets set to compressed block size, so an ITG error is also (unavoidably) triggered.
2616 vuid = ycbcr ? "VUID-VkImageCopy-srcImage-01727" : "VUID-VkImageCopy-srcOffset-00157";
2617 copy_region.srcOffset = {2, 4, 0}; // source width
Mark Lobodzinski20310782020-02-28 14:25:17 -07002618 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, vuid);
2619 m_errorMonitor->SetDesiredFailureMsg(kErrorBit,
unknown088160a2019-05-23 17:43:13 -06002620 "VUID-vkCmdCopyImage-srcOffset-01783"); // srcOffset image transfer granularity
2621 m_commandBuffer->CopyImage(image_1.image(), VK_IMAGE_LAYOUT_GENERAL, image_2.image(), VK_IMAGE_LAYOUT_GENERAL, 1, &copy_region);
2622 m_errorMonitor->VerifyFound();
2623 copy_region.srcOffset = {12, 1, 0}; // source height
Mark Lobodzinski20310782020-02-28 14:25:17 -07002624 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, vuid);
2625 m_errorMonitor->SetDesiredFailureMsg(kErrorBit,
unknown088160a2019-05-23 17:43:13 -06002626 "VUID-vkCmdCopyImage-srcOffset-01783"); // srcOffset image transfer granularity
2627 m_commandBuffer->CopyImage(image_1.image(), VK_IMAGE_LAYOUT_GENERAL, image_2.image(), VK_IMAGE_LAYOUT_GENERAL, 1, &copy_region);
2628 m_errorMonitor->VerifyFound();
2629 copy_region.srcOffset = {0, 0, 0};
2630
2631 vuid = ycbcr ? "VUID-VkImageCopy-dstImage-01731" : "VUID-VkImageCopy-dstOffset-00162";
2632 copy_region.dstOffset = {1, 0, 0}; // dest width
Mark Lobodzinski20310782020-02-28 14:25:17 -07002633 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, vuid);
2634 m_errorMonitor->SetDesiredFailureMsg(kErrorBit,
unknown088160a2019-05-23 17:43:13 -06002635 "VUID-vkCmdCopyImage-dstOffset-01784"); // dstOffset image transfer granularity
2636 m_commandBuffer->CopyImage(image_1.image(), VK_IMAGE_LAYOUT_GENERAL, image_2.image(), VK_IMAGE_LAYOUT_GENERAL, 1, &copy_region);
2637 m_errorMonitor->VerifyFound();
2638 copy_region.dstOffset = {4, 1, 0}; // dest height
Mark Lobodzinski20310782020-02-28 14:25:17 -07002639 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, vuid);
2640 m_errorMonitor->SetDesiredFailureMsg(kErrorBit,
unknown088160a2019-05-23 17:43:13 -06002641 "VUID-vkCmdCopyImage-dstOffset-01784"); // dstOffset image transfer granularity
2642 m_commandBuffer->CopyImage(image_1.image(), VK_IMAGE_LAYOUT_GENERAL, image_2.image(), VK_IMAGE_LAYOUT_GENERAL, 1, &copy_region);
2643 m_errorMonitor->VerifyFound();
2644 copy_region.dstOffset = {0, 0, 0};
2645
2646 // Copy extent must be multiples of compressed block sizes {4, 4, 1} if not full width/height
2647 vuid = ycbcr ? "VUID-VkImageCopy-srcImage-01728" : "VUID-VkImageCopy-extent-00158";
2648 copy_region.extent = {62, 60, 1}; // source width
Mark Lobodzinski20310782020-02-28 14:25:17 -07002649 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, vuid);
2650 m_errorMonitor->SetDesiredFailureMsg(kErrorBit,
unknown088160a2019-05-23 17:43:13 -06002651 "VUID-vkCmdCopyImage-srcOffset-01783"); // src extent image transfer granularity
2652 m_commandBuffer->CopyImage(image_1.image(), VK_IMAGE_LAYOUT_GENERAL, image_2.image(), VK_IMAGE_LAYOUT_GENERAL, 1, &copy_region);
2653 m_errorMonitor->VerifyFound();
2654 vuid = ycbcr ? "VUID-VkImageCopy-srcImage-01729" : "VUID-VkImageCopy-extent-00159";
2655 copy_region.extent = {60, 62, 1}; // source height
Mark Lobodzinski20310782020-02-28 14:25:17 -07002656 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, vuid);
2657 m_errorMonitor->SetDesiredFailureMsg(kErrorBit,
unknown088160a2019-05-23 17:43:13 -06002658 "VUID-vkCmdCopyImage-srcOffset-01783"); // src extent image transfer granularity
2659 m_commandBuffer->CopyImage(image_1.image(), VK_IMAGE_LAYOUT_GENERAL, image_2.image(), VK_IMAGE_LAYOUT_GENERAL, 1, &copy_region);
2660 m_errorMonitor->VerifyFound();
2661
2662 vuid = ycbcr ? "VUID-VkImageCopy-dstImage-01732" : "VUID-VkImageCopy-extent-00163";
2663 copy_region.extent = {62, 60, 1}; // dest width
Mark Lobodzinski20310782020-02-28 14:25:17 -07002664 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, vuid);
2665 m_errorMonitor->SetDesiredFailureMsg(kErrorBit,
unknown088160a2019-05-23 17:43:13 -06002666 "VUID-vkCmdCopyImage-dstOffset-01784"); // dst extent image transfer granularity
2667 m_commandBuffer->CopyImage(image_2.image(), VK_IMAGE_LAYOUT_GENERAL, image_1.image(), VK_IMAGE_LAYOUT_GENERAL, 1, &copy_region);
2668 m_errorMonitor->VerifyFound();
2669 vuid = ycbcr ? "VUID-VkImageCopy-dstImage-01733" : "VUID-VkImageCopy-extent-00164";
2670 copy_region.extent = {60, 62, 1}; // dest height
Mark Lobodzinski20310782020-02-28 14:25:17 -07002671 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, vuid);
2672 m_errorMonitor->SetDesiredFailureMsg(kErrorBit,
unknown088160a2019-05-23 17:43:13 -06002673 "VUID-vkCmdCopyImage-dstOffset-01784"); // dst extent image transfer granularity
2674 m_commandBuffer->CopyImage(image_2.image(), VK_IMAGE_LAYOUT_GENERAL, image_1.image(), VK_IMAGE_LAYOUT_GENERAL, 1, &copy_region);
2675 m_errorMonitor->VerifyFound();
2676
2677 // Note: "VUID-VkImageCopy-extent-00160", "VUID-VkImageCopy-extent-00165", "VUID-VkImageCopy-srcImage-01730",
2678 // "VUID-VkImageCopy-dstImage-01734"
2679 // There are currently no supported compressed formats with a block depth other than 1,
2680 // so impossible to create a 'not a multiple' condition for depth.
2681 m_commandBuffer->end();
2682}
2683
2684TEST_F(VkLayerTest, CopyImageSinglePlane422Alignment) {
2685 // Image copy tests on single-plane _422 formats with block alignment errors
2686
2687 // Enable KHR multiplane req'd extensions
2688 bool mp_extensions = InstanceExtensionSupported(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME,
2689 VK_KHR_GET_MEMORY_REQUIREMENTS_2_SPEC_VERSION);
2690 if (mp_extensions) {
2691 m_instance_extension_names.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
2692 }
Mark Lobodzinski09ce9c42020-03-06 10:02:44 -07002693 ASSERT_NO_FATAL_FAILURE(InitFramework(m_errorMonitor));
unknown088160a2019-05-23 17:43:13 -06002694 mp_extensions = mp_extensions && DeviceExtensionSupported(gpu(), nullptr, VK_KHR_MAINTENANCE1_EXTENSION_NAME);
2695 mp_extensions = mp_extensions && DeviceExtensionSupported(gpu(), nullptr, VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME);
2696 mp_extensions = mp_extensions && DeviceExtensionSupported(gpu(), nullptr, VK_KHR_BIND_MEMORY_2_EXTENSION_NAME);
2697 mp_extensions = mp_extensions && DeviceExtensionSupported(gpu(), nullptr, VK_KHR_SAMPLER_YCBCR_CONVERSION_EXTENSION_NAME);
2698 if (mp_extensions) {
2699 m_device_extension_names.push_back(VK_KHR_MAINTENANCE1_EXTENSION_NAME);
2700 m_device_extension_names.push_back(VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME);
2701 m_device_extension_names.push_back(VK_KHR_BIND_MEMORY_2_EXTENSION_NAME);
2702 m_device_extension_names.push_back(VK_KHR_SAMPLER_YCBCR_CONVERSION_EXTENSION_NAME);
2703 } else {
2704 printf("%s test requires KHR multiplane extensions, not available. Skipping.\n", kSkipPrefix);
2705 return;
2706 }
2707 ASSERT_NO_FATAL_FAILURE(InitState());
2708
2709 // Select a _422 format and verify support
2710 VkImageCreateInfo ci = {};
2711 ci.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
2712 ci.pNext = NULL;
2713 ci.flags = 0;
2714 ci.imageType = VK_IMAGE_TYPE_2D;
2715 ci.format = VK_FORMAT_G8B8G8R8_422_UNORM_KHR;
2716 ci.tiling = VK_IMAGE_TILING_OPTIMAL;
2717 ci.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
2718 ci.mipLevels = 1;
2719 ci.arrayLayers = 1;
2720 ci.samples = VK_SAMPLE_COUNT_1_BIT;
2721 ci.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
2722 ci.queueFamilyIndexCount = 0;
2723 ci.pQueueFamilyIndices = NULL;
2724 ci.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
2725
2726 // Verify formats
2727 VkFormatFeatureFlags features = VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT;
2728 bool supported = ImageFormatAndFeaturesSupported(instance(), gpu(), ci, features);
2729 if (!supported) {
2730 printf("%s Single-plane _422 image format not supported. Skipping test.\n", kSkipPrefix);
2731 return; // Assume there's low ROI on searching for different mp formats
2732 }
2733
2734 // Create images
2735 ci.extent = {64, 64, 1};
2736 VkImageObj image_422(m_device);
2737 image_422.init(&ci);
2738 ASSERT_TRUE(image_422.initialized());
2739
2740 ci.extent = {64, 64, 1};
2741 ci.format = VK_FORMAT_R8G8B8A8_UNORM;
2742 VkImageObj image_ucmp(m_device);
2743 image_ucmp.init(&ci);
2744 ASSERT_TRUE(image_ucmp.initialized());
2745
2746 m_commandBuffer->begin();
2747
2748 VkImageCopy copy_region;
2749 copy_region.extent = {48, 48, 1};
2750 copy_region.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
2751 copy_region.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
2752 copy_region.srcSubresource.mipLevel = 0;
2753 copy_region.dstSubresource.mipLevel = 0;
2754 copy_region.srcSubresource.baseArrayLayer = 0;
2755 copy_region.dstSubresource.baseArrayLayer = 0;
2756 copy_region.srcSubresource.layerCount = 1;
2757 copy_region.dstSubresource.layerCount = 1;
2758 copy_region.srcOffset = {0, 0, 0};
2759 copy_region.dstOffset = {0, 0, 0};
2760
2761 // Src offsets must be multiples of compressed block sizes
2762 copy_region.srcOffset = {3, 4, 0}; // source offset x
Mark Lobodzinski20310782020-02-28 14:25:17 -07002763 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkImageCopy-srcImage-01727");
2764 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdCopyImage-srcOffset-01783");
unknown088160a2019-05-23 17:43:13 -06002765 m_commandBuffer->CopyImage(image_422.image(), VK_IMAGE_LAYOUT_GENERAL, image_ucmp.image(), VK_IMAGE_LAYOUT_GENERAL, 1,
2766 &copy_region);
2767 m_errorMonitor->VerifyFound();
2768 copy_region.srcOffset = {0, 0, 0};
2769
2770 // Dst offsets must be multiples of compressed block sizes
2771 copy_region.dstOffset = {1, 0, 0};
Mark Lobodzinski20310782020-02-28 14:25:17 -07002772 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkImageCopy-dstImage-01731");
2773 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdCopyImage-dstOffset-01784");
Mark Lobodzinski20310782020-02-28 14:25:17 -07002774 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkImageCopy-dstOffset-00150");
unknown088160a2019-05-23 17:43:13 -06002775 m_commandBuffer->CopyImage(image_ucmp.image(), VK_IMAGE_LAYOUT_GENERAL, image_422.image(), VK_IMAGE_LAYOUT_GENERAL, 1,
2776 &copy_region);
2777 m_errorMonitor->VerifyFound();
2778 copy_region.dstOffset = {0, 0, 0};
2779
2780 // Copy extent must be multiples of compressed block sizes if not full width/height
2781 copy_region.extent = {31, 60, 1}; // 422 source, extent.x
Mark Lobodzinski20310782020-02-28 14:25:17 -07002782 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkImageCopy-srcImage-01728");
2783 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdCopyImage-srcOffset-01783");
unknown088160a2019-05-23 17:43:13 -06002784 m_commandBuffer->CopyImage(image_422.image(), VK_IMAGE_LAYOUT_GENERAL, image_ucmp.image(), VK_IMAGE_LAYOUT_GENERAL, 1,
2785 &copy_region);
2786 m_errorMonitor->VerifyFound();
2787
unknown357e1782019-09-25 17:57:40 -06002788 // 422 dest
unknown088160a2019-05-23 17:43:13 -06002789 m_commandBuffer->CopyImage(image_ucmp.image(), VK_IMAGE_LAYOUT_GENERAL, image_422.image(), VK_IMAGE_LAYOUT_GENERAL, 1,
2790 &copy_region);
unknown357e1782019-09-25 17:57:40 -06002791 m_errorMonitor->VerifyNotFound();
unknown088160a2019-05-23 17:43:13 -06002792 copy_region.dstOffset = {0, 0, 0};
2793
2794 m_commandBuffer->end();
2795}
2796
2797TEST_F(VkLayerTest, CopyImageMultiplaneAspectBits) {
2798 // Image copy tests on multiplane images with aspect errors
2799
2800 // Enable KHR multiplane req'd extensions
2801 bool mp_extensions = InstanceExtensionSupported(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME,
2802 VK_KHR_GET_MEMORY_REQUIREMENTS_2_SPEC_VERSION);
2803 if (mp_extensions) {
2804 m_instance_extension_names.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
2805 }
Mark Lobodzinski09ce9c42020-03-06 10:02:44 -07002806 ASSERT_NO_FATAL_FAILURE(InitFramework(m_errorMonitor));
unknown088160a2019-05-23 17:43:13 -06002807 mp_extensions = mp_extensions && DeviceExtensionSupported(gpu(), nullptr, VK_KHR_MAINTENANCE1_EXTENSION_NAME);
2808 mp_extensions = mp_extensions && DeviceExtensionSupported(gpu(), nullptr, VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME);
2809 mp_extensions = mp_extensions && DeviceExtensionSupported(gpu(), nullptr, VK_KHR_BIND_MEMORY_2_EXTENSION_NAME);
2810 mp_extensions = mp_extensions && DeviceExtensionSupported(gpu(), nullptr, VK_KHR_SAMPLER_YCBCR_CONVERSION_EXTENSION_NAME);
2811 if (mp_extensions) {
2812 m_device_extension_names.push_back(VK_KHR_MAINTENANCE1_EXTENSION_NAME);
2813 m_device_extension_names.push_back(VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME);
2814 m_device_extension_names.push_back(VK_KHR_BIND_MEMORY_2_EXTENSION_NAME);
2815 m_device_extension_names.push_back(VK_KHR_SAMPLER_YCBCR_CONVERSION_EXTENSION_NAME);
2816 } else {
2817 printf("%s test requires KHR multiplane extensions, not available. Skipping.\n", kSkipPrefix);
2818 return;
2819 }
2820 ASSERT_NO_FATAL_FAILURE(InitState());
2821
2822 // Select multi-plane formats and verify support
2823 VkFormat mp3_format = VK_FORMAT_G8_B8_R8_3PLANE_422_UNORM_KHR;
2824 VkFormat mp2_format = VK_FORMAT_G8_B8R8_2PLANE_422_UNORM_KHR;
2825
2826 VkImageCreateInfo ci = {};
2827 ci.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
2828 ci.pNext = NULL;
2829 ci.flags = 0;
2830 ci.imageType = VK_IMAGE_TYPE_2D;
2831 ci.format = mp2_format;
2832 ci.extent = {256, 256, 1};
2833 ci.tiling = VK_IMAGE_TILING_OPTIMAL;
2834 ci.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
2835 ci.mipLevels = 1;
2836 ci.arrayLayers = 1;
2837 ci.samples = VK_SAMPLE_COUNT_1_BIT;
2838 ci.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
2839 ci.queueFamilyIndexCount = 0;
2840 ci.pQueueFamilyIndices = NULL;
2841 ci.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
2842
2843 // Verify formats
2844 VkFormatFeatureFlags features = VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT;
2845 bool supported = ImageFormatAndFeaturesSupported(instance(), gpu(), ci, features);
2846 ci.format = VK_FORMAT_D24_UNORM_S8_UINT;
2847 supported = supported && ImageFormatAndFeaturesSupported(instance(), gpu(), ci, features);
2848 ci.format = mp3_format;
2849 supported = supported && ImageFormatAndFeaturesSupported(instance(), gpu(), ci, features);
2850 if (!supported) {
2851 printf("%s Multiplane image formats or optimally tiled depth-stencil buffers not supported. Skipping test.\n",
2852 kSkipPrefix);
2853 return; // Assume there's low ROI on searching for different mp formats
2854 }
2855
2856 // Create images
2857 VkImageObj mp3_image(m_device);
2858 mp3_image.init(&ci);
2859 ASSERT_TRUE(mp3_image.initialized());
2860
2861 ci.format = mp2_format;
2862 VkImageObj mp2_image(m_device);
2863 mp2_image.init(&ci);
2864 ASSERT_TRUE(mp2_image.initialized());
2865
2866 ci.format = VK_FORMAT_D24_UNORM_S8_UINT;
2867 VkImageObj sp_image(m_device);
2868 sp_image.init(&ci);
2869 ASSERT_TRUE(sp_image.initialized());
2870
2871 m_commandBuffer->begin();
2872
2873 VkImageCopy copy_region;
2874 copy_region.extent = {128, 128, 1};
2875 copy_region.srcSubresource.aspectMask = VK_IMAGE_ASPECT_PLANE_2_BIT_KHR;
2876 copy_region.dstSubresource.aspectMask = VK_IMAGE_ASPECT_PLANE_2_BIT_KHR;
2877 copy_region.srcSubresource.mipLevel = 0;
2878 copy_region.dstSubresource.mipLevel = 0;
2879 copy_region.srcSubresource.baseArrayLayer = 0;
2880 copy_region.dstSubresource.baseArrayLayer = 0;
2881 copy_region.srcSubresource.layerCount = 1;
2882 copy_region.dstSubresource.layerCount = 1;
2883 copy_region.srcOffset = {0, 0, 0};
2884 copy_region.dstOffset = {0, 0, 0};
2885
Mark Lobodzinski20310782020-02-28 14:25:17 -07002886 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkImageCopy-srcImage-01552");
unknown088160a2019-05-23 17:43:13 -06002887 m_commandBuffer->CopyImage(mp2_image.image(), VK_IMAGE_LAYOUT_GENERAL, mp3_image.image(), VK_IMAGE_LAYOUT_GENERAL, 1,
2888 &copy_region);
2889 m_errorMonitor->VerifyFound();
2890
unknown088160a2019-05-23 17:43:13 -06002891 copy_region.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
2892 copy_region.dstSubresource.aspectMask = VK_IMAGE_ASPECT_PLANE_0_BIT_KHR;
Mark Lobodzinski20310782020-02-28 14:25:17 -07002893 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkImageCopy-srcImage-01553");
unknown088160a2019-05-23 17:43:13 -06002894 m_commandBuffer->CopyImage(mp3_image.image(), VK_IMAGE_LAYOUT_GENERAL, mp2_image.image(), VK_IMAGE_LAYOUT_GENERAL, 1,
2895 &copy_region);
2896 m_errorMonitor->VerifyFound();
2897
2898 copy_region.srcSubresource.aspectMask = VK_IMAGE_ASPECT_PLANE_1_BIT_KHR;
2899 copy_region.dstSubresource.aspectMask = VK_IMAGE_ASPECT_PLANE_2_BIT_KHR;
Mark Lobodzinski20310782020-02-28 14:25:17 -07002900 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkImageCopy-dstImage-01554");
unknown088160a2019-05-23 17:43:13 -06002901 m_commandBuffer->CopyImage(mp3_image.image(), VK_IMAGE_LAYOUT_GENERAL, mp2_image.image(), VK_IMAGE_LAYOUT_GENERAL, 1,
2902 &copy_region);
2903 m_errorMonitor->VerifyFound();
2904
2905 copy_region.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
Mark Lobodzinski20310782020-02-28 14:25:17 -07002906 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkImageCopy-dstImage-01555");
unknown088160a2019-05-23 17:43:13 -06002907 m_commandBuffer->CopyImage(mp2_image.image(), VK_IMAGE_LAYOUT_GENERAL, mp3_image.image(), VK_IMAGE_LAYOUT_GENERAL, 1,
2908 &copy_region);
2909 m_errorMonitor->VerifyFound();
2910
2911 copy_region.dstSubresource.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT;
Mark Lobodzinski20310782020-02-28 14:25:17 -07002912 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkImageCopy-srcImage-01556");
sfricke-samsung99dc12c2020-04-23 01:52:01 -07002913 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdCopyImage-None-01549"); // since also non-compatiable
unknown088160a2019-05-23 17:43:13 -06002914 m_commandBuffer->CopyImage(mp2_image.image(), VK_IMAGE_LAYOUT_GENERAL, sp_image.image(), VK_IMAGE_LAYOUT_GENERAL, 1,
2915 &copy_region);
2916 m_errorMonitor->VerifyFound();
2917
2918 copy_region.srcSubresource.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT;
2919 copy_region.dstSubresource.aspectMask = VK_IMAGE_ASPECT_PLANE_2_BIT_KHR;
Mark Lobodzinski20310782020-02-28 14:25:17 -07002920 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkImageCopy-dstImage-01557");
sfricke-samsung99dc12c2020-04-23 01:52:01 -07002921 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdCopyImage-None-01549"); // since also non-compatiable
unknown088160a2019-05-23 17:43:13 -06002922 m_commandBuffer->CopyImage(sp_image.image(), VK_IMAGE_LAYOUT_GENERAL, mp3_image.image(), VK_IMAGE_LAYOUT_GENERAL, 1,
2923 &copy_region);
2924 m_errorMonitor->VerifyFound();
2925
2926 m_commandBuffer->end();
2927}
2928
2929TEST_F(VkLayerTest, CopyImageSrcSizeExceeded) {
2930 // Image copy with source region specified greater than src image size
2931 ASSERT_NO_FATAL_FAILURE(Init());
2932
2933 // Create images with full mip chain
2934 VkImageCreateInfo ci;
2935 ci.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
2936 ci.pNext = NULL;
2937 ci.flags = 0;
2938 ci.imageType = VK_IMAGE_TYPE_3D;
2939 ci.format = VK_FORMAT_R8G8B8A8_UNORM;
2940 ci.extent = {32, 32, 8};
2941 ci.mipLevels = 6;
2942 ci.arrayLayers = 1;
2943 ci.samples = VK_SAMPLE_COUNT_1_BIT;
2944 ci.tiling = VK_IMAGE_TILING_OPTIMAL;
2945 ci.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
2946 ci.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
2947 ci.queueFamilyIndexCount = 0;
2948 ci.pQueueFamilyIndices = NULL;
2949 ci.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
2950
2951 VkImageObj src_image(m_device);
2952 src_image.init(&ci);
2953 ASSERT_TRUE(src_image.initialized());
2954
2955 // Dest image with one more mip level
2956 ci.extent = {64, 64, 16};
2957 ci.mipLevels = 7;
2958 ci.usage = VK_IMAGE_USAGE_TRANSFER_DST_BIT;
2959 VkImageObj dst_image(m_device);
2960 dst_image.init(&ci);
2961 ASSERT_TRUE(dst_image.initialized());
2962
2963 m_commandBuffer->begin();
2964
2965 VkImageCopy copy_region;
2966 copy_region.extent = {32, 32, 8};
2967 copy_region.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
2968 copy_region.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
2969 copy_region.srcSubresource.mipLevel = 0;
2970 copy_region.dstSubresource.mipLevel = 0;
2971 copy_region.srcSubresource.baseArrayLayer = 0;
2972 copy_region.dstSubresource.baseArrayLayer = 0;
2973 copy_region.srcSubresource.layerCount = 1;
2974 copy_region.dstSubresource.layerCount = 1;
2975 copy_region.srcOffset = {0, 0, 0};
2976 copy_region.dstOffset = {0, 0, 0};
2977
2978 m_errorMonitor->ExpectSuccess();
2979 m_commandBuffer->CopyImage(src_image.image(), VK_IMAGE_LAYOUT_GENERAL, dst_image.image(), VK_IMAGE_LAYOUT_GENERAL, 1,
2980 &copy_region);
2981 m_errorMonitor->VerifyNotFound();
2982
2983 // Source exceeded in x-dim, VU 01202
2984 copy_region.srcOffset.x = 4;
Mark Lobodzinski20310782020-02-28 14:25:17 -07002985 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkImageCopy-srcOffset-00144");
unknown088160a2019-05-23 17:43:13 -06002986 m_commandBuffer->CopyImage(src_image.image(), VK_IMAGE_LAYOUT_GENERAL, dst_image.image(), VK_IMAGE_LAYOUT_GENERAL, 1,
2987 &copy_region);
2988 m_errorMonitor->VerifyFound();
2989
2990 // Source exceeded in y-dim, VU 01203
2991 copy_region.srcOffset.x = 0;
2992 copy_region.extent.height = 48;
Mark Lobodzinski20310782020-02-28 14:25:17 -07002993 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkImageCopy-srcOffset-00145");
unknown088160a2019-05-23 17:43:13 -06002994 m_commandBuffer->CopyImage(src_image.image(), VK_IMAGE_LAYOUT_GENERAL, dst_image.image(), VK_IMAGE_LAYOUT_GENERAL, 1,
2995 &copy_region);
2996 m_errorMonitor->VerifyFound();
2997
2998 // Source exceeded in z-dim, VU 01204
2999 copy_region.extent = {4, 4, 4};
3000 copy_region.srcSubresource.mipLevel = 2;
Mark Lobodzinski20310782020-02-28 14:25:17 -07003001 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkImageCopy-srcOffset-00147");
unknown088160a2019-05-23 17:43:13 -06003002 m_commandBuffer->CopyImage(src_image.image(), VK_IMAGE_LAYOUT_GENERAL, dst_image.image(), VK_IMAGE_LAYOUT_GENERAL, 1,
3003 &copy_region);
3004 m_errorMonitor->VerifyFound();
3005
3006 m_commandBuffer->end();
3007}
3008
3009TEST_F(VkLayerTest, CopyImageDstSizeExceeded) {
3010 // Image copy with dest region specified greater than dest image size
3011 ASSERT_NO_FATAL_FAILURE(Init());
3012
3013 // Create images with full mip chain
3014 VkImageCreateInfo ci;
3015 ci.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
3016 ci.pNext = NULL;
3017 ci.flags = 0;
3018 ci.imageType = VK_IMAGE_TYPE_3D;
3019 ci.format = VK_FORMAT_R8G8B8A8_UNORM;
3020 ci.extent = {32, 32, 8};
3021 ci.mipLevels = 6;
3022 ci.arrayLayers = 1;
3023 ci.samples = VK_SAMPLE_COUNT_1_BIT;
3024 ci.tiling = VK_IMAGE_TILING_OPTIMAL;
3025 ci.usage = VK_IMAGE_USAGE_TRANSFER_DST_BIT;
3026 ci.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
3027 ci.queueFamilyIndexCount = 0;
3028 ci.pQueueFamilyIndices = NULL;
3029 ci.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
3030
3031 VkImageObj dst_image(m_device);
3032 dst_image.init(&ci);
3033 ASSERT_TRUE(dst_image.initialized());
3034
3035 // Src image with one more mip level
3036 ci.extent = {64, 64, 16};
3037 ci.mipLevels = 7;
3038 ci.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
3039 VkImageObj src_image(m_device);
3040 src_image.init(&ci);
3041 ASSERT_TRUE(src_image.initialized());
3042
3043 m_commandBuffer->begin();
3044
3045 VkImageCopy copy_region;
3046 copy_region.extent = {32, 32, 8};
3047 copy_region.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
3048 copy_region.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
3049 copy_region.srcSubresource.mipLevel = 0;
3050 copy_region.dstSubresource.mipLevel = 0;
3051 copy_region.srcSubresource.baseArrayLayer = 0;
3052 copy_region.dstSubresource.baseArrayLayer = 0;
3053 copy_region.srcSubresource.layerCount = 1;
3054 copy_region.dstSubresource.layerCount = 1;
3055 copy_region.srcOffset = {0, 0, 0};
3056 copy_region.dstOffset = {0, 0, 0};
3057
3058 m_errorMonitor->ExpectSuccess();
3059 m_commandBuffer->CopyImage(src_image.image(), VK_IMAGE_LAYOUT_GENERAL, dst_image.image(), VK_IMAGE_LAYOUT_GENERAL, 1,
3060 &copy_region);
3061 m_errorMonitor->VerifyNotFound();
3062
3063 // Dest exceeded in x-dim, VU 01205
3064 copy_region.dstOffset.x = 4;
Mark Lobodzinski20310782020-02-28 14:25:17 -07003065 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkImageCopy-dstOffset-00150");
unknown088160a2019-05-23 17:43:13 -06003066 m_commandBuffer->CopyImage(src_image.image(), VK_IMAGE_LAYOUT_GENERAL, dst_image.image(), VK_IMAGE_LAYOUT_GENERAL, 1,
3067 &copy_region);
3068 m_errorMonitor->VerifyFound();
3069
3070 // Dest exceeded in y-dim, VU 01206
3071 copy_region.dstOffset.x = 0;
3072 copy_region.extent.height = 48;
Mark Lobodzinski20310782020-02-28 14:25:17 -07003073 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkImageCopy-dstOffset-00151");
unknown088160a2019-05-23 17:43:13 -06003074 m_commandBuffer->CopyImage(src_image.image(), VK_IMAGE_LAYOUT_GENERAL, dst_image.image(), VK_IMAGE_LAYOUT_GENERAL, 1,
3075 &copy_region);
3076 m_errorMonitor->VerifyFound();
3077
3078 // Dest exceeded in z-dim, VU 01207
3079 copy_region.extent = {4, 4, 4};
3080 copy_region.dstSubresource.mipLevel = 2;
Mark Lobodzinski20310782020-02-28 14:25:17 -07003081 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkImageCopy-dstOffset-00153");
unknown088160a2019-05-23 17:43:13 -06003082 m_commandBuffer->CopyImage(src_image.image(), VK_IMAGE_LAYOUT_GENERAL, dst_image.image(), VK_IMAGE_LAYOUT_GENERAL, 1,
3083 &copy_region);
3084 m_errorMonitor->VerifyFound();
3085
3086 m_commandBuffer->end();
3087}
3088
sfricke-samsung8ceaaea2020-03-07 14:08:08 -08003089TEST_F(VkLayerTest, CopyImageMultiPlaneSizeExceeded) {
3090 TEST_DESCRIPTION("Image Copy for multi-planar format that exceed size of plane for both src and dst");
3091
3092 // Enable KHR multiplane req'd extensions
3093 bool mp_extensions = InstanceExtensionSupported(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME,
3094 VK_KHR_GET_MEMORY_REQUIREMENTS_2_SPEC_VERSION);
3095 if (mp_extensions == true) {
3096 m_instance_extension_names.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
3097 }
3098 ASSERT_NO_FATAL_FAILURE(InitFramework(m_errorMonitor));
3099 mp_extensions = mp_extensions && DeviceExtensionSupported(gpu(), nullptr, VK_KHR_MAINTENANCE1_EXTENSION_NAME);
3100 mp_extensions = mp_extensions && DeviceExtensionSupported(gpu(), nullptr, VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME);
3101 mp_extensions = mp_extensions && DeviceExtensionSupported(gpu(), nullptr, VK_KHR_BIND_MEMORY_2_EXTENSION_NAME);
3102 mp_extensions = mp_extensions && DeviceExtensionSupported(gpu(), nullptr, VK_KHR_SAMPLER_YCBCR_CONVERSION_EXTENSION_NAME);
3103 if (mp_extensions == true) {
3104 m_device_extension_names.push_back(VK_KHR_MAINTENANCE1_EXTENSION_NAME);
3105 m_device_extension_names.push_back(VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME);
3106 m_device_extension_names.push_back(VK_KHR_BIND_MEMORY_2_EXTENSION_NAME);
3107 m_device_extension_names.push_back(VK_KHR_SAMPLER_YCBCR_CONVERSION_EXTENSION_NAME);
3108 } else {
3109 printf("%s test requires KHR multiplane extensions, not available. Skipping.\n", kSkipPrefix);
3110 return;
3111 }
3112 ASSERT_NO_FATAL_FAILURE(InitState());
3113
sfricke-samsung99dc12c2020-04-23 01:52:01 -07003114 // Try to use VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM because need multi-plane format for some tests and likely supported due to
3115 // copy support being required with samplerYcbcrConversion feature
sfricke-samsung8ceaaea2020-03-07 14:08:08 -08003116 VkFormatProperties props = {0, 0, 0};
3117 bool missing_format_support = false;
sfricke-samsung99dc12c2020-04-23 01:52:01 -07003118 vk::GetPhysicalDeviceFormatProperties(m_device->phy().handle(), VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM, &props);
sfricke-samsung8ceaaea2020-03-07 14:08:08 -08003119 missing_format_support |= (props.bufferFeatures == 0 && props.linearTilingFeatures == 0 && props.optimalTilingFeatures == 0);
3120 missing_format_support |= (props.optimalTilingFeatures & VK_FORMAT_FEATURE_TRANSFER_SRC_BIT) == 0;
3121 missing_format_support |= (props.optimalTilingFeatures & VK_FORMAT_FEATURE_TRANSFER_DST_BIT) == 0;
3122
3123 if (missing_format_support == true) {
sfricke-samsung99dc12c2020-04-23 01:52:01 -07003124 printf("%s VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM transfer not supported; skipped.\n", kSkipPrefix);
sfricke-samsung8ceaaea2020-03-07 14:08:08 -08003125 return;
3126 }
3127
3128 // 128^2 texels in plane_0 and 64^2 texels in plane_1
3129 VkImageObj src_image(m_device);
3130 VkImageObj dst_image(m_device);
sfricke-samsung99dc12c2020-04-23 01:52:01 -07003131 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 -08003132 ASSERT_TRUE(src_image.initialized());
sfricke-samsung99dc12c2020-04-23 01:52:01 -07003133 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 -08003134 ASSERT_TRUE(dst_image.initialized());
3135
3136 VkImageCopy copy_region = {};
3137 copy_region.extent = {64, 64, 1}; // Size of plane 1
3138 copy_region.srcSubresource.aspectMask = VK_IMAGE_ASPECT_PLANE_1_BIT;
3139 copy_region.dstSubresource.aspectMask = VK_IMAGE_ASPECT_PLANE_1_BIT;
3140 copy_region.srcSubresource.mipLevel = 0;
3141 copy_region.dstSubresource.mipLevel = 0;
3142 copy_region.srcSubresource.baseArrayLayer = 0;
3143 copy_region.dstSubresource.baseArrayLayer = 0;
3144 copy_region.srcSubresource.layerCount = 1;
3145 copy_region.dstSubresource.layerCount = 1;
3146 copy_region.srcOffset = {0, 0, 0};
3147 copy_region.dstOffset = {0, 0, 0};
3148 VkImageCopy original_region = copy_region;
3149
3150 m_commandBuffer->begin();
3151
3152 // Should be able to do a 64x64 copy from plane 1 -> Plane 1
3153 m_errorMonitor->ExpectSuccess();
3154 m_commandBuffer->CopyImage(src_image.image(), VK_IMAGE_LAYOUT_GENERAL, dst_image.image(), VK_IMAGE_LAYOUT_GENERAL, 1,
3155 &copy_region);
3156 m_errorMonitor->VerifyNotFound();
3157
3158 // Should be able to do a 64x64 copy from plane 0 -> Plane 0
3159 copy_region.srcSubresource.aspectMask = VK_IMAGE_ASPECT_PLANE_0_BIT;
3160 copy_region.dstSubresource.aspectMask = VK_IMAGE_ASPECT_PLANE_0_BIT;
3161 m_errorMonitor->ExpectSuccess();
3162 m_commandBuffer->CopyImage(src_image.image(), VK_IMAGE_LAYOUT_GENERAL, dst_image.image(), VK_IMAGE_LAYOUT_GENERAL, 1,
3163 &copy_region);
3164 m_errorMonitor->VerifyNotFound();
3165
3166 // Should be able to do a 64x64 copy from plane 0 -> Plane 1
3167 copy_region.srcSubresource.aspectMask = VK_IMAGE_ASPECT_PLANE_0_BIT;
3168 copy_region.dstSubresource.aspectMask = VK_IMAGE_ASPECT_PLANE_1_BIT;
3169 m_errorMonitor->ExpectSuccess();
3170 m_commandBuffer->CopyImage(src_image.image(), VK_IMAGE_LAYOUT_GENERAL, dst_image.image(), VK_IMAGE_LAYOUT_GENERAL, 1,
3171 &copy_region);
3172 m_errorMonitor->VerifyNotFound();
3173
3174 // Should be able to do a 64x64 copy from plane 0 -> Plane 1
3175 copy_region.srcSubresource.aspectMask = VK_IMAGE_ASPECT_PLANE_1_BIT;
3176 copy_region.dstSubresource.aspectMask = VK_IMAGE_ASPECT_PLANE_0_BIT;
3177 m_errorMonitor->ExpectSuccess();
3178 m_commandBuffer->CopyImage(src_image.image(), VK_IMAGE_LAYOUT_GENERAL, dst_image.image(), VK_IMAGE_LAYOUT_GENERAL, 1,
3179 &copy_region);
3180 m_errorMonitor->VerifyNotFound();
3181
3182 // Should be able to do a 128x64 copy from plane 0 -> Plane 0
3183 copy_region.extent = {128, 64, 1};
3184 copy_region.srcSubresource.aspectMask = VK_IMAGE_ASPECT_PLANE_0_BIT;
3185 copy_region.dstSubresource.aspectMask = VK_IMAGE_ASPECT_PLANE_0_BIT;
3186 m_errorMonitor->ExpectSuccess();
3187 m_commandBuffer->CopyImage(src_image.image(), VK_IMAGE_LAYOUT_GENERAL, dst_image.image(), VK_IMAGE_LAYOUT_GENERAL, 1,
3188 &copy_region);
3189 m_errorMonitor->VerifyNotFound();
3190
3191 // 128x64 copy from plane 0 -> Plane 1
3192 copy_region.extent = {128, 64, 1};
3193 copy_region.srcSubresource.aspectMask = VK_IMAGE_ASPECT_PLANE_0_BIT;
3194 copy_region.dstSubresource.aspectMask = VK_IMAGE_ASPECT_PLANE_1_BIT;
sfricke-samsung8ceaaea2020-03-07 14:08:08 -08003195 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkImageCopy-dstOffset-00150");
3196 m_commandBuffer->CopyImage(src_image.image(), VK_IMAGE_LAYOUT_GENERAL, dst_image.image(), VK_IMAGE_LAYOUT_GENERAL, 1,
3197 &copy_region);
3198 m_errorMonitor->VerifyFound();
3199
3200 // 128x64 copy from plane 1 -> Plane 0
3201 copy_region.extent = {128, 64, 1};
3202 copy_region.srcSubresource.aspectMask = VK_IMAGE_ASPECT_PLANE_1_BIT;
3203 copy_region.dstSubresource.aspectMask = VK_IMAGE_ASPECT_PLANE_0_BIT;
sfricke-samsung8ceaaea2020-03-07 14:08:08 -08003204 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkImageCopy-srcOffset-00144");
3205 m_commandBuffer->CopyImage(src_image.image(), VK_IMAGE_LAYOUT_GENERAL, dst_image.image(), VK_IMAGE_LAYOUT_GENERAL, 1,
3206 &copy_region);
3207 m_errorMonitor->VerifyFound();
3208
3209 // src exceeded in y-dim from offset
3210 copy_region = original_region;
3211 copy_region.srcOffset.y = 4;
sfricke-samsung8ceaaea2020-03-07 14:08:08 -08003212 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkImageCopy-srcOffset-00145");
3213 m_commandBuffer->CopyImage(src_image.image(), VK_IMAGE_LAYOUT_GENERAL, dst_image.image(), VK_IMAGE_LAYOUT_GENERAL, 1,
3214 &copy_region);
3215 m_errorMonitor->VerifyFound();
3216
3217 // dst exceeded in y-dim from offset
3218 copy_region = original_region;
3219 copy_region.dstOffset.y = 4;
sfricke-samsung8ceaaea2020-03-07 14:08:08 -08003220 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkImageCopy-dstOffset-00151");
3221 m_commandBuffer->CopyImage(src_image.image(), VK_IMAGE_LAYOUT_GENERAL, dst_image.image(), VK_IMAGE_LAYOUT_GENERAL, 1,
3222 &copy_region);
3223 m_errorMonitor->VerifyFound();
3224
3225 m_commandBuffer->end();
3226}
3227
unknown088160a2019-05-23 17:43:13 -06003228TEST_F(VkLayerTest, CopyImageFormatSizeMismatch) {
sfricke-samsung51067b22020-04-30 21:41:17 -07003229 if (!EnableDeviceProfileLayer()) {
3230 printf("%s Failed to enable device profile layer.\n", kSkipPrefix);
3231 return;
3232 }
unknown088160a2019-05-23 17:43:13 -06003233
sfricke-samsung8ceaaea2020-03-07 14:08:08 -08003234 // Enable KHR multiplane req'd extensions
3235 bool mp_extensions = InstanceExtensionSupported(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME,
3236 VK_KHR_GET_MEMORY_REQUIREMENTS_2_SPEC_VERSION);
3237 if (mp_extensions == true) {
3238 m_instance_extension_names.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
3239 }
3240 ASSERT_NO_FATAL_FAILURE(InitFramework(m_errorMonitor));
3241 mp_extensions = mp_extensions && DeviceExtensionSupported(gpu(), nullptr, VK_KHR_MAINTENANCE1_EXTENSION_NAME);
3242 mp_extensions = mp_extensions && DeviceExtensionSupported(gpu(), nullptr, VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME);
3243 mp_extensions = mp_extensions && DeviceExtensionSupported(gpu(), nullptr, VK_KHR_BIND_MEMORY_2_EXTENSION_NAME);
3244 mp_extensions = mp_extensions && DeviceExtensionSupported(gpu(), nullptr, VK_KHR_SAMPLER_YCBCR_CONVERSION_EXTENSION_NAME);
3245 if (mp_extensions == true) {
3246 m_device_extension_names.push_back(VK_KHR_MAINTENANCE1_EXTENSION_NAME);
3247 m_device_extension_names.push_back(VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME);
3248 m_device_extension_names.push_back(VK_KHR_BIND_MEMORY_2_EXTENSION_NAME);
3249 m_device_extension_names.push_back(VK_KHR_SAMPLER_YCBCR_CONVERSION_EXTENSION_NAME);
3250 }
3251 ASSERT_NO_FATAL_FAILURE(InitState());
unknown088160a2019-05-23 17:43:13 -06003252
sfricke-samsung51067b22020-04-30 21:41:17 -07003253 PFN_vkSetPhysicalDeviceFormatPropertiesEXT fpvkSetPhysicalDeviceFormatPropertiesEXT = nullptr;
3254 PFN_vkGetOriginalPhysicalDeviceFormatPropertiesEXT fpvkGetOriginalPhysicalDeviceFormatPropertiesEXT = nullptr;
sfricke-samsungdce5f692020-03-07 13:59:31 -08003255
sfricke-samsung51067b22020-04-30 21:41:17 -07003256 // Load required functions
3257 if (!LoadDeviceProfileLayer(fpvkSetPhysicalDeviceFormatPropertiesEXT, fpvkGetOriginalPhysicalDeviceFormatPropertiesEXT)) {
3258 printf("%s Failed to device profile layer.\n", kSkipPrefix);
3259 return;
3260 }
3261
3262 // Set transfer for all potential used formats
3263 VkFormatProperties format_props;
3264 fpvkGetOriginalPhysicalDeviceFormatPropertiesEXT(gpu(), VK_FORMAT_R8_UNORM, &format_props);
3265 format_props.optimalTilingFeatures |= (VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT);
3266 fpvkSetPhysicalDeviceFormatPropertiesEXT(gpu(), VK_FORMAT_R8_UNORM, format_props);
3267
3268 fpvkGetOriginalPhysicalDeviceFormatPropertiesEXT(gpu(), VK_FORMAT_R8_UINT, &format_props);
3269 format_props.optimalTilingFeatures |= (VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT);
3270 fpvkSetPhysicalDeviceFormatPropertiesEXT(gpu(), VK_FORMAT_R8_UINT, format_props);
unknown088160a2019-05-23 17:43:13 -06003271
3272 VkImageCreateInfo image_create_info = {};
3273 image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
3274 image_create_info.pNext = NULL;
3275 image_create_info.imageType = VK_IMAGE_TYPE_2D;
unknown088160a2019-05-23 17:43:13 -06003276 image_create_info.extent.width = 32;
3277 image_create_info.extent.height = 32;
3278 image_create_info.extent.depth = 1;
3279 image_create_info.mipLevels = 1;
3280 image_create_info.arrayLayers = 1;
3281 image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
sfricke-samsung51067b22020-04-30 21:41:17 -07003282 image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL;
3283 image_create_info.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
unknown088160a2019-05-23 17:43:13 -06003284 image_create_info.flags = 0;
3285
sfricke-samsung51067b22020-04-30 21:41:17 -07003286 image_create_info.format = VK_FORMAT_R8_UNORM;
3287 VkImageObj image_8b_unorm(m_device);
3288 image_8b_unorm.init(&image_create_info);
unknown088160a2019-05-23 17:43:13 -06003289
sfricke-samsung51067b22020-04-30 21:41:17 -07003290 image_create_info.format = VK_FORMAT_R8_UINT;
3291 VkImageObj image_8b_uint(m_device);
3292 image_8b_uint.init(&image_create_info);
3293
3294 // First try to test two single plane mismatch
3295 {
3296 fpvkGetOriginalPhysicalDeviceFormatPropertiesEXT(gpu(), VK_FORMAT_R8G8B8A8_UNORM, &format_props);
3297 format_props.optimalTilingFeatures |= (VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT);
3298 fpvkSetPhysicalDeviceFormatPropertiesEXT(gpu(), VK_FORMAT_R8G8B8A8_UNORM, format_props);
3299
3300 image_create_info.format = VK_FORMAT_R8G8B8A8_UNORM;
3301 VkImageObj image_32b_unorm(m_device);
3302 image_32b_unorm.init(&image_create_info);
3303
3304 m_commandBuffer->begin();
3305 VkImageCopy copyRegion;
3306 copyRegion.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
3307 copyRegion.srcSubresource.mipLevel = 0;
3308 copyRegion.srcSubresource.baseArrayLayer = 0;
3309 copyRegion.srcSubresource.layerCount = 1;
3310 copyRegion.srcOffset.x = 0;
3311 copyRegion.srcOffset.y = 0;
3312 copyRegion.srcOffset.z = 0;
3313 copyRegion.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
3314 copyRegion.dstSubresource.mipLevel = 0;
3315 copyRegion.dstSubresource.baseArrayLayer = 0;
3316 copyRegion.dstSubresource.layerCount = 1;
3317 copyRegion.dstOffset.x = 0;
3318 copyRegion.dstOffset.y = 0;
3319 copyRegion.dstOffset.z = 0;
3320 copyRegion.extent.width = 1;
3321 copyRegion.extent.height = 1;
3322 copyRegion.extent.depth = 1;
3323
3324 // Sanity check between two 8bit formats
3325 m_errorMonitor->ExpectSuccess();
3326 m_commandBuffer->CopyImage(image_8b_unorm.handle(), VK_IMAGE_LAYOUT_GENERAL, image_8b_uint.handle(),
3327 VK_IMAGE_LAYOUT_GENERAL, 1, &copyRegion);
3328 m_errorMonitor->VerifyNotFound();
3329
3330 const char *vuid = (mp_extensions) ? "VUID-vkCmdCopyImage-srcImage-01548" : "VUID-vkCmdCopyImage-srcImage-00135";
3331 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, vuid);
3332 m_commandBuffer->CopyImage(image_8b_unorm.handle(), VK_IMAGE_LAYOUT_GENERAL, image_32b_unorm.handle(),
3333 VK_IMAGE_LAYOUT_GENERAL, 1, &copyRegion);
3334 m_errorMonitor->VerifyFound();
3335
3336 // Swap src and dst
3337 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, vuid);
3338 m_commandBuffer->CopyImage(image_32b_unorm.handle(), VK_IMAGE_LAYOUT_GENERAL, image_8b_unorm.handle(),
3339 VK_IMAGE_LAYOUT_GENERAL, 1, &copyRegion);
3340 m_errorMonitor->VerifyFound();
3341
3342 m_commandBuffer->end();
unknown088160a2019-05-23 17:43:13 -06003343 }
3344
sfricke-samsung51067b22020-04-30 21:41:17 -07003345 // DstImage is a mismatched plane of a multi-planar format
3346 if (mp_extensions == false) {
3347 printf("%s No multi-planar support; section of tests skipped.\n", kSkipPrefix);
3348 } else {
3349 fpvkGetOriginalPhysicalDeviceFormatPropertiesEXT(gpu(), VK_FORMAT_G8_B8R8_2PLANE_420_UNORM, &format_props);
3350 format_props.optimalTilingFeatures |= (VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT);
3351 fpvkSetPhysicalDeviceFormatPropertiesEXT(gpu(), VK_FORMAT_G8_B8R8_2PLANE_420_UNORM, format_props);
unknown088160a2019-05-23 17:43:13 -06003352
sfricke-samsung51067b22020-04-30 21:41:17 -07003353 image_create_info.format = VK_FORMAT_G8_B8R8_2PLANE_420_UNORM;
3354 VkImageObj image_8b_16b_420_unorm(m_device);
3355 image_8b_16b_420_unorm.init(&image_create_info);
unknown088160a2019-05-23 17:43:13 -06003356
sfricke-samsung51067b22020-04-30 21:41:17 -07003357 m_commandBuffer->begin();
3358 VkImageCopy copyRegion;
3359 copyRegion.srcSubresource.mipLevel = 0;
3360 copyRegion.srcSubresource.baseArrayLayer = 0;
3361 copyRegion.srcSubresource.layerCount = 1;
3362 copyRegion.srcOffset.x = 0;
3363 copyRegion.srcOffset.y = 0;
3364 copyRegion.srcOffset.z = 0;
3365 copyRegion.dstSubresource.mipLevel = 0;
3366 copyRegion.dstSubresource.baseArrayLayer = 0;
3367 copyRegion.dstSubresource.layerCount = 1;
3368 copyRegion.dstOffset.x = 0;
3369 copyRegion.dstOffset.y = 0;
3370 copyRegion.dstOffset.z = 0;
3371 copyRegion.extent.width = 1;
3372 copyRegion.extent.height = 1;
3373 copyRegion.extent.depth = 1;
unknown088160a2019-05-23 17:43:13 -06003374
sfricke-samsung51067b22020-04-30 21:41:17 -07003375 // First test single-plane -> multi-plan
3376 copyRegion.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
3377 copyRegion.dstSubresource.aspectMask = VK_IMAGE_ASPECT_PLANE_0_BIT;
unknown088160a2019-05-23 17:43:13 -06003378
sfricke-samsung51067b22020-04-30 21:41:17 -07003379 // Plane 0 is VK_FORMAT_R8_UNORM so this should succeed
3380 m_errorMonitor->ExpectSuccess();
3381 m_commandBuffer->CopyImage(image_8b_unorm.handle(), VK_IMAGE_LAYOUT_GENERAL, image_8b_16b_420_unorm.handle(),
3382 VK_IMAGE_LAYOUT_GENERAL, 1, &copyRegion);
3383 m_errorMonitor->VerifyNotFound();
unknown088160a2019-05-23 17:43:13 -06003384
sfricke-samsung51067b22020-04-30 21:41:17 -07003385 // Make sure no false postiives if Compatible format
3386 m_errorMonitor->ExpectSuccess();
3387 m_commandBuffer->CopyImage(image_8b_uint.handle(), VK_IMAGE_LAYOUT_GENERAL, image_8b_16b_420_unorm.handle(),
3388 VK_IMAGE_LAYOUT_GENERAL, 1, &copyRegion);
3389 m_errorMonitor->VerifyNotFound();
unknown088160a2019-05-23 17:43:13 -06003390
sfricke-samsung51067b22020-04-30 21:41:17 -07003391 // Plane 1 is VK_FORMAT_R8G8_UNORM so this should fail
3392 copyRegion.dstSubresource.aspectMask = VK_IMAGE_ASPECT_PLANE_1_BIT;
3393 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdCopyImage-None-01549");
3394 m_commandBuffer->CopyImage(image_8b_unorm.handle(), VK_IMAGE_LAYOUT_GENERAL, image_8b_16b_420_unorm.handle(),
3395 VK_IMAGE_LAYOUT_GENERAL, 1, &copyRegion);
3396 m_errorMonitor->VerifyFound();
unknown088160a2019-05-23 17:43:13 -06003397
sfricke-samsung51067b22020-04-30 21:41:17 -07003398 // Same tests but swap src and dst
3399 copyRegion.srcSubresource.aspectMask = VK_IMAGE_ASPECT_PLANE_0_BIT;
3400 copyRegion.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
sfricke-samsungdce5f692020-03-07 13:59:31 -08003401
sfricke-samsung51067b22020-04-30 21:41:17 -07003402 m_errorMonitor->ExpectSuccess();
3403 m_commandBuffer->CopyImage(image_8b_16b_420_unorm.handle(), VK_IMAGE_LAYOUT_GENERAL, image_8b_unorm.handle(),
3404 VK_IMAGE_LAYOUT_GENERAL, 1, &copyRegion);
3405 m_errorMonitor->VerifyNotFound();
3406
3407 m_errorMonitor->ExpectSuccess();
3408 m_commandBuffer->CopyImage(image_8b_16b_420_unorm.handle(), VK_IMAGE_LAYOUT_GENERAL, image_8b_uint.handle(),
3409 VK_IMAGE_LAYOUT_GENERAL, 1, &copyRegion);
3410 m_errorMonitor->VerifyNotFound();
3411
3412 copyRegion.srcSubresource.aspectMask = VK_IMAGE_ASPECT_PLANE_1_BIT;
3413 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdCopyImage-None-01549");
3414 m_commandBuffer->CopyImage(image_8b_16b_420_unorm.handle(), VK_IMAGE_LAYOUT_GENERAL, image_8b_unorm.handle(),
3415 VK_IMAGE_LAYOUT_GENERAL, 1, &copyRegion);
3416 m_errorMonitor->VerifyFound();
3417
3418 m_commandBuffer->end();
3419 }
unknown088160a2019-05-23 17:43:13 -06003420}
3421
3422TEST_F(VkLayerTest, CopyImageDepthStencilFormatMismatch) {
3423 ASSERT_NO_FATAL_FAILURE(Init());
3424 auto depth_format = FindSupportedDepthStencilFormat(gpu());
3425 if (!depth_format) {
3426 printf("%s Couldn't depth stencil image format.\n", kSkipPrefix);
3427 return;
3428 }
3429
3430 VkFormatProperties properties;
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06003431 vk::GetPhysicalDeviceFormatProperties(m_device->phy().handle(), VK_FORMAT_D32_SFLOAT, &properties);
unknown088160a2019-05-23 17:43:13 -06003432 if (properties.optimalTilingFeatures == 0) {
3433 printf("%s Image format not supported; skipped.\n", kSkipPrefix);
3434 return;
3435 }
3436
3437 VkImageObj srcImage(m_device);
3438 srcImage.Init(32, 32, 1, VK_FORMAT_D32_SFLOAT, VK_IMAGE_USAGE_TRANSFER_SRC_BIT, VK_IMAGE_TILING_OPTIMAL);
3439 ASSERT_TRUE(srcImage.initialized());
3440 VkImageObj dstImage(m_device);
3441 dstImage.Init(32, 32, 1, depth_format, VK_IMAGE_USAGE_TRANSFER_DST_BIT, VK_IMAGE_TILING_OPTIMAL);
3442 ASSERT_TRUE(dstImage.initialized());
3443
3444 // Create two images of different types and try to copy between them
3445
3446 m_commandBuffer->begin();
3447 VkImageCopy copyRegion;
3448 copyRegion.srcSubresource.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT;
3449 copyRegion.srcSubresource.mipLevel = 0;
3450 copyRegion.srcSubresource.baseArrayLayer = 0;
3451 copyRegion.srcSubresource.layerCount = 1;
3452 copyRegion.srcOffset.x = 0;
3453 copyRegion.srcOffset.y = 0;
3454 copyRegion.srcOffset.z = 0;
3455 copyRegion.dstSubresource.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT;
3456 copyRegion.dstSubresource.mipLevel = 0;
3457 copyRegion.dstSubresource.baseArrayLayer = 0;
3458 copyRegion.dstSubresource.layerCount = 1;
3459 copyRegion.dstOffset.x = 0;
3460 copyRegion.dstOffset.y = 0;
3461 copyRegion.dstOffset.z = 0;
3462 copyRegion.extent.width = 1;
3463 copyRegion.extent.height = 1;
3464 copyRegion.extent.depth = 1;
3465
sfricke-samsung99dc12c2020-04-23 01:52:01 -07003466 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdCopyImage-srcImage-00135");
unknown088160a2019-05-23 17:43:13 -06003467 m_commandBuffer->CopyImage(srcImage.handle(), VK_IMAGE_LAYOUT_GENERAL, dstImage.handle(), VK_IMAGE_LAYOUT_GENERAL, 1,
3468 &copyRegion);
3469 m_commandBuffer->end();
3470
3471 m_errorMonitor->VerifyFound();
3472}
3473
3474TEST_F(VkLayerTest, CopyImageSampleCountMismatch) {
3475 TEST_DESCRIPTION("Image copies with sample count mis-matches");
3476
3477 ASSERT_NO_FATAL_FAILURE(Init());
3478
3479 VkImageFormatProperties image_format_properties;
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06003480 vk::GetPhysicalDeviceImageFormatProperties(gpu(), VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_TYPE_2D, VK_IMAGE_TILING_OPTIMAL,
3481 VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT, 0,
3482 &image_format_properties);
unknown088160a2019-05-23 17:43:13 -06003483
3484 if ((0 == (VK_SAMPLE_COUNT_2_BIT & image_format_properties.sampleCounts)) ||
3485 (0 == (VK_SAMPLE_COUNT_4_BIT & image_format_properties.sampleCounts))) {
3486 printf("%s Image multi-sample support not found; skipped.\n", kSkipPrefix);
3487 return;
3488 }
3489
3490 VkImageCreateInfo ci;
3491 ci.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
3492 ci.pNext = NULL;
3493 ci.flags = 0;
3494 ci.imageType = VK_IMAGE_TYPE_2D;
3495 ci.format = VK_FORMAT_R8G8B8A8_UNORM;
3496 ci.extent = {128, 128, 1};
3497 ci.mipLevels = 1;
3498 ci.arrayLayers = 1;
3499 ci.samples = VK_SAMPLE_COUNT_1_BIT;
3500 ci.tiling = VK_IMAGE_TILING_OPTIMAL;
3501 ci.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
3502 ci.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
3503 ci.queueFamilyIndexCount = 0;
3504 ci.pQueueFamilyIndices = NULL;
3505 ci.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
3506
3507 VkImageObj image1(m_device);
3508 image1.init(&ci);
3509 ASSERT_TRUE(image1.initialized());
3510
3511 ci.samples = VK_SAMPLE_COUNT_2_BIT;
3512 VkImageObj image2(m_device);
3513 image2.init(&ci);
3514 ASSERT_TRUE(image2.initialized());
3515
3516 ci.samples = VK_SAMPLE_COUNT_4_BIT;
3517 VkImageObj image4(m_device);
3518 image4.init(&ci);
3519 ASSERT_TRUE(image4.initialized());
3520
3521 m_commandBuffer->begin();
3522
3523 VkImageCopy copyRegion;
3524 copyRegion.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
3525 copyRegion.srcSubresource.mipLevel = 0;
3526 copyRegion.srcSubresource.baseArrayLayer = 0;
3527 copyRegion.srcSubresource.layerCount = 1;
3528 copyRegion.srcOffset = {0, 0, 0};
3529 copyRegion.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
3530 copyRegion.dstSubresource.mipLevel = 0;
3531 copyRegion.dstSubresource.baseArrayLayer = 0;
3532 copyRegion.dstSubresource.layerCount = 1;
3533 copyRegion.dstOffset = {0, 0, 0};
3534 copyRegion.extent = {128, 128, 1};
3535
3536 // Copy a single sample image to/from a multi-sample image
Mark Lobodzinski20310782020-02-28 14:25:17 -07003537 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdCopyImage-srcImage-00136");
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06003538 vk::CmdCopyImage(m_commandBuffer->handle(), image1.handle(), VK_IMAGE_LAYOUT_GENERAL, image4.handle(), VK_IMAGE_LAYOUT_GENERAL,
3539 1, &copyRegion);
unknown088160a2019-05-23 17:43:13 -06003540 m_errorMonitor->VerifyFound();
3541
Mark Lobodzinski20310782020-02-28 14:25:17 -07003542 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdCopyImage-srcImage-00136");
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06003543 vk::CmdCopyImage(m_commandBuffer->handle(), image2.handle(), VK_IMAGE_LAYOUT_GENERAL, image1.handle(), VK_IMAGE_LAYOUT_GENERAL,
3544 1, &copyRegion);
unknown088160a2019-05-23 17:43:13 -06003545 m_errorMonitor->VerifyFound();
3546
3547 // Copy between multi-sample images with different sample counts
Mark Lobodzinski20310782020-02-28 14:25:17 -07003548 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdCopyImage-srcImage-00136");
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06003549 vk::CmdCopyImage(m_commandBuffer->handle(), image2.handle(), VK_IMAGE_LAYOUT_GENERAL, image4.handle(), VK_IMAGE_LAYOUT_GENERAL,
3550 1, &copyRegion);
unknown088160a2019-05-23 17:43:13 -06003551 m_errorMonitor->VerifyFound();
3552
Mark Lobodzinski20310782020-02-28 14:25:17 -07003553 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdCopyImage-srcImage-00136");
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06003554 vk::CmdCopyImage(m_commandBuffer->handle(), image4.handle(), VK_IMAGE_LAYOUT_GENERAL, image2.handle(), VK_IMAGE_LAYOUT_GENERAL,
3555 1, &copyRegion);
unknown088160a2019-05-23 17:43:13 -06003556 m_errorMonitor->VerifyFound();
3557
3558 m_commandBuffer->end();
3559}
3560
3561TEST_F(VkLayerTest, CopyImageAspectMismatch) {
3562 TEST_DESCRIPTION("Image copies with aspect mask errors");
sfricke-samsung99dc12c2020-04-23 01:52:01 -07003563
3564 if (!EnableDeviceProfileLayer()) {
3565 printf("%s Failed to enable device profile layer.\n", kSkipPrefix);
3566 return;
3567 }
3568
3569 bool mp_extensions = InstanceExtensionSupported(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME, 1);
3570 if (mp_extensions) {
3571 m_instance_extension_names.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
3572 }
3573
3574 ASSERT_NO_FATAL_FAILURE(InitFramework(m_errorMonitor));
3575 mp_extensions = mp_extensions && DeviceExtensionSupported(gpu(), nullptr, VK_KHR_MAINTENANCE1_EXTENSION_NAME);
3576 mp_extensions = mp_extensions && DeviceExtensionSupported(gpu(), nullptr, VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME);
3577 mp_extensions = mp_extensions && DeviceExtensionSupported(gpu(), nullptr, VK_KHR_BIND_MEMORY_2_EXTENSION_NAME);
3578 mp_extensions = mp_extensions && DeviceExtensionSupported(gpu(), nullptr, VK_KHR_SAMPLER_YCBCR_CONVERSION_EXTENSION_NAME);
3579 if (mp_extensions) {
3580 m_device_extension_names.push_back(VK_KHR_MAINTENANCE1_EXTENSION_NAME);
3581 m_device_extension_names.push_back(VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME);
3582 m_device_extension_names.push_back(VK_KHR_BIND_MEMORY_2_EXTENSION_NAME);
3583 m_device_extension_names.push_back(VK_KHR_SAMPLER_YCBCR_CONVERSION_EXTENSION_NAME);
3584 }
3585 ASSERT_NO_FATAL_FAILURE(InitState());
3586
3587 PFN_vkSetPhysicalDeviceFormatPropertiesEXT fpvkSetPhysicalDeviceFormatPropertiesEXT = nullptr;
3588 PFN_vkGetOriginalPhysicalDeviceFormatPropertiesEXT fpvkGetOriginalPhysicalDeviceFormatPropertiesEXT = nullptr;
3589
3590 if (!LoadDeviceProfileLayer(fpvkSetPhysicalDeviceFormatPropertiesEXT, fpvkGetOriginalPhysicalDeviceFormatPropertiesEXT)) {
3591 printf("%s Required extensions are not avaiable.\n", kSkipPrefix);
3592 return;
3593 }
3594
unknown088160a2019-05-23 17:43:13 -06003595 auto ds_format = FindSupportedDepthStencilFormat(gpu());
3596 if (!ds_format) {
3597 printf("%s Couldn't find depth stencil format.\n", kSkipPrefix);
3598 return;
3599 }
3600
sfricke-samsung99dc12c2020-04-23 01:52:01 -07003601 // Add Transfer support for all used formats
3602 VkFormatProperties formatProps;
3603 fpvkGetOriginalPhysicalDeviceFormatPropertiesEXT(gpu(), VK_FORMAT_R32_SFLOAT, &formatProps);
3604 formatProps.optimalTilingFeatures |= (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT);
3605 fpvkSetPhysicalDeviceFormatPropertiesEXT(gpu(), VK_FORMAT_R32_SFLOAT, formatProps);
3606 fpvkGetOriginalPhysicalDeviceFormatPropertiesEXT(gpu(), VK_FORMAT_D32_SFLOAT, &formatProps);
3607 formatProps.optimalTilingFeatures |= (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT);
3608 fpvkSetPhysicalDeviceFormatPropertiesEXT(gpu(), VK_FORMAT_R32_SFLOAT, formatProps);
3609 fpvkGetOriginalPhysicalDeviceFormatPropertiesEXT(gpu(), ds_format, &formatProps);
3610 formatProps.optimalTilingFeatures |= (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT);
3611 fpvkSetPhysicalDeviceFormatPropertiesEXT(gpu(), ds_format, formatProps);
3612
unknown088160a2019-05-23 17:43:13 -06003613 VkImageObj color_image(m_device), ds_image(m_device), depth_image(m_device);
3614 color_image.Init(128, 128, 1, VK_FORMAT_R32_SFLOAT, VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT);
3615 depth_image.Init(128, 128, 1, VK_FORMAT_D32_SFLOAT, VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT,
3616 VK_IMAGE_TILING_OPTIMAL, 0);
3617 ds_image.Init(128, 128, 1, ds_format, VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT,
3618 VK_IMAGE_TILING_OPTIMAL, 0);
3619 ASSERT_TRUE(color_image.initialized());
3620 ASSERT_TRUE(depth_image.initialized());
3621 ASSERT_TRUE(ds_image.initialized());
3622
3623 VkImageCopy copyRegion;
3624 copyRegion.srcSubresource.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT;
3625 copyRegion.srcSubresource.mipLevel = 0;
3626 copyRegion.srcSubresource.baseArrayLayer = 0;
3627 copyRegion.srcSubresource.layerCount = 1;
3628 copyRegion.srcOffset = {0, 0, 0};
3629 copyRegion.dstSubresource.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT;
3630 copyRegion.dstSubresource.mipLevel = 0;
3631 copyRegion.dstSubresource.baseArrayLayer = 0;
3632 copyRegion.dstSubresource.layerCount = 1;
3633 copyRegion.dstOffset = {64, 0, 0};
3634 copyRegion.extent = {64, 128, 1};
3635
3636 // Submitting command before command buffer is in recording state
Mark Lobodzinski20310782020-02-28 14:25:17 -07003637 m_errorMonitor->SetDesiredFailureMsg(kErrorBit,
unknown088160a2019-05-23 17:43:13 -06003638 "You must call vkBeginCommandBuffer"); // "VUID-vkCmdCopyImage-commandBuffer-recording");
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06003639 vk::CmdCopyImage(m_commandBuffer->handle(), depth_image.handle(), VK_IMAGE_LAYOUT_GENERAL, depth_image.handle(),
3640 VK_IMAGE_LAYOUT_GENERAL, 1, &copyRegion);
unknown088160a2019-05-23 17:43:13 -06003641 m_errorMonitor->VerifyFound();
3642
3643 m_commandBuffer->begin();
3644
3645 // Src and dest aspect masks don't match
3646 copyRegion.dstSubresource.aspectMask = VK_IMAGE_ASPECT_STENCIL_BIT;
sfricke-samsung99dc12c2020-04-23 01:52:01 -07003647 const char *vuid = mp_extensions ? "VUID-VkImageCopy-srcImage-01551" : "VUID-VkImageCopy-aspectMask-00137";
Mark Lobodzinski20310782020-02-28 14:25:17 -07003648 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, vuid);
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06003649 vk::CmdCopyImage(m_commandBuffer->handle(), ds_image.handle(), VK_IMAGE_LAYOUT_GENERAL, ds_image.handle(),
3650 VK_IMAGE_LAYOUT_GENERAL, 1, &copyRegion);
unknown088160a2019-05-23 17:43:13 -06003651 m_errorMonitor->VerifyFound();
3652 copyRegion.dstSubresource.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT;
3653
3654 // Illegal combinations of aspect bits
3655 copyRegion.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT | VK_IMAGE_ASPECT_DEPTH_BIT; // color must be alone
3656 copyRegion.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
Mark Lobodzinski20310782020-02-28 14:25:17 -07003657 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkImageSubresourceLayers-aspectMask-00167");
unknown088160a2019-05-23 17:43:13 -06003658 // These aspect/format mismatches are redundant but unavoidable here
Mark Lobodzinski20310782020-02-28 14:25:17 -07003659 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkImageCopy-aspectMask-00142");
3660 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, vuid);
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06003661 vk::CmdCopyImage(m_commandBuffer->handle(), color_image.handle(), VK_IMAGE_LAYOUT_GENERAL, color_image.handle(),
3662 VK_IMAGE_LAYOUT_GENERAL, 1, &copyRegion);
unknown088160a2019-05-23 17:43:13 -06003663 m_errorMonitor->VerifyFound();
3664 // same test for dstSubresource
3665 copyRegion.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
3666 copyRegion.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT | VK_IMAGE_ASPECT_DEPTH_BIT; // color must be alone
Mark Lobodzinski20310782020-02-28 14:25:17 -07003667 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkImageSubresourceLayers-aspectMask-00167");
unknown088160a2019-05-23 17:43:13 -06003668 // These aspect/format mismatches are redundant but unavoidable here
Mark Lobodzinski20310782020-02-28 14:25:17 -07003669 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkImageCopy-aspectMask-00143");
3670 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, vuid);
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06003671 vk::CmdCopyImage(m_commandBuffer->handle(), color_image.handle(), VK_IMAGE_LAYOUT_GENERAL, color_image.handle(),
3672 VK_IMAGE_LAYOUT_GENERAL, 1, &copyRegion);
unknown088160a2019-05-23 17:43:13 -06003673 m_errorMonitor->VerifyFound();
3674
3675 // Metadata aspect is illegal
3676 copyRegion.srcSubresource.aspectMask = VK_IMAGE_ASPECT_METADATA_BIT;
3677 copyRegion.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
Mark Lobodzinski20310782020-02-28 14:25:17 -07003678 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkImageSubresourceLayers-aspectMask-00168");
unknown088160a2019-05-23 17:43:13 -06003679 // These aspect/format mismatches are redundant but unavoidable here
Mark Lobodzinski20310782020-02-28 14:25:17 -07003680 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, vuid);
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06003681 vk::CmdCopyImage(m_commandBuffer->handle(), color_image.handle(), VK_IMAGE_LAYOUT_GENERAL, color_image.handle(),
3682 VK_IMAGE_LAYOUT_GENERAL, 1, &copyRegion);
unknown088160a2019-05-23 17:43:13 -06003683 m_errorMonitor->VerifyFound();
3684 // same test for dstSubresource
3685 copyRegion.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
3686 copyRegion.dstSubresource.aspectMask = VK_IMAGE_ASPECT_METADATA_BIT;
Mark Lobodzinski20310782020-02-28 14:25:17 -07003687 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkImageSubresourceLayers-aspectMask-00168");
unknown088160a2019-05-23 17:43:13 -06003688 // These aspect/format mismatches are redundant but unavoidable here
Mark Lobodzinski20310782020-02-28 14:25:17 -07003689 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, vuid);
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06003690 vk::CmdCopyImage(m_commandBuffer->handle(), color_image.handle(), VK_IMAGE_LAYOUT_GENERAL, color_image.handle(),
3691 VK_IMAGE_LAYOUT_GENERAL, 1, &copyRegion);
unknown088160a2019-05-23 17:43:13 -06003692 m_errorMonitor->VerifyFound();
3693
3694 copyRegion.srcSubresource.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT;
3695 copyRegion.dstSubresource.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT;
sfricke-samsung99dc12c2020-04-23 01:52:01 -07003696 const char *compatible_vuid = mp_extensions ? "VUID-vkCmdCopyImage-srcImage-01548" : "VUID-vkCmdCopyImage-srcImage-00135";
unknown088160a2019-05-23 17:43:13 -06003697
3698 // Aspect mask doesn't match source image format
Mark Lobodzinski20310782020-02-28 14:25:17 -07003699 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkImageCopy-aspectMask-00142");
unknown088160a2019-05-23 17:43:13 -06003700 // Again redundant but unavoidable
sfricke-samsung99dc12c2020-04-23 01:52:01 -07003701 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, compatible_vuid);
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06003702 vk::CmdCopyImage(m_commandBuffer->handle(), color_image.handle(), VK_IMAGE_LAYOUT_GENERAL, depth_image.handle(),
3703 VK_IMAGE_LAYOUT_GENERAL, 1, &copyRegion);
unknown088160a2019-05-23 17:43:13 -06003704 m_errorMonitor->VerifyFound();
3705
3706 // Aspect mask doesn't match dest image format
3707 copyRegion.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
3708 copyRegion.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
Mark Lobodzinski20310782020-02-28 14:25:17 -07003709 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkImageCopy-aspectMask-00143");
unknown088160a2019-05-23 17:43:13 -06003710 // Again redundant but unavoidable
sfricke-samsung99dc12c2020-04-23 01:52:01 -07003711 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, compatible_vuid);
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06003712 vk::CmdCopyImage(m_commandBuffer->handle(), color_image.handle(), VK_IMAGE_LAYOUT_GENERAL, depth_image.handle(),
3713 VK_IMAGE_LAYOUT_GENERAL, 1, &copyRegion);
unknown088160a2019-05-23 17:43:13 -06003714 m_errorMonitor->VerifyFound();
3715
3716 m_commandBuffer->end();
3717}
3718
3719TEST_F(VkLayerTest, ResolveImageLowSampleCount) {
Mark Lobodzinski20310782020-02-28 14:25:17 -07003720 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "vkCmdResolveImage called with source sample count less than 2.");
unknown088160a2019-05-23 17:43:13 -06003721
3722 ASSERT_NO_FATAL_FAILURE(Init());
3723
3724 // Create two images of sample count 1 and try to Resolve between them
3725
3726 VkImageCreateInfo image_create_info = {};
3727 image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
3728 image_create_info.pNext = NULL;
3729 image_create_info.imageType = VK_IMAGE_TYPE_2D;
3730 image_create_info.format = VK_FORMAT_B8G8R8A8_UNORM;
3731 image_create_info.extent.width = 32;
3732 image_create_info.extent.height = 1;
3733 image_create_info.extent.depth = 1;
3734 image_create_info.mipLevels = 1;
3735 image_create_info.arrayLayers = 1;
3736 image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
3737 image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL;
3738 image_create_info.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
3739 image_create_info.flags = 0;
3740
3741 VkImageObj srcImage(m_device);
3742 srcImage.init(&image_create_info);
3743 ASSERT_TRUE(srcImage.initialized());
3744
3745 VkImageObj dstImage(m_device);
3746 dstImage.init(&image_create_info);
3747 ASSERT_TRUE(dstImage.initialized());
3748
3749 m_commandBuffer->begin();
3750 VkImageResolve resolveRegion;
3751 resolveRegion.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
3752 resolveRegion.srcSubresource.mipLevel = 0;
3753 resolveRegion.srcSubresource.baseArrayLayer = 0;
3754 resolveRegion.srcSubresource.layerCount = 1;
3755 resolveRegion.srcOffset.x = 0;
3756 resolveRegion.srcOffset.y = 0;
3757 resolveRegion.srcOffset.z = 0;
3758 resolveRegion.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
3759 resolveRegion.dstSubresource.mipLevel = 0;
3760 resolveRegion.dstSubresource.baseArrayLayer = 0;
3761 resolveRegion.dstSubresource.layerCount = 1;
3762 resolveRegion.dstOffset.x = 0;
3763 resolveRegion.dstOffset.y = 0;
3764 resolveRegion.dstOffset.z = 0;
3765 resolveRegion.extent.width = 1;
3766 resolveRegion.extent.height = 1;
3767 resolveRegion.extent.depth = 1;
3768 m_commandBuffer->ResolveImage(srcImage.handle(), VK_IMAGE_LAYOUT_GENERAL, dstImage.handle(), VK_IMAGE_LAYOUT_GENERAL, 1,
3769 &resolveRegion);
3770 m_commandBuffer->end();
3771
3772 m_errorMonitor->VerifyFound();
3773}
3774
3775TEST_F(VkLayerTest, ResolveImageHighSampleCount) {
Mark Lobodzinski20310782020-02-28 14:25:17 -07003776 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "vkCmdResolveImage called with dest sample count greater than 1.");
unknown088160a2019-05-23 17:43:13 -06003777
3778 ASSERT_NO_FATAL_FAILURE(Init());
3779
3780 // Create two images of sample count 4 and try to Resolve between them
3781
3782 VkImageCreateInfo image_create_info = {};
3783 image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
3784 image_create_info.pNext = NULL;
3785 image_create_info.imageType = VK_IMAGE_TYPE_2D;
3786 image_create_info.format = VK_FORMAT_B8G8R8A8_UNORM;
3787 image_create_info.extent.width = 32;
3788 image_create_info.extent.height = 1;
3789 image_create_info.extent.depth = 1;
3790 image_create_info.mipLevels = 1;
3791 image_create_info.arrayLayers = 1;
3792 image_create_info.samples = VK_SAMPLE_COUNT_4_BIT;
3793 image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL;
3794 // Note: Some implementations expect color attachment usage for any
3795 // multisample surface
3796 image_create_info.usage =
3797 VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
3798 image_create_info.flags = 0;
3799
3800 VkImageObj srcImage(m_device);
3801 srcImage.init(&image_create_info);
3802 ASSERT_TRUE(srcImage.initialized());
3803
3804 VkImageObj dstImage(m_device);
3805 dstImage.init(&image_create_info);
3806 ASSERT_TRUE(dstImage.initialized());
3807
3808 m_commandBuffer->begin();
3809 // Need memory barrier to VK_IMAGE_LAYOUT_GENERAL for source and dest?
3810 // VK_IMAGE_LAYOUT_UNDEFINED = 0,
3811 // VK_IMAGE_LAYOUT_GENERAL = 1,
3812 VkImageResolve resolveRegion;
3813 resolveRegion.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
3814 resolveRegion.srcSubresource.mipLevel = 0;
3815 resolveRegion.srcSubresource.baseArrayLayer = 0;
3816 resolveRegion.srcSubresource.layerCount = 1;
3817 resolveRegion.srcOffset.x = 0;
3818 resolveRegion.srcOffset.y = 0;
3819 resolveRegion.srcOffset.z = 0;
3820 resolveRegion.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
3821 resolveRegion.dstSubresource.mipLevel = 0;
3822 resolveRegion.dstSubresource.baseArrayLayer = 0;
3823 resolveRegion.dstSubresource.layerCount = 1;
3824 resolveRegion.dstOffset.x = 0;
3825 resolveRegion.dstOffset.y = 0;
3826 resolveRegion.dstOffset.z = 0;
3827 resolveRegion.extent.width = 1;
3828 resolveRegion.extent.height = 1;
3829 resolveRegion.extent.depth = 1;
3830 m_commandBuffer->ResolveImage(srcImage.handle(), VK_IMAGE_LAYOUT_GENERAL, dstImage.handle(), VK_IMAGE_LAYOUT_GENERAL, 1,
3831 &resolveRegion);
3832 m_commandBuffer->end();
3833
3834 m_errorMonitor->VerifyFound();
3835}
3836
3837TEST_F(VkLayerTest, ResolveImageFormatMismatch) {
Mark Lobodzinski20310782020-02-28 14:25:17 -07003838 m_errorMonitor->SetDesiredFailureMsg(kWarningBit, "vkCmdResolveImage called with unmatched source and dest formats.");
unknown088160a2019-05-23 17:43:13 -06003839
3840 ASSERT_NO_FATAL_FAILURE(Init());
3841
3842 // Create two images of different types and try to copy between them
locke-lunarg8e2c91b2019-06-11 17:53:26 -06003843 VkImageObj srcImage(m_device);
3844 VkImageObj dstImage(m_device);
unknown088160a2019-05-23 17:43:13 -06003845
3846 VkImageCreateInfo image_create_info = {};
3847 image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
3848 image_create_info.pNext = NULL;
3849 image_create_info.imageType = VK_IMAGE_TYPE_2D;
3850 image_create_info.format = VK_FORMAT_B8G8R8A8_UNORM;
3851 image_create_info.extent.width = 32;
3852 image_create_info.extent.height = 1;
3853 image_create_info.extent.depth = 1;
3854 image_create_info.mipLevels = 1;
3855 image_create_info.arrayLayers = 1;
3856 image_create_info.samples = VK_SAMPLE_COUNT_2_BIT;
3857 image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL;
3858 // Note: Some implementations expect color attachment usage for any
3859 // multisample surface
3860 image_create_info.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
3861 image_create_info.flags = 0;
locke-lunarg8e2c91b2019-06-11 17:53:26 -06003862 srcImage.init(&image_create_info);
unknown088160a2019-05-23 17:43:13 -06003863
3864 // Set format to something other than source image
3865 image_create_info.format = VK_FORMAT_R32_SFLOAT;
3866 // Note: Some implementations expect color attachment usage for any
3867 // multisample surface
3868 image_create_info.usage = VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
3869 image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
locke-lunarg8e2c91b2019-06-11 17:53:26 -06003870 dstImage.init(&image_create_info);
unknown088160a2019-05-23 17:43:13 -06003871
3872 m_commandBuffer->begin();
3873 // Need memory barrier to VK_IMAGE_LAYOUT_GENERAL for source and dest?
3874 // VK_IMAGE_LAYOUT_UNDEFINED = 0,
3875 // VK_IMAGE_LAYOUT_GENERAL = 1,
3876 VkImageResolve resolveRegion;
3877 resolveRegion.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
3878 resolveRegion.srcSubresource.mipLevel = 0;
3879 resolveRegion.srcSubresource.baseArrayLayer = 0;
3880 resolveRegion.srcSubresource.layerCount = 1;
3881 resolveRegion.srcOffset.x = 0;
3882 resolveRegion.srcOffset.y = 0;
3883 resolveRegion.srcOffset.z = 0;
3884 resolveRegion.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
3885 resolveRegion.dstSubresource.mipLevel = 0;
3886 resolveRegion.dstSubresource.baseArrayLayer = 0;
3887 resolveRegion.dstSubresource.layerCount = 1;
3888 resolveRegion.dstOffset.x = 0;
3889 resolveRegion.dstOffset.y = 0;
3890 resolveRegion.dstOffset.z = 0;
3891 resolveRegion.extent.width = 1;
3892 resolveRegion.extent.height = 1;
3893 resolveRegion.extent.depth = 1;
locke-lunarg8e2c91b2019-06-11 17:53:26 -06003894 m_commandBuffer->ResolveImage(srcImage.handle(), VK_IMAGE_LAYOUT_GENERAL, dstImage.handle(), VK_IMAGE_LAYOUT_GENERAL, 1,
3895 &resolveRegion);
unknown088160a2019-05-23 17:43:13 -06003896 m_commandBuffer->end();
3897
3898 m_errorMonitor->VerifyFound();
unknown088160a2019-05-23 17:43:13 -06003899}
3900
3901TEST_F(VkLayerTest, ResolveImageTypeMismatch) {
Mark Lobodzinski20310782020-02-28 14:25:17 -07003902 m_errorMonitor->SetDesiredFailureMsg(kWarningBit, "vkCmdResolveImage called with unmatched source and dest image types.");
unknown088160a2019-05-23 17:43:13 -06003903
3904 ASSERT_NO_FATAL_FAILURE(Init());
3905
3906 // Create two images of different types and try to copy between them
locke-lunarg8e2c91b2019-06-11 17:53:26 -06003907 VkImageObj srcImage(m_device);
3908 VkImageObj dstImage(m_device);
unknown088160a2019-05-23 17:43:13 -06003909
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_2_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 = VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
3925 image_create_info.flags = 0;
locke-lunarg8e2c91b2019-06-11 17:53:26 -06003926 srcImage.init(&image_create_info);
unknown088160a2019-05-23 17:43:13 -06003927
3928 image_create_info.imageType = VK_IMAGE_TYPE_1D;
3929 // Note: Some implementations expect color attachment usage for any
3930 // multisample surface
3931 image_create_info.usage = VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
3932 image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
locke-lunarg8e2c91b2019-06-11 17:53:26 -06003933 dstImage.init(&image_create_info);
unknown088160a2019-05-23 17:43:13 -06003934
3935 m_commandBuffer->begin();
3936 // Need memory barrier to VK_IMAGE_LAYOUT_GENERAL for source and dest?
3937 // VK_IMAGE_LAYOUT_UNDEFINED = 0,
3938 // VK_IMAGE_LAYOUT_GENERAL = 1,
3939 VkImageResolve resolveRegion;
3940 resolveRegion.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
3941 resolveRegion.srcSubresource.mipLevel = 0;
3942 resolveRegion.srcSubresource.baseArrayLayer = 0;
3943 resolveRegion.srcSubresource.layerCount = 1;
3944 resolveRegion.srcOffset.x = 0;
3945 resolveRegion.srcOffset.y = 0;
3946 resolveRegion.srcOffset.z = 0;
3947 resolveRegion.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
3948 resolveRegion.dstSubresource.mipLevel = 0;
3949 resolveRegion.dstSubresource.baseArrayLayer = 0;
3950 resolveRegion.dstSubresource.layerCount = 1;
3951 resolveRegion.dstOffset.x = 0;
3952 resolveRegion.dstOffset.y = 0;
3953 resolveRegion.dstOffset.z = 0;
3954 resolveRegion.extent.width = 1;
3955 resolveRegion.extent.height = 1;
3956 resolveRegion.extent.depth = 1;
locke-lunarg8e2c91b2019-06-11 17:53:26 -06003957 m_commandBuffer->ResolveImage(srcImage.handle(), VK_IMAGE_LAYOUT_GENERAL, dstImage.handle(), VK_IMAGE_LAYOUT_GENERAL, 1,
3958 &resolveRegion);
unknown088160a2019-05-23 17:43:13 -06003959 m_commandBuffer->end();
3960
3961 m_errorMonitor->VerifyFound();
unknown088160a2019-05-23 17:43:13 -06003962}
3963
3964TEST_F(VkLayerTest, ResolveImageLayoutMismatch) {
3965 ASSERT_NO_FATAL_FAILURE(Init());
3966
3967 // Create two images of different types and try to copy between them
3968 VkImageObj srcImage(m_device);
3969 VkImageObj dstImage(m_device);
3970
3971 VkImageCreateInfo image_create_info = {};
3972 image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
3973 image_create_info.pNext = NULL;
3974 image_create_info.imageType = VK_IMAGE_TYPE_2D;
3975 image_create_info.format = VK_FORMAT_B8G8R8A8_UNORM;
3976 image_create_info.extent.width = 32;
3977 image_create_info.extent.height = 32;
3978 image_create_info.extent.depth = 1;
3979 image_create_info.mipLevels = 1;
3980 image_create_info.arrayLayers = 1;
3981 image_create_info.samples = VK_SAMPLE_COUNT_2_BIT;
3982 image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL;
3983 image_create_info.usage =
3984 VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
3985 // Note: Some implementations expect color attachment usage for any
3986 // multisample surface
3987 image_create_info.flags = 0;
3988 srcImage.init(&image_create_info);
3989 ASSERT_TRUE(srcImage.initialized());
3990
3991 // Note: Some implementations expect color attachment usage for any
3992 // multisample surface
3993 image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
3994 dstImage.init(&image_create_info);
3995 ASSERT_TRUE(dstImage.initialized());
3996
3997 m_commandBuffer->begin();
3998 // source image must have valid contents before resolve
3999 VkClearColorValue clear_color = {{0, 0, 0, 0}};
4000 VkImageSubresourceRange subresource = {};
4001 subresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
4002 subresource.layerCount = 1;
4003 subresource.levelCount = 1;
4004 srcImage.SetLayout(m_commandBuffer, VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
4005 m_commandBuffer->ClearColorImage(srcImage.image(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &clear_color, 1, &subresource);
4006 srcImage.SetLayout(m_commandBuffer, VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL);
4007 dstImage.SetLayout(m_commandBuffer, VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
4008
4009 VkImageResolve resolveRegion;
4010 resolveRegion.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
4011 resolveRegion.srcSubresource.mipLevel = 0;
4012 resolveRegion.srcSubresource.baseArrayLayer = 0;
4013 resolveRegion.srcSubresource.layerCount = 1;
4014 resolveRegion.srcOffset.x = 0;
4015 resolveRegion.srcOffset.y = 0;
4016 resolveRegion.srcOffset.z = 0;
4017 resolveRegion.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
4018 resolveRegion.dstSubresource.mipLevel = 0;
4019 resolveRegion.dstSubresource.baseArrayLayer = 0;
4020 resolveRegion.dstSubresource.layerCount = 1;
4021 resolveRegion.dstOffset.x = 0;
4022 resolveRegion.dstOffset.y = 0;
4023 resolveRegion.dstOffset.z = 0;
4024 resolveRegion.extent.width = 1;
4025 resolveRegion.extent.height = 1;
4026 resolveRegion.extent.depth = 1;
4027 // source image layout mismatch
Mark Lobodzinski20310782020-02-28 14:25:17 -07004028 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdResolveImage-srcImageLayout-00260");
unknown088160a2019-05-23 17:43:13 -06004029 m_commandBuffer->ResolveImage(srcImage.image(), VK_IMAGE_LAYOUT_GENERAL, dstImage.image(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
4030 1, &resolveRegion);
4031 m_errorMonitor->VerifyFound();
4032 // dst image layout mismatch
Mark Lobodzinski20310782020-02-28 14:25:17 -07004033 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdResolveImage-dstImageLayout-00262");
unknown088160a2019-05-23 17:43:13 -06004034 m_commandBuffer->ResolveImage(srcImage.image(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, dstImage.image(), VK_IMAGE_LAYOUT_GENERAL,
4035 1, &resolveRegion);
4036 m_errorMonitor->VerifyFound();
4037 m_commandBuffer->end();
4038}
4039
4040TEST_F(VkLayerTest, ResolveInvalidSubresource) {
4041 ASSERT_NO_FATAL_FAILURE(Init());
4042
4043 // Create two images of different types and try to copy between them
4044 VkImageObj srcImage(m_device);
4045 VkImageObj dstImage(m_device);
4046
4047 VkImageCreateInfo image_create_info = {};
4048 image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
4049 image_create_info.pNext = NULL;
4050 image_create_info.imageType = VK_IMAGE_TYPE_2D;
4051 image_create_info.format = VK_FORMAT_B8G8R8A8_UNORM;
4052 image_create_info.extent.width = 32;
4053 image_create_info.extent.height = 32;
4054 image_create_info.extent.depth = 1;
4055 image_create_info.mipLevels = 1;
4056 image_create_info.arrayLayers = 1;
4057 image_create_info.samples = VK_SAMPLE_COUNT_2_BIT;
4058 image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL;
4059 image_create_info.usage =
4060 VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
4061 // Note: Some implementations expect color attachment usage for any
4062 // multisample surface
4063 image_create_info.flags = 0;
4064 srcImage.init(&image_create_info);
4065 ASSERT_TRUE(srcImage.initialized());
4066
4067 // Note: Some implementations expect color attachment usage for any
4068 // multisample surface
4069 image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
4070 dstImage.init(&image_create_info);
4071 ASSERT_TRUE(dstImage.initialized());
4072
4073 m_commandBuffer->begin();
4074 // source image must have valid contents before resolve
4075 VkClearColorValue clear_color = {{0, 0, 0, 0}};
4076 VkImageSubresourceRange subresource = {};
4077 subresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
4078 subresource.layerCount = 1;
4079 subresource.levelCount = 1;
4080 srcImage.SetLayout(m_commandBuffer, VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
4081 m_commandBuffer->ClearColorImage(srcImage.image(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &clear_color, 1, &subresource);
4082 srcImage.SetLayout(m_commandBuffer, VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL);
4083 dstImage.SetLayout(m_commandBuffer, VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
4084
4085 VkImageResolve resolveRegion;
4086 resolveRegion.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
4087 resolveRegion.srcSubresource.mipLevel = 0;
4088 resolveRegion.srcSubresource.baseArrayLayer = 0;
4089 resolveRegion.srcSubresource.layerCount = 1;
4090 resolveRegion.srcOffset.x = 0;
4091 resolveRegion.srcOffset.y = 0;
4092 resolveRegion.srcOffset.z = 0;
4093 resolveRegion.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
4094 resolveRegion.dstSubresource.mipLevel = 0;
4095 resolveRegion.dstSubresource.baseArrayLayer = 0;
4096 resolveRegion.dstSubresource.layerCount = 1;
4097 resolveRegion.dstOffset.x = 0;
4098 resolveRegion.dstOffset.y = 0;
4099 resolveRegion.dstOffset.z = 0;
4100 resolveRegion.extent.width = 1;
4101 resolveRegion.extent.height = 1;
4102 resolveRegion.extent.depth = 1;
4103 // invalid source mip level
4104 resolveRegion.srcSubresource.mipLevel = image_create_info.mipLevels;
Mark Lobodzinski20310782020-02-28 14:25:17 -07004105 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdResolveImage-srcSubresource-01709");
unknown088160a2019-05-23 17:43:13 -06004106 m_commandBuffer->ResolveImage(srcImage.image(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, dstImage.image(),
4107 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &resolveRegion);
4108 m_errorMonitor->VerifyFound();
4109 resolveRegion.srcSubresource.mipLevel = 0;
4110 // invalid dest mip level
4111 resolveRegion.dstSubresource.mipLevel = image_create_info.mipLevels;
Mark Lobodzinski20310782020-02-28 14:25:17 -07004112 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdResolveImage-dstSubresource-01710");
unknown088160a2019-05-23 17:43:13 -06004113 m_commandBuffer->ResolveImage(srcImage.image(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, dstImage.image(),
4114 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &resolveRegion);
4115 m_errorMonitor->VerifyFound();
4116 resolveRegion.dstSubresource.mipLevel = 0;
4117 // invalid source array layer range
4118 resolveRegion.srcSubresource.baseArrayLayer = image_create_info.arrayLayers;
Mark Lobodzinski20310782020-02-28 14:25:17 -07004119 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdResolveImage-srcSubresource-01711");
unknown088160a2019-05-23 17:43:13 -06004120 m_commandBuffer->ResolveImage(srcImage.image(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, dstImage.image(),
4121 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &resolveRegion);
4122 m_errorMonitor->VerifyFound();
4123 resolveRegion.srcSubresource.baseArrayLayer = 0;
4124 // invalid dest array layer range
4125 resolveRegion.dstSubresource.baseArrayLayer = image_create_info.arrayLayers;
Mark Lobodzinski20310782020-02-28 14:25:17 -07004126 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdResolveImage-dstSubresource-01712");
unknown088160a2019-05-23 17:43:13 -06004127 m_commandBuffer->ResolveImage(srcImage.image(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, dstImage.image(),
4128 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &resolveRegion);
4129 m_errorMonitor->VerifyFound();
4130 resolveRegion.dstSubresource.baseArrayLayer = 0;
4131
4132 m_commandBuffer->end();
4133}
4134
4135TEST_F(VkLayerTest, ClearImageErrors) {
4136 TEST_DESCRIPTION("Call ClearColorImage w/ a depth|stencil image and ClearDepthStencilImage with a color image.");
4137
4138 ASSERT_NO_FATAL_FAILURE(Init());
4139 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
4140
4141 m_commandBuffer->begin();
4142
4143 // Color image
4144 VkClearColorValue clear_color;
4145 memset(clear_color.uint32, 0, sizeof(uint32_t) * 4);
4146 const VkFormat color_format = VK_FORMAT_B8G8R8A8_UNORM;
4147 const int32_t img_width = 32;
4148 const int32_t img_height = 32;
4149 VkImageCreateInfo image_create_info = {};
4150 image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
4151 image_create_info.pNext = NULL;
4152 image_create_info.imageType = VK_IMAGE_TYPE_2D;
4153 image_create_info.format = color_format;
4154 image_create_info.extent.width = img_width;
4155 image_create_info.extent.height = img_height;
4156 image_create_info.extent.depth = 1;
4157 image_create_info.mipLevels = 1;
4158 image_create_info.arrayLayers = 1;
4159 image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
4160 image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL;
4161
4162 image_create_info.usage = VK_IMAGE_USAGE_SAMPLED_BIT;
4163 vk_testing::Image color_image_no_transfer;
4164 color_image_no_transfer.init(*m_device, image_create_info);
4165
4166 image_create_info.usage = VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
4167 vk_testing::Image color_image;
4168 color_image.init(*m_device, image_create_info);
4169
4170 const VkImageSubresourceRange color_range = vk_testing::Image::subresource_range(image_create_info, VK_IMAGE_ASPECT_COLOR_BIT);
4171
4172 // Depth/Stencil image
4173 VkClearDepthStencilValue clear_value = {0};
4174 VkImageCreateInfo ds_image_create_info = vk_testing::Image::create_info();
4175 ds_image_create_info.imageType = VK_IMAGE_TYPE_2D;
4176 ds_image_create_info.format = VK_FORMAT_D16_UNORM;
4177 ds_image_create_info.extent.width = 64;
4178 ds_image_create_info.extent.height = 64;
4179 ds_image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL;
4180 ds_image_create_info.usage = VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
4181
4182 vk_testing::Image ds_image;
4183 ds_image.init(*m_device, ds_image_create_info);
4184
4185 const VkImageSubresourceRange ds_range = vk_testing::Image::subresource_range(ds_image_create_info, VK_IMAGE_ASPECT_DEPTH_BIT);
4186
Mark Lobodzinski20310782020-02-28 14:25:17 -07004187 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "vkCmdClearColorImage called with depth/stencil image.");
unknown088160a2019-05-23 17:43:13 -06004188
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06004189 vk::CmdClearColorImage(m_commandBuffer->handle(), ds_image.handle(), VK_IMAGE_LAYOUT_GENERAL, &clear_color, 1, &color_range);
unknown088160a2019-05-23 17:43:13 -06004190
4191 m_errorMonitor->VerifyFound();
4192
Mark Lobodzinski20310782020-02-28 14:25:17 -07004193 m_errorMonitor->SetDesiredFailureMsg(kErrorBit,
unknown088160a2019-05-23 17:43:13 -06004194 "vkCmdClearColorImage called with image created without VK_IMAGE_USAGE_TRANSFER_DST_BIT");
4195
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06004196 vk::CmdClearColorImage(m_commandBuffer->handle(), color_image_no_transfer.handle(), VK_IMAGE_LAYOUT_GENERAL, &clear_color, 1,
4197 &color_range);
unknown088160a2019-05-23 17:43:13 -06004198
4199 m_errorMonitor->VerifyFound();
4200
4201 // Call CmdClearDepthStencilImage with color image
Mark Lobodzinski20310782020-02-28 14:25:17 -07004202 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "vkCmdClearDepthStencilImage called without a depth/stencil image.");
unknown088160a2019-05-23 17:43:13 -06004203
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06004204 vk::CmdClearDepthStencilImage(m_commandBuffer->handle(), color_image.handle(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
4205 &clear_value, 1, &ds_range);
unknown088160a2019-05-23 17:43:13 -06004206
4207 m_errorMonitor->VerifyFound();
4208}
4209
4210TEST_F(VkLayerTest, CommandQueueFlags) {
4211 TEST_DESCRIPTION(
4212 "Allocate a command buffer on a queue that does not support graphics and try to issue a graphics-only command");
4213
4214 ASSERT_NO_FATAL_FAILURE(Init());
4215
4216 uint32_t queueFamilyIndex = m_device->QueueFamilyWithoutCapabilities(VK_QUEUE_GRAPHICS_BIT);
4217 if (queueFamilyIndex == UINT32_MAX) {
4218 printf("%s Non-graphics queue family not found; skipped.\n", kSkipPrefix);
4219 return;
4220 } else {
4221 // Create command pool on a non-graphics queue
4222 VkCommandPoolObj command_pool(m_device, queueFamilyIndex);
4223
4224 // Setup command buffer on pool
4225 VkCommandBufferObj command_buffer(m_device, &command_pool);
4226 command_buffer.begin();
4227
4228 // Issue a graphics only command
Mark Lobodzinski20310782020-02-28 14:25:17 -07004229 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdSetViewport-commandBuffer-cmdpool");
unknown088160a2019-05-23 17:43:13 -06004230 VkViewport viewport = {0, 0, 16, 16, 0, 1};
4231 command_buffer.SetViewport(0, 1, &viewport);
4232 m_errorMonitor->VerifyFound();
4233 }
4234}
4235
4236TEST_F(VkLayerTest, ExecuteUnrecordedSecondaryCB) {
4237 TEST_DESCRIPTION("Attempt vkCmdExecuteCommands with a CB in the initial state");
4238 ASSERT_NO_FATAL_FAILURE(Init());
4239 VkCommandBufferObj secondary(m_device, m_commandPool, VK_COMMAND_BUFFER_LEVEL_SECONDARY);
4240 // never record secondary
4241
Mark Lobodzinski20310782020-02-28 14:25:17 -07004242 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdExecuteCommands-pCommandBuffers-00089");
unknown088160a2019-05-23 17:43:13 -06004243 m_commandBuffer->begin();
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06004244 vk::CmdExecuteCommands(m_commandBuffer->handle(), 1, &secondary.handle());
unknown088160a2019-05-23 17:43:13 -06004245 m_errorMonitor->VerifyFound();
4246 m_commandBuffer->end();
4247}
4248
4249TEST_F(VkLayerTest, ExecuteSecondaryCBWithLayoutMismatch) {
4250 TEST_DESCRIPTION("Attempt vkCmdExecuteCommands with a CB with incorrect initial layout.");
4251
Mark Lobodzinski09ce9c42020-03-06 10:02:44 -07004252 ASSERT_NO_FATAL_FAILURE(InitFramework(m_errorMonitor));
unknown088160a2019-05-23 17:43:13 -06004253 ASSERT_NO_FATAL_FAILURE(InitState(nullptr, nullptr, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT));
4254
4255 VkImageCreateInfo image_create_info = {};
4256 image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
4257 image_create_info.pNext = NULL;
4258 image_create_info.imageType = VK_IMAGE_TYPE_2D;
4259 image_create_info.format = VK_FORMAT_B8G8R8A8_UNORM;
4260 image_create_info.extent.width = 32;
4261 image_create_info.extent.height = 1;
4262 image_create_info.extent.depth = 1;
4263 image_create_info.mipLevels = 1;
4264 image_create_info.arrayLayers = 1;
4265 image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
4266 image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL;
4267 image_create_info.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
4268 image_create_info.flags = 0;
4269
4270 VkImageSubresource image_sub = VkImageObj::subresource(VK_IMAGE_ASPECT_COLOR_BIT, 0, 0);
4271 VkImageSubresourceRange image_sub_range = VkImageObj::subresource_range(image_sub);
4272
4273 VkImageObj image(m_device);
4274 image.init(&image_create_info);
4275 ASSERT_TRUE(image.initialized());
4276 VkImageMemoryBarrier image_barrier =
4277 image.image_memory_barrier(0, 0, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_GENERAL, image_sub_range);
4278
4279 auto pipeline = [&image_barrier](const VkCommandBufferObj &cb, VkImageLayout old_layout, VkImageLayout new_layout) {
4280 image_barrier.oldLayout = old_layout;
4281 image_barrier.newLayout = new_layout;
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06004282 vk::CmdPipelineBarrier(cb.handle(), VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, 0, nullptr,
4283 0, nullptr, 1, &image_barrier);
unknown088160a2019-05-23 17:43:13 -06004284 };
4285
4286 // Validate that mismatched use of image layout in secondary command buffer is caught at record time
4287 VkCommandBufferObj secondary(m_device, m_commandPool, VK_COMMAND_BUFFER_LEVEL_SECONDARY);
4288 secondary.begin();
4289 pipeline(secondary, VK_IMAGE_LAYOUT_GENERAL, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
4290 secondary.end();
4291
Mark Lobodzinski20310782020-02-28 14:25:17 -07004292 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "UNASSIGNED-vkCmdExecuteCommands-commandBuffer-00001");
unknown088160a2019-05-23 17:43:13 -06004293 m_commandBuffer->begin();
4294 pipeline(*m_commandBuffer, VK_IMAGE_LAYOUT_GENERAL, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL);
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06004295 vk::CmdExecuteCommands(m_commandBuffer->handle(), 1, &secondary.handle());
unknown088160a2019-05-23 17:43:13 -06004296 m_errorMonitor->VerifyFound();
4297
unknown088160a2019-05-23 17:43:13 -06004298 m_commandBuffer->reset();
4299 secondary.reset();
4300
4301 // Validate that UNDEFINED doesn't false positive on us
4302 secondary.begin();
4303 pipeline(secondary, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
4304 secondary.end();
4305 m_commandBuffer->begin();
4306 pipeline(*m_commandBuffer, VK_IMAGE_LAYOUT_GENERAL, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
4307 m_errorMonitor->ExpectSuccess();
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06004308 vk::CmdExecuteCommands(m_commandBuffer->handle(), 1, &secondary.handle());
unknown088160a2019-05-23 17:43:13 -06004309 m_errorMonitor->VerifyNotFound();
4310 m_commandBuffer->end();
4311}
4312
4313TEST_F(VkLayerTest, SetDynViewportParamTests) {
4314 TEST_DESCRIPTION("Test parameters of vkCmdSetViewport without multiViewport feature");
4315
4316 SetTargetApiVersion(VK_API_VERSION_1_1);
4317 VkPhysicalDeviceFeatures features{};
4318 ASSERT_NO_FATAL_FAILURE(Init(&features));
4319
4320 const VkViewport vp = {0.0, 0.0, 64.0, 64.0, 0.0, 1.0};
4321 const VkViewport viewports[] = {vp, vp};
4322
4323 m_commandBuffer->begin();
4324
4325 // array tests
Mark Lobodzinski20310782020-02-28 14:25:17 -07004326 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdSetViewport-firstViewport-01224");
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06004327 vk::CmdSetViewport(m_commandBuffer->handle(), 1, 1, viewports);
unknown088160a2019-05-23 17:43:13 -06004328 m_errorMonitor->VerifyFound();
4329
Mark Lobodzinski20310782020-02-28 14:25:17 -07004330 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdSetViewport-viewportCount-arraylength");
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06004331 vk::CmdSetViewport(m_commandBuffer->handle(), 0, 0, nullptr);
unknown088160a2019-05-23 17:43:13 -06004332 m_errorMonitor->VerifyFound();
4333
Mark Lobodzinski20310782020-02-28 14:25:17 -07004334 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdSetViewport-viewportCount-01225");
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06004335 vk::CmdSetViewport(m_commandBuffer->handle(), 0, 2, viewports);
unknown088160a2019-05-23 17:43:13 -06004336 m_errorMonitor->VerifyFound();
4337
Mark Lobodzinski20310782020-02-28 14:25:17 -07004338 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdSetViewport-firstViewport-01224");
4339 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdSetViewport-viewportCount-01225");
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06004340 vk::CmdSetViewport(m_commandBuffer->handle(), 1, 2, viewports);
unknown088160a2019-05-23 17:43:13 -06004341 m_errorMonitor->VerifyFound();
4342
Mark Lobodzinski20310782020-02-28 14:25:17 -07004343 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdSetViewport-pViewports-parameter");
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06004344 vk::CmdSetViewport(m_commandBuffer->handle(), 0, 1, nullptr);
unknown088160a2019-05-23 17:43:13 -06004345 m_errorMonitor->VerifyFound();
4346
4347 // core viewport tests
4348 using std::vector;
4349 struct TestCase {
4350 VkViewport vp;
4351 std::string veid;
4352 };
4353
4354 // not necessarily boundary values (unspecified cast rounding), but guaranteed to be over limit
4355 const auto one_past_max_w = NearestGreater(static_cast<float>(m_device->props.limits.maxViewportDimensions[0]));
4356 const auto one_past_max_h = NearestGreater(static_cast<float>(m_device->props.limits.maxViewportDimensions[1]));
4357
4358 const auto min_bound = m_device->props.limits.viewportBoundsRange[0];
4359 const auto max_bound = m_device->props.limits.viewportBoundsRange[1];
4360 const auto one_before_min_bounds = NearestSmaller(min_bound);
4361 const auto one_past_max_bounds = NearestGreater(max_bound);
4362
4363 const auto below_zero = NearestSmaller(0.0f);
4364 const auto past_one = NearestGreater(1.0f);
4365
4366 vector<TestCase> test_cases = {
4367 {{0.0, 0.0, 0.0, 64.0, 0.0, 1.0}, "VUID-VkViewport-width-01770"},
4368 {{0.0, 0.0, one_past_max_w, 64.0, 0.0, 1.0}, "VUID-VkViewport-width-01771"},
4369 {{0.0, 0.0, NAN, 64.0, 0.0, 1.0}, "VUID-VkViewport-width-01770"},
4370 {{0.0, 0.0, 64.0, one_past_max_h, 0.0, 1.0}, "VUID-VkViewport-height-01773"},
4371 {{one_before_min_bounds, 0.0, 64.0, 64.0, 0.0, 1.0}, "VUID-VkViewport-x-01774"},
4372 {{one_past_max_bounds, 0.0, 64.0, 64.0, 0.0, 1.0}, "VUID-VkViewport-x-01232"},
4373 {{NAN, 0.0, 64.0, 64.0, 0.0, 1.0}, "VUID-VkViewport-x-01774"},
4374 {{0.0, one_before_min_bounds, 64.0, 64.0, 0.0, 1.0}, "VUID-VkViewport-y-01775"},
4375 {{0.0, NAN, 64.0, 64.0, 0.0, 1.0}, "VUID-VkViewport-y-01775"},
4376 {{max_bound, 0.0, 1.0, 64.0, 0.0, 1.0}, "VUID-VkViewport-x-01232"},
4377 {{0.0, max_bound, 64.0, 1.0, 0.0, 1.0}, "VUID-VkViewport-y-01233"},
4378 {{0.0, 0.0, 64.0, 64.0, below_zero, 1.0}, "VUID-VkViewport-minDepth-01234"},
4379 {{0.0, 0.0, 64.0, 64.0, past_one, 1.0}, "VUID-VkViewport-minDepth-01234"},
4380 {{0.0, 0.0, 64.0, 64.0, NAN, 1.0}, "VUID-VkViewport-minDepth-01234"},
4381 {{0.0, 0.0, 64.0, 64.0, 0.0, below_zero}, "VUID-VkViewport-maxDepth-01235"},
4382 {{0.0, 0.0, 64.0, 64.0, 0.0, past_one}, "VUID-VkViewport-maxDepth-01235"},
4383 {{0.0, 0.0, 64.0, 64.0, 0.0, NAN}, "VUID-VkViewport-maxDepth-01235"},
4384 };
4385
4386 if (DeviceValidationVersion() < VK_API_VERSION_1_1) {
4387 test_cases.push_back({{0.0, 0.0, 64.0, 0.0, 0.0, 1.0}, "VUID-VkViewport-height-01772"});
4388 test_cases.push_back({{0.0, 0.0, 64.0, NAN, 0.0, 1.0}, "VUID-VkViewport-height-01772"});
4389 } else {
4390 test_cases.push_back({{0.0, 0.0, 64.0, NAN, 0.0, 1.0}, "VUID-VkViewport-height-01773"});
4391 }
4392
4393 for (const auto &test_case : test_cases) {
Mark Lobodzinski20310782020-02-28 14:25:17 -07004394 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, test_case.veid);
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06004395 vk::CmdSetViewport(m_commandBuffer->handle(), 0, 1, &test_case.vp);
unknown088160a2019-05-23 17:43:13 -06004396 m_errorMonitor->VerifyFound();
4397 }
4398}
4399
4400TEST_F(VkLayerTest, SetDynViewportParamMaintenance1Tests) {
4401 TEST_DESCRIPTION("Verify errors are detected on misuse of SetViewport with a negative viewport extension enabled.");
4402
Mark Lobodzinski09ce9c42020-03-06 10:02:44 -07004403 ASSERT_NO_FATAL_FAILURE(InitFramework(m_errorMonitor));
unknown088160a2019-05-23 17:43:13 -06004404
4405 if (DeviceExtensionSupported(gpu(), nullptr, VK_KHR_MAINTENANCE1_EXTENSION_NAME)) {
4406 m_device_extension_names.push_back(VK_KHR_MAINTENANCE1_EXTENSION_NAME);
4407 } else {
4408 printf("%s VK_KHR_maintenance1 extension not supported -- skipping test\n", kSkipPrefix);
4409 return;
4410 }
4411 ASSERT_NO_FATAL_FAILURE(InitState());
4412
4413 NegHeightViewportTests(m_device, m_commandBuffer, m_errorMonitor);
4414}
4415
4416TEST_F(VkLayerTest, SetDynViewportParamMultiviewportTests) {
4417 TEST_DESCRIPTION("Test parameters of vkCmdSetViewport with multiViewport feature enabled");
4418
4419 ASSERT_NO_FATAL_FAILURE(Init());
4420
4421 if (!m_device->phy().features().multiViewport) {
4422 printf("%s VkPhysicalDeviceFeatures::multiViewport is not supported -- skipping test.\n", kSkipPrefix);
4423 return;
4424 }
4425
unknown088160a2019-05-23 17:43:13 -06004426 m_commandBuffer->begin();
4427
Mark Lobodzinski20310782020-02-28 14:25:17 -07004428 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdSetViewport-viewportCount-arraylength");
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06004429 vk::CmdSetViewport(m_commandBuffer->handle(), 0, 0, nullptr);
unknown088160a2019-05-23 17:43:13 -06004430 m_errorMonitor->VerifyFound();
4431
Petr Kraus14e49492019-09-09 20:13:29 +02004432 const auto max_viewports = m_device->props.limits.maxViewports;
4433
Mark Lobodzinski20310782020-02-28 14:25:17 -07004434 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdSetViewport-pViewports-parameter");
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06004435 vk::CmdSetViewport(m_commandBuffer->handle(), 0, max_viewports, nullptr);
unknown088160a2019-05-23 17:43:13 -06004436 m_errorMonitor->VerifyFound();
4437
Petr Kraus14e49492019-09-09 20:13:29 +02004438 const uint32_t too_big_max_viewports = 65536 + 1; // let's say this is too much to allocate
4439 if (max_viewports >= too_big_max_viewports) {
4440 printf("%s VkPhysicalDeviceLimits::maxViewports is too large to practically test against -- skipping part of test.\n",
4441 kSkipPrefix);
4442 } else {
4443 const VkViewport vp = {0.0, 0.0, 64.0, 64.0, 0.0, 1.0};
4444 const std::vector<VkViewport> viewports(max_viewports + 1, vp);
4445
Mark Lobodzinski20310782020-02-28 14:25:17 -07004446 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdSetViewport-firstViewport-01223");
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06004447 vk::CmdSetViewport(m_commandBuffer->handle(), 0, max_viewports + 1, viewports.data());
Petr Kraus14e49492019-09-09 20:13:29 +02004448 m_errorMonitor->VerifyFound();
4449
Mark Lobodzinski20310782020-02-28 14:25:17 -07004450 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdSetViewport-firstViewport-01223");
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06004451 vk::CmdSetViewport(m_commandBuffer->handle(), max_viewports, 1, viewports.data());
Petr Kraus14e49492019-09-09 20:13:29 +02004452 m_errorMonitor->VerifyFound();
4453
Mark Lobodzinski20310782020-02-28 14:25:17 -07004454 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdSetViewport-firstViewport-01223");
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06004455 vk::CmdSetViewport(m_commandBuffer->handle(), 1, max_viewports, viewports.data());
Petr Kraus14e49492019-09-09 20:13:29 +02004456 m_errorMonitor->VerifyFound();
4457
Mark Lobodzinski20310782020-02-28 14:25:17 -07004458 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdSetViewport-viewportCount-arraylength");
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06004459 vk::CmdSetViewport(m_commandBuffer->handle(), 1, 0, viewports.data());
Petr Kraus14e49492019-09-09 20:13:29 +02004460 m_errorMonitor->VerifyFound();
unknown088160a2019-05-23 17:43:13 -06004461 }
unknown088160a2019-05-23 17:43:13 -06004462}
4463
4464TEST_F(VkLayerTest, BadRenderPassScopeSecondaryCmdBuffer) {
4465 TEST_DESCRIPTION(
4466 "Test secondary buffers executed in wrong render pass scope wrt VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT");
4467
4468 ASSERT_NO_FATAL_FAILURE(Init());
4469 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
4470
4471 VkCommandBufferObj sec_cmdbuff_inside_rp(m_device, m_commandPool, VK_COMMAND_BUFFER_LEVEL_SECONDARY);
4472 VkCommandBufferObj sec_cmdbuff_outside_rp(m_device, m_commandPool, VK_COMMAND_BUFFER_LEVEL_SECONDARY);
4473
4474 const VkCommandBufferInheritanceInfo cmdbuff_ii = {
4475 VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO,
4476 nullptr, // pNext
4477 m_renderPass,
4478 0, // subpass
4479 m_framebuffer,
4480 };
4481 const VkCommandBufferBeginInfo cmdbuff_bi_tmpl = {VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,
4482 nullptr, // pNext
4483 VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT, &cmdbuff_ii};
4484
4485 VkCommandBufferBeginInfo cmdbuff_inside_rp_bi = cmdbuff_bi_tmpl;
4486 cmdbuff_inside_rp_bi.flags |= VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT;
4487 sec_cmdbuff_inside_rp.begin(&cmdbuff_inside_rp_bi);
4488 sec_cmdbuff_inside_rp.end();
4489
4490 VkCommandBufferBeginInfo cmdbuff_outside_rp_bi = cmdbuff_bi_tmpl;
4491 cmdbuff_outside_rp_bi.flags &= ~VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT;
4492 sec_cmdbuff_outside_rp.begin(&cmdbuff_outside_rp_bi);
4493 sec_cmdbuff_outside_rp.end();
4494
4495 m_commandBuffer->begin();
4496
Mark Lobodzinski20310782020-02-28 14:25:17 -07004497 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdExecuteCommands-pCommandBuffers-00100");
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06004498 vk::CmdExecuteCommands(m_commandBuffer->handle(), 1, &sec_cmdbuff_inside_rp.handle());
unknown088160a2019-05-23 17:43:13 -06004499 m_errorMonitor->VerifyFound();
4500
4501 const VkRenderPassBeginInfo rp_bi{VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,
4502 nullptr, // pNext
4503 m_renderPass,
4504 m_framebuffer,
4505 {{0, 0}, {32, 32}},
4506 static_cast<uint32_t>(m_renderPassClearValues.size()),
4507 m_renderPassClearValues.data()};
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06004508 vk::CmdBeginRenderPass(m_commandBuffer->handle(), &rp_bi, VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS);
unknown088160a2019-05-23 17:43:13 -06004509
Mark Lobodzinski20310782020-02-28 14:25:17 -07004510 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdExecuteCommands-pCommandBuffers-00096");
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06004511 vk::CmdExecuteCommands(m_commandBuffer->handle(), 1, &sec_cmdbuff_outside_rp.handle());
unknown088160a2019-05-23 17:43:13 -06004512 m_errorMonitor->VerifyFound();
4513}
4514
4515TEST_F(VkLayerTest, SecondaryCommandBufferClearColorAttachmentsRenderArea) {
4516 TEST_DESCRIPTION(
4517 "Create a secondary command buffer with CmdClearAttachments call that has a rect outside of renderPass renderArea");
4518 ASSERT_NO_FATAL_FAILURE(Init());
4519 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
4520
4521 VkCommandBufferAllocateInfo command_buffer_allocate_info = {};
4522 command_buffer_allocate_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
4523 command_buffer_allocate_info.commandPool = m_commandPool->handle();
4524 command_buffer_allocate_info.level = VK_COMMAND_BUFFER_LEVEL_SECONDARY;
4525 command_buffer_allocate_info.commandBufferCount = 1;
4526
4527 VkCommandBuffer secondary_command_buffer;
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06004528 ASSERT_VK_SUCCESS(vk::AllocateCommandBuffers(m_device->device(), &command_buffer_allocate_info, &secondary_command_buffer));
unknown088160a2019-05-23 17:43:13 -06004529 VkCommandBufferBeginInfo command_buffer_begin_info = {};
4530 VkCommandBufferInheritanceInfo command_buffer_inheritance_info = {};
4531 command_buffer_inheritance_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO;
4532 command_buffer_inheritance_info.renderPass = m_renderPass;
4533 command_buffer_inheritance_info.framebuffer = m_framebuffer;
4534
4535 command_buffer_begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
4536 command_buffer_begin_info.flags =
4537 VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT | VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT;
4538 command_buffer_begin_info.pInheritanceInfo = &command_buffer_inheritance_info;
4539
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06004540 vk::BeginCommandBuffer(secondary_command_buffer, &command_buffer_begin_info);
unknown088160a2019-05-23 17:43:13 -06004541 VkClearAttachment color_attachment;
4542 color_attachment.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
4543 color_attachment.clearValue.color.float32[0] = 0;
4544 color_attachment.clearValue.color.float32[1] = 0;
4545 color_attachment.clearValue.color.float32[2] = 0;
4546 color_attachment.clearValue.color.float32[3] = 0;
4547 color_attachment.colorAttachment = 0;
4548 // x extent of 257 exceeds render area of 256
Mark Lobodzinski62490892019-06-28 09:58:27 -06004549 VkClearRect clear_rect = {{{0, 0}, {257, 32}}, 0, 1};
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06004550 vk::CmdClearAttachments(secondary_command_buffer, 1, &color_attachment, 1, &clear_rect);
4551 vk::EndCommandBuffer(secondary_command_buffer);
unknown088160a2019-05-23 17:43:13 -06004552 m_commandBuffer->begin();
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06004553 vk::CmdBeginRenderPass(m_commandBuffer->handle(), &m_renderPassBeginInfo, VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS);
unknown088160a2019-05-23 17:43:13 -06004554
Mark Lobodzinski20310782020-02-28 14:25:17 -07004555 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdClearAttachments-pRects-00016");
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06004556 vk::CmdExecuteCommands(m_commandBuffer->handle(), 1, &secondary_command_buffer);
unknown088160a2019-05-23 17:43:13 -06004557 m_errorMonitor->VerifyFound();
4558
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06004559 vk::CmdEndRenderPass(m_commandBuffer->handle());
unknown088160a2019-05-23 17:43:13 -06004560 m_commandBuffer->end();
4561}
4562
4563TEST_F(VkLayerTest, PushDescriptorSetCmdPushBadArgs) {
4564 TEST_DESCRIPTION("Attempt to push a push descriptor set with incorrect arguments.");
4565 if (InstanceExtensionSupported(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME)) {
4566 m_instance_extension_names.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
4567 } else {
4568 printf("%s %s Extension not supported, skipping tests\n", kSkipPrefix,
4569 VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
4570 return;
4571 }
4572
Mark Lobodzinski09ce9c42020-03-06 10:02:44 -07004573 ASSERT_NO_FATAL_FAILURE(InitFramework(m_errorMonitor));
unknown088160a2019-05-23 17:43:13 -06004574 if (DeviceExtensionSupported(gpu(), nullptr, VK_KHR_PUSH_DESCRIPTOR_EXTENSION_NAME)) {
4575 m_device_extension_names.push_back(VK_KHR_PUSH_DESCRIPTOR_EXTENSION_NAME);
4576 } else {
4577 printf("%s %s Extension not supported, skipping tests\n", kSkipPrefix, VK_KHR_PUSH_DESCRIPTOR_EXTENSION_NAME);
4578 return;
4579 }
4580 ASSERT_NO_FATAL_FAILURE(InitState());
4581
4582 auto push_descriptor_prop = GetPushDescriptorProperties(instance(), gpu());
4583 if (push_descriptor_prop.maxPushDescriptors < 1) {
4584 // Some implementations report an invalid maxPushDescriptors of 0
4585 printf("%s maxPushDescriptors is zero, skipping tests\n", kSkipPrefix);
4586 return;
4587 }
4588
4589 // Create ordinary and push descriptor set layout
4590 VkDescriptorSetLayoutBinding binding = {0, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1, VK_SHADER_STAGE_FRAGMENT_BIT, nullptr};
4591 const VkDescriptorSetLayoutObj ds_layout(m_device, {binding});
4592 ASSERT_TRUE(ds_layout.initialized());
4593 const VkDescriptorSetLayoutObj push_ds_layout(m_device, {binding}, VK_DESCRIPTOR_SET_LAYOUT_CREATE_PUSH_DESCRIPTOR_BIT_KHR);
4594 ASSERT_TRUE(push_ds_layout.initialized());
4595
4596 // Now use the descriptor set layouts to create a pipeline layout
4597 const VkPipelineLayoutObj pipeline_layout(m_device, {&push_ds_layout, &ds_layout});
4598 ASSERT_TRUE(pipeline_layout.initialized());
4599
4600 // Create a descriptor to push
4601 const uint32_t buffer_data[4] = {4, 5, 6, 7};
4602 VkConstantBufferObj buffer_obj(m_device, sizeof(buffer_data), &buffer_data);
4603 ASSERT_TRUE(buffer_obj.initialized());
4604
4605 // Create a "write" struct, noting that the buffer_info cannot be a temporary arg (the return from write_descriptor_set
4606 // references its data), and the DescriptorSet() can be temporary, because the value is ignored
4607 VkDescriptorBufferInfo buffer_info = {buffer_obj.handle(), 0, VK_WHOLE_SIZE};
4608
4609 VkWriteDescriptorSet descriptor_write = vk_testing::Device::write_descriptor_set(
4610 vk_testing::DescriptorSet(), 0, 0, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1, &buffer_info);
4611
4612 // Find address of extension call and make the call
4613 PFN_vkCmdPushDescriptorSetKHR vkCmdPushDescriptorSetKHR =
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06004614 (PFN_vkCmdPushDescriptorSetKHR)vk::GetDeviceProcAddr(m_device->device(), "vkCmdPushDescriptorSetKHR");
unknown088160a2019-05-23 17:43:13 -06004615 ASSERT_TRUE(vkCmdPushDescriptorSetKHR != nullptr);
4616
4617 // Section 1: Queue family matching/capabilities.
4618 // Create command pool on a non-graphics queue
4619 const uint32_t no_gfx_qfi = m_device->QueueFamilyMatching(VK_QUEUE_COMPUTE_BIT, VK_QUEUE_GRAPHICS_BIT);
4620 const uint32_t transfer_only_qfi =
4621 m_device->QueueFamilyMatching(VK_QUEUE_TRANSFER_BIT, (VK_QUEUE_COMPUTE_BIT | VK_QUEUE_GRAPHICS_BIT));
4622 if ((UINT32_MAX == transfer_only_qfi) && (UINT32_MAX == no_gfx_qfi)) {
unknownc3033e52019-06-21 16:56:20 -06004623 printf("%s No compute or transfer only queue family, skipping bindpoint and queue tests.\n", kSkipPrefix);
unknown088160a2019-05-23 17:43:13 -06004624 } else {
4625 const uint32_t err_qfi = (UINT32_MAX == no_gfx_qfi) ? transfer_only_qfi : no_gfx_qfi;
4626
4627 VkCommandPoolObj command_pool(m_device, err_qfi);
4628 ASSERT_TRUE(command_pool.initialized());
4629 VkCommandBufferObj command_buffer(m_device, &command_pool);
4630 ASSERT_TRUE(command_buffer.initialized());
4631 command_buffer.begin();
4632
Mark Lobodzinski20310782020-02-28 14:25:17 -07004633 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdPushDescriptorSetKHR-pipelineBindPoint-00363");
4634 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkWriteDescriptorSet-descriptorType-00330");
unknown088160a2019-05-23 17:43:13 -06004635 if (err_qfi == transfer_only_qfi) {
4636 // This as this queue neither supports the gfx or compute bindpoints, we'll get two errors
Mark Lobodzinski20310782020-02-28 14:25:17 -07004637 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdPushDescriptorSetKHR-commandBuffer-cmdpool");
unknown088160a2019-05-23 17:43:13 -06004638 }
4639 vkCmdPushDescriptorSetKHR(command_buffer.handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_layout.handle(), 0, 1,
4640 &descriptor_write);
4641 m_errorMonitor->VerifyFound();
4642 command_buffer.end();
4643
4644 // If we succeed in testing only one condition above, we need to test the other below.
4645 if ((UINT32_MAX != transfer_only_qfi) && (err_qfi != transfer_only_qfi)) {
4646 // Need to test the neither compute/gfx supported case separately.
4647 VkCommandPoolObj tran_command_pool(m_device, transfer_only_qfi);
4648 ASSERT_TRUE(tran_command_pool.initialized());
4649 VkCommandBufferObj tran_command_buffer(m_device, &tran_command_pool);
4650 ASSERT_TRUE(tran_command_buffer.initialized());
4651 tran_command_buffer.begin();
4652
4653 // We can't avoid getting *both* errors in this case
Mark Lobodzinski20310782020-02-28 14:25:17 -07004654 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdPushDescriptorSetKHR-pipelineBindPoint-00363");
4655 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkWriteDescriptorSet-descriptorType-00330");
4656 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdPushDescriptorSetKHR-commandBuffer-cmdpool");
unknown088160a2019-05-23 17:43:13 -06004657 vkCmdPushDescriptorSetKHR(tran_command_buffer.handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_layout.handle(), 0, 1,
4658 &descriptor_write);
4659 m_errorMonitor->VerifyFound();
4660 tran_command_buffer.end();
4661 }
4662 }
4663
4664 // Push to the non-push binding
4665 m_commandBuffer->begin();
Mark Lobodzinski20310782020-02-28 14:25:17 -07004666 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdPushDescriptorSetKHR-set-00365");
unknown088160a2019-05-23 17:43:13 -06004667 vkCmdPushDescriptorSetKHR(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_layout.handle(), 1, 1,
4668 &descriptor_write);
4669 m_errorMonitor->VerifyFound();
4670
4671 // Specify set out of bounds
Mark Lobodzinski20310782020-02-28 14:25:17 -07004672 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdPushDescriptorSetKHR-set-00364");
unknown088160a2019-05-23 17:43:13 -06004673 vkCmdPushDescriptorSetKHR(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_layout.handle(), 2, 1,
4674 &descriptor_write);
4675 m_errorMonitor->VerifyFound();
4676 m_commandBuffer->end();
4677
4678 // This is a test for VUID-vkCmdPushDescriptorSetKHR-commandBuffer-recording
4679 // TODO: Add VALIDATION_ERROR_ code support to core_validation::ValidateCmd
Mark Lobodzinski20310782020-02-28 14:25:17 -07004680 m_errorMonitor->SetDesiredFailureMsg(kErrorBit,
unknown088160a2019-05-23 17:43:13 -06004681 "You must call vkBeginCommandBuffer() before this call to vkCmdPushDescriptorSetKHR()");
Mark Lobodzinski20310782020-02-28 14:25:17 -07004682 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkWriteDescriptorSet-descriptorType-00330");
unknown088160a2019-05-23 17:43:13 -06004683 vkCmdPushDescriptorSetKHR(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_layout.handle(), 0, 1,
4684 &descriptor_write);
4685 m_errorMonitor->VerifyFound();
4686}
4687
Jeremy Hayesf96a5162020-02-10 13:49:31 -07004688TEST_F(VkLayerTest, PushDescriptorSetCmdBufferOffsetUnaligned) {
4689 TEST_DESCRIPTION("Attempt to push a push descriptor set buffer with unaligned offset.");
4690 if (InstanceExtensionSupported(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME)) {
4691 m_instance_extension_names.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
4692 } else {
4693 printf("%s %s Extension not supported, skipping tests\n", kSkipPrefix,
4694 VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
4695 return;
4696 }
4697
Mark Lobodzinski09ce9c42020-03-06 10:02:44 -07004698 ASSERT_NO_FATAL_FAILURE(InitFramework(m_errorMonitor));
Jeremy Hayesf96a5162020-02-10 13:49:31 -07004699 if (DeviceExtensionSupported(gpu(), nullptr, VK_KHR_PUSH_DESCRIPTOR_EXTENSION_NAME)) {
4700 m_device_extension_names.push_back(VK_KHR_PUSH_DESCRIPTOR_EXTENSION_NAME);
4701 } else {
4702 printf("%s %s Extension not supported, skipping tests\n", kSkipPrefix, VK_KHR_PUSH_DESCRIPTOR_EXTENSION_NAME);
4703 return;
4704 }
4705 ASSERT_NO_FATAL_FAILURE(InitState());
4706
4707 auto const push_descriptor_prop = GetPushDescriptorProperties(instance(), gpu());
4708 if (push_descriptor_prop.maxPushDescriptors < 1) {
4709 // Some implementations report an invalid maxPushDescriptors of 0.
4710 printf("%s maxPushDescriptors is zero, skipping test\n", kSkipPrefix);
4711 return;
4712 }
4713
4714 auto const min_alignment = m_device->props.limits.minUniformBufferOffsetAlignment;
4715 if (min_alignment == 0) {
4716 printf("%s minUniformBufferOffsetAlignment is zero, skipping test\n", kSkipPrefix);
4717 return;
4718 }
4719
4720 VkDescriptorSetLayoutBinding binding = {0, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1, VK_SHADER_STAGE_FRAGMENT_BIT, nullptr};
4721 const VkDescriptorSetLayoutObj push_ds_layout(m_device, {binding}, VK_DESCRIPTOR_SET_LAYOUT_CREATE_PUSH_DESCRIPTOR_BIT_KHR);
4722 ASSERT_TRUE(push_ds_layout.initialized());
4723
4724 const VkPipelineLayoutObj pipeline_layout(m_device, {&push_ds_layout});
4725 ASSERT_TRUE(pipeline_layout.initialized());
4726
4727 const uint32_t buffer_data[4] = {4, 5, 6, 7};
4728 VkConstantBufferObj buffer_obj(m_device, sizeof(buffer_data), &buffer_data, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT);
4729 ASSERT_TRUE(buffer_obj.initialized());
4730
4731 // Use an invalid alignment.
4732 VkDescriptorBufferInfo buffer_info = {buffer_obj.handle(), min_alignment - 1, VK_WHOLE_SIZE};
4733 VkWriteDescriptorSet descriptor_write = vk_testing::Device::write_descriptor_set(
4734 vk_testing::DescriptorSet(), 0, 0, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1, &buffer_info);
4735
4736 PFN_vkCmdPushDescriptorSetKHR vkCmdPushDescriptorSetKHR =
4737 (PFN_vkCmdPushDescriptorSetKHR)vk::GetDeviceProcAddr(m_device->device(), "vkCmdPushDescriptorSetKHR");
4738 ASSERT_TRUE(vkCmdPushDescriptorSetKHR != nullptr);
4739
4740 m_commandBuffer->begin();
Mark Lobodzinski20310782020-02-28 14:25:17 -07004741 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkWriteDescriptorSet-descriptorType-00327");
Jeremy Hayesf96a5162020-02-10 13:49:31 -07004742 vkCmdPushDescriptorSetKHR(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_layout.handle(), 0, 1,
4743 &descriptor_write);
4744 m_errorMonitor->VerifyFound();
4745
4746 m_commandBuffer->end();
4747}
4748
unknown088160a2019-05-23 17:43:13 -06004749TEST_F(VkLayerTest, SetDynScissorParamTests) {
4750 TEST_DESCRIPTION("Test parameters of vkCmdSetScissor without multiViewport feature");
4751
4752 VkPhysicalDeviceFeatures features{};
4753 ASSERT_NO_FATAL_FAILURE(Init(&features));
4754
4755 const VkRect2D scissor = {{0, 0}, {16, 16}};
4756 const VkRect2D scissors[] = {scissor, scissor};
4757
4758 m_commandBuffer->begin();
4759
4760 // array tests
Mark Lobodzinski20310782020-02-28 14:25:17 -07004761 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdSetScissor-firstScissor-00593");
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06004762 vk::CmdSetScissor(m_commandBuffer->handle(), 1, 1, scissors);
unknown088160a2019-05-23 17:43:13 -06004763 m_errorMonitor->VerifyFound();
4764
Mark Lobodzinski20310782020-02-28 14:25:17 -07004765 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdSetScissor-scissorCount-arraylength");
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06004766 vk::CmdSetScissor(m_commandBuffer->handle(), 0, 0, nullptr);
unknown088160a2019-05-23 17:43:13 -06004767 m_errorMonitor->VerifyFound();
4768
Mark Lobodzinski20310782020-02-28 14:25:17 -07004769 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdSetScissor-scissorCount-00594");
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06004770 vk::CmdSetScissor(m_commandBuffer->handle(), 0, 2, scissors);
unknown088160a2019-05-23 17:43:13 -06004771 m_errorMonitor->VerifyFound();
4772
Mark Lobodzinski20310782020-02-28 14:25:17 -07004773 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdSetScissor-firstScissor-00593");
4774 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdSetScissor-scissorCount-00594");
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06004775 vk::CmdSetScissor(m_commandBuffer->handle(), 1, 2, scissors);
unknown088160a2019-05-23 17:43:13 -06004776 m_errorMonitor->VerifyFound();
4777
Mark Lobodzinski20310782020-02-28 14:25:17 -07004778 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdSetScissor-pScissors-parameter");
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06004779 vk::CmdSetScissor(m_commandBuffer->handle(), 0, 1, nullptr);
unknown088160a2019-05-23 17:43:13 -06004780 m_errorMonitor->VerifyFound();
4781
4782 struct TestCase {
4783 VkRect2D scissor;
4784 std::string vuid;
4785 };
4786
4787 std::vector<TestCase> test_cases = {{{{-1, 0}, {16, 16}}, "VUID-vkCmdSetScissor-x-00595"},
4788 {{{0, -1}, {16, 16}}, "VUID-vkCmdSetScissor-x-00595"},
4789 {{{1, 0}, {INT32_MAX, 16}}, "VUID-vkCmdSetScissor-offset-00596"},
4790 {{{INT32_MAX, 0}, {1, 16}}, "VUID-vkCmdSetScissor-offset-00596"},
4791 {{{0, 0}, {uint32_t{INT32_MAX} + 1, 16}}, "VUID-vkCmdSetScissor-offset-00596"},
4792 {{{0, 1}, {16, INT32_MAX}}, "VUID-vkCmdSetScissor-offset-00597"},
4793 {{{0, INT32_MAX}, {16, 1}}, "VUID-vkCmdSetScissor-offset-00597"},
4794 {{{0, 0}, {16, uint32_t{INT32_MAX} + 1}}, "VUID-vkCmdSetScissor-offset-00597"}};
4795
4796 for (const auto &test_case : test_cases) {
Mark Lobodzinski20310782020-02-28 14:25:17 -07004797 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, test_case.vuid);
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06004798 vk::CmdSetScissor(m_commandBuffer->handle(), 0, 1, &test_case.scissor);
unknown088160a2019-05-23 17:43:13 -06004799 m_errorMonitor->VerifyFound();
4800 }
4801
4802 m_commandBuffer->end();
4803}
4804
4805TEST_F(VkLayerTest, SetDynScissorParamMultiviewportTests) {
4806 TEST_DESCRIPTION("Test parameters of vkCmdSetScissor with multiViewport feature enabled");
4807
4808 ASSERT_NO_FATAL_FAILURE(Init());
4809
4810 if (!m_device->phy().features().multiViewport) {
4811 printf("%s VkPhysicalDeviceFeatures::multiViewport is not supported -- skipping test.\n", kSkipPrefix);
4812 return;
4813 }
4814
unknown088160a2019-05-23 17:43:13 -06004815 m_commandBuffer->begin();
4816
Mark Lobodzinski20310782020-02-28 14:25:17 -07004817 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdSetScissor-scissorCount-arraylength");
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06004818 vk::CmdSetScissor(m_commandBuffer->handle(), 0, 0, nullptr);
unknown088160a2019-05-23 17:43:13 -06004819 m_errorMonitor->VerifyFound();
4820
Petr Kraus14e49492019-09-09 20:13:29 +02004821 const auto max_scissors = m_device->props.limits.maxViewports;
4822
Mark Lobodzinski20310782020-02-28 14:25:17 -07004823 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdSetScissor-pScissors-parameter");
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06004824 vk::CmdSetScissor(m_commandBuffer->handle(), 0, max_scissors, nullptr);
unknown088160a2019-05-23 17:43:13 -06004825 m_errorMonitor->VerifyFound();
4826
Petr Kraus14e49492019-09-09 20:13:29 +02004827 const uint32_t too_big_max_scissors = 65536 + 1; // let's say this is too much to allocate
4828 if (max_scissors >= too_big_max_scissors) {
4829 printf("%s VkPhysicalDeviceLimits::maxViewports is too large to practically test against -- skipping part of test.\n",
4830 kSkipPrefix);
4831 } else {
4832 const VkRect2D scissor = {{0, 0}, {16, 16}};
4833 const std::vector<VkRect2D> scissors(max_scissors + 1, scissor);
4834
Mark Lobodzinski20310782020-02-28 14:25:17 -07004835 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdSetScissor-firstScissor-00592");
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06004836 vk::CmdSetScissor(m_commandBuffer->handle(), 0, max_scissors + 1, scissors.data());
Petr Kraus14e49492019-09-09 20:13:29 +02004837 m_errorMonitor->VerifyFound();
4838
Mark Lobodzinski20310782020-02-28 14:25:17 -07004839 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdSetScissor-firstScissor-00592");
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06004840 vk::CmdSetScissor(m_commandBuffer->handle(), max_scissors, 1, scissors.data());
Petr Kraus14e49492019-09-09 20:13:29 +02004841 m_errorMonitor->VerifyFound();
4842
Mark Lobodzinski20310782020-02-28 14:25:17 -07004843 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdSetScissor-firstScissor-00592");
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06004844 vk::CmdSetScissor(m_commandBuffer->handle(), 1, max_scissors, scissors.data());
Petr Kraus14e49492019-09-09 20:13:29 +02004845 m_errorMonitor->VerifyFound();
4846
Mark Lobodzinski20310782020-02-28 14:25:17 -07004847 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdSetScissor-scissorCount-arraylength");
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06004848 vk::CmdSetScissor(m_commandBuffer->handle(), 1, 0, scissors.data());
Petr Kraus14e49492019-09-09 20:13:29 +02004849 m_errorMonitor->VerifyFound();
unknown088160a2019-05-23 17:43:13 -06004850 }
unknown088160a2019-05-23 17:43:13 -06004851}
4852
4853TEST_F(VkLayerTest, DrawIndirect) {
4854 TEST_DESCRIPTION("Test covered valid usage for vkCmdDrawIndirect");
4855
4856 ASSERT_NO_FATAL_FAILURE(Init());
4857 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
4858
locke-lunarg8e2c91b2019-06-11 17:53:26 -06004859 CreatePipelineHelper pipe(*this);
4860 pipe.InitInfo();
4861 const VkDynamicState dyn_states[] = {VK_DYNAMIC_STATE_VIEWPORT, VK_DYNAMIC_STATE_SCISSOR};
4862 VkPipelineDynamicStateCreateInfo dyn_state_ci = {};
4863 dyn_state_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO;
4864 dyn_state_ci.dynamicStateCount = size(dyn_states);
4865 dyn_state_ci.pDynamicStates = dyn_states;
4866 pipe.dyn_state_ci_ = dyn_state_ci;
4867 pipe.InitState();
4868 pipe.CreateGraphicsPipeline();
unknown088160a2019-05-23 17:43:13 -06004869
4870 m_commandBuffer->begin();
4871 m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
4872
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06004873 vk::CmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.pipeline_);
4874 vk::CmdBindDescriptorSets(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.pipeline_layout_.handle(), 0, 1,
4875 &pipe.descriptor_set_->set_, 0, NULL);
unknown088160a2019-05-23 17:43:13 -06004876
4877 VkViewport viewport = {0, 0, 16, 16, 0, 1};
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06004878 vk::CmdSetViewport(m_commandBuffer->handle(), 0, 1, &viewport);
unknown088160a2019-05-23 17:43:13 -06004879 VkRect2D scissor = {{0, 0}, {16, 16}};
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06004880 vk::CmdSetScissor(m_commandBuffer->handle(), 0, 1, &scissor);
unknown088160a2019-05-23 17:43:13 -06004881
4882 VkBufferCreateInfo buffer_create_info = {VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO};
4883 buffer_create_info.usage = VK_BUFFER_USAGE_VERTEX_BUFFER_BIT;
4884 buffer_create_info.size = sizeof(VkDrawIndirectCommand);
locke-lunarg8e2c91b2019-06-11 17:53:26 -06004885 VkBufferObj draw_buffer;
4886 draw_buffer.init(*m_device, buffer_create_info);
unknown088160a2019-05-23 17:43:13 -06004887
4888 // VUID-vkCmdDrawIndirect-buffer-02709
Mark Lobodzinski20310782020-02-28 14:25:17 -07004889 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdDrawIndirect-buffer-02709");
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06004890 vk::CmdDrawIndirect(m_commandBuffer->handle(), draw_buffer.handle(), 0, 1, sizeof(VkDrawIndirectCommand));
unknown088160a2019-05-23 17:43:13 -06004891 m_errorMonitor->VerifyFound();
4892
4893 m_commandBuffer->EndRenderPass();
4894 m_commandBuffer->end();
unknown088160a2019-05-23 17:43:13 -06004895}
4896
Mark Lobodzinski977f0342019-12-19 14:24:09 -07004897TEST_F(VkLayerTest, DrawIndirectByteCountEXT) {
4898 TEST_DESCRIPTION("Test covered valid usage for vkCmdDrawIndirectByteCountEXT");
4899
4900 if (InstanceExtensionSupported(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME)) {
4901 m_instance_extension_names.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
4902 } else {
4903 printf("%s Did not find required instance extension %s; skipped.\n", kSkipPrefix,
4904 VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
4905 return;
4906 }
Mark Lobodzinski09ce9c42020-03-06 10:02:44 -07004907 ASSERT_NO_FATAL_FAILURE(InitFramework(m_errorMonitor));
Mark Lobodzinski977f0342019-12-19 14:24:09 -07004908
4909 if (DeviceExtensionSupported(gpu(), nullptr, VK_EXT_TRANSFORM_FEEDBACK_EXTENSION_NAME)) {
4910 m_device_extension_names.push_back(VK_EXT_TRANSFORM_FEEDBACK_EXTENSION_NAME);
4911 } else {
4912 printf("%s VK_EXT_transform_feedback extension not supported, skipping test\n", kSkipPrefix);
Mark Lobodzinskid01b2bc2019-12-20 10:19:36 -07004913 return;
Mark Lobodzinski977f0342019-12-19 14:24:09 -07004914 }
4915
4916 ASSERT_NO_FATAL_FAILURE(InitState());
4917 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
4918
4919 PFN_vkCmdDrawIndirectByteCountEXT fpvkCmdDrawIndirectByteCountEXT =
4920 (PFN_vkCmdDrawIndirectByteCountEXT)vk::GetDeviceProcAddr(device(), "vkCmdDrawIndirectByteCountEXT");
4921
4922 m_commandBuffer->begin();
4923 m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
4924 VkBufferCreateInfo buffer_create_info = {VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO};
4925 buffer_create_info.usage = VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT;
4926 buffer_create_info.size = 1024;
4927 VkBufferObj counter_buffer;
4928 counter_buffer.init(*m_device, buffer_create_info);
4929
4930 // VUID-vkCmdDrawIndirectByteCountEXT-vertexStride-02289
Mark Lobodzinski20310782020-02-28 14:25:17 -07004931 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdDrawIndirectByteCountEXT-vertexStride-02289");
Mark Lobodzinski977f0342019-12-19 14:24:09 -07004932 fpvkCmdDrawIndirectByteCountEXT(m_commandBuffer->handle(), 1, 0, counter_buffer.handle(), 0, 1, 0xCADECADE);
4933 m_errorMonitor->VerifyFound();
4934
4935 m_commandBuffer->EndRenderPass();
4936 m_commandBuffer->end();
4937}
4938
unknown088160a2019-05-23 17:43:13 -06004939TEST_F(VkLayerTest, DrawIndirectCountKHR) {
4940 TEST_DESCRIPTION("Test covered valid usage for vkCmdDrawIndirectCountKHR");
4941
Mark Lobodzinski09ce9c42020-03-06 10:02:44 -07004942 ASSERT_NO_FATAL_FAILURE(InitFramework(m_errorMonitor));
unknown088160a2019-05-23 17:43:13 -06004943 if (DeviceExtensionSupported(gpu(), nullptr, VK_KHR_DRAW_INDIRECT_COUNT_EXTENSION_NAME)) {
4944 m_device_extension_names.push_back(VK_KHR_DRAW_INDIRECT_COUNT_EXTENSION_NAME);
4945 } else {
4946 printf(" VK_KHR_draw_indirect_count Extension not supported, skipping test\n");
4947 return;
4948 }
4949 ASSERT_NO_FATAL_FAILURE(InitState());
4950 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
4951
4952 VkMemoryRequirements memory_requirements;
4953 VkMemoryAllocateInfo memory_allocate_info = {VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO};
4954
4955 auto vkCmdDrawIndirectCountKHR =
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06004956 (PFN_vkCmdDrawIndirectCountKHR)vk::GetDeviceProcAddr(m_device->device(), "vkCmdDrawIndirectCountKHR");
unknown088160a2019-05-23 17:43:13 -06004957
locke-lunarg8e2c91b2019-06-11 17:53:26 -06004958 CreatePipelineHelper pipe(*this);
4959 pipe.InitInfo();
4960 const VkDynamicState dyn_states[] = {VK_DYNAMIC_STATE_VIEWPORT, VK_DYNAMIC_STATE_SCISSOR};
4961 VkPipelineDynamicStateCreateInfo dyn_state_ci = {};
4962 dyn_state_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO;
4963 dyn_state_ci.dynamicStateCount = size(dyn_states);
4964 dyn_state_ci.pDynamicStates = dyn_states;
4965 pipe.dyn_state_ci_ = dyn_state_ci;
4966 pipe.InitState();
4967 pipe.CreateGraphicsPipeline();
unknown088160a2019-05-23 17:43:13 -06004968
4969 m_commandBuffer->begin();
4970 m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
4971
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06004972 vk::CmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.pipeline_);
4973 vk::CmdBindDescriptorSets(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.pipeline_layout_.handle(), 0, 1,
4974 &pipe.descriptor_set_->set_, 0, NULL);
unknown088160a2019-05-23 17:43:13 -06004975
4976 VkViewport viewport = {0, 0, 16, 16, 0, 1};
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06004977 vk::CmdSetViewport(m_commandBuffer->handle(), 0, 1, &viewport);
unknown088160a2019-05-23 17:43:13 -06004978 VkRect2D scissor = {{0, 0}, {16, 16}};
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06004979 vk::CmdSetScissor(m_commandBuffer->handle(), 0, 1, &scissor);
unknown088160a2019-05-23 17:43:13 -06004980
4981 VkBufferCreateInfo buffer_create_info = {VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO};
4982 buffer_create_info.size = sizeof(VkDrawIndirectCommand);
4983 buffer_create_info.usage = VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT;
4984 VkBuffer draw_buffer;
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06004985 vk::CreateBuffer(m_device->device(), &buffer_create_info, nullptr, &draw_buffer);
unknown088160a2019-05-23 17:43:13 -06004986
4987 VkBufferCreateInfo count_buffer_create_info = {VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO};
4988 count_buffer_create_info.size = sizeof(uint32_t);
4989 count_buffer_create_info.usage = VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT;
locke-lunarg8e2c91b2019-06-11 17:53:26 -06004990 VkBufferObj count_buffer;
4991 count_buffer.init(*m_device, count_buffer_create_info);
unknown088160a2019-05-23 17:43:13 -06004992
Mike Schuchardt65847d92019-12-20 13:50:47 -08004993 // VUID-vkCmdDrawIndirectCount-buffer-02708
Mark Lobodzinski20310782020-02-28 14:25:17 -07004994 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdDrawIndirectCount-buffer-02708");
locke-lunarg8e2c91b2019-06-11 17:53:26 -06004995 vkCmdDrawIndirectCountKHR(m_commandBuffer->handle(), draw_buffer, 0, count_buffer.handle(), 0, 1,
4996 sizeof(VkDrawIndirectCommand));
unknown088160a2019-05-23 17:43:13 -06004997 m_errorMonitor->VerifyFound();
4998
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06004999 vk::GetBufferMemoryRequirements(m_device->device(), draw_buffer, &memory_requirements);
unknown088160a2019-05-23 17:43:13 -06005000 memory_allocate_info.allocationSize = memory_requirements.size;
5001 m_device->phy().set_memory_type(memory_requirements.memoryTypeBits, &memory_allocate_info, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT);
5002 VkDeviceMemory draw_buffer_memory;
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06005003 vk::AllocateMemory(m_device->device(), &memory_allocate_info, NULL, &draw_buffer_memory);
5004 vk::BindBufferMemory(m_device->device(), draw_buffer, draw_buffer_memory, 0);
unknown088160a2019-05-23 17:43:13 -06005005
5006 VkBuffer count_buffer_unbound;
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06005007 vk::CreateBuffer(m_device->device(), &count_buffer_create_info, nullptr, &count_buffer_unbound);
unknown088160a2019-05-23 17:43:13 -06005008
Mike Schuchardt65847d92019-12-20 13:50:47 -08005009 // VUID-vkCmdDrawIndirectCount-countBuffer-02714
Mark Lobodzinski20310782020-02-28 14:25:17 -07005010 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdDrawIndirectCount-countBuffer-02714");
unknown088160a2019-05-23 17:43:13 -06005011 vkCmdDrawIndirectCountKHR(m_commandBuffer->handle(), draw_buffer, 0, count_buffer_unbound, 0, 1, sizeof(VkDrawIndirectCommand));
5012 m_errorMonitor->VerifyFound();
5013
Mike Schuchardt65847d92019-12-20 13:50:47 -08005014 // VUID-vkCmdDrawIndirectCount-offset-02710
Mark Lobodzinski20310782020-02-28 14:25:17 -07005015 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdDrawIndirectCount-offset-02710");
locke-lunarg8e2c91b2019-06-11 17:53:26 -06005016 vkCmdDrawIndirectCountKHR(m_commandBuffer->handle(), draw_buffer, 1, count_buffer.handle(), 0, 1,
5017 sizeof(VkDrawIndirectCommand));
unknown088160a2019-05-23 17:43:13 -06005018 m_errorMonitor->VerifyFound();
5019
Mike Schuchardt65847d92019-12-20 13:50:47 -08005020 // VUID-vkCmdDrawIndirectCount-countBufferOffset-02716
Mark Lobodzinski20310782020-02-28 14:25:17 -07005021 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdDrawIndirectCount-countBufferOffset-02716");
locke-lunarg8e2c91b2019-06-11 17:53:26 -06005022 vkCmdDrawIndirectCountKHR(m_commandBuffer->handle(), draw_buffer, 0, count_buffer.handle(), 1, 1,
5023 sizeof(VkDrawIndirectCommand));
unknown088160a2019-05-23 17:43:13 -06005024 m_errorMonitor->VerifyFound();
5025
Mike Schuchardt65847d92019-12-20 13:50:47 -08005026 // VUID-vkCmdDrawIndirectCount-stride-03110
Mark Lobodzinski20310782020-02-28 14:25:17 -07005027 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdDrawIndirectCount-stride-03110");
locke-lunarg8e2c91b2019-06-11 17:53:26 -06005028 vkCmdDrawIndirectCountKHR(m_commandBuffer->handle(), draw_buffer, 0, count_buffer.handle(), 0, 1, 1);
unknown088160a2019-05-23 17:43:13 -06005029 m_errorMonitor->VerifyFound();
5030
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06005031 // 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 -06005032 // these:
Mike Schuchardt65847d92019-12-20 13:50:47 -08005033 // VUID-vkCmdDrawIndirectCount-renderPass-02684
5034 // VUID-vkCmdDrawIndirectCount-subpass-02685
5035 // VUID-vkCmdDrawIndirectCount-commandBuffer-02701
unknown088160a2019-05-23 17:43:13 -06005036
5037 m_commandBuffer->EndRenderPass();
5038 m_commandBuffer->end();
5039
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06005040 vk::DestroyBuffer(m_device->device(), draw_buffer, 0);
5041 vk::DestroyBuffer(m_device->device(), count_buffer_unbound, 0);
unknown088160a2019-05-23 17:43:13 -06005042
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06005043 vk::FreeMemory(m_device->device(), draw_buffer_memory, 0);
unknown088160a2019-05-23 17:43:13 -06005044}
5045
5046TEST_F(VkLayerTest, DrawIndexedIndirectCountKHR) {
5047 TEST_DESCRIPTION("Test covered valid usage for vkCmdDrawIndexedIndirectCountKHR");
5048
Mark Lobodzinski09ce9c42020-03-06 10:02:44 -07005049 ASSERT_NO_FATAL_FAILURE(InitFramework(m_errorMonitor));
unknown088160a2019-05-23 17:43:13 -06005050 if (DeviceExtensionSupported(gpu(), nullptr, VK_KHR_DRAW_INDIRECT_COUNT_EXTENSION_NAME)) {
5051 m_device_extension_names.push_back(VK_KHR_DRAW_INDIRECT_COUNT_EXTENSION_NAME);
5052 } else {
5053 printf(" VK_KHR_draw_indirect_count Extension not supported, skipping test\n");
5054 return;
5055 }
5056 ASSERT_NO_FATAL_FAILURE(InitState());
5057 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
5058
unknown088160a2019-05-23 17:43:13 -06005059 auto vkCmdDrawIndexedIndirectCountKHR =
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06005060 (PFN_vkCmdDrawIndexedIndirectCountKHR)vk::GetDeviceProcAddr(m_device->device(), "vkCmdDrawIndexedIndirectCountKHR");
unknown088160a2019-05-23 17:43:13 -06005061
locke-lunarg8e2c91b2019-06-11 17:53:26 -06005062 CreatePipelineHelper pipe(*this);
5063 pipe.InitInfo();
5064 const VkDynamicState dyn_states[] = {VK_DYNAMIC_STATE_VIEWPORT, VK_DYNAMIC_STATE_SCISSOR};
5065 VkPipelineDynamicStateCreateInfo dyn_state_ci = {};
5066 dyn_state_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO;
5067 dyn_state_ci.dynamicStateCount = size(dyn_states);
5068 dyn_state_ci.pDynamicStates = dyn_states;
5069 pipe.dyn_state_ci_ = dyn_state_ci;
5070 pipe.InitState();
5071 pipe.CreateGraphicsPipeline();
unknown088160a2019-05-23 17:43:13 -06005072
5073 m_commandBuffer->begin();
5074 m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
5075
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06005076 vk::CmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.pipeline_);
5077 vk::CmdBindDescriptorSets(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.pipeline_layout_.handle(), 0, 1,
5078 &pipe.descriptor_set_->set_, 0, NULL);
unknown088160a2019-05-23 17:43:13 -06005079
5080 VkViewport viewport = {0, 0, 16, 16, 0, 1};
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06005081 vk::CmdSetViewport(m_commandBuffer->handle(), 0, 1, &viewport);
unknown088160a2019-05-23 17:43:13 -06005082 VkRect2D scissor = {{0, 0}, {16, 16}};
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06005083 vk::CmdSetScissor(m_commandBuffer->handle(), 0, 1, &scissor);
unknown088160a2019-05-23 17:43:13 -06005084
5085 VkBufferCreateInfo buffer_create_info = {VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO};
5086 buffer_create_info.size = sizeof(VkDrawIndexedIndirectCommand);
5087 buffer_create_info.usage = VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT;
locke-lunarg8e2c91b2019-06-11 17:53:26 -06005088 VkBufferObj draw_buffer;
5089 draw_buffer.init(*m_device, buffer_create_info);
unknown088160a2019-05-23 17:43:13 -06005090
5091 VkBufferCreateInfo count_buffer_create_info = {VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO};
5092 count_buffer_create_info.size = sizeof(uint32_t);
5093 count_buffer_create_info.usage = VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT;
locke-lunarg8e2c91b2019-06-11 17:53:26 -06005094 VkBufferObj count_buffer;
5095 count_buffer.init(*m_device, count_buffer_create_info);
unknown088160a2019-05-23 17:43:13 -06005096
5097 VkBufferCreateInfo index_buffer_create_info = {VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO};
5098 index_buffer_create_info.size = sizeof(uint32_t);
5099 index_buffer_create_info.usage = VK_BUFFER_USAGE_INDEX_BUFFER_BIT;
locke-lunarg8e2c91b2019-06-11 17:53:26 -06005100 VkBufferObj index_buffer;
5101 index_buffer.init(*m_device, index_buffer_create_info);
unknown088160a2019-05-23 17:43:13 -06005102
Mike Schuchardt65847d92019-12-20 13:50:47 -08005103 // VUID-vkCmdDrawIndexedIndirectCount-commandBuffer-02701 (partial - only tests whether the index buffer is bound)
Mark Lobodzinski20310782020-02-28 14:25:17 -07005104 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdDrawIndexedIndirectCount-commandBuffer-02701");
locke-lunarg8e2c91b2019-06-11 17:53:26 -06005105 vkCmdDrawIndexedIndirectCountKHR(m_commandBuffer->handle(), draw_buffer.handle(), 0, count_buffer.handle(), 0, 1,
unknown088160a2019-05-23 17:43:13 -06005106 sizeof(VkDrawIndexedIndirectCommand));
5107 m_errorMonitor->VerifyFound();
5108
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06005109 vk::CmdBindIndexBuffer(m_commandBuffer->handle(), index_buffer.handle(), 0, VK_INDEX_TYPE_UINT32);
unknown088160a2019-05-23 17:43:13 -06005110
5111 VkBuffer draw_buffer_unbound;
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06005112 vk::CreateBuffer(m_device->device(), &count_buffer_create_info, nullptr, &draw_buffer_unbound);
unknown088160a2019-05-23 17:43:13 -06005113
Mike Schuchardt65847d92019-12-20 13:50:47 -08005114 // VUID-vkCmdDrawIndexedIndirectCount-buffer-02708
Mark Lobodzinski20310782020-02-28 14:25:17 -07005115 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdDrawIndexedIndirectCount-buffer-02708");
locke-lunarg8e2c91b2019-06-11 17:53:26 -06005116 vkCmdDrawIndexedIndirectCountKHR(m_commandBuffer->handle(), draw_buffer_unbound, 0, count_buffer.handle(), 0, 1,
unknown088160a2019-05-23 17:43:13 -06005117 sizeof(VkDrawIndexedIndirectCommand));
5118 m_errorMonitor->VerifyFound();
5119
5120 VkBuffer count_buffer_unbound;
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06005121 vk::CreateBuffer(m_device->device(), &count_buffer_create_info, nullptr, &count_buffer_unbound);
unknown088160a2019-05-23 17:43:13 -06005122
Mike Schuchardt65847d92019-12-20 13:50:47 -08005123 // VUID-vkCmdDrawIndexedIndirectCount-countBuffer-02714
Mark Lobodzinski20310782020-02-28 14:25:17 -07005124 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdDrawIndexedIndirectCount-countBuffer-02714");
locke-lunarg8e2c91b2019-06-11 17:53:26 -06005125 vkCmdDrawIndexedIndirectCountKHR(m_commandBuffer->handle(), draw_buffer.handle(), 0, count_buffer_unbound, 0, 1,
unknown088160a2019-05-23 17:43:13 -06005126 sizeof(VkDrawIndexedIndirectCommand));
5127 m_errorMonitor->VerifyFound();
5128
Mike Schuchardt65847d92019-12-20 13:50:47 -08005129 // VUID-vkCmdDrawIndexedIndirectCount-offset-02710
Mark Lobodzinski20310782020-02-28 14:25:17 -07005130 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdDrawIndexedIndirectCount-offset-02710");
locke-lunarg8e2c91b2019-06-11 17:53:26 -06005131 vkCmdDrawIndexedIndirectCountKHR(m_commandBuffer->handle(), draw_buffer.handle(), 1, count_buffer.handle(), 0, 1,
unknown088160a2019-05-23 17:43:13 -06005132 sizeof(VkDrawIndexedIndirectCommand));
5133 m_errorMonitor->VerifyFound();
5134
Mike Schuchardt65847d92019-12-20 13:50:47 -08005135 // VUID-vkCmdDrawIndexedIndirectCount-countBufferOffset-02716
Mark Lobodzinski20310782020-02-28 14:25:17 -07005136 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdDrawIndexedIndirectCount-countBufferOffset-02716");
locke-lunarg8e2c91b2019-06-11 17:53:26 -06005137 vkCmdDrawIndexedIndirectCountKHR(m_commandBuffer->handle(), draw_buffer.handle(), 0, count_buffer.handle(), 1, 1,
unknown088160a2019-05-23 17:43:13 -06005138 sizeof(VkDrawIndexedIndirectCommand));
5139 m_errorMonitor->VerifyFound();
5140
Mike Schuchardt65847d92019-12-20 13:50:47 -08005141 // VUID-vkCmdDrawIndexedIndirectCount-stride-03142
Mark Lobodzinski20310782020-02-28 14:25:17 -07005142 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdDrawIndexedIndirectCount-stride-03142");
locke-lunarg8e2c91b2019-06-11 17:53:26 -06005143 vkCmdDrawIndexedIndirectCountKHR(m_commandBuffer->handle(), draw_buffer.handle(), 0, count_buffer.handle(), 0, 1, 1);
unknown088160a2019-05-23 17:43:13 -06005144 m_errorMonitor->VerifyFound();
5145
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06005146 // 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 -06005147 // these:
Mike Schuchardt65847d92019-12-20 13:50:47 -08005148 // VUID-vkCmdDrawIndexedIndirectCount-renderPass-02684
5149 // VUID-vkCmdDrawIndexedIndirectCount-subpass-02685
5150 // VUID-vkCmdDrawIndexedIndirectCount-commandBuffer-02701 (partial)
unknown088160a2019-05-23 17:43:13 -06005151
5152 m_commandBuffer->EndRenderPass();
5153 m_commandBuffer->end();
5154
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06005155 vk::DestroyBuffer(m_device->device(), draw_buffer_unbound, 0);
5156 vk::DestroyBuffer(m_device->device(), count_buffer_unbound, 0);
unknown088160a2019-05-23 17:43:13 -06005157}
5158
sfricke-samsung860d3b22020-05-04 21:08:29 -07005159TEST_F(VkLayerTest, DrawIndirectCountFeature) {
5160 TEST_DESCRIPTION("Test covered valid usage for the 1.2 drawIndirectCount feature");
5161
5162 SetTargetApiVersion(VK_API_VERSION_1_2);
5163 ASSERT_NO_FATAL_FAILURE(Init());
5164 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
5165 if (DeviceValidationVersion() < VK_API_VERSION_1_2) {
5166 printf("%s Tests requires Vulkan 1.2+, skipping test\n", kSkipPrefix);
5167 return;
5168 }
5169
5170 VkBufferObj indirect_buffer;
5171 indirect_buffer.init(*m_device, sizeof(VkDrawIndirectCommand), VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT,
5172 VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT);
5173
5174 VkBufferObj indexed_indirect_buffer;
5175 indexed_indirect_buffer.init(*m_device, sizeof(VkDrawIndexedIndirectCommand), VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT,
5176 VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT);
5177
5178 VkBufferObj count_buffer;
5179 count_buffer.init(*m_device, sizeof(uint32_t), VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT);
5180
5181 VkBufferObj index_buffer;
5182 index_buffer.init(*m_device, sizeof(uint32_t), VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, VK_BUFFER_USAGE_INDEX_BUFFER_BIT);
5183
5184 CreatePipelineHelper pipe(*this);
5185 pipe.InitInfo();
5186 pipe.InitState();
5187 pipe.CreateGraphicsPipeline();
5188
5189 // Make calls to valid commands but without the drawIndirectCount feature set
5190 m_commandBuffer->begin();
5191 m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
5192
5193 vk::CmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.pipeline_);
5194
5195 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdDrawIndirectCount-None-02836");
5196 vk::CmdDrawIndirectCount(m_commandBuffer->handle(), indirect_buffer.handle(), 0, count_buffer.handle(), 0, 1,
5197 sizeof(VkDrawIndirectCommand));
5198 m_errorMonitor->VerifyFound();
5199
5200 vk::CmdBindIndexBuffer(m_commandBuffer->handle(), index_buffer.handle(), 0, VK_INDEX_TYPE_UINT32);
5201
5202 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdDrawIndexedIndirect-None-02837");
5203 vk::CmdDrawIndexedIndirectCount(m_commandBuffer->handle(), indexed_indirect_buffer.handle(), 0, count_buffer.handle(), 0, 1,
5204 sizeof(VkDrawIndexedIndirectCommand));
5205 m_errorMonitor->VerifyFound();
5206
5207 m_commandBuffer->EndRenderPass();
5208 m_commandBuffer->end();
5209}
5210
unknown088160a2019-05-23 17:43:13 -06005211TEST_F(VkLayerTest, ExclusiveScissorNV) {
5212 TEST_DESCRIPTION("Test VK_NV_scissor_exclusive with multiViewport disabled.");
5213
5214 if (InstanceExtensionSupported(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME)) {
5215 m_instance_extension_names.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
5216 } else {
5217 printf("%s Did not find required instance extension %s; skipped.\n", kSkipPrefix,
5218 VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
5219 return;
5220 }
Mark Lobodzinski09ce9c42020-03-06 10:02:44 -07005221 ASSERT_NO_FATAL_FAILURE(InitFramework(m_errorMonitor));
unknown088160a2019-05-23 17:43:13 -06005222 std::array<const char *, 1> required_device_extensions = {{VK_NV_SCISSOR_EXCLUSIVE_EXTENSION_NAME}};
5223 for (auto device_extension : required_device_extensions) {
5224 if (DeviceExtensionSupported(gpu(), nullptr, device_extension)) {
5225 m_device_extension_names.push_back(device_extension);
5226 } else {
5227 printf("%s %s Extension not supported, skipping tests\n", kSkipPrefix, device_extension);
5228 return;
5229 }
5230 }
5231
5232 PFN_vkGetPhysicalDeviceFeatures2KHR vkGetPhysicalDeviceFeatures2KHR =
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06005233 (PFN_vkGetPhysicalDeviceFeatures2KHR)vk::GetInstanceProcAddr(instance(), "vkGetPhysicalDeviceFeatures2KHR");
unknown088160a2019-05-23 17:43:13 -06005234 ASSERT_TRUE(vkGetPhysicalDeviceFeatures2KHR != nullptr);
5235
5236 // Create a device that enables exclusive scissor but disables multiViewport
5237 auto exclusive_scissor_features = lvl_init_struct<VkPhysicalDeviceExclusiveScissorFeaturesNV>();
5238 auto features2 = lvl_init_struct<VkPhysicalDeviceFeatures2KHR>(&exclusive_scissor_features);
5239 vkGetPhysicalDeviceFeatures2KHR(gpu(), &features2);
5240
5241 features2.features.multiViewport = VK_FALSE;
5242
5243 ASSERT_NO_FATAL_FAILURE(InitState(nullptr, &features2));
5244 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
5245
5246 if (m_device->phy().properties().limits.maxViewports) {
5247 printf("%s Device doesn't support the necessary number of viewports, skipping test.\n", kSkipPrefix);
5248 return;
5249 }
5250
5251 // Based on PSOViewportStateTests
5252 {
5253 VkViewport viewport = {0.0f, 0.0f, 64.0f, 64.0f, 0.0f, 1.0f};
5254 VkViewport viewports[] = {viewport, viewport};
5255 VkRect2D scissor = {{0, 0}, {64, 64}};
5256 VkRect2D scissors[100] = {scissor, scissor};
5257
5258 using std::vector;
5259 struct TestCase {
5260 uint32_t viewport_count;
5261 VkViewport *viewports;
5262 uint32_t scissor_count;
5263 VkRect2D *scissors;
5264 uint32_t exclusive_scissor_count;
5265 VkRect2D *exclusive_scissors;
5266
5267 vector<std::string> vuids;
5268 };
5269
5270 vector<TestCase> test_cases = {
5271 {1,
5272 viewports,
5273 1,
5274 scissors,
5275 2,
5276 scissors,
5277 {"VUID-VkPipelineViewportExclusiveScissorStateCreateInfoNV-exclusiveScissorCount-02027",
5278 "VUID-VkPipelineViewportExclusiveScissorStateCreateInfoNV-exclusiveScissorCount-02029"}},
5279 {1,
5280 viewports,
5281 1,
5282 scissors,
5283 100,
5284 scissors,
5285 {"VUID-VkPipelineViewportExclusiveScissorStateCreateInfoNV-exclusiveScissorCount-02027",
5286 "VUID-VkPipelineViewportExclusiveScissorStateCreateInfoNV-exclusiveScissorCount-02028",
5287 "VUID-VkPipelineViewportExclusiveScissorStateCreateInfoNV-exclusiveScissorCount-02029"}},
5288 {1,
5289 viewports,
5290 1,
5291 scissors,
5292 1,
5293 nullptr,
5294 {"VUID-VkPipelineViewportExclusiveScissorStateCreateInfoNV-pDynamicStates-02030"}},
5295 };
5296
5297 for (const auto &test_case : test_cases) {
5298 VkPipelineViewportExclusiveScissorStateCreateInfoNV exc = {
5299 VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_EXCLUSIVE_SCISSOR_STATE_CREATE_INFO_NV};
5300
5301 const auto break_vp = [&test_case, &exc](CreatePipelineHelper &helper) {
5302 helper.vp_state_ci_.viewportCount = test_case.viewport_count;
5303 helper.vp_state_ci_.pViewports = test_case.viewports;
5304 helper.vp_state_ci_.scissorCount = test_case.scissor_count;
5305 helper.vp_state_ci_.pScissors = test_case.scissors;
5306 helper.vp_state_ci_.pNext = &exc;
5307
5308 exc.exclusiveScissorCount = test_case.exclusive_scissor_count;
5309 exc.pExclusiveScissors = test_case.exclusive_scissors;
5310 };
Mark Lobodzinski20310782020-02-28 14:25:17 -07005311 CreatePipelineHelper::OneshotTest(*this, break_vp, kErrorBit, test_case.vuids);
unknown088160a2019-05-23 17:43:13 -06005312 }
5313 }
5314
5315 // Based on SetDynScissorParamTests
5316 {
5317 auto vkCmdSetExclusiveScissorNV =
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06005318 (PFN_vkCmdSetExclusiveScissorNV)vk::GetDeviceProcAddr(m_device->device(), "vkCmdSetExclusiveScissorNV");
unknown088160a2019-05-23 17:43:13 -06005319
5320 const VkRect2D scissor = {{0, 0}, {16, 16}};
5321 const VkRect2D scissors[] = {scissor, scissor};
5322
5323 m_commandBuffer->begin();
5324
Mark Lobodzinski20310782020-02-28 14:25:17 -07005325 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdSetExclusiveScissorNV-firstExclusiveScissor-02035");
unknown088160a2019-05-23 17:43:13 -06005326 vkCmdSetExclusiveScissorNV(m_commandBuffer->handle(), 1, 1, scissors);
5327 m_errorMonitor->VerifyFound();
5328
Mark Lobodzinski20310782020-02-28 14:25:17 -07005329 m_errorMonitor->SetDesiredFailureMsg(kErrorBit,
unknown088160a2019-05-23 17:43:13 -06005330 "vkCmdSetExclusiveScissorNV: parameter exclusiveScissorCount must be greater than 0");
5331 vkCmdSetExclusiveScissorNV(m_commandBuffer->handle(), 0, 0, nullptr);
5332 m_errorMonitor->VerifyFound();
5333
Mark Lobodzinski20310782020-02-28 14:25:17 -07005334 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdSetExclusiveScissorNV-exclusiveScissorCount-02036");
unknown088160a2019-05-23 17:43:13 -06005335 vkCmdSetExclusiveScissorNV(m_commandBuffer->handle(), 0, 2, scissors);
5336 m_errorMonitor->VerifyFound();
5337
Mark Lobodzinski20310782020-02-28 14:25:17 -07005338 m_errorMonitor->SetDesiredFailureMsg(kErrorBit,
unknown088160a2019-05-23 17:43:13 -06005339 "vkCmdSetExclusiveScissorNV: parameter exclusiveScissorCount must be greater than 0");
Mark Lobodzinski20310782020-02-28 14:25:17 -07005340 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdSetExclusiveScissorNV-firstExclusiveScissor-02035");
unknown088160a2019-05-23 17:43:13 -06005341 vkCmdSetExclusiveScissorNV(m_commandBuffer->handle(), 1, 0, scissors);
5342 m_errorMonitor->VerifyFound();
5343
Mark Lobodzinski20310782020-02-28 14:25:17 -07005344 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdSetExclusiveScissorNV-firstExclusiveScissor-02035");
5345 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdSetExclusiveScissorNV-exclusiveScissorCount-02036");
unknown088160a2019-05-23 17:43:13 -06005346 vkCmdSetExclusiveScissorNV(m_commandBuffer->handle(), 1, 2, scissors);
5347 m_errorMonitor->VerifyFound();
5348
Mark Lobodzinski20310782020-02-28 14:25:17 -07005349 m_errorMonitor->SetDesiredFailureMsg(kErrorBit,
unknown088160a2019-05-23 17:43:13 -06005350 "vkCmdSetExclusiveScissorNV: required parameter pExclusiveScissors specified as NULL");
5351 vkCmdSetExclusiveScissorNV(m_commandBuffer->handle(), 0, 1, nullptr);
5352 m_errorMonitor->VerifyFound();
5353
5354 struct TestCase {
5355 VkRect2D scissor;
5356 std::string vuid;
5357 };
5358
5359 std::vector<TestCase> test_cases = {
5360 {{{-1, 0}, {16, 16}}, "VUID-vkCmdSetExclusiveScissorNV-x-02037"},
5361 {{{0, -1}, {16, 16}}, "VUID-vkCmdSetExclusiveScissorNV-x-02037"},
5362 {{{1, 0}, {INT32_MAX, 16}}, "VUID-vkCmdSetExclusiveScissorNV-offset-02038"},
5363 {{{INT32_MAX, 0}, {1, 16}}, "VUID-vkCmdSetExclusiveScissorNV-offset-02038"},
5364 {{{0, 0}, {uint32_t{INT32_MAX} + 1, 16}}, "VUID-vkCmdSetExclusiveScissorNV-offset-02038"},
5365 {{{0, 1}, {16, INT32_MAX}}, "VUID-vkCmdSetExclusiveScissorNV-offset-02039"},
5366 {{{0, INT32_MAX}, {16, 1}}, "VUID-vkCmdSetExclusiveScissorNV-offset-02039"},
5367 {{{0, 0}, {16, uint32_t{INT32_MAX} + 1}}, "VUID-vkCmdSetExclusiveScissorNV-offset-02039"}};
5368
5369 for (const auto &test_case : test_cases) {
Mark Lobodzinski20310782020-02-28 14:25:17 -07005370 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, test_case.vuid);
unknown088160a2019-05-23 17:43:13 -06005371 vkCmdSetExclusiveScissorNV(m_commandBuffer->handle(), 0, 1, &test_case.scissor);
5372 m_errorMonitor->VerifyFound();
5373 }
5374
5375 m_commandBuffer->end();
5376 }
5377}
5378
5379TEST_F(VkLayerTest, MeshShaderNV) {
5380 TEST_DESCRIPTION("Test VK_NV_mesh_shader.");
5381
5382 if (InstanceExtensionSupported(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME)) {
5383 m_instance_extension_names.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
5384 } else {
5385 printf("%s Did not find required instance extension %s; skipped.\n", kSkipPrefix,
5386 VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
5387 return;
5388 }
Mark Lobodzinski09ce9c42020-03-06 10:02:44 -07005389 ASSERT_NO_FATAL_FAILURE(InitFramework(m_errorMonitor));
unknown088160a2019-05-23 17:43:13 -06005390 std::array<const char *, 1> required_device_extensions = {{VK_NV_MESH_SHADER_EXTENSION_NAME}};
5391 for (auto device_extension : required_device_extensions) {
5392 if (DeviceExtensionSupported(gpu(), nullptr, device_extension)) {
5393 m_device_extension_names.push_back(device_extension);
5394 } else {
5395 printf("%s %s Extension not supported, skipping tests\n", kSkipPrefix, device_extension);
5396 return;
5397 }
5398 }
5399
Tony-LunarG048f5012020-04-29 16:55:11 -06005400 if (IsPlatform(kMockICD) || DeviceSimulation()) {
unknown088160a2019-05-23 17:43:13 -06005401 printf("%sNot suppored by MockICD, skipping tests\n", kSkipPrefix);
5402 return;
5403 }
5404
5405 PFN_vkGetPhysicalDeviceFeatures2KHR vkGetPhysicalDeviceFeatures2KHR =
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06005406 (PFN_vkGetPhysicalDeviceFeatures2KHR)vk::GetInstanceProcAddr(instance(), "vkGetPhysicalDeviceFeatures2KHR");
unknown088160a2019-05-23 17:43:13 -06005407 ASSERT_TRUE(vkGetPhysicalDeviceFeatures2KHR != nullptr);
5408
5409 // Create a device that enables mesh_shader
5410 auto mesh_shader_features = lvl_init_struct<VkPhysicalDeviceMeshShaderFeaturesNV>();
5411 auto features2 = lvl_init_struct<VkPhysicalDeviceFeatures2KHR>(&mesh_shader_features);
5412 vkGetPhysicalDeviceFeatures2KHR(gpu(), &features2);
5413 features2.features.multiDrawIndirect = VK_FALSE;
5414
5415 ASSERT_NO_FATAL_FAILURE(InitState(nullptr, &features2));
5416 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
5417
5418 static const char vertShaderText[] =
5419 "#version 450\n"
5420 "vec2 vertices[3];\n"
5421 "void main() {\n"
5422 " vertices[0] = vec2(-1.0, -1.0);\n"
5423 " vertices[1] = vec2( 1.0, -1.0);\n"
5424 " vertices[2] = vec2( 0.0, 1.0);\n"
5425 " gl_Position = vec4(vertices[gl_VertexIndex % 3], 0.0, 1.0);\n"
5426 " gl_PointSize = 1.0f;\n"
5427 "}\n";
5428
5429 static const char meshShaderText[] =
5430 "#version 450\n"
5431 "#extension GL_NV_mesh_shader : require\n"
5432 "layout(local_size_x = 1) in;\n"
5433 "layout(max_vertices = 3) out;\n"
5434 "layout(max_primitives = 1) out;\n"
5435 "layout(triangles) out;\n"
5436 "void main() {\n"
5437 " gl_MeshVerticesNV[0].gl_Position = vec4(-1.0, -1.0, 0, 1);\n"
5438 " gl_MeshVerticesNV[1].gl_Position = vec4( 1.0, -1.0, 0, 1);\n"
5439 " gl_MeshVerticesNV[2].gl_Position = vec4( 0.0, 1.0, 0, 1);\n"
5440 " gl_PrimitiveIndicesNV[0] = 0;\n"
5441 " gl_PrimitiveIndicesNV[1] = 1;\n"
5442 " gl_PrimitiveIndicesNV[2] = 2;\n"
5443 " gl_PrimitiveCountNV = 1;\n"
5444 "}\n";
5445
5446 VkShaderObj vs(m_device, vertShaderText, VK_SHADER_STAGE_VERTEX_BIT, this);
5447 VkShaderObj ms(m_device, meshShaderText, VK_SHADER_STAGE_MESH_BIT_NV, this);
5448 VkShaderObj fs(m_device, bindStateFragShaderText, VK_SHADER_STAGE_FRAGMENT_BIT, this);
5449
5450 // Test pipeline creation
5451 {
5452 // can't mix mesh with vertex
5453 const auto break_vp = [&](CreatePipelineHelper &helper) {
5454 helper.shader_stages_ = {vs.GetStageCreateInfo(), fs.GetStageCreateInfo(), ms.GetStageCreateInfo()};
5455 };
Mark Lobodzinski20310782020-02-28 14:25:17 -07005456 CreatePipelineHelper::OneshotTest(*this, break_vp, kErrorBit,
unknown088160a2019-05-23 17:43:13 -06005457 vector<std::string>({"VUID-VkGraphicsPipelineCreateInfo-pStages-02095"}));
5458
5459 // vertex or mesh must be present
5460 const auto break_vp2 = [&](CreatePipelineHelper &helper) { helper.shader_stages_ = {fs.GetStageCreateInfo()}; };
Mark Lobodzinski20310782020-02-28 14:25:17 -07005461 CreatePipelineHelper::OneshotTest(*this, break_vp2, kErrorBit,
unknown088160a2019-05-23 17:43:13 -06005462 vector<std::string>({"VUID-VkGraphicsPipelineCreateInfo-stage-02096"}));
5463
5464 // vertexinput and inputassembly must be valid when vertex stage is present
5465 const auto break_vp3 = [&](CreatePipelineHelper &helper) {
5466 helper.shader_stages_ = {vs.GetStageCreateInfo(), fs.GetStageCreateInfo()};
5467 helper.gp_ci_.pVertexInputState = nullptr;
5468 helper.gp_ci_.pInputAssemblyState = nullptr;
5469 };
Mark Lobodzinski20310782020-02-28 14:25:17 -07005470 CreatePipelineHelper::OneshotTest(*this, break_vp3, kErrorBit,
unknown088160a2019-05-23 17:43:13 -06005471 vector<std::string>({"VUID-VkGraphicsPipelineCreateInfo-pStages-02097",
5472 "VUID-VkGraphicsPipelineCreateInfo-pStages-02098"}));
5473 }
5474
5475 PFN_vkCmdDrawMeshTasksIndirectNV vkCmdDrawMeshTasksIndirectNV =
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06005476 (PFN_vkCmdDrawMeshTasksIndirectNV)vk::GetInstanceProcAddr(instance(), "vkCmdDrawMeshTasksIndirectNV");
unknown088160a2019-05-23 17:43:13 -06005477
5478 VkBufferCreateInfo buffer_create_info = {VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO};
5479 buffer_create_info.size = sizeof(uint32_t);
5480 buffer_create_info.usage = VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT;
5481 VkBuffer buffer;
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06005482 VkResult result = vk::CreateBuffer(m_device->device(), &buffer_create_info, nullptr, &buffer);
unknown088160a2019-05-23 17:43:13 -06005483 ASSERT_VK_SUCCESS(result);
5484
5485 m_commandBuffer->begin();
5486
Mark Lobodzinski20310782020-02-28 14:25:17 -07005487 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdDrawMeshTasksIndirectNV-drawCount-02146");
5488 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdDrawMeshTasksIndirectNV-drawCount-02718");
unknown088160a2019-05-23 17:43:13 -06005489 vkCmdDrawMeshTasksIndirectNV(m_commandBuffer->handle(), buffer, 0, 2, 0);
5490 m_errorMonitor->VerifyFound();
5491
5492 m_commandBuffer->end();
5493
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06005494 vk::DestroyBuffer(m_device->device(), buffer, 0);
unknown088160a2019-05-23 17:43:13 -06005495}
5496
5497TEST_F(VkLayerTest, MeshShaderDisabledNV) {
5498 TEST_DESCRIPTION("Test VK_NV_mesh_shader VUs with NV_mesh_shader disabled.");
5499 ASSERT_NO_FATAL_FAILURE(Init());
5500 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
5501
5502 VkEvent event;
5503 VkEventCreateInfo event_create_info{};
5504 event_create_info.sType = VK_STRUCTURE_TYPE_EVENT_CREATE_INFO;
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06005505 vk::CreateEvent(m_device->device(), &event_create_info, nullptr, &event);
unknown088160a2019-05-23 17:43:13 -06005506
5507 m_commandBuffer->begin();
5508
Mark Lobodzinski20310782020-02-28 14:25:17 -07005509 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdSetEvent-stageMask-02107");
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06005510 vk::CmdSetEvent(m_commandBuffer->handle(), event, VK_PIPELINE_STAGE_MESH_SHADER_BIT_NV);
unknown088160a2019-05-23 17:43:13 -06005511 m_errorMonitor->VerifyFound();
5512
Mark Lobodzinski20310782020-02-28 14:25:17 -07005513 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdSetEvent-stageMask-02108");
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06005514 vk::CmdSetEvent(m_commandBuffer->handle(), event, VK_PIPELINE_STAGE_TASK_SHADER_BIT_NV);
unknown088160a2019-05-23 17:43:13 -06005515 m_errorMonitor->VerifyFound();
5516
Mark Lobodzinski20310782020-02-28 14:25:17 -07005517 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdResetEvent-stageMask-02109");
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06005518 vk::CmdResetEvent(m_commandBuffer->handle(), event, VK_PIPELINE_STAGE_MESH_SHADER_BIT_NV);
unknown088160a2019-05-23 17:43:13 -06005519 m_errorMonitor->VerifyFound();
5520
Mark Lobodzinski20310782020-02-28 14:25:17 -07005521 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdResetEvent-stageMask-02110");
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06005522 vk::CmdResetEvent(m_commandBuffer->handle(), event, VK_PIPELINE_STAGE_TASK_SHADER_BIT_NV);
unknown088160a2019-05-23 17:43:13 -06005523 m_errorMonitor->VerifyFound();
5524
Mark Lobodzinski20310782020-02-28 14:25:17 -07005525 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdWaitEvents-srcStageMask-02111");
5526 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdWaitEvents-dstStageMask-02113");
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06005527 vk::CmdWaitEvents(m_commandBuffer->handle(), 1, &event, VK_PIPELINE_STAGE_MESH_SHADER_BIT_NV,
5528 VK_PIPELINE_STAGE_MESH_SHADER_BIT_NV, 0, nullptr, 0, nullptr, 0, nullptr);
unknown088160a2019-05-23 17:43:13 -06005529 m_errorMonitor->VerifyFound();
5530
Mark Lobodzinski20310782020-02-28 14:25:17 -07005531 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdWaitEvents-srcStageMask-02112");
5532 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdWaitEvents-dstStageMask-02114");
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06005533 vk::CmdWaitEvents(m_commandBuffer->handle(), 1, &event, VK_PIPELINE_STAGE_TASK_SHADER_BIT_NV,
5534 VK_PIPELINE_STAGE_TASK_SHADER_BIT_NV, 0, nullptr, 0, nullptr, 0, nullptr);
unknown088160a2019-05-23 17:43:13 -06005535 m_errorMonitor->VerifyFound();
5536
Mark Lobodzinski20310782020-02-28 14:25:17 -07005537 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdPipelineBarrier-srcStageMask-02115");
5538 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdPipelineBarrier-dstStageMask-02117");
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06005539 vk::CmdPipelineBarrier(m_commandBuffer->handle(), VK_PIPELINE_STAGE_MESH_SHADER_BIT_NV, VK_PIPELINE_STAGE_MESH_SHADER_BIT_NV, 0,
5540 0, nullptr, 0, nullptr, 0, nullptr);
unknown088160a2019-05-23 17:43:13 -06005541 m_errorMonitor->VerifyFound();
5542
Mark Lobodzinski20310782020-02-28 14:25:17 -07005543 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdPipelineBarrier-srcStageMask-02116");
5544 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdPipelineBarrier-dstStageMask-02118");
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06005545 vk::CmdPipelineBarrier(m_commandBuffer->handle(), VK_PIPELINE_STAGE_TASK_SHADER_BIT_NV, VK_PIPELINE_STAGE_TASK_SHADER_BIT_NV, 0,
5546 0, nullptr, 0, nullptr, 0, nullptr);
unknown088160a2019-05-23 17:43:13 -06005547 m_errorMonitor->VerifyFound();
5548
5549 m_commandBuffer->end();
5550
5551 VkSemaphoreCreateInfo semaphore_create_info = {};
5552 semaphore_create_info.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO;
5553 VkSemaphore semaphore;
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06005554 ASSERT_VK_SUCCESS(vk::CreateSemaphore(m_device->device(), &semaphore_create_info, nullptr, &semaphore));
unknown088160a2019-05-23 17:43:13 -06005555
5556 VkPipelineStageFlags stage_flags = VK_PIPELINE_STAGE_MESH_SHADER_BIT_NV | VK_PIPELINE_STAGE_TASK_SHADER_BIT_NV;
5557 VkSubmitInfo submit_info = {};
5558
5559 // Signal the semaphore so the next test can wait on it.
5560 submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
5561 submit_info.signalSemaphoreCount = 1;
5562 submit_info.pSignalSemaphores = &semaphore;
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06005563 vk::QueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
unknown088160a2019-05-23 17:43:13 -06005564 m_errorMonitor->VerifyNotFound();
5565
5566 submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
5567 submit_info.signalSemaphoreCount = 0;
5568 submit_info.pSignalSemaphores = nullptr;
5569 submit_info.waitSemaphoreCount = 1;
5570 submit_info.pWaitSemaphores = &semaphore;
5571 submit_info.pWaitDstStageMask = &stage_flags;
5572
Mark Lobodzinski20310782020-02-28 14:25:17 -07005573 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkSubmitInfo-pWaitDstStageMask-02089");
5574 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkSubmitInfo-pWaitDstStageMask-02090");
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06005575 vk::QueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
unknown088160a2019-05-23 17:43:13 -06005576 m_errorMonitor->VerifyFound();
5577
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06005578 vk::QueueWaitIdle(m_device->m_queue);
unknown088160a2019-05-23 17:43:13 -06005579
5580 VkShaderObj vs(m_device, bindStateVertShaderText, VK_SHADER_STAGE_VERTEX_BIT, this);
5581 VkPipelineShaderStageCreateInfo meshStage = {VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO};
5582 meshStage = vs.GetStageCreateInfo();
5583 meshStage.stage = VK_SHADER_STAGE_MESH_BIT_NV;
5584 VkPipelineShaderStageCreateInfo taskStage = {VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO};
5585 taskStage = vs.GetStageCreateInfo();
5586 taskStage.stage = VK_SHADER_STAGE_TASK_BIT_NV;
5587
5588 // mesh and task shaders not supported
5589 const auto break_vp = [&](CreatePipelineHelper &helper) {
5590 helper.shader_stages_ = {meshStage, taskStage, vs.GetStageCreateInfo()};
5591 };
5592 CreatePipelineHelper::OneshotTest(
Mark Lobodzinski20310782020-02-28 14:25:17 -07005593 *this, break_vp, kErrorBit,
unknown088160a2019-05-23 17:43:13 -06005594 vector<std::string>({"VUID-VkPipelineShaderStageCreateInfo-pName-00707", "VUID-VkPipelineShaderStageCreateInfo-pName-00707",
5595 "VUID-VkPipelineShaderStageCreateInfo-stage-02091",
5596 "VUID-VkPipelineShaderStageCreateInfo-stage-02092"}));
5597
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06005598 vk::DestroyEvent(m_device->device(), event, nullptr);
5599 vk::DestroySemaphore(m_device->device(), semaphore, nullptr);
unknown088160a2019-05-23 17:43:13 -06005600}
Chris Mayerc93536f2019-09-19 16:34:49 +02005601
5602TEST_F(VkLayerTest, ViewportWScalingNV) {
5603 TEST_DESCRIPTION("Verify VK_NV_clip_space_w_scaling");
5604
Mark Lobodzinski09ce9c42020-03-06 10:02:44 -07005605 ASSERT_NO_FATAL_FAILURE(InitFramework(m_errorMonitor));
Chris Mayerc93536f2019-09-19 16:34:49 +02005606
5607 VkPhysicalDeviceFeatures device_features = {};
5608 ASSERT_NO_FATAL_FAILURE(GetPhysicalDeviceFeatures(&device_features));
5609
5610 if (!device_features.multiViewport) {
5611 printf("%s VkPhysicalDeviceFeatures::multiViewport is not supported, skipping tests\n", kSkipPrefix);
5612 return;
5613 }
5614
5615 if (DeviceExtensionSupported(gpu(), nullptr, VK_NV_CLIP_SPACE_W_SCALING_EXTENSION_NAME)) {
5616 m_device_extension_names.push_back(VK_NV_CLIP_SPACE_W_SCALING_EXTENSION_NAME);
5617 } else {
5618 printf("%s %s Extension not supported, skipping tests\n", kSkipPrefix, VK_NV_CLIP_SPACE_W_SCALING_EXTENSION_NAME);
5619 return;
5620 }
5621
5622 ASSERT_NO_FATAL_FAILURE(InitState(&device_features));
5623 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
5624
5625 auto vkCmdSetViewportWScalingNV =
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06005626 reinterpret_cast<PFN_vkCmdSetViewportWScalingNV>(vk::GetDeviceProcAddr(m_device->device(), "vkCmdSetViewportWScalingNV"));
Chris Mayerc93536f2019-09-19 16:34:49 +02005627
5628 const char vs_src[] = R"(
5629 #version 450
5630 const vec2 positions[] = { vec2(-1.0f, 1.0f),
5631 vec2( 1.0f, 1.0f),
5632 vec2(-1.0f, -1.0f),
5633 vec2( 1.0f, -1.0f) };
5634 out gl_PerVertex {
5635 vec4 gl_Position;
5636 };
5637
5638 void main() {
5639 gl_Position = vec4(positions[gl_VertexIndex % 4], 0.0f, 1.0f);
5640 })";
5641
5642 const char fs_src[] = R"(
5643 #version 450
5644 layout(location = 0) out vec4 outColor;
5645
5646 void main() {
5647 outColor = vec4(0.0f, 1.0f, 0.0f, 1.0f);
5648 })";
5649
5650 const std::vector<VkViewport> vp = {
5651 {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}};
5652 const std::vector<VkRect2D> sc = {{{0, 0}, {32, 32}}, {{32, 0}, {32, 32}}, {{0, 32}, {32, 32}}, {{32, 32}, {32, 32}}};
5653 const std::vector<VkViewportWScalingNV> scale = {{-0.2f, -0.2f}, {0.2f, -0.2f}, {-0.2f, 0.2f}, {0.2f, 0.2f}};
5654
5655 const uint32_t vp_count = static_cast<uint32_t>(vp.size());
5656
5657 VkPipelineViewportWScalingStateCreateInfoNV vpsi = {VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_W_SCALING_STATE_CREATE_INFO_NV};
5658 vpsi.viewportWScalingEnable = VK_TRUE;
5659 vpsi.viewportCount = vp_count;
5660 vpsi.pViewportWScalings = scale.data();
5661
5662 VkPipelineViewportStateCreateInfo vpci = {VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO};
5663 vpci.viewportCount = vp_count;
5664 vpci.pViewports = vp.data();
5665 vpci.scissorCount = vp_count;
5666 vpci.pScissors = sc.data();
5667 vpci.pNext = &vpsi;
5668
5669 const auto set_vpci = [&vpci](CreatePipelineHelper &helper) { helper.vp_state_ci_ = vpci; };
5670
5671 // Make sure no errors show up when creating the pipeline with w-scaling enabled
Mark Lobodzinski20310782020-02-28 14:25:17 -07005672 CreatePipelineHelper::OneshotTest(*this, set_vpci, kErrorBit, vector<std::string>(), true);
Chris Mayerc93536f2019-09-19 16:34:49 +02005673
5674 // Create pipeline with w-scaling enabled but without a valid scaling array
5675 vpsi.pViewportWScalings = nullptr;
Mark Lobodzinski20310782020-02-28 14:25:17 -07005676 CreatePipelineHelper::OneshotTest(*this, set_vpci, kErrorBit,
Chris Mayerc93536f2019-09-19 16:34:49 +02005677 vector<std::string>({"VUID-VkGraphicsPipelineCreateInfo-pDynamicStates-01715"}));
5678
5679 vpsi.pViewportWScalings = scale.data();
5680
5681 // Create pipeline with w-scaling enabled but without matching viewport counts
5682 vpsi.viewportCount = 1;
Mark Lobodzinski20310782020-02-28 14:25:17 -07005683 CreatePipelineHelper::OneshotTest(*this, set_vpci, kErrorBit,
Chris Mayerc93536f2019-09-19 16:34:49 +02005684 vector<std::string>({"VUID-VkPipelineViewportStateCreateInfo-viewportWScalingEnable-01726"}));
5685
5686 const VkPipelineLayoutObj pl(m_device);
5687
5688 VkShaderObj vs(m_device, vs_src, VK_SHADER_STAGE_VERTEX_BIT, this);
5689 VkShaderObj fs(m_device, fs_src, VK_SHADER_STAGE_FRAGMENT_BIT, this);
5690
5691 VkPipelineObj pipe(m_device);
5692 pipe.AddDefaultColorAttachment();
5693 pipe.AddShader(&vs);
5694 pipe.AddShader(&fs);
5695 pipe.SetViewport(vp);
5696 pipe.SetScissor(sc);
5697 pipe.CreateVKPipeline(pl.handle(), renderPass());
5698
5699 VkPipelineObj pipeDynWScale(m_device);
5700 pipeDynWScale.AddDefaultColorAttachment();
5701 pipeDynWScale.AddShader(&vs);
5702 pipeDynWScale.AddShader(&fs);
5703 pipeDynWScale.SetViewport(vp);
5704 pipeDynWScale.SetScissor(sc);
5705 pipeDynWScale.MakeDynamic(VK_DYNAMIC_STATE_VIEWPORT_W_SCALING_NV);
5706 pipeDynWScale.CreateVKPipeline(pl.handle(), renderPass());
5707
5708 m_commandBuffer->begin();
5709
5710 // Bind pipeline without dynamic w scaling enabled
5711 m_errorMonitor->ExpectSuccess();
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06005712 vk::CmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.handle());
Chris Mayerc93536f2019-09-19 16:34:49 +02005713 m_errorMonitor->VerifyNotFound();
5714
Chris Mayerc93536f2019-09-19 16:34:49 +02005715 // Bind pipeline that has dynamic w-scaling enabled
5716 m_errorMonitor->ExpectSuccess();
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06005717 vk::CmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeDynWScale.handle());
Chris Mayerc93536f2019-09-19 16:34:49 +02005718 m_errorMonitor->VerifyNotFound();
5719
5720 const auto max_vps = m_device->props.limits.maxViewports;
5721
Mark Lobodzinski20310782020-02-28 14:25:17 -07005722 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdSetViewportWScalingNV-firstViewport-01323");
Chris Mayerc93536f2019-09-19 16:34:49 +02005723 vkCmdSetViewportWScalingNV(m_commandBuffer->handle(), max_vps, vp_count, scale.data());
5724 m_errorMonitor->VerifyFound();
5725
Mark Lobodzinski20310782020-02-28 14:25:17 -07005726 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdSetViewportWScalingNV-firstViewport-01324");
Chris Mayerc93536f2019-09-19 16:34:49 +02005727 vkCmdSetViewportWScalingNV(m_commandBuffer->handle(), 1, max_vps, scale.data());
5728 m_errorMonitor->VerifyFound();
5729
5730 m_errorMonitor->ExpectSuccess();
5731 vkCmdSetViewportWScalingNV(m_commandBuffer->handle(), 0, vp_count, scale.data());
5732 m_errorMonitor->VerifyNotFound();
5733
5734 m_commandBuffer->end();
5735}
sfricke-samsung914e8002020-01-07 22:26:18 -08005736
5737TEST_F(VkLayerTest, CreateSamplerYcbcrConversionEnable) {
5738 TEST_DESCRIPTION("Checks samplerYcbcrConversion is enabled before calling vkCreateSamplerYcbcrConversion");
5739
5740 // Enable Sampler YCbCr Conversion req'd extensions
5741 // Only need revision 1 of vkGetPhysicalDeviceProperties2 and this allows more device capable for testing
5742 bool mp_extensions = InstanceExtensionSupported(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME, 1);
5743 if (mp_extensions) {
5744 m_instance_extension_names.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
5745 }
5746 SetTargetApiVersion(VK_API_VERSION_1_1);
Mark Lobodzinski09ce9c42020-03-06 10:02:44 -07005747 ASSERT_NO_FATAL_FAILURE(InitFramework(m_errorMonitor));
sfricke-samsung914e8002020-01-07 22:26:18 -08005748 mp_extensions = mp_extensions && DeviceExtensionSupported(gpu(), nullptr, VK_KHR_MAINTENANCE1_EXTENSION_NAME);
5749 mp_extensions = mp_extensions && DeviceExtensionSupported(gpu(), nullptr, VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME);
5750 mp_extensions = mp_extensions && DeviceExtensionSupported(gpu(), nullptr, VK_KHR_BIND_MEMORY_2_EXTENSION_NAME);
5751 mp_extensions = mp_extensions && DeviceExtensionSupported(gpu(), nullptr, VK_KHR_SAMPLER_YCBCR_CONVERSION_EXTENSION_NAME);
5752 if (mp_extensions) {
5753 m_device_extension_names.push_back(VK_KHR_MAINTENANCE1_EXTENSION_NAME);
5754 m_device_extension_names.push_back(VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME);
5755 m_device_extension_names.push_back(VK_KHR_BIND_MEMORY_2_EXTENSION_NAME);
5756 m_device_extension_names.push_back(VK_KHR_SAMPLER_YCBCR_CONVERSION_EXTENSION_NAME);
5757 } else {
5758 printf("%s test requires Sampler YCbCr Conversion extensions, not available. Skipping.\n", kSkipPrefix);
5759 return;
5760 }
5761
5762 // Explictly not enable Ycbcr Conversion Features
5763 VkPhysicalDeviceSamplerYcbcrConversionFeatures ycbcr_features = {};
5764 ycbcr_features.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SAMPLER_YCBCR_CONVERSION_FEATURES;
5765 ycbcr_features.samplerYcbcrConversion = VK_FALSE;
5766 ASSERT_NO_FATAL_FAILURE(InitState(nullptr, &ycbcr_features));
5767
5768 PFN_vkCreateSamplerYcbcrConversionKHR vkCreateSamplerYcbcrConversionFunction =
5769 (PFN_vkCreateSamplerYcbcrConversionKHR)vk::GetDeviceProcAddr(m_device->handle(), "vkCreateSamplerYcbcrConversionKHR");
5770 if (vkCreateSamplerYcbcrConversionFunction == nullptr) {
5771 printf("%s did not find vkCreateSamplerYcbcrConversionKHR function pointer; Skipping.\n", kSkipPrefix);
5772 return;
5773 }
5774
5775 // Create Ycbcr conversion
5776 VkSamplerYcbcrConversion conversions;
5777 VkSamplerYcbcrConversionCreateInfo ycbcr_create_info = {VK_STRUCTURE_TYPE_SAMPLER_YCBCR_CONVERSION_CREATE_INFO,
5778 NULL,
5779 VK_FORMAT_G8_B8R8_2PLANE_420_UNORM_KHR,
5780 VK_SAMPLER_YCBCR_MODEL_CONVERSION_RGB_IDENTITY,
5781 VK_SAMPLER_YCBCR_RANGE_ITU_FULL,
5782 {VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY,
5783 VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY},
5784 VK_CHROMA_LOCATION_COSITED_EVEN,
5785 VK_CHROMA_LOCATION_COSITED_EVEN,
5786 VK_FILTER_NEAREST,
5787 false};
5788
Mark Lobodzinski20310782020-02-28 14:25:17 -07005789 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCreateSamplerYcbcrConversion-None-01648");
sfricke-samsung914e8002020-01-07 22:26:18 -08005790 vkCreateSamplerYcbcrConversionFunction(m_device->handle(), &ycbcr_create_info, nullptr, &conversions);
5791 m_errorMonitor->VerifyFound();
Shannon McPherson50421602020-01-28 15:18:46 -07005792}
Jeremy Hayescd7df2c2020-05-21 16:36:47 -06005793
5794TEST_F(VkLayerTest, TransformFeedbackFeatureEnabled) {
5795 TEST_DESCRIPTION("VkPhysicalDeviceTransformFeedbackFeaturesEXT::transformFeedback must be enabled");
5796
5797 if (!InstanceExtensionSupported(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME)) {
5798 printf("%s Did not find required instance extension %s; skipped.\n", kSkipPrefix,
5799 VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
5800 return;
5801 }
5802 m_instance_extension_names.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
5803
5804 ASSERT_NO_FATAL_FAILURE(InitFramework(m_errorMonitor));
5805
5806 if (!DeviceExtensionSupported(gpu(), nullptr, VK_EXT_TRANSFORM_FEEDBACK_EXTENSION_NAME)) {
5807 printf("%s %s Extension not supported, skipping tests\n", kSkipPrefix, VK_EXT_TRANSFORM_FEEDBACK_EXTENSION_NAME);
5808 return;
5809 }
5810 m_device_extension_names.push_back(VK_EXT_TRANSFORM_FEEDBACK_EXTENSION_NAME);
5811
5812 {
5813 PFN_vkGetPhysicalDeviceFeatures2KHR vkGetPhysicalDeviceFeatures2KHR =
5814 (PFN_vkGetPhysicalDeviceFeatures2KHR)vk::GetInstanceProcAddr(instance(), "vkGetPhysicalDeviceFeatures2KHR");
5815 ASSERT_TRUE(vkGetPhysicalDeviceFeatures2KHR != nullptr);
5816
5817 auto tf_features = lvl_init_struct<VkPhysicalDeviceTransformFeedbackFeaturesEXT>();
5818 auto pd_features = lvl_init_struct<VkPhysicalDeviceFeatures2>(&tf_features);
5819 vkGetPhysicalDeviceFeatures2KHR(gpu(), &pd_features);
5820
5821 if (!tf_features.transformFeedback) {
5822 printf("%s transformFeedback not supported; skipped.\n", kSkipPrefix);
5823 return;
5824 }
5825 }
5826
5827 ASSERT_NO_FATAL_FAILURE(InitState());
5828 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
5829
5830 {
5831 auto vkCmdBindTransformFeedbackBuffersEXT = (PFN_vkCmdBindTransformFeedbackBuffersEXT)vk::GetDeviceProcAddr(
5832 m_device->device(), "vkCmdBindTransformFeedbackBuffersEXT");
5833 ASSERT_TRUE(vkCmdBindTransformFeedbackBuffersEXT != nullptr);
5834
5835 auto info = lvl_init_struct<VkBufferCreateInfo>();
5836 info.usage = VK_BUFFER_USAGE_TRANSFORM_FEEDBACK_BUFFER_BIT_EXT;
5837 info.size = 4;
5838 VkBufferObj buffer;
5839 buffer.init(*m_device, info);
5840 VkDeviceSize offsets[1]{};
5841
5842 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdBindTransformFeedbackBuffersEXT-transformFeedback-02355");
5843 vkCmdBindTransformFeedbackBuffersEXT(m_commandBuffer->handle(), 0, 1, &buffer.handle(), offsets, nullptr);
5844 m_errorMonitor->VerifyFound();
5845 }
5846
5847 {
5848 auto vkCmdBeginTransformFeedbackEXT =
5849 (PFN_vkCmdBeginTransformFeedbackEXT)vk::GetDeviceProcAddr(m_device->device(), "vkCmdBeginTransformFeedbackEXT");
5850 ASSERT_TRUE(vkCmdBeginTransformFeedbackEXT != nullptr);
5851
5852 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdBeginTransformFeedbackEXT-transformFeedback-02366");
5853 vkCmdBeginTransformFeedbackEXT(m_commandBuffer->handle(), 0, 1, nullptr, nullptr);
5854 m_errorMonitor->VerifyFound();
5855 }
5856
5857 {
5858 auto vkCmdEndTransformFeedbackEXT =
5859 (PFN_vkCmdEndTransformFeedbackEXT)vk::GetDeviceProcAddr(m_device->device(), "vkCmdEndTransformFeedbackEXT");
5860 ASSERT_TRUE(vkCmdEndTransformFeedbackEXT != nullptr);
5861
5862 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdEndTransformFeedbackEXT-transformFeedback-02374");
5863 m_errorMonitor->SetUnexpectedError("VUID-vkCmdEndTransformFeedbackEXT-None-02375");
5864 vkCmdEndTransformFeedbackEXT(m_commandBuffer->handle(), 0, 1, nullptr, nullptr);
5865 m_errorMonitor->VerifyFound();
5866 }
5867}
5868
5869TEST_F(VkLayerTest, TransformFeedbackCmdBindTransformFeedbackBuffersEXT) {
5870 TEST_DESCRIPTION("Submit invalid arguments to vkCmdBindTransformFeedbackBuffersEXT");
5871
5872 if (!InstanceExtensionSupported(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME)) {
5873 printf("%s Did not find required instance extension %s; skipped.\n", kSkipPrefix,
5874 VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
5875 return;
5876 }
5877 m_instance_extension_names.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
5878
5879 ASSERT_NO_FATAL_FAILURE(InitFramework(m_errorMonitor));
5880
5881 if (!DeviceExtensionSupported(gpu(), nullptr, VK_EXT_TRANSFORM_FEEDBACK_EXTENSION_NAME)) {
5882 printf("%s %s Extension not supported, skipping tests\n", kSkipPrefix, VK_EXT_TRANSFORM_FEEDBACK_EXTENSION_NAME);
5883 return;
5884 }
5885 m_device_extension_names.push_back(VK_EXT_TRANSFORM_FEEDBACK_EXTENSION_NAME);
5886
5887 {
5888 PFN_vkGetPhysicalDeviceFeatures2KHR vkGetPhysicalDeviceFeatures2KHR =
5889 (PFN_vkGetPhysicalDeviceFeatures2KHR)vk::GetInstanceProcAddr(instance(), "vkGetPhysicalDeviceFeatures2KHR");
5890 ASSERT_TRUE(vkGetPhysicalDeviceFeatures2KHR != nullptr);
5891
5892 auto tf_features = lvl_init_struct<VkPhysicalDeviceTransformFeedbackFeaturesEXT>();
5893 auto pd_features = lvl_init_struct<VkPhysicalDeviceFeatures2>(&tf_features);
5894 vkGetPhysicalDeviceFeatures2KHR(gpu(), &pd_features);
5895
5896 if (!tf_features.transformFeedback) {
5897 printf("%s transformFeedback not supported; skipped.\n", kSkipPrefix);
5898 return;
5899 }
5900
5901 ASSERT_NO_FATAL_FAILURE(InitState(nullptr, &pd_features));
5902 }
5903
5904 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
5905
5906 auto vkCmdBindTransformFeedbackBuffersEXT =
5907 (PFN_vkCmdBindTransformFeedbackBuffersEXT)vk::GetDeviceProcAddr(m_device->device(), "vkCmdBindTransformFeedbackBuffersEXT");
5908 ASSERT_TRUE(vkCmdBindTransformFeedbackBuffersEXT != nullptr);
5909
5910 {
5911 auto tf_properties = lvl_init_struct<VkPhysicalDeviceTransformFeedbackPropertiesEXT>();
5912 auto pd_properties = lvl_init_struct<VkPhysicalDeviceProperties2>(&tf_properties);
5913 vk::GetPhysicalDeviceProperties2(gpu(), &pd_properties);
5914
5915 auto info = lvl_init_struct<VkBufferCreateInfo>();
5916 info.usage = VK_BUFFER_USAGE_TRANSFORM_FEEDBACK_BUFFER_BIT_EXT;
5917 info.size = 8;
5918 VkBufferObj const buffer_obj(*m_device, info);
5919
5920 // Request a firstBinding that is too large.
5921 {
5922 auto const firstBinding = tf_properties.maxTransformFeedbackBuffers;
5923 VkDeviceSize const offsets[1]{};
5924
5925 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdBindTransformFeedbackBuffersEXT-firstBinding-02356");
5926 m_errorMonitor->SetUnexpectedError("VUID-vkCmdBindTransformFeedbackBuffersEXT-firstBinding-02357");
5927 vkCmdBindTransformFeedbackBuffersEXT(m_commandBuffer->handle(), firstBinding, 1, &buffer_obj.handle(), offsets,
5928 nullptr);
5929 m_errorMonitor->VerifyFound();
5930 }
5931
5932 // Request too many bindings.
5933 if (tf_properties.maxTransformFeedbackBuffers < std::numeric_limits<uint32_t>::max()) {
5934 auto const bindingCount = tf_properties.maxTransformFeedbackBuffers + 1;
5935 std::vector<VkBuffer> buffers(bindingCount, buffer_obj.handle());
5936
5937 std::vector<VkDeviceSize> offsets(bindingCount);
5938
5939 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdBindTransformFeedbackBuffersEXT-firstBinding-02357");
5940 vkCmdBindTransformFeedbackBuffersEXT(m_commandBuffer->handle(), 0, bindingCount, buffers.data(), offsets.data(),
5941 nullptr);
5942 m_errorMonitor->VerifyFound();
5943 }
5944
5945 // Request a size that is larger than the maximum size.
5946 if (tf_properties.maxTransformFeedbackBufferSize < std::numeric_limits<VkDeviceSize>::max()) {
5947 VkDeviceSize const offsets[1]{};
5948 VkDeviceSize const sizes[1]{tf_properties.maxTransformFeedbackBufferSize + 1};
5949
5950 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdBindTransformFeedbackBuffersEXT-pSize-02361");
5951 vkCmdBindTransformFeedbackBuffersEXT(m_commandBuffer->handle(), 0, 1, &buffer_obj.handle(), offsets, sizes);
5952 m_errorMonitor->VerifyFound();
5953 }
5954 }
5955
5956 {
5957 auto info = lvl_init_struct<VkBufferCreateInfo>();
5958 info.usage = VK_BUFFER_USAGE_TRANSFORM_FEEDBACK_BUFFER_BIT_EXT;
5959 info.size = 8;
5960 VkBufferObj const buffer_obj(*m_device, info);
5961
5962 // Request an offset that is too large.
5963 {
5964 VkDeviceSize const offsets[1]{info.size + 4};
5965
5966 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdBindTransformFeedbackBuffersEXT-pOffsets-02358");
5967 vkCmdBindTransformFeedbackBuffersEXT(m_commandBuffer->handle(), 0, 1, &buffer_obj.handle(), offsets, nullptr);
5968 m_errorMonitor->VerifyFound();
5969 }
5970
5971 // Request an offset that is not a multiple of 4.
5972 {
5973 VkDeviceSize const offsets[1]{1};
5974
5975 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdBindTransformFeedbackBuffersEXT-pOffsets-02359");
5976 vkCmdBindTransformFeedbackBuffersEXT(m_commandBuffer->handle(), 0, 1, &buffer_obj.handle(), offsets, nullptr);
5977 m_errorMonitor->VerifyFound();
5978 }
5979
5980 // Request a size that is larger than the buffer's size.
5981 {
5982 VkDeviceSize const offsets[1]{};
5983 VkDeviceSize const sizes[1]{info.size + 1};
5984
5985 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdBindTransformFeedbackBuffersEXT-pSizes-02362");
5986 m_errorMonitor->SetUnexpectedError("VUID-vkCmdBindTransformFeedbackBuffersEXT-pOffsets-02363");
5987 vkCmdBindTransformFeedbackBuffersEXT(m_commandBuffer->handle(), 0, 1, &buffer_obj.handle(), offsets, sizes);
5988 m_errorMonitor->VerifyFound();
5989 }
5990
5991 // Request an offset and size whose sum is larger than the buffer's size.
5992 {
5993 VkDeviceSize const offsets[1]{4};
5994 VkDeviceSize const sizes[1]{info.size - 3};
5995
5996 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdBindTransformFeedbackBuffersEXT-pOffsets-02363");
5997 vkCmdBindTransformFeedbackBuffersEXT(m_commandBuffer->handle(), 0, 1, &buffer_obj.handle(), offsets, sizes);
5998 m_errorMonitor->VerifyFound();
5999 }
6000
6001 // Bind while transform feedback is active.
6002 {
6003 auto vkCmdBeginTransformFeedbackEXT =
6004 (PFN_vkCmdBeginTransformFeedbackEXT)vk::GetDeviceProcAddr(m_device->device(), "vkCmdBeginTransformFeedbackEXT");
6005 ASSERT_TRUE(vkCmdBeginTransformFeedbackEXT != nullptr);
6006 vkCmdBeginTransformFeedbackEXT(m_commandBuffer->handle(), 0, 1, nullptr, nullptr);
6007
6008 VkDeviceSize const offsets[1]{};
6009
6010 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdBindTransformFeedbackBuffersEXT-None-02365");
6011 vkCmdBindTransformFeedbackBuffersEXT(m_commandBuffer->handle(), 0, 1, &buffer_obj.handle(), offsets, nullptr);
6012 m_errorMonitor->VerifyFound();
6013
6014 auto vkCmdEndTransformFeedbackEXT =
6015 (PFN_vkCmdEndTransformFeedbackEXT)vk::GetDeviceProcAddr(m_device->device(), "vkCmdEndTransformFeedbackEXT");
6016 ASSERT_TRUE(vkCmdEndTransformFeedbackEXT != nullptr);
6017 vkCmdEndTransformFeedbackEXT(m_commandBuffer->handle(), 0, 1, nullptr, nullptr);
6018 }
6019 }
6020
6021 // Don't set VK_BUFFER_USAGE_TRANSFORM_FEEDBACK_BUFFER_BIT_EXT.
6022 {
6023 auto info = lvl_init_struct<VkBufferCreateInfo>();
6024 // info.usage = VK_BUFFER_USAGE_TRANSFORM_FEEDBACK_BUFFER_BIT_EXT;
6025 info.size = 4;
6026 VkBufferObj const buffer_obj(*m_device, info);
6027
6028 VkDeviceSize const offsets[1]{};
6029
6030 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdBindTransformFeedbackBuffersEXT-pBuffers-02360");
6031 vkCmdBindTransformFeedbackBuffersEXT(m_commandBuffer->handle(), 0, 1, &buffer_obj.handle(), offsets, nullptr);
6032 m_errorMonitor->VerifyFound();
6033 }
6034
6035 // Don't bind memory.
6036 {
6037 VkBuffer buffer{};
6038 {
6039 auto vkCreateBuffer = (PFN_vkCreateBuffer)vk::GetDeviceProcAddr(m_device->device(), "vkCreateBuffer");
6040 ASSERT_TRUE(vkCreateBuffer != nullptr);
6041
6042 auto info = lvl_init_struct<VkBufferCreateInfo>();
6043 info.usage = VK_BUFFER_USAGE_TRANSFORM_FEEDBACK_BUFFER_BIT_EXT;
6044 info.size = 4;
6045 vkCreateBuffer(m_device->device(), &info, nullptr, &buffer);
6046 }
6047
6048 VkDeviceSize const offsets[1]{};
6049
6050 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdBindTransformFeedbackBuffersEXT-pBuffers-02364");
6051 vkCmdBindTransformFeedbackBuffersEXT(m_commandBuffer->handle(), 0, 1, &buffer, offsets, nullptr);
6052 m_errorMonitor->VerifyFound();
6053 }
6054}
6055
6056TEST_F(VkLayerTest, TransformFeedbackCmdBeginTransformFeedbackEXT) {
6057 TEST_DESCRIPTION("Submit invalid arguments to vkCmdBeginTransformFeedbackEXT");
6058
6059 if (!InstanceExtensionSupported(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME)) {
6060 printf("%s Did not find required instance extension %s; skipped.\n", kSkipPrefix,
6061 VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
6062 return;
6063 }
6064 m_instance_extension_names.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
6065
6066 ASSERT_NO_FATAL_FAILURE(InitFramework(m_errorMonitor));
6067
6068 if (!DeviceExtensionSupported(gpu(), nullptr, VK_EXT_TRANSFORM_FEEDBACK_EXTENSION_NAME)) {
6069 printf("%s %s Extension not supported, skipping tests\n", kSkipPrefix, VK_EXT_TRANSFORM_FEEDBACK_EXTENSION_NAME);
6070 return;
6071 }
6072 m_device_extension_names.push_back(VK_EXT_TRANSFORM_FEEDBACK_EXTENSION_NAME);
6073
6074 {
6075 PFN_vkGetPhysicalDeviceFeatures2KHR vkGetPhysicalDeviceFeatures2KHR =
6076 (PFN_vkGetPhysicalDeviceFeatures2KHR)vk::GetInstanceProcAddr(instance(), "vkGetPhysicalDeviceFeatures2KHR");
6077 ASSERT_TRUE(vkGetPhysicalDeviceFeatures2KHR != nullptr);
6078
6079 auto tf_features = lvl_init_struct<VkPhysicalDeviceTransformFeedbackFeaturesEXT>();
6080 auto pd_features = lvl_init_struct<VkPhysicalDeviceFeatures2>(&tf_features);
6081 vkGetPhysicalDeviceFeatures2KHR(gpu(), &pd_features);
6082
6083 if (!tf_features.transformFeedback) {
6084 printf("%s transformFeedback not supported; skipped.\n", kSkipPrefix);
6085 return;
6086 }
6087
6088 ASSERT_NO_FATAL_FAILURE(InitState(nullptr, &pd_features));
6089 }
6090
6091 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
6092
6093 auto vkCmdBeginTransformFeedbackEXT =
6094 (PFN_vkCmdBeginTransformFeedbackEXT)vk::GetDeviceProcAddr(m_device->device(), "vkCmdBeginTransformFeedbackEXT");
6095 ASSERT_TRUE(vkCmdBeginTransformFeedbackEXT != nullptr);
6096
6097 {
6098 auto tf_properties = lvl_init_struct<VkPhysicalDeviceTransformFeedbackPropertiesEXT>();
6099 auto pd_properties = lvl_init_struct<VkPhysicalDeviceProperties2>(&tf_properties);
6100 vk::GetPhysicalDeviceProperties2(gpu(), &pd_properties);
6101
6102 // Request a firstCounterBuffer that is too large.
6103 {
6104 auto const firstCounterBuffer = tf_properties.maxTransformFeedbackBuffers;
6105
6106 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdBeginTransformFeedbackEXT-firstCounterBuffer-02368");
6107 m_errorMonitor->SetUnexpectedError("VUID-vkCmdBeginTransformFeedbackEXT-firstCounterBuffer-02369");
6108 vkCmdBeginTransformFeedbackEXT(m_commandBuffer->handle(), firstCounterBuffer, 1, nullptr, nullptr);
6109 m_errorMonitor->VerifyFound();
6110 }
6111
6112 // Request too many buffers.
6113 if (tf_properties.maxTransformFeedbackBuffers < std::numeric_limits<uint32_t>::max()) {
6114 auto const counterBufferCount = tf_properties.maxTransformFeedbackBuffers + 1;
6115
6116 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdBeginTransformFeedbackEXT-firstCounterBuffer-02369");
6117 vkCmdBeginTransformFeedbackEXT(m_commandBuffer->handle(), 0, counterBufferCount, nullptr, nullptr);
6118 m_errorMonitor->VerifyFound();
6119 }
6120 }
6121
6122 // Request an out-of-bounds location.
6123 {
6124 auto info = lvl_init_struct<VkBufferCreateInfo>();
6125 info.usage = VK_BUFFER_USAGE_TRANSFORM_FEEDBACK_COUNTER_BUFFER_BIT_EXT;
6126 info.size = 4;
6127 VkBufferObj const buffer_obj(*m_device, info);
6128
6129 VkDeviceSize const offsets[1]{1};
6130
6131 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdBeginTransformFeedbackEXT-pCounterBufferOffsets-02370");
6132 vkCmdBeginTransformFeedbackEXT(m_commandBuffer->handle(), 0, 1, &buffer_obj.handle(), offsets);
6133 m_errorMonitor->VerifyFound();
6134 }
6135
6136 // Request specific offsets without specifying buffers.
6137 {
6138 VkDeviceSize const offsets[1]{};
6139
6140 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdBeginTransformFeedbackEXT-pCounterBuffer-02371");
6141 vkCmdBeginTransformFeedbackEXT(m_commandBuffer->handle(), 0, 1, nullptr, offsets);
6142 m_errorMonitor->VerifyFound();
6143 }
6144
6145 // Don't set VK_BUFFER_USAGE_TRANSFORM_FEEDBACK_COUNTER_BUFFER_BIT_EXT.
6146 {
6147 auto info = lvl_init_struct<VkBufferCreateInfo>();
6148 // info.usage = VK_BUFFER_USAGE_TRANSFORM_FEEDBACK_COUNTER_BUFFER_BIT_EXT;
6149 info.size = 4;
6150 VkBufferObj const buffer_obj(*m_device, info);
6151
6152 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdBeginTransformFeedbackEXT-pCounterBuffers-02372");
6153 vkCmdBeginTransformFeedbackEXT(m_commandBuffer->handle(), 0, 1, &buffer_obj.handle(), nullptr);
6154 m_errorMonitor->VerifyFound();
6155 }
6156
6157 // Begin while transform feedback is active.
6158 {
6159 vkCmdBeginTransformFeedbackEXT(m_commandBuffer->handle(), 0, 1, nullptr, nullptr);
6160
6161 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdBeginTransformFeedbackEXT-None-02367");
6162 vkCmdBeginTransformFeedbackEXT(m_commandBuffer->handle(), 0, 1, nullptr, nullptr);
6163 m_errorMonitor->VerifyFound();
6164
6165 auto vkCmdEndTransformFeedbackEXT =
6166 (PFN_vkCmdEndTransformFeedbackEXT)vk::GetDeviceProcAddr(m_device->device(), "vkCmdEndTransformFeedbackEXT");
6167 ASSERT_TRUE(vkCmdEndTransformFeedbackEXT != nullptr);
6168
6169 vkCmdEndTransformFeedbackEXT(m_commandBuffer->handle(), 0, 1, nullptr, nullptr);
6170 }
6171}
6172
6173TEST_F(VkLayerTest, TransformFeedbackCmdEndTransformFeedbackEXT) {
6174 TEST_DESCRIPTION("Submit invalid arguments to vkCmdEndTransformFeedbackEXT");
6175
6176 if (!InstanceExtensionSupported(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME)) {
6177 printf("%s Did not find required instance extension %s; skipped.\n", kSkipPrefix,
6178 VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
6179 return;
6180 }
6181 m_instance_extension_names.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
6182
6183 ASSERT_NO_FATAL_FAILURE(InitFramework(m_errorMonitor));
6184
6185 if (!DeviceExtensionSupported(gpu(), nullptr, VK_EXT_TRANSFORM_FEEDBACK_EXTENSION_NAME)) {
6186 printf("%s %s Extension not supported, skipping tests\n", kSkipPrefix, VK_EXT_TRANSFORM_FEEDBACK_EXTENSION_NAME);
6187 return;
6188 }
6189 m_device_extension_names.push_back(VK_EXT_TRANSFORM_FEEDBACK_EXTENSION_NAME);
6190
6191 {
6192 PFN_vkGetPhysicalDeviceFeatures2KHR vkGetPhysicalDeviceFeatures2KHR =
6193 (PFN_vkGetPhysicalDeviceFeatures2KHR)vk::GetInstanceProcAddr(instance(), "vkGetPhysicalDeviceFeatures2KHR");
6194 ASSERT_TRUE(vkGetPhysicalDeviceFeatures2KHR != nullptr);
6195
6196 auto tf_features = lvl_init_struct<VkPhysicalDeviceTransformFeedbackFeaturesEXT>();
6197 auto pd_features = lvl_init_struct<VkPhysicalDeviceFeatures2>(&tf_features);
6198 vkGetPhysicalDeviceFeatures2KHR(gpu(), &pd_features);
6199
6200 if (!tf_features.transformFeedback) {
6201 printf("%s transformFeedback not supported; skipped.\n", kSkipPrefix);
6202 return;
6203 }
6204
6205 ASSERT_NO_FATAL_FAILURE(InitState(nullptr, &pd_features));
6206 }
6207
6208 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
6209
6210 auto vkCmdEndTransformFeedbackEXT =
6211 (PFN_vkCmdEndTransformFeedbackEXT)vk::GetDeviceProcAddr(m_device->device(), "vkCmdEndTransformFeedbackEXT");
6212 ASSERT_TRUE(vkCmdEndTransformFeedbackEXT != nullptr);
6213
6214 {
6215 // Activate transform feedback.
6216 auto vkCmdBeginTransformFeedbackEXT =
6217 (PFN_vkCmdBeginTransformFeedbackEXT)vk::GetDeviceProcAddr(m_device->device(), "vkCmdBeginTransformFeedbackEXT");
6218 ASSERT_TRUE(vkCmdBeginTransformFeedbackEXT != nullptr);
6219 vkCmdBeginTransformFeedbackEXT(m_commandBuffer->handle(), 0, 1, nullptr, nullptr);
6220
6221 {
6222 auto tf_properties = lvl_init_struct<VkPhysicalDeviceTransformFeedbackPropertiesEXT>();
6223 auto pd_properties = lvl_init_struct<VkPhysicalDeviceProperties2>(&tf_properties);
6224 vk::GetPhysicalDeviceProperties2(gpu(), &pd_properties);
6225
6226 // Request a firstCounterBuffer that is too large.
6227 {
6228 auto const firstCounterBuffer = tf_properties.maxTransformFeedbackBuffers;
6229
6230 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdEndTransformFeedbackEXT-firstCounterBuffer-02376");
6231 m_errorMonitor->SetUnexpectedError("VUID-vkCmdEndTransformFeedbackEXT-firstCounterBuffer-02377");
6232 vkCmdEndTransformFeedbackEXT(m_commandBuffer->handle(), firstCounterBuffer, 1, nullptr, nullptr);
6233 m_errorMonitor->VerifyFound();
6234 }
6235
6236 // Request too many buffers.
6237 if (tf_properties.maxTransformFeedbackBuffers < std::numeric_limits<uint32_t>::max()) {
6238 auto const counterBufferCount = tf_properties.maxTransformFeedbackBuffers + 1;
6239
6240 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdEndTransformFeedbackEXT-firstCounterBuffer-02377");
6241 vkCmdEndTransformFeedbackEXT(m_commandBuffer->handle(), 0, counterBufferCount, nullptr, nullptr);
6242 m_errorMonitor->VerifyFound();
6243 }
6244 }
6245
6246 // Request an out-of-bounds location.
6247 {
6248 auto info = lvl_init_struct<VkBufferCreateInfo>();
6249 info.usage = VK_BUFFER_USAGE_TRANSFORM_FEEDBACK_COUNTER_BUFFER_BIT_EXT;
6250 info.size = 4;
6251 VkBufferObj const buffer_obj(*m_device, info);
6252
6253 VkDeviceSize const offsets[1]{1};
6254
6255 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdEndTransformFeedbackEXT-pCounterBufferOffsets-02378");
6256 vkCmdEndTransformFeedbackEXT(m_commandBuffer->handle(), 0, 1, &buffer_obj.handle(), offsets);
6257 m_errorMonitor->VerifyFound();
6258 }
6259
6260 // Request specific offsets without specifying buffers.
6261 {
6262 VkDeviceSize const offsets[1]{};
6263
6264 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdEndTransformFeedbackEXT-pCounterBuffer-02379");
6265 vkCmdEndTransformFeedbackEXT(m_commandBuffer->handle(), 0, 1, nullptr, offsets);
6266 m_errorMonitor->VerifyFound();
6267 }
6268
6269 // Don't set VK_BUFFER_USAGE_TRANSFORM_FEEDBACK_COUNTER_BUFFER_BIT_EXT.
6270 {
6271 auto info = lvl_init_struct<VkBufferCreateInfo>();
6272 // info.usage = VK_BUFFER_USAGE_TRANSFORM_FEEDBACK_COUNTER_BUFFER_BIT_EXT;
6273 info.size = 4;
6274 VkBufferObj const buffer_obj(*m_device, info);
6275
6276 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdEndTransformFeedbackEXT-pCounterBuffers-02380");
6277 vkCmdEndTransformFeedbackEXT(m_commandBuffer->handle(), 0, 1, &buffer_obj.handle(), nullptr);
6278 m_errorMonitor->VerifyFound();
6279 }
6280 }
6281
6282 // End while transform feedback is inactive.
6283 {
6284 vkCmdEndTransformFeedbackEXT(m_commandBuffer->handle(), 0, 1, nullptr, nullptr);
6285
6286 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdEndTransformFeedbackEXT-None-02375");
6287 vkCmdEndTransformFeedbackEXT(m_commandBuffer->handle(), 0, 1, nullptr, nullptr);
6288 m_errorMonitor->VerifyFound();
6289 }
6290}