blob: 048113a511105d190be194487db86037320cdfd7 [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
sfricke-samsungae9f00a2020-05-28 20:48:49 -0700742TEST_F(VkLayerTest, CommandBufferPrimaryFlags) {
743 ASSERT_NO_FATAL_FAILURE(Init());
744
745 // Calls AllocateCommandBuffers
746 VkCommandBufferObj commandBuffer(m_device, m_commandPool);
747
748 VkCommandBufferBeginInfo cmd_buf_info = {};
749 cmd_buf_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
750 cmd_buf_info.pNext = NULL;
751 cmd_buf_info.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT | VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT;
752
753 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkBeginCommandBuffer-commandBuffer-02840");
754 vk::BeginCommandBuffer(commandBuffer.handle(), &cmd_buf_info);
755 m_errorMonitor->VerifyFound();
756}
757
unknown088160a2019-05-23 17:43:13 -0600758TEST_F(VkLayerTest, ClearColorAttachmentsOutsideRenderPass) {
759 // Call CmdClearAttachmentss outside of an active RenderPass
760
Mark Lobodzinski20310782020-02-28 14:25:17 -0700761 m_errorMonitor->SetDesiredFailureMsg(kErrorBit,
unknown088160a2019-05-23 17:43:13 -0600762 "vkCmdClearAttachments(): This call must be issued inside an active render pass");
763
764 ASSERT_NO_FATAL_FAILURE(Init());
765 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
766
767 // Start no RenderPass
768 m_commandBuffer->begin();
769
770 VkClearAttachment color_attachment;
771 color_attachment.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
772 color_attachment.clearValue.color.float32[0] = 0;
773 color_attachment.clearValue.color.float32[1] = 0;
774 color_attachment.clearValue.color.float32[2] = 0;
775 color_attachment.clearValue.color.float32[3] = 0;
776 color_attachment.colorAttachment = 0;
Mark Lobodzinskid5447512019-06-28 09:56:36 -0600777 VkClearRect clear_rect = {{{0, 0}, {32, 32}}, 0, 1};
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -0600778 vk::CmdClearAttachments(m_commandBuffer->handle(), 1, &color_attachment, 1, &clear_rect);
unknown088160a2019-05-23 17:43:13 -0600779
780 m_errorMonitor->VerifyFound();
781}
782
Mark Lobodzinski7d7da062019-06-27 16:01:39 -0600783TEST_F(VkLayerTest, ClearColorAttachmentsZeroLayercount) {
784 TEST_DESCRIPTION("Call CmdClearAttachments with a pRect having a layerCount of zero.");
785
Mark Lobodzinski20310782020-02-28 14:25:17 -0700786 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdClearAttachments-layerCount-01934");
Mark Lobodzinski7d7da062019-06-27 16:01:39 -0600787
788 ASSERT_NO_FATAL_FAILURE(Init());
789 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
790
791 m_commandBuffer->begin();
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -0600792 vk::CmdBeginRenderPass(m_commandBuffer->handle(), &renderPassBeginInfo(), VK_SUBPASS_CONTENTS_INLINE);
Mark Lobodzinski7d7da062019-06-27 16:01:39 -0600793
794 VkClearAttachment color_attachment;
795 color_attachment.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
796 color_attachment.clearValue.color.float32[0] = 0;
797 color_attachment.clearValue.color.float32[1] = 0;
798 color_attachment.clearValue.color.float32[2] = 0;
799 color_attachment.clearValue.color.float32[3] = 0;
800 color_attachment.colorAttachment = 0;
801 VkClearRect clear_rect = {{{0, 0}, {32, 32}}};
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -0600802 vk::CmdClearAttachments(m_commandBuffer->handle(), 1, &color_attachment, 1, &clear_rect);
Mark Lobodzinski7d7da062019-06-27 16:01:39 -0600803
804 m_errorMonitor->VerifyFound();
805}
806
sfricke-samsungf0f3d8b2020-04-25 02:20:47 -0700807TEST_F(VkLayerTest, ClearColorAttachmentsZeroExtent) {
808 TEST_DESCRIPTION("Call CmdClearAttachments with a pRect having a rect2D extent of zero.");
809
810 ASSERT_NO_FATAL_FAILURE(Init());
811 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
812
813 m_commandBuffer->begin();
814 vk::CmdBeginRenderPass(m_commandBuffer->handle(), &renderPassBeginInfo(), VK_SUBPASS_CONTENTS_INLINE);
815
816 VkClearAttachment color_attachment;
817 color_attachment.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
818 color_attachment.clearValue.color.float32[0] = 0;
819 color_attachment.clearValue.color.float32[1] = 0;
820 color_attachment.clearValue.color.float32[2] = 0;
821 color_attachment.clearValue.color.float32[3] = 0;
822 color_attachment.colorAttachment = 0;
823 VkClearRect clear_rect = {};
824 clear_rect.rect.offset = {0, 0};
825 clear_rect.baseArrayLayer = 0;
826 clear_rect.layerCount = 1;
827
828 clear_rect.rect.extent = {0, 1};
829 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdClearAttachments-rect-02682");
830 vk::CmdClearAttachments(m_commandBuffer->handle(), 1, &color_attachment, 1, &clear_rect);
831 m_errorMonitor->VerifyFound();
832
833 clear_rect.rect.extent = {1, 0};
834 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdClearAttachments-rect-02683");
835 vk::CmdClearAttachments(m_commandBuffer->handle(), 1, &color_attachment, 1, &clear_rect);
836 m_errorMonitor->VerifyFound();
837}
838
unknown088160a2019-05-23 17:43:13 -0600839TEST_F(VkLayerTest, ExecuteCommandsPrimaryCB) {
840 TEST_DESCRIPTION("Attempt vkCmdExecuteCommands with a primary command buffer (should only be secondary)");
841
842 ASSERT_NO_FATAL_FAILURE(Init());
843 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
844
845 // An empty primary command buffer
846 VkCommandBufferObj cb(m_device, m_commandPool);
847 cb.begin();
848 cb.end();
849
850 m_commandBuffer->begin();
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -0600851 vk::CmdBeginRenderPass(m_commandBuffer->handle(), &renderPassBeginInfo(), VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS);
unknown088160a2019-05-23 17:43:13 -0600852 VkCommandBuffer handle = cb.handle();
853
Mark Lobodzinski20310782020-02-28 14:25:17 -0700854 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdExecuteCommands-pCommandBuffers-00088");
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -0600855 vk::CmdExecuteCommands(m_commandBuffer->handle(), 1, &handle);
unknown088160a2019-05-23 17:43:13 -0600856 m_errorMonitor->VerifyFound();
857
858 m_errorMonitor->SetUnexpectedError("All elements of pCommandBuffers must not be in the pending state");
859
860 m_commandBuffer->EndRenderPass();
861 m_commandBuffer->end();
862}
863
Petr Kraus8e53cf02020-01-03 05:30:04 +0100864TEST_F(VkLayerTest, ExecuteCommandsToSecondaryCB) {
865 TEST_DESCRIPTION("Attempt vkCmdExecuteCommands to a Secondary command buffer");
866
867 ASSERT_NO_FATAL_FAILURE(Init());
868
869 VkCommandBufferObj main_cb(m_device, m_commandPool, VK_COMMAND_BUFFER_LEVEL_SECONDARY);
870 VkCommandBufferObj secondary_cb(m_device, m_commandPool, VK_COMMAND_BUFFER_LEVEL_SECONDARY);
871 secondary_cb.begin();
872 secondary_cb.end();
873
874 main_cb.begin();
Mark Lobodzinski20310782020-02-28 14:25:17 -0700875 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdExecuteCommands-bufferlevel");
Petr Kraus8e53cf02020-01-03 05:30:04 +0100876 vk::CmdExecuteCommands(main_cb.handle(), 1, &secondary_cb.handle());
877 m_errorMonitor->VerifyFound();
878}
879
unknown088160a2019-05-23 17:43:13 -0600880TEST_F(VkLayerTest, InvalidVertexAttributeAlignment) {
881 TEST_DESCRIPTION("Check for proper aligment of attribAddress which depends on a bound pipeline and on a bound vertex buffer");
882
883 ASSERT_NO_FATAL_FAILURE(Init());
884 ASSERT_NO_FATAL_FAILURE(InitViewport());
885 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
886
887 const VkPipelineLayoutObj pipeline_layout(m_device);
888
889 struct VboEntry {
890 uint16_t input0[2];
891 uint32_t input1;
892 float input2[4];
893 };
894
895 const unsigned vbo_entry_count = 3;
896 const VboEntry vbo_data[vbo_entry_count] = {};
897
898 VkConstantBufferObj vbo(m_device, static_cast<int>(sizeof(VboEntry) * vbo_entry_count),
899 reinterpret_cast<const void *>(vbo_data), VK_BUFFER_USAGE_VERTEX_BUFFER_BIT);
900
901 VkVertexInputBindingDescription input_binding;
902 input_binding.binding = 0;
903 input_binding.stride = sizeof(VboEntry);
904 input_binding.inputRate = VK_VERTEX_INPUT_RATE_VERTEX;
905
906 VkVertexInputAttributeDescription input_attribs[3];
907
908 input_attribs[0].binding = 0;
909 // Location switch between attrib[0] and attrib[1] is intentional
910 input_attribs[0].location = 1;
911 input_attribs[0].format = VK_FORMAT_A8B8G8R8_UNORM_PACK32;
912 input_attribs[0].offset = offsetof(VboEntry, input1);
913
914 input_attribs[1].binding = 0;
915 input_attribs[1].location = 0;
916 input_attribs[1].format = VK_FORMAT_R16G16_UNORM;
917 input_attribs[1].offset = offsetof(VboEntry, input0);
918
919 input_attribs[2].binding = 0;
920 input_attribs[2].location = 2;
921 input_attribs[2].format = VK_FORMAT_R32G32B32A32_SFLOAT;
922 input_attribs[2].offset = offsetof(VboEntry, input2);
923
924 char const *vsSource =
925 "#version 450\n"
926 "\n"
927 "layout(location = 0) in vec2 input0;"
928 "layout(location = 1) in vec4 input1;"
929 "layout(location = 2) in vec4 input2;"
930 "\n"
931 "void main(){\n"
932 " gl_Position = input1 + input2;\n"
933 " gl_Position.xy += input0;\n"
934 "}\n";
unknown088160a2019-05-23 17:43:13 -0600935
936 VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
locke-lunarg8e2c91b2019-06-11 17:53:26 -0600937 VkShaderObj fs(m_device, bindStateFragShaderText, VK_SHADER_STAGE_FRAGMENT_BIT, this);
unknown088160a2019-05-23 17:43:13 -0600938
939 VkPipelineObj pipe1(m_device);
940 pipe1.AddDefaultColorAttachment();
941 pipe1.AddShader(&vs);
942 pipe1.AddShader(&fs);
943 pipe1.AddVertexInputBindings(&input_binding, 1);
944 pipe1.AddVertexInputAttribs(&input_attribs[0], 3);
945 pipe1.SetViewport(m_viewports);
946 pipe1.SetScissor(m_scissors);
947 pipe1.CreateVKPipeline(pipeline_layout.handle(), renderPass());
948
949 input_binding.stride = 6;
950
951 VkPipelineObj pipe2(m_device);
952 pipe2.AddDefaultColorAttachment();
953 pipe2.AddShader(&vs);
954 pipe2.AddShader(&fs);
955 pipe2.AddVertexInputBindings(&input_binding, 1);
956 pipe2.AddVertexInputAttribs(&input_attribs[0], 3);
957 pipe2.SetViewport(m_viewports);
958 pipe2.SetScissor(m_scissors);
959 pipe2.CreateVKPipeline(pipeline_layout.handle(), renderPass());
960
961 m_commandBuffer->begin();
962 m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
963
964 // Test with invalid buffer offset
965 VkDeviceSize offset = 1;
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -0600966 vk::CmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe1.handle());
967 vk::CmdBindVertexBuffers(m_commandBuffer->handle(), 0, 1, &vbo.handle(), &offset);
Mark Lobodzinski20310782020-02-28 14:25:17 -0700968 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "Invalid attribAddress alignment for vertex attribute 0");
969 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "Invalid attribAddress alignment for vertex attribute 1");
970 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "Invalid attribAddress alignment for vertex attribute 2");
unknown088160a2019-05-23 17:43:13 -0600971 m_commandBuffer->Draw(1, 0, 0, 0);
972 m_errorMonitor->VerifyFound();
973
974 // Test with invalid buffer stride
975 offset = 0;
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -0600976 vk::CmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe2.handle());
977 vk::CmdBindVertexBuffers(m_commandBuffer->handle(), 0, 1, &vbo.handle(), &offset);
Mark Lobodzinski20310782020-02-28 14:25:17 -0700978 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "Invalid attribAddress alignment for vertex attribute 0");
unknown088160a2019-05-23 17:43:13 -0600979 // Attribute[1] is aligned properly even with a wrong stride
Mark Lobodzinski20310782020-02-28 14:25:17 -0700980 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "Invalid attribAddress alignment for vertex attribute 2");
unknown088160a2019-05-23 17:43:13 -0600981 m_commandBuffer->Draw(1, 0, 0, 0);
982 m_errorMonitor->VerifyFound();
983
984 m_commandBuffer->EndRenderPass();
985 m_commandBuffer->end();
986}
987
988TEST_F(VkLayerTest, NonSimultaneousSecondaryMarksPrimary) {
989 ASSERT_NO_FATAL_FAILURE(Init());
locke-lunarg77b9f7c2019-06-18 00:06:03 -0600990 const char *simultaneous_use_message = "UNASSIGNED-CoreValidation-DrawState-InvalidCommandBufferSimultaneousUse";
unknown088160a2019-05-23 17:43:13 -0600991
992 VkCommandBufferObj secondary(m_device, m_commandPool, VK_COMMAND_BUFFER_LEVEL_SECONDARY);
993
994 secondary.begin();
995 secondary.end();
996
997 VkCommandBufferBeginInfo cbbi = {
998 VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,
999 nullptr,
1000 VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT,
1001 nullptr,
1002 };
1003
1004 m_commandBuffer->begin(&cbbi);
Mark Lobodzinski20310782020-02-28 14:25:17 -07001005 m_errorMonitor->SetDesiredFailureMsg(kWarningBit, simultaneous_use_message);
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06001006 vk::CmdExecuteCommands(m_commandBuffer->handle(), 1, &secondary.handle());
unknown088160a2019-05-23 17:43:13 -06001007 m_errorMonitor->VerifyFound();
1008 m_commandBuffer->end();
1009}
1010
1011TEST_F(VkLayerTest, SimultaneousUseSecondaryTwoExecutes) {
1012 ASSERT_NO_FATAL_FAILURE(Init());
1013
John Zulauff1640d12019-08-13 15:39:58 -06001014 const char *simultaneous_use_message = "VUID-vkCmdExecuteCommands-pCommandBuffers-00092";
unknown088160a2019-05-23 17:43:13 -06001015
1016 VkCommandBufferObj secondary(m_device, m_commandPool, VK_COMMAND_BUFFER_LEVEL_SECONDARY);
1017
1018 VkCommandBufferInheritanceInfo inh = {
1019 VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO,
1020 nullptr,
1021 };
1022 VkCommandBufferBeginInfo cbbi = {VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, nullptr, 0, &inh};
1023
1024 secondary.begin(&cbbi);
1025 secondary.end();
1026
1027 m_commandBuffer->begin();
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06001028 vk::CmdExecuteCommands(m_commandBuffer->handle(), 1, &secondary.handle());
Mark Lobodzinski20310782020-02-28 14:25:17 -07001029 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, simultaneous_use_message);
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06001030 vk::CmdExecuteCommands(m_commandBuffer->handle(), 1, &secondary.handle());
unknown088160a2019-05-23 17:43:13 -06001031 m_errorMonitor->VerifyFound();
1032 m_commandBuffer->end();
1033}
1034
1035TEST_F(VkLayerTest, SimultaneousUseSecondarySingleExecute) {
1036 ASSERT_NO_FATAL_FAILURE(Init());
1037
1038 // variation on previous test executing the same CB twice in the same
1039 // CmdExecuteCommands call
1040
John Zulauff1640d12019-08-13 15:39:58 -06001041 const char *simultaneous_use_message = "VUID-vkCmdExecuteCommands-pCommandBuffers-00093";
unknown088160a2019-05-23 17:43:13 -06001042
1043 VkCommandBufferObj secondary(m_device, m_commandPool, VK_COMMAND_BUFFER_LEVEL_SECONDARY);
1044
1045 VkCommandBufferInheritanceInfo inh = {
1046 VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO,
1047 nullptr,
1048 };
1049 VkCommandBufferBeginInfo cbbi = {VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, nullptr, 0, &inh};
1050
1051 secondary.begin(&cbbi);
1052 secondary.end();
1053
1054 m_commandBuffer->begin();
1055 VkCommandBuffer cbs[] = {secondary.handle(), secondary.handle()};
Mark Lobodzinski20310782020-02-28 14:25:17 -07001056 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, simultaneous_use_message);
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06001057 vk::CmdExecuteCommands(m_commandBuffer->handle(), 2, cbs);
unknown088160a2019-05-23 17:43:13 -06001058 m_errorMonitor->VerifyFound();
1059 m_commandBuffer->end();
1060}
1061
1062TEST_F(VkLayerTest, SimultaneousUseOneShot) {
1063 TEST_DESCRIPTION("Submit the same command buffer twice in one submit looking for simultaneous use and one time submit errors");
1064 const char *simultaneous_use_message = "is already in use and is not marked for simultaneous use";
1065 const char *one_shot_message = "VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT set, but has been submitted";
1066 ASSERT_NO_FATAL_FAILURE(Init());
1067
1068 VkCommandBuffer cmd_bufs[2];
1069 VkCommandBufferAllocateInfo alloc_info;
1070 alloc_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
1071 alloc_info.pNext = NULL;
1072 alloc_info.commandBufferCount = 2;
1073 alloc_info.commandPool = m_commandPool->handle();
1074 alloc_info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06001075 vk::AllocateCommandBuffers(m_device->device(), &alloc_info, cmd_bufs);
unknown088160a2019-05-23 17:43:13 -06001076
1077 VkCommandBufferBeginInfo cb_binfo;
1078 cb_binfo.pNext = NULL;
1079 cb_binfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
1080 cb_binfo.pInheritanceInfo = VK_NULL_HANDLE;
1081 cb_binfo.flags = 0;
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06001082 vk::BeginCommandBuffer(cmd_bufs[0], &cb_binfo);
unknown088160a2019-05-23 17:43:13 -06001083 VkViewport viewport = {0, 0, 16, 16, 0, 1};
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06001084 vk::CmdSetViewport(cmd_bufs[0], 0, 1, &viewport);
1085 vk::EndCommandBuffer(cmd_bufs[0]);
unknown088160a2019-05-23 17:43:13 -06001086 VkCommandBuffer duplicates[2] = {cmd_bufs[0], cmd_bufs[0]};
1087
1088 VkSubmitInfo submit_info = {};
1089 submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
1090 submit_info.commandBufferCount = 2;
1091 submit_info.pCommandBuffers = duplicates;
Mark Lobodzinski20310782020-02-28 14:25:17 -07001092 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, simultaneous_use_message);
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06001093 vk::QueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
unknown088160a2019-05-23 17:43:13 -06001094 m_errorMonitor->VerifyFound();
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06001095 vk::QueueWaitIdle(m_device->m_queue);
unknown088160a2019-05-23 17:43:13 -06001096
1097 // Set one time use and now look for one time submit
1098 duplicates[0] = duplicates[1] = cmd_bufs[1];
1099 cb_binfo.flags = VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT | VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT;
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06001100 vk::BeginCommandBuffer(cmd_bufs[1], &cb_binfo);
1101 vk::CmdSetViewport(cmd_bufs[1], 0, 1, &viewport);
1102 vk::EndCommandBuffer(cmd_bufs[1]);
Mark Lobodzinski20310782020-02-28 14:25:17 -07001103 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, one_shot_message);
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06001104 vk::QueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
unknown088160a2019-05-23 17:43:13 -06001105 m_errorMonitor->VerifyFound();
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06001106 vk::QueueWaitIdle(m_device->m_queue);
unknown088160a2019-05-23 17:43:13 -06001107}
1108
1109TEST_F(VkLayerTest, DrawTimeImageViewTypeMismatchWithPipeline) {
1110 TEST_DESCRIPTION(
1111 "Test that an error is produced when an image view type does not match the dimensionality declared in the shader");
1112
Mark Lobodzinski20310782020-02-28 14:25:17 -07001113 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "requires an image view of type VK_IMAGE_VIEW_TYPE_3D");
unknown088160a2019-05-23 17:43:13 -06001114
1115 ASSERT_NO_FATAL_FAILURE(Init());
1116 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
1117
unknown088160a2019-05-23 17:43:13 -06001118 char const *fsSource =
1119 "#version 450\n"
1120 "\n"
1121 "layout(set=0, binding=0) uniform sampler3D s;\n"
1122 "layout(location=0) out vec4 color;\n"
1123 "void main() {\n"
1124 " color = texture(s, vec3(0));\n"
1125 "}\n";
locke-lunarg8e2c91b2019-06-11 17:53:26 -06001126 VkShaderObj vs(m_device, bindStateVertShaderText, VK_SHADER_STAGE_VERTEX_BIT, this);
unknown088160a2019-05-23 17:43:13 -06001127 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
1128
1129 VkPipelineObj pipe(m_device);
1130 pipe.AddShader(&vs);
1131 pipe.AddShader(&fs);
1132 pipe.AddDefaultColorAttachment();
1133
1134 VkTextureObj texture(m_device, nullptr);
1135 VkSamplerObj sampler(m_device);
1136
1137 VkDescriptorSetObj descriptorSet(m_device);
1138 descriptorSet.AppendSamplerTexture(&sampler, &texture);
1139 descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
1140
1141 VkResult err = pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass());
1142 ASSERT_VK_SUCCESS(err);
1143
1144 m_commandBuffer->begin();
1145 m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
1146
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06001147 vk::CmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.handle());
unknown088160a2019-05-23 17:43:13 -06001148 m_commandBuffer->BindDescriptorSet(descriptorSet);
1149
1150 VkViewport viewport = {0, 0, 16, 16, 0, 1};
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06001151 vk::CmdSetViewport(m_commandBuffer->handle(), 0, 1, &viewport);
unknown088160a2019-05-23 17:43:13 -06001152 VkRect2D scissor = {{0, 0}, {16, 16}};
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06001153 vk::CmdSetScissor(m_commandBuffer->handle(), 0, 1, &scissor);
unknown088160a2019-05-23 17:43:13 -06001154
1155 // error produced here.
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06001156 vk::CmdDraw(m_commandBuffer->handle(), 3, 1, 0, 0);
unknown088160a2019-05-23 17:43:13 -06001157
1158 m_errorMonitor->VerifyFound();
1159
1160 m_commandBuffer->EndRenderPass();
1161 m_commandBuffer->end();
1162}
1163
1164TEST_F(VkLayerTest, DrawTimeImageMultisampleMismatchWithPipeline) {
1165 TEST_DESCRIPTION(
1166 "Test that an error is produced when a multisampled images are consumed via singlesample images types in the shader, or "
1167 "vice versa.");
1168
Mark Lobodzinski20310782020-02-28 14:25:17 -07001169 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "requires bound image to have multiple samples");
unknown088160a2019-05-23 17:43:13 -06001170
1171 ASSERT_NO_FATAL_FAILURE(Init());
1172 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
1173
unknown088160a2019-05-23 17:43:13 -06001174 char const *fsSource =
1175 "#version 450\n"
1176 "\n"
1177 "layout(set=0, binding=0) uniform sampler2DMS s;\n"
1178 "layout(location=0) out vec4 color;\n"
1179 "void main() {\n"
1180 " color = texelFetch(s, ivec2(0), 0);\n"
1181 "}\n";
locke-lunarg8e2c91b2019-06-11 17:53:26 -06001182 VkShaderObj vs(m_device, bindStateVertShaderText, VK_SHADER_STAGE_VERTEX_BIT, this);
unknown088160a2019-05-23 17:43:13 -06001183 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
1184
1185 VkPipelineObj pipe(m_device);
1186 pipe.AddShader(&vs);
1187 pipe.AddShader(&fs);
1188 pipe.AddDefaultColorAttachment();
1189
1190 VkTextureObj texture(m_device, nullptr); // THIS LINE CAUSES CRASH ON MALI
1191 VkSamplerObj sampler(m_device);
1192
1193 VkDescriptorSetObj descriptorSet(m_device);
1194 descriptorSet.AppendSamplerTexture(&sampler, &texture);
1195 descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
1196
1197 VkResult err = pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass());
1198 ASSERT_VK_SUCCESS(err);
1199
1200 m_commandBuffer->begin();
1201 m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
1202
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06001203 vk::CmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.handle());
unknown088160a2019-05-23 17:43:13 -06001204 m_commandBuffer->BindDescriptorSet(descriptorSet);
1205
1206 VkViewport viewport = {0, 0, 16, 16, 0, 1};
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06001207 vk::CmdSetViewport(m_commandBuffer->handle(), 0, 1, &viewport);
unknown088160a2019-05-23 17:43:13 -06001208 VkRect2D scissor = {{0, 0}, {16, 16}};
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06001209 vk::CmdSetScissor(m_commandBuffer->handle(), 0, 1, &scissor);
unknown088160a2019-05-23 17:43:13 -06001210
1211 // error produced here.
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06001212 vk::CmdDraw(m_commandBuffer->handle(), 3, 1, 0, 0);
unknown088160a2019-05-23 17:43:13 -06001213
1214 m_errorMonitor->VerifyFound();
1215
1216 m_commandBuffer->EndRenderPass();
1217 m_commandBuffer->end();
1218}
1219
1220TEST_F(VkLayerTest, DrawTimeImageComponentTypeMismatchWithPipeline) {
1221 TEST_DESCRIPTION(
1222 "Test that an error is produced when the component type of an imageview disagrees with the type in the shader.");
1223
Mark Lobodzinski20310782020-02-28 14:25:17 -07001224 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "SINT component type, but bound descriptor");
unknown088160a2019-05-23 17:43:13 -06001225
1226 ASSERT_NO_FATAL_FAILURE(Init());
1227 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
1228
unknown088160a2019-05-23 17:43:13 -06001229 char const *fsSource =
1230 "#version 450\n"
1231 "\n"
1232 "layout(set=0, binding=0) uniform isampler2D s;\n"
1233 "layout(location=0) out vec4 color;\n"
1234 "void main() {\n"
1235 " color = texelFetch(s, ivec2(0), 0);\n"
1236 "}\n";
locke-lunarg8e2c91b2019-06-11 17:53:26 -06001237 VkShaderObj vs(m_device, bindStateVertShaderText, VK_SHADER_STAGE_VERTEX_BIT, this);
unknown088160a2019-05-23 17:43:13 -06001238 VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
1239
1240 VkPipelineObj pipe(m_device);
1241 pipe.AddShader(&vs);
1242 pipe.AddShader(&fs);
1243 pipe.AddDefaultColorAttachment();
1244
1245 VkTextureObj texture(m_device, nullptr); // UNORM texture by default, incompatible with isampler2D
1246 VkSamplerObj sampler(m_device);
1247
1248 VkDescriptorSetObj descriptorSet(m_device);
1249 descriptorSet.AppendSamplerTexture(&sampler, &texture);
1250 descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
1251
1252 VkResult err = pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass());
1253 ASSERT_VK_SUCCESS(err);
1254
1255 m_commandBuffer->begin();
1256 m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
1257
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06001258 vk::CmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.handle());
unknown088160a2019-05-23 17:43:13 -06001259 m_commandBuffer->BindDescriptorSet(descriptorSet);
1260
1261 VkViewport viewport = {0, 0, 16, 16, 0, 1};
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06001262 vk::CmdSetViewport(m_commandBuffer->handle(), 0, 1, &viewport);
unknown088160a2019-05-23 17:43:13 -06001263 VkRect2D scissor = {{0, 0}, {16, 16}};
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06001264 vk::CmdSetScissor(m_commandBuffer->handle(), 0, 1, &scissor);
unknown088160a2019-05-23 17:43:13 -06001265
1266 // error produced here.
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06001267 vk::CmdDraw(m_commandBuffer->handle(), 3, 1, 0, 0);
unknown088160a2019-05-23 17:43:13 -06001268
1269 m_errorMonitor->VerifyFound();
1270
1271 m_commandBuffer->EndRenderPass();
1272 m_commandBuffer->end();
1273}
1274
unknown088160a2019-05-23 17:43:13 -06001275TEST_F(VkLayerTest, CopyImageLayerCountMismatch) {
1276 TEST_DESCRIPTION(
1277 "Try to copy between images with the source subresource having a different layerCount than the destination subresource");
1278 ASSERT_NO_FATAL_FAILURE(Init());
1279
1280 // Create two images to copy between
1281 VkImageObj src_image_obj(m_device);
1282 VkImageObj dst_image_obj(m_device);
1283
1284 VkImageCreateInfo image_create_info = {};
1285 image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
1286 image_create_info.pNext = NULL;
1287 image_create_info.imageType = VK_IMAGE_TYPE_2D;
1288 image_create_info.format = VK_FORMAT_B8G8R8A8_UNORM;
1289 image_create_info.extent.width = 32;
1290 image_create_info.extent.height = 32;
1291 image_create_info.extent.depth = 1;
1292 image_create_info.mipLevels = 1;
1293 image_create_info.arrayLayers = 4;
1294 image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
1295 image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL;
1296 image_create_info.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
1297 image_create_info.flags = 0;
1298
1299 src_image_obj.init(&image_create_info);
1300 ASSERT_TRUE(src_image_obj.initialized());
1301
1302 image_create_info.usage = VK_IMAGE_USAGE_TRANSFER_DST_BIT;
1303 dst_image_obj.init(&image_create_info);
1304 ASSERT_TRUE(dst_image_obj.initialized());
1305
1306 m_commandBuffer->begin();
1307 VkImageCopy copyRegion;
1308 copyRegion.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
1309 copyRegion.srcSubresource.mipLevel = 0;
1310 copyRegion.srcSubresource.baseArrayLayer = 0;
1311 copyRegion.srcSubresource.layerCount = 1;
1312 copyRegion.srcOffset.x = 0;
1313 copyRegion.srcOffset.y = 0;
1314 copyRegion.srcOffset.z = 0;
1315 copyRegion.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
1316 copyRegion.dstSubresource.mipLevel = 0;
1317 copyRegion.dstSubresource.baseArrayLayer = 0;
1318 // Introduce failure by forcing the dst layerCount to differ from src
1319 copyRegion.dstSubresource.layerCount = 3;
1320 copyRegion.dstOffset.x = 0;
1321 copyRegion.dstOffset.y = 0;
1322 copyRegion.dstOffset.z = 0;
1323 copyRegion.extent.width = 1;
1324 copyRegion.extent.height = 1;
1325 copyRegion.extent.depth = 1;
1326
Mark Lobodzinski20310782020-02-28 14:25:17 -07001327 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkImageCopy-extent-00140");
unknown088160a2019-05-23 17:43:13 -06001328 m_commandBuffer->CopyImage(src_image_obj.image(), VK_IMAGE_LAYOUT_GENERAL, dst_image_obj.image(), VK_IMAGE_LAYOUT_GENERAL, 1,
1329 &copyRegion);
1330 m_errorMonitor->VerifyFound();
1331}
1332
1333TEST_F(VkLayerTest, CompressedImageMipCopyTests) {
1334 TEST_DESCRIPTION("Image/Buffer copies for higher mip levels");
1335
1336 ASSERT_NO_FATAL_FAILURE(Init());
1337
1338 VkPhysicalDeviceFeatures device_features = {};
1339 ASSERT_NO_FATAL_FAILURE(GetPhysicalDeviceFeatures(&device_features));
1340 VkFormat compressed_format = VK_FORMAT_UNDEFINED;
1341 if (device_features.textureCompressionBC) {
1342 compressed_format = VK_FORMAT_BC3_SRGB_BLOCK;
1343 } else if (device_features.textureCompressionETC2) {
1344 compressed_format = VK_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK;
1345 } else if (device_features.textureCompressionASTC_LDR) {
1346 compressed_format = VK_FORMAT_ASTC_4x4_UNORM_BLOCK;
1347 } else {
1348 printf("%s No compressed formats supported - CompressedImageMipCopyTests skipped.\n", kSkipPrefix);
1349 return;
1350 }
1351
1352 VkImageCreateInfo ci;
1353 ci.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
1354 ci.pNext = NULL;
1355 ci.flags = 0;
1356 ci.imageType = VK_IMAGE_TYPE_2D;
1357 ci.format = compressed_format;
1358 ci.extent = {32, 32, 1};
1359 ci.mipLevels = 6;
1360 ci.arrayLayers = 1;
1361 ci.samples = VK_SAMPLE_COUNT_1_BIT;
1362 ci.tiling = VK_IMAGE_TILING_OPTIMAL;
1363 ci.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
1364 ci.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
1365 ci.queueFamilyIndexCount = 0;
1366 ci.pQueueFamilyIndices = NULL;
1367 ci.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
1368
1369 VkImageObj image(m_device);
1370 image.init(&ci);
1371 ASSERT_TRUE(image.initialized());
1372
1373 VkImageObj odd_image(m_device);
1374 ci.extent = {31, 32, 1}; // Mips are [31,32] [15,16] [7,8] [3,4], [1,2] [1,1]
1375 odd_image.init(&ci);
1376 ASSERT_TRUE(odd_image.initialized());
1377
1378 // Allocate buffers
1379 VkMemoryPropertyFlags reqs = 0;
1380 VkBufferObj buffer_1024, buffer_64, buffer_16, buffer_8;
1381 buffer_1024.init_as_src_and_dst(*m_device, 1024, reqs);
1382 buffer_64.init_as_src_and_dst(*m_device, 64, reqs);
1383 buffer_16.init_as_src_and_dst(*m_device, 16, reqs);
1384 buffer_8.init_as_src_and_dst(*m_device, 8, reqs);
1385
1386 VkBufferImageCopy region = {};
1387 region.bufferRowLength = 0;
1388 region.bufferImageHeight = 0;
1389 region.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
1390 region.imageSubresource.layerCount = 1;
1391 region.imageOffset = {0, 0, 0};
1392 region.bufferOffset = 0;
1393
1394 // start recording
1395 m_commandBuffer->begin();
1396
1397 // Mip level copies that work - 5 levels
1398 m_errorMonitor->ExpectSuccess();
1399
1400 // Mip 0 should fit in 1k buffer - 1k texels @ 1b each
1401 region.imageExtent = {32, 32, 1};
1402 region.imageSubresource.mipLevel = 0;
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06001403 vk::CmdCopyImageToBuffer(m_commandBuffer->handle(), image.handle(), VK_IMAGE_LAYOUT_GENERAL, buffer_1024.handle(), 1, &region);
1404 vk::CmdCopyBufferToImage(m_commandBuffer->handle(), buffer_1024.handle(), image.handle(), VK_IMAGE_LAYOUT_GENERAL, 1, &region);
unknown088160a2019-05-23 17:43:13 -06001405
1406 // Mip 2 should fit in 64b buffer - 64 texels @ 1b each
1407 region.imageExtent = {8, 8, 1};
1408 region.imageSubresource.mipLevel = 2;
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06001409 vk::CmdCopyImageToBuffer(m_commandBuffer->handle(), image.handle(), VK_IMAGE_LAYOUT_GENERAL, buffer_64.handle(), 1, &region);
1410 vk::CmdCopyBufferToImage(m_commandBuffer->handle(), buffer_64.handle(), image.handle(), VK_IMAGE_LAYOUT_GENERAL, 1, &region);
unknown088160a2019-05-23 17:43:13 -06001411
1412 // Mip 3 should fit in 16b buffer - 16 texels @ 1b each
1413 region.imageExtent = {4, 4, 1};
1414 region.imageSubresource.mipLevel = 3;
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06001415 vk::CmdCopyImageToBuffer(m_commandBuffer->handle(), image.handle(), VK_IMAGE_LAYOUT_GENERAL, buffer_16.handle(), 1, &region);
1416 vk::CmdCopyBufferToImage(m_commandBuffer->handle(), buffer_16.handle(), image.handle(), VK_IMAGE_LAYOUT_GENERAL, 1, &region);
unknown088160a2019-05-23 17:43:13 -06001417
1418 // Mip 4&5 should fit in 16b buffer with no complaint - 4 & 1 texels @ 1b each
1419 region.imageExtent = {2, 2, 1};
1420 region.imageSubresource.mipLevel = 4;
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06001421 vk::CmdCopyImageToBuffer(m_commandBuffer->handle(), image.handle(), VK_IMAGE_LAYOUT_GENERAL, buffer_16.handle(), 1, &region);
1422 vk::CmdCopyBufferToImage(m_commandBuffer->handle(), buffer_16.handle(), image.handle(), VK_IMAGE_LAYOUT_GENERAL, 1, &region);
unknown088160a2019-05-23 17:43:13 -06001423
1424 region.imageExtent = {1, 1, 1};
1425 region.imageSubresource.mipLevel = 5;
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06001426 vk::CmdCopyImageToBuffer(m_commandBuffer->handle(), image.handle(), VK_IMAGE_LAYOUT_GENERAL, buffer_16.handle(), 1, &region);
1427 vk::CmdCopyBufferToImage(m_commandBuffer->handle(), buffer_16.handle(), image.handle(), VK_IMAGE_LAYOUT_GENERAL, 1, &region);
unknown088160a2019-05-23 17:43:13 -06001428 m_errorMonitor->VerifyNotFound();
1429
1430 // Buffer must accommodate a full compressed block, regardless of texel count
Mark Lobodzinski20310782020-02-28 14:25:17 -07001431 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdCopyImageToBuffer-pRegions-00183");
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06001432 vk::CmdCopyImageToBuffer(m_commandBuffer->handle(), image.handle(), VK_IMAGE_LAYOUT_GENERAL, buffer_8.handle(), 1, &region);
unknown088160a2019-05-23 17:43:13 -06001433 m_errorMonitor->VerifyFound();
Mark Lobodzinski20310782020-02-28 14:25:17 -07001434 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdCopyBufferToImage-pRegions-00171");
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06001435 vk::CmdCopyBufferToImage(m_commandBuffer->handle(), buffer_8.handle(), image.handle(), VK_IMAGE_LAYOUT_GENERAL, 1, &region);
unknown088160a2019-05-23 17:43:13 -06001436 m_errorMonitor->VerifyFound();
1437
sfricke-samsung3a10b922020-05-13 23:23:16 -07001438 std::string vuid;
1439 bool ycbcr = (DeviceExtensionEnabled(VK_KHR_SAMPLER_YCBCR_CONVERSION_EXTENSION_NAME) ||
1440 (DeviceValidationVersion() >= VK_API_VERSION_1_1));
1441
unknown088160a2019-05-23 17:43:13 -06001442 // Copy width < compressed block size, but not the full mip width
1443 region.imageExtent = {1, 2, 1};
1444 region.imageSubresource.mipLevel = 4;
sfricke-samsung3a10b922020-05-13 23:23:16 -07001445 vuid = ycbcr ? "VUID-VkBufferImageCopy-None-01739" : "VUID-VkBufferImageCopy-imageExtent-00207";
1446 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, vuid); // width not a multiple of compressed block width
Mark Lobodzinski20310782020-02-28 14:25:17 -07001447 m_errorMonitor->SetDesiredFailureMsg(kErrorBit,
unknown088160a2019-05-23 17:43:13 -06001448 "VUID-vkCmdCopyImageToBuffer-imageOffset-01794"); // image transfer granularity
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06001449 vk::CmdCopyImageToBuffer(m_commandBuffer->handle(), image.handle(), VK_IMAGE_LAYOUT_GENERAL, buffer_16.handle(), 1, &region);
unknown088160a2019-05-23 17:43:13 -06001450 m_errorMonitor->VerifyFound();
sfricke-samsung3a10b922020-05-13 23:23:16 -07001451 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, vuid); // width not a multiple of compressed block width
Mark Lobodzinski20310782020-02-28 14:25:17 -07001452 m_errorMonitor->SetDesiredFailureMsg(kErrorBit,
unknown088160a2019-05-23 17:43:13 -06001453 "VUID-vkCmdCopyBufferToImage-imageOffset-01793"); // image transfer granularity
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06001454 vk::CmdCopyBufferToImage(m_commandBuffer->handle(), buffer_16.handle(), image.handle(), VK_IMAGE_LAYOUT_GENERAL, 1, &region);
unknown088160a2019-05-23 17:43:13 -06001455 m_errorMonitor->VerifyFound();
1456
1457 // Copy height < compressed block size but not the full mip height
1458 region.imageExtent = {2, 1, 1};
sfricke-samsung3a10b922020-05-13 23:23:16 -07001459 vuid = ycbcr ? "VUID-VkBufferImageCopy-None-01740" : "VUID-VkBufferImageCopy-imageExtent-00208";
1460 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, vuid); // height not a multiple of compressed block width
Mark Lobodzinski20310782020-02-28 14:25:17 -07001461 m_errorMonitor->SetDesiredFailureMsg(kErrorBit,
unknown088160a2019-05-23 17:43:13 -06001462 "VUID-vkCmdCopyImageToBuffer-imageOffset-01794"); // image transfer granularity
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06001463 vk::CmdCopyImageToBuffer(m_commandBuffer->handle(), image.handle(), VK_IMAGE_LAYOUT_GENERAL, buffer_16.handle(), 1, &region);
unknown088160a2019-05-23 17:43:13 -06001464 m_errorMonitor->VerifyFound();
sfricke-samsung3a10b922020-05-13 23:23:16 -07001465 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, vuid); // height not a multiple of compressed block width
Mark Lobodzinski20310782020-02-28 14:25:17 -07001466 m_errorMonitor->SetDesiredFailureMsg(kErrorBit,
unknown088160a2019-05-23 17:43:13 -06001467 "VUID-vkCmdCopyBufferToImage-imageOffset-01793"); // image transfer granularity
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06001468 vk::CmdCopyBufferToImage(m_commandBuffer->handle(), buffer_16.handle(), image.handle(), VK_IMAGE_LAYOUT_GENERAL, 1, &region);
unknown088160a2019-05-23 17:43:13 -06001469 m_errorMonitor->VerifyFound();
1470
1471 // Offsets must be multiple of compressed block size
1472 region.imageOffset = {1, 1, 0};
1473 region.imageExtent = {1, 1, 1};
sfricke-samsung3a10b922020-05-13 23:23:16 -07001474 vuid = ycbcr ? "VUID-VkBufferImageCopy-None-01737" : "VUID-VkBufferImageCopy-imageOffset-00205";
1475 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, vuid); // imageOffset not a multiple of block size
Mark Lobodzinski20310782020-02-28 14:25:17 -07001476 m_errorMonitor->SetDesiredFailureMsg(kErrorBit,
unknown088160a2019-05-23 17:43:13 -06001477 "VUID-vkCmdCopyImageToBuffer-imageOffset-01794"); // image transfer granularity
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06001478 vk::CmdCopyImageToBuffer(m_commandBuffer->handle(), image.handle(), VK_IMAGE_LAYOUT_GENERAL, buffer_16.handle(), 1, &region);
unknown088160a2019-05-23 17:43:13 -06001479 m_errorMonitor->VerifyFound();
sfricke-samsung3a10b922020-05-13 23:23:16 -07001480 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, vuid); // imageOffset not a multiple of block size
Mark Lobodzinski20310782020-02-28 14:25:17 -07001481 m_errorMonitor->SetDesiredFailureMsg(kErrorBit,
unknown088160a2019-05-23 17:43:13 -06001482 "VUID-vkCmdCopyBufferToImage-imageOffset-01793"); // image transfer granularity
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06001483 vk::CmdCopyBufferToImage(m_commandBuffer->handle(), buffer_16.handle(), image.handle(), VK_IMAGE_LAYOUT_GENERAL, 1, &region);
unknown088160a2019-05-23 17:43:13 -06001484 m_errorMonitor->VerifyFound();
1485
1486 // Offset + extent width = mip width - should succeed
1487 region.imageOffset = {4, 4, 0};
1488 region.imageExtent = {3, 4, 1};
1489 region.imageSubresource.mipLevel = 2;
1490 m_errorMonitor->ExpectSuccess();
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06001491 vk::CmdCopyImageToBuffer(m_commandBuffer->handle(), odd_image.handle(), VK_IMAGE_LAYOUT_GENERAL, buffer_16.handle(), 1,
1492 &region);
1493 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->VerifyNotFound();
1496
unknown088160a2019-05-23 17:43:13 -06001497 // Offset + extent width < mip width and not a multiple of block width - should fail
1498 region.imageExtent = {3, 3, 1};
sfricke-samsung3a10b922020-05-13 23:23:16 -07001499 vuid = ycbcr ? "VUID-VkBufferImageCopy-None-01740" : "VUID-VkBufferImageCopy-imageExtent-00208";
1500 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, vuid); // offset+extent not a multiple of block width
Mark Lobodzinski20310782020-02-28 14:25:17 -07001501 m_errorMonitor->SetDesiredFailureMsg(kErrorBit,
unknown088160a2019-05-23 17:43:13 -06001502 "VUID-vkCmdCopyImageToBuffer-imageOffset-01794"); // image transfer granularity
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06001503 vk::CmdCopyImageToBuffer(m_commandBuffer->handle(), odd_image.handle(), VK_IMAGE_LAYOUT_GENERAL, buffer_16.handle(), 1,
1504 &region);
unknown088160a2019-05-23 17:43:13 -06001505 m_errorMonitor->VerifyFound();
sfricke-samsung3a10b922020-05-13 23:23:16 -07001506 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, vuid); // offset+extent not a multiple of block width
Mark Lobodzinski20310782020-02-28 14:25:17 -07001507 m_errorMonitor->SetDesiredFailureMsg(kErrorBit,
unknown088160a2019-05-23 17:43:13 -06001508 "VUID-vkCmdCopyBufferToImage-imageOffset-01793"); // image transfer granularity
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06001509 vk::CmdCopyBufferToImage(m_commandBuffer->handle(), buffer_16.handle(), odd_image.handle(), VK_IMAGE_LAYOUT_GENERAL, 1,
1510 &region);
unknown088160a2019-05-23 17:43:13 -06001511 m_errorMonitor->VerifyFound();
1512}
1513
1514TEST_F(VkLayerTest, ImageBufferCopyTests) {
1515 TEST_DESCRIPTION("Image to buffer and buffer to image tests");
sfricke-samsung6d97e562020-01-07 22:01:00 -08001516
1517 // Enable KHR multiplane req'd extensions for multi-planar copy tests
1518 bool mp_extensions = InstanceExtensionSupported(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME,
1519 VK_KHR_GET_MEMORY_REQUIREMENTS_2_SPEC_VERSION);
1520 if (mp_extensions) {
1521 m_instance_extension_names.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
1522 }
Mark Lobodzinski09ce9c42020-03-06 10:02:44 -07001523 ASSERT_NO_FATAL_FAILURE(InitFramework(m_errorMonitor, nullptr));
sfricke-samsung6d97e562020-01-07 22:01:00 -08001524 mp_extensions = mp_extensions && DeviceExtensionSupported(gpu(), nullptr, VK_KHR_MAINTENANCE1_EXTENSION_NAME);
1525 mp_extensions = mp_extensions && DeviceExtensionSupported(gpu(), nullptr, VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME);
1526 mp_extensions = mp_extensions && DeviceExtensionSupported(gpu(), nullptr, VK_KHR_BIND_MEMORY_2_EXTENSION_NAME);
1527 mp_extensions = mp_extensions && DeviceExtensionSupported(gpu(), nullptr, VK_KHR_SAMPLER_YCBCR_CONVERSION_EXTENSION_NAME);
1528 if (mp_extensions) {
1529 m_device_extension_names.push_back(VK_KHR_MAINTENANCE1_EXTENSION_NAME);
1530 m_device_extension_names.push_back(VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME);
1531 m_device_extension_names.push_back(VK_KHR_BIND_MEMORY_2_EXTENSION_NAME);
1532 m_device_extension_names.push_back(VK_KHR_SAMPLER_YCBCR_CONVERSION_EXTENSION_NAME);
1533 }
1534 ASSERT_NO_FATAL_FAILURE(InitState());
unknown088160a2019-05-23 17:43:13 -06001535
1536 // Bail if any dimension of transfer granularity is 0.
1537 auto index = m_device->graphics_queue_node_index_;
1538 auto queue_family_properties = m_device->phy().queue_properties();
1539 if ((queue_family_properties[index].minImageTransferGranularity.depth == 0) ||
1540 (queue_family_properties[index].minImageTransferGranularity.width == 0) ||
1541 (queue_family_properties[index].minImageTransferGranularity.height == 0)) {
1542 printf("%s Subresource copies are disallowed when xfer granularity (x|y|z) is 0. Skipped.\n", kSkipPrefix);
1543 return;
1544 }
1545
sfricke-samsung6d97e562020-01-07 22:01:00 -08001546 // All VkImageObj must be defined here as if defined inside below scopes will cause image memory to be deleted when out of scope
1547 // 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 -07001548 VkImageObj image_64k(m_device); // 128^2 texels, 64k
1549 VkImageObj image_16k(m_device); // 64^2 texels, 16k
sfricke-samsung6d97e562020-01-07 22:01:00 -08001550 // depth stencil
unknown088160a2019-05-23 17:43:13 -06001551 VkImageObj image_16k_depth(m_device); // 64^2 texels, depth, 16k
1552 VkImageObj ds_image_4D_1S(m_device); // 256^2 texels, 512kb (256k depth, 64k stencil, 192k pack)
1553 VkImageObj ds_image_3D_1S(m_device); // 256^2 texels, 256kb (192k depth, 64k stencil)
1554 VkImageObj ds_image_2D(m_device); // 256^2 texels, 128k (128k depth)
1555 VkImageObj ds_image_1S(m_device); // 256^2 texels, 64k (64k stencil)
sfricke-samsung6d97e562020-01-07 22:01:00 -08001556 // compression
1557 VkImageObj image_16k_4x4comp(m_device); // 128^2 texels as 32^2 compressed (4x4) blocks, 16k
1558 VkImageObj image_NPOT_4x4comp(m_device); // 130^2 texels as 33^2 compressed (4x4) blocks
1559 // multi-planar
1560 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 -06001561
sfricke-samsung6d97e562020-01-07 22:01:00 -08001562 // Verify R8G8B8A8_UINT format is supported for transfer
1563 bool missing_rgba_support = false;
1564 VkFormatProperties props = {0, 0, 0};
1565 vk::GetPhysicalDeviceFormatProperties(m_device->phy().handle(), VK_FORMAT_R8G8B8A8_UINT, &props);
1566 missing_rgba_support |= (props.bufferFeatures == 0 && props.linearTilingFeatures == 0 && props.optimalTilingFeatures == 0);
1567 missing_rgba_support |= (props.optimalTilingFeatures & VK_FORMAT_FEATURE_TRANSFER_SRC_BIT) == 0;
1568 missing_rgba_support |= (props.optimalTilingFeatures & VK_FORMAT_FEATURE_TRANSFER_DST_BIT) == 0;
1569
1570 if (!missing_rgba_support) {
1571 image_64k.Init(128, 128, 1, VK_FORMAT_R8G8B8A8_UINT,
1572 VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT,
1573 VK_IMAGE_TILING_OPTIMAL, 0);
1574 ASSERT_TRUE(image_64k.initialized());
1575
1576 image_16k.Init(64, 64, 1, VK_FORMAT_R8G8B8A8_UINT,
1577 VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT,
1578 VK_IMAGE_TILING_OPTIMAL, 0);
1579 ASSERT_TRUE(image_16k.initialized());
1580 }
unknown088160a2019-05-23 17:43:13 -06001581
1582 // Verify all needed Depth/Stencil formats are supported
1583 bool missing_ds_support = false;
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06001584 vk::GetPhysicalDeviceFormatProperties(m_device->phy().handle(), VK_FORMAT_D32_SFLOAT_S8_UINT, &props);
unknown088160a2019-05-23 17:43:13 -06001585 missing_ds_support |= (props.bufferFeatures == 0 && props.linearTilingFeatures == 0 && props.optimalTilingFeatures == 0);
1586 missing_ds_support |= (props.optimalTilingFeatures & VK_FORMAT_FEATURE_TRANSFER_SRC_BIT) == 0;
1587 missing_ds_support |= (props.optimalTilingFeatures & VK_FORMAT_FEATURE_TRANSFER_DST_BIT) == 0;
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06001588 vk::GetPhysicalDeviceFormatProperties(m_device->phy().handle(), VK_FORMAT_D24_UNORM_S8_UINT, &props);
unknown088160a2019-05-23 17:43:13 -06001589 missing_ds_support |= (props.bufferFeatures == 0 && props.linearTilingFeatures == 0 && props.optimalTilingFeatures == 0);
1590 missing_ds_support |= (props.optimalTilingFeatures & VK_FORMAT_FEATURE_TRANSFER_SRC_BIT) == 0;
1591 missing_ds_support |= (props.optimalTilingFeatures & VK_FORMAT_FEATURE_TRANSFER_DST_BIT) == 0;
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06001592 vk::GetPhysicalDeviceFormatProperties(m_device->phy().handle(), VK_FORMAT_D16_UNORM, &props);
unknown088160a2019-05-23 17:43:13 -06001593 missing_ds_support |= (props.bufferFeatures == 0 && props.linearTilingFeatures == 0 && props.optimalTilingFeatures == 0);
1594 missing_ds_support |= (props.optimalTilingFeatures & VK_FORMAT_FEATURE_TRANSFER_SRC_BIT) == 0;
1595 missing_ds_support |= (props.optimalTilingFeatures & VK_FORMAT_FEATURE_TRANSFER_DST_BIT) == 0;
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06001596 vk::GetPhysicalDeviceFormatProperties(m_device->phy().handle(), VK_FORMAT_S8_UINT, &props);
unknown088160a2019-05-23 17:43:13 -06001597 missing_ds_support |= (props.bufferFeatures == 0 && props.linearTilingFeatures == 0 && props.optimalTilingFeatures == 0);
1598 missing_ds_support |= (props.optimalTilingFeatures & VK_FORMAT_FEATURE_TRANSFER_SRC_BIT) == 0;
1599 missing_ds_support |= (props.optimalTilingFeatures & VK_FORMAT_FEATURE_TRANSFER_DST_BIT) == 0;
1600
1601 if (!missing_ds_support) {
1602 image_16k_depth.Init(64, 64, 1, VK_FORMAT_D24_UNORM_S8_UINT,
1603 VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT, VK_IMAGE_TILING_OPTIMAL, 0);
1604 ASSERT_TRUE(image_16k_depth.initialized());
1605
1606 ds_image_4D_1S.Init(
1607 256, 256, 1, VK_FORMAT_D32_SFLOAT_S8_UINT,
1608 VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT,
1609 VK_IMAGE_TILING_OPTIMAL, 0);
1610 ASSERT_TRUE(ds_image_4D_1S.initialized());
1611
1612 ds_image_3D_1S.Init(
1613 256, 256, 1, VK_FORMAT_D24_UNORM_S8_UINT,
1614 VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT,
1615 VK_IMAGE_TILING_OPTIMAL, 0);
1616 ASSERT_TRUE(ds_image_3D_1S.initialized());
1617
1618 ds_image_2D.Init(
1619 256, 256, 1, VK_FORMAT_D16_UNORM,
1620 VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT,
1621 VK_IMAGE_TILING_OPTIMAL, 0);
1622 ASSERT_TRUE(ds_image_2D.initialized());
1623
1624 ds_image_1S.Init(
1625 256, 256, 1, VK_FORMAT_S8_UINT,
1626 VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT,
1627 VK_IMAGE_TILING_OPTIMAL, 0);
1628 ASSERT_TRUE(ds_image_1S.initialized());
1629 }
1630
1631 // Allocate buffers
1632 VkBufferObj buffer_256k, buffer_128k, buffer_64k, buffer_16k;
1633 VkMemoryPropertyFlags reqs = 0;
1634 buffer_256k.init_as_src_and_dst(*m_device, 262144, reqs); // 256k
1635 buffer_128k.init_as_src_and_dst(*m_device, 131072, reqs); // 128k
1636 buffer_64k.init_as_src_and_dst(*m_device, 65536, reqs); // 64k
1637 buffer_16k.init_as_src_and_dst(*m_device, 16384, reqs); // 16k
1638
1639 VkBufferImageCopy region = {};
1640 region.bufferRowLength = 0;
1641 region.bufferImageHeight = 0;
1642 region.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
1643 region.imageSubresource.layerCount = 1;
1644 region.imageOffset = {0, 0, 0};
1645 region.imageExtent = {64, 64, 1};
1646 region.bufferOffset = 0;
1647
sfricke-samsung6d97e562020-01-07 22:01:00 -08001648 if (missing_rgba_support) {
1649 printf("%s R8G8B8A8_UINT transfer unsupported - skipping RGBA tests.\n", kSkipPrefix);
unknown088160a2019-05-23 17:43:13 -06001650
sfricke-samsung6d97e562020-01-07 22:01:00 -08001651 // start recording for future tests
1652 m_commandBuffer->begin();
1653 } else {
1654 // attempt copies before putting command buffer in recording state
Mark Lobodzinski20310782020-02-28 14:25:17 -07001655 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdCopyBufferToImage-commandBuffer-recording");
sfricke-samsung6d97e562020-01-07 22:01:00 -08001656 vk::CmdCopyBufferToImage(m_commandBuffer->handle(), buffer_64k.handle(), image_64k.handle(), VK_IMAGE_LAYOUT_GENERAL, 1,
1657 &region);
unknown088160a2019-05-23 17:43:13 -06001658 m_errorMonitor->VerifyFound();
1659
Mark Lobodzinski20310782020-02-28 14:25:17 -07001660 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdCopyImageToBuffer-commandBuffer-recording");
sfricke-samsung6d97e562020-01-07 22:01:00 -08001661 vk::CmdCopyImageToBuffer(m_commandBuffer->handle(), image_64k.handle(), VK_IMAGE_LAYOUT_GENERAL, buffer_64k.handle(), 1,
1662 &region);
1663 m_errorMonitor->VerifyFound();
1664
1665 // start recording
1666 m_commandBuffer->begin();
1667
1668 // successful copies
1669 m_errorMonitor->ExpectSuccess();
1670 vk::CmdCopyImageToBuffer(m_commandBuffer->handle(), image_16k.handle(), VK_IMAGE_LAYOUT_GENERAL, buffer_16k.handle(), 1,
1671 &region);
1672 vk::CmdCopyBufferToImage(m_commandBuffer->handle(), buffer_16k.handle(), image_16k.handle(), VK_IMAGE_LAYOUT_GENERAL, 1,
1673 &region);
1674 region.imageOffset.x = 16; // 16k copy, offset requires larger image
1675 vk::CmdCopyImageToBuffer(m_commandBuffer->handle(), image_64k.handle(), VK_IMAGE_LAYOUT_GENERAL, buffer_16k.handle(), 1,
1676 &region);
1677 region.imageExtent.height = 78; // > 16k copy requires larger buffer & image
1678 vk::CmdCopyBufferToImage(m_commandBuffer->handle(), buffer_64k.handle(), image_64k.handle(), VK_IMAGE_LAYOUT_GENERAL, 1,
1679 &region);
1680 region.imageOffset.x = 0;
1681 region.imageExtent.height = 64;
1682 region.bufferOffset = 256; // 16k copy with buffer offset, requires larger buffer
1683 vk::CmdCopyImageToBuffer(m_commandBuffer->handle(), image_16k.handle(), VK_IMAGE_LAYOUT_GENERAL, buffer_64k.handle(), 1,
1684 &region);
1685 m_errorMonitor->VerifyNotFound();
1686
1687 // image/buffer too small (extent too large) on copy to image
1688 region.imageExtent = {65, 64, 1};
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");
Mark Lobodzinski20310782020-02-28 14:25:17 -07001696 m_errorMonitor->SetDesiredFailureMsg(kErrorBit,
sfricke-samsung6d97e562020-01-07 22:01:00 -08001697 "VUID-vkCmdCopyBufferToImage-pRegions-00172"); // image too small
1698 vk::CmdCopyBufferToImage(m_commandBuffer->handle(), buffer_64k.handle(), image_16k.handle(), VK_IMAGE_LAYOUT_GENERAL, 1,
1699 &region);
1700 m_errorMonitor->VerifyFound();
1701
1702 // image/buffer too small (offset) on copy to image
1703 region.imageExtent = {64, 64, 1};
1704 region.imageOffset = {0, 4, 0};
Mark Lobodzinski20310782020-02-28 14:25:17 -07001705 m_errorMonitor->SetDesiredFailureMsg(kErrorBit,
sfricke-samsung6d97e562020-01-07 22:01:00 -08001706 "VUID-vkCmdCopyBufferToImage-pRegions-00171"); // buffer too small
1707 vk::CmdCopyBufferToImage(m_commandBuffer->handle(), buffer_16k.handle(), image_64k.handle(), VK_IMAGE_LAYOUT_GENERAL, 1,
1708 &region);
1709 m_errorMonitor->VerifyFound();
1710
1711 m_errorMonitor->SetUnexpectedError("VUID-VkBufferImageCopy-imageOffset-00197");
1712 m_errorMonitor->SetUnexpectedError("VUID-VkBufferImageCopy-imageOffset-00198");
Mark Lobodzinski20310782020-02-28 14:25:17 -07001713 m_errorMonitor->SetDesiredFailureMsg(kErrorBit,
sfricke-samsung6d97e562020-01-07 22:01:00 -08001714 "VUID-vkCmdCopyBufferToImage-pRegions-00172"); // image too small
1715 vk::CmdCopyBufferToImage(m_commandBuffer->handle(), buffer_64k.handle(), image_16k.handle(), VK_IMAGE_LAYOUT_GENERAL, 1,
1716 &region);
1717 m_errorMonitor->VerifyFound();
1718
1719 // image/buffer too small on copy to buffer
1720 region.imageExtent = {64, 64, 1};
1721 region.imageOffset = {0, 0, 0};
1722 region.bufferOffset = 4;
Mark Lobodzinski20310782020-02-28 14:25:17 -07001723 m_errorMonitor->SetDesiredFailureMsg(kErrorBit,
sfricke-samsung6d97e562020-01-07 22:01:00 -08001724 "VUID-vkCmdCopyImageToBuffer-pRegions-00183"); // buffer too small
1725 vk::CmdCopyImageToBuffer(m_commandBuffer->handle(), image_64k.handle(), VK_IMAGE_LAYOUT_GENERAL, buffer_16k.handle(), 1,
1726 &region);
1727 m_errorMonitor->VerifyFound();
1728
1729 region.imageExtent = {64, 65, 1};
1730 region.bufferOffset = 0;
1731 m_errorMonitor->SetUnexpectedError("VUID-VkBufferImageCopy-imageOffset-00198");
Mark Lobodzinski20310782020-02-28 14:25:17 -07001732 m_errorMonitor->SetDesiredFailureMsg(kErrorBit,
sfricke-samsung6d97e562020-01-07 22:01:00 -08001733 "VUID-vkCmdCopyImageToBuffer-pRegions-00182"); // image too small
1734 vk::CmdCopyImageToBuffer(m_commandBuffer->handle(), image_16k.handle(), VK_IMAGE_LAYOUT_GENERAL, buffer_64k.handle(), 1,
1735 &region);
1736 m_errorMonitor->VerifyFound();
1737
1738 // buffer size OK but rowlength causes loose packing
Mark Lobodzinski20310782020-02-28 14:25:17 -07001739 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdCopyImageToBuffer-pRegions-00183");
sfricke-samsung6d97e562020-01-07 22:01:00 -08001740 region.imageExtent = {64, 64, 1};
1741 region.bufferRowLength = 68;
1742 vk::CmdCopyImageToBuffer(m_commandBuffer->handle(), image_16k.handle(), VK_IMAGE_LAYOUT_GENERAL, buffer_16k.handle(), 1,
1743 &region);
1744 m_errorMonitor->VerifyFound();
1745
1746 // An extent with zero area should produce a warning, but no error
Mark Lobodzinski20310782020-02-28 14:25:17 -07001747 m_errorMonitor->SetDesiredFailureMsg(kWarningBit | kErrorBit, "} has zero area");
sfricke-samsung6d97e562020-01-07 22:01:00 -08001748 region.imageExtent.width = 0;
1749 vk::CmdCopyImageToBuffer(m_commandBuffer->handle(), image_16k.handle(), VK_IMAGE_LAYOUT_GENERAL, buffer_16k.handle(), 1,
1750 &region);
1751 m_errorMonitor->VerifyFound();
1752
1753 // aspect bits
1754 region.imageExtent = {64, 64, 1};
1755 region.bufferRowLength = 0;
1756 region.bufferImageHeight = 0;
1757 if (!missing_ds_support) {
Mark Lobodzinski20310782020-02-28 14:25:17 -07001758 m_errorMonitor->SetDesiredFailureMsg(kErrorBit,
sfricke-samsung6d97e562020-01-07 22:01:00 -08001759 "VUID-VkBufferImageCopy-aspectMask-00212"); // more than 1 aspect bit set
1760 region.imageSubresource.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT;
1761 vk::CmdCopyImageToBuffer(m_commandBuffer->handle(), image_16k_depth.handle(), VK_IMAGE_LAYOUT_GENERAL,
1762 buffer_16k.handle(), 1, &region);
1763 m_errorMonitor->VerifyFound();
1764
Mark Lobodzinski20310782020-02-28 14:25:17 -07001765 m_errorMonitor->SetDesiredFailureMsg(kErrorBit,
sfricke-samsung6d97e562020-01-07 22:01:00 -08001766 "VUID-VkBufferImageCopy-aspectMask-00211"); // different mis-matched aspect
1767 region.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
1768 vk::CmdCopyImageToBuffer(m_commandBuffer->handle(), image_16k_depth.handle(), VK_IMAGE_LAYOUT_GENERAL,
1769 buffer_16k.handle(), 1, &region);
1770 m_errorMonitor->VerifyFound();
1771 }
1772
Mark Lobodzinski20310782020-02-28 14:25:17 -07001773 m_errorMonitor->SetDesiredFailureMsg(kErrorBit,
sfricke-samsung6d97e562020-01-07 22:01:00 -08001774 "VUID-VkBufferImageCopy-aspectMask-00211"); // mis-matched aspect
1775 region.imageSubresource.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT;
1776 vk::CmdCopyImageToBuffer(m_commandBuffer->handle(), image_16k.handle(), VK_IMAGE_LAYOUT_GENERAL, buffer_16k.handle(), 1,
1777 &region);
1778 m_errorMonitor->VerifyFound();
unknown088160a2019-05-23 17:43:13 -06001779 region.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
sfricke-samsung6d97e562020-01-07 22:01:00 -08001780
1781 // Out-of-range mip levels should fail
1782 region.imageSubresource.mipLevel = image_16k.create_info().mipLevels + 1;
Mark Lobodzinski20310782020-02-28 14:25:17 -07001783 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdCopyImageToBuffer-imageSubresource-01703");
sfricke-samsung6d97e562020-01-07 22:01:00 -08001784 m_errorMonitor->SetUnexpectedError("VUID-VkBufferImageCopy-imageOffset-00197");
1785 m_errorMonitor->SetUnexpectedError("VUID-VkBufferImageCopy-imageOffset-00198");
1786 m_errorMonitor->SetUnexpectedError("VUID-VkBufferImageCopy-imageOffset-00200");
1787 m_errorMonitor->SetDesiredFailureMsg(
Mark Lobodzinski20310782020-02-28 14:25:17 -07001788 kErrorBit,
sfricke-samsung6d97e562020-01-07 22:01:00 -08001789 "VUID-vkCmdCopyImageToBuffer-pRegions-00182"); // unavoidable "region exceeds image bounds" for non-existent mip
1790 vk::CmdCopyImageToBuffer(m_commandBuffer->handle(), image_16k.handle(), VK_IMAGE_LAYOUT_GENERAL, buffer_16k.handle(), 1,
1791 &region);
1792 m_errorMonitor->VerifyFound();
Mark Lobodzinski20310782020-02-28 14:25:17 -07001793 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdCopyBufferToImage-imageSubresource-01701");
sfricke-samsung6d97e562020-01-07 22:01:00 -08001794 m_errorMonitor->SetUnexpectedError("VUID-VkBufferImageCopy-imageOffset-00197");
1795 m_errorMonitor->SetUnexpectedError("VUID-VkBufferImageCopy-imageOffset-00198");
1796 m_errorMonitor->SetUnexpectedError("VUID-VkBufferImageCopy-imageOffset-00200");
1797 m_errorMonitor->SetDesiredFailureMsg(
Mark Lobodzinski20310782020-02-28 14:25:17 -07001798 kErrorBit,
sfricke-samsung6d97e562020-01-07 22:01:00 -08001799 "VUID-vkCmdCopyBufferToImage-pRegions-00172"); // unavoidable "region exceeds image bounds" for non-existent mip
1800 vk::CmdCopyBufferToImage(m_commandBuffer->handle(), buffer_16k.handle(), image_16k.handle(), VK_IMAGE_LAYOUT_GENERAL, 1,
1801 &region);
1802 m_errorMonitor->VerifyFound();
1803 region.imageSubresource.mipLevel = 0;
1804
1805 // Out-of-range array layers should fail
1806 region.imageSubresource.baseArrayLayer = image_16k.create_info().arrayLayers;
1807 region.imageSubresource.layerCount = 1;
Mark Lobodzinski20310782020-02-28 14:25:17 -07001808 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdCopyImageToBuffer-imageSubresource-01704");
sfricke-samsung6d97e562020-01-07 22:01:00 -08001809 vk::CmdCopyImageToBuffer(m_commandBuffer->handle(), image_16k.handle(), VK_IMAGE_LAYOUT_GENERAL, buffer_16k.handle(), 1,
1810 &region);
1811 m_errorMonitor->VerifyFound();
Mark Lobodzinski20310782020-02-28 14:25:17 -07001812 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdCopyBufferToImage-imageSubresource-01702");
sfricke-samsung6d97e562020-01-07 22:01:00 -08001813 vk::CmdCopyBufferToImage(m_commandBuffer->handle(), buffer_16k.handle(), image_16k.handle(), VK_IMAGE_LAYOUT_GENERAL, 1,
1814 &region);
1815 m_errorMonitor->VerifyFound();
1816 region.imageSubresource.baseArrayLayer = 0;
1817
1818 // Layout mismatch should fail
Mark Lobodzinski20310782020-02-28 14:25:17 -07001819 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdCopyImageToBuffer-srcImageLayout-00189");
sfricke-samsung6d97e562020-01-07 22:01:00 -08001820 vk::CmdCopyImageToBuffer(m_commandBuffer->handle(), image_16k.handle(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
1821 buffer_16k.handle(), 1, &region);
1822 m_errorMonitor->VerifyFound();
Mark Lobodzinski20310782020-02-28 14:25:17 -07001823 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdCopyBufferToImage-dstImageLayout-00180");
sfricke-samsung6d97e562020-01-07 22:01:00 -08001824 vk::CmdCopyBufferToImage(m_commandBuffer->handle(), buffer_16k.handle(), image_16k.handle(),
1825 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &region);
unknown088160a2019-05-23 17:43:13 -06001826 m_errorMonitor->VerifyFound();
1827 }
1828
unknown088160a2019-05-23 17:43:13 -06001829 // Test Depth/Stencil copies
1830 if (missing_ds_support) {
1831 printf("%s Depth / Stencil formats unsupported - skipping D/S tests.\n", kSkipPrefix);
1832 } else {
1833 VkBufferImageCopy ds_region = {};
1834 ds_region.bufferOffset = 0;
1835 ds_region.bufferRowLength = 0;
1836 ds_region.bufferImageHeight = 0;
1837 ds_region.imageSubresource.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT;
1838 ds_region.imageSubresource.mipLevel = 0;
1839 ds_region.imageSubresource.baseArrayLayer = 0;
1840 ds_region.imageSubresource.layerCount = 1;
1841 ds_region.imageOffset = {0, 0, 0};
1842 ds_region.imageExtent = {256, 256, 1};
1843
1844 // Depth copies that should succeed
1845 m_errorMonitor->ExpectSuccess(); // Extract 4b depth per texel, pack into 256k buffer
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06001846 vk::CmdCopyImageToBuffer(m_commandBuffer->handle(), ds_image_4D_1S.handle(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
1847 buffer_256k.handle(), 1, &ds_region);
unknown088160a2019-05-23 17:43:13 -06001848 m_errorMonitor->VerifyNotFound();
1849
1850 m_errorMonitor->ExpectSuccess(); // Extract 3b depth per texel, pack (loose) into 256k buffer
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06001851 vk::CmdCopyImageToBuffer(m_commandBuffer->handle(), ds_image_3D_1S.handle(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
1852 buffer_256k.handle(), 1, &ds_region);
unknown088160a2019-05-23 17:43:13 -06001853 m_errorMonitor->VerifyNotFound();
1854
1855 m_errorMonitor->ExpectSuccess(); // Copy 2b depth per texel, into 128k buffer
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06001856 vk::CmdCopyImageToBuffer(m_commandBuffer->handle(), ds_image_2D.handle(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
1857 buffer_128k.handle(), 1, &ds_region);
unknown088160a2019-05-23 17:43:13 -06001858 m_errorMonitor->VerifyNotFound();
1859
1860 // Depth copies that should fail
1861 ds_region.bufferOffset = 4;
1862 m_errorMonitor->SetDesiredFailureMsg(
Mark Lobodzinski20310782020-02-28 14:25:17 -07001863 kErrorBit,
unknown088160a2019-05-23 17:43:13 -06001864 "VUID-vkCmdCopyImageToBuffer-pRegions-00183"); // Extract 4b depth per texel, pack into 256k buffer
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06001865 vk::CmdCopyImageToBuffer(m_commandBuffer->handle(), ds_image_4D_1S.handle(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
1866 buffer_256k.handle(), 1, &ds_region);
unknown088160a2019-05-23 17:43:13 -06001867 m_errorMonitor->VerifyFound();
1868
1869 m_errorMonitor->SetDesiredFailureMsg(
Mark Lobodzinski20310782020-02-28 14:25:17 -07001870 kErrorBit,
unknown088160a2019-05-23 17:43:13 -06001871 "VUID-vkCmdCopyImageToBuffer-pRegions-00183"); // Extract 3b depth per texel, pack (loose) into 256k buffer
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06001872 vk::CmdCopyImageToBuffer(m_commandBuffer->handle(), ds_image_3D_1S.handle(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
1873 buffer_256k.handle(), 1, &ds_region);
unknown088160a2019-05-23 17:43:13 -06001874 m_errorMonitor->VerifyFound();
1875
1876 m_errorMonitor->SetDesiredFailureMsg(
Mark Lobodzinski20310782020-02-28 14:25:17 -07001877 kErrorBit,
unknown088160a2019-05-23 17:43:13 -06001878 "VUID-vkCmdCopyImageToBuffer-pRegions-00183"); // Copy 2b depth per texel, into 128k buffer
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06001879 vk::CmdCopyImageToBuffer(m_commandBuffer->handle(), ds_image_2D.handle(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
1880 buffer_128k.handle(), 1, &ds_region);
unknown088160a2019-05-23 17:43:13 -06001881 m_errorMonitor->VerifyFound();
1882
1883 // Stencil copies that should succeed
1884 ds_region.bufferOffset = 0;
1885 ds_region.imageSubresource.aspectMask = VK_IMAGE_ASPECT_STENCIL_BIT;
1886 m_errorMonitor->ExpectSuccess(); // Extract 1b stencil per texel, pack into 64k buffer
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06001887 vk::CmdCopyImageToBuffer(m_commandBuffer->handle(), ds_image_4D_1S.handle(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
1888 buffer_64k.handle(), 1, &ds_region);
unknown088160a2019-05-23 17:43:13 -06001889 m_errorMonitor->VerifyNotFound();
1890
1891 m_errorMonitor->ExpectSuccess(); // Extract 1b stencil per texel, pack into 64k buffer
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06001892 vk::CmdCopyImageToBuffer(m_commandBuffer->handle(), ds_image_3D_1S.handle(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
1893 buffer_64k.handle(), 1, &ds_region);
unknown088160a2019-05-23 17:43:13 -06001894 m_errorMonitor->VerifyNotFound();
1895
1896 m_errorMonitor->ExpectSuccess(); // Copy 1b depth per texel, into 64k buffer
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06001897 vk::CmdCopyImageToBuffer(m_commandBuffer->handle(), ds_image_1S.handle(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
1898 buffer_64k.handle(), 1, &ds_region);
unknown088160a2019-05-23 17:43:13 -06001899 m_errorMonitor->VerifyNotFound();
1900
1901 // Stencil copies that should fail
1902 m_errorMonitor->SetDesiredFailureMsg(
Mark Lobodzinski20310782020-02-28 14:25:17 -07001903 kErrorBit,
unknown088160a2019-05-23 17:43:13 -06001904 "VUID-vkCmdCopyImageToBuffer-pRegions-00183"); // Extract 1b stencil per texel, pack into 64k buffer
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06001905 vk::CmdCopyImageToBuffer(m_commandBuffer->handle(), ds_image_4D_1S.handle(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
1906 buffer_16k.handle(), 1, &ds_region);
unknown088160a2019-05-23 17:43:13 -06001907 m_errorMonitor->VerifyFound();
1908
1909 m_errorMonitor->SetDesiredFailureMsg(
Mark Lobodzinski20310782020-02-28 14:25:17 -07001910 kErrorBit,
unknown088160a2019-05-23 17:43:13 -06001911 "VUID-vkCmdCopyImageToBuffer-pRegions-00183"); // Extract 1b stencil per texel, pack into 64k buffer
1912 ds_region.bufferRowLength = 260;
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06001913 vk::CmdCopyImageToBuffer(m_commandBuffer->handle(), ds_image_3D_1S.handle(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
1914 buffer_64k.handle(), 1, &ds_region);
unknown088160a2019-05-23 17:43:13 -06001915 m_errorMonitor->VerifyFound();
1916
1917 ds_region.bufferRowLength = 0;
1918 ds_region.bufferOffset = 4;
1919 m_errorMonitor->SetDesiredFailureMsg(
Mark Lobodzinski20310782020-02-28 14:25:17 -07001920 kErrorBit,
unknown088160a2019-05-23 17:43:13 -06001921 "VUID-vkCmdCopyImageToBuffer-pRegions-00183"); // Copy 1b depth per texel, into 64k buffer
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06001922 vk::CmdCopyImageToBuffer(m_commandBuffer->handle(), ds_image_1S.handle(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
1923 buffer_64k.handle(), 1, &ds_region);
unknown088160a2019-05-23 17:43:13 -06001924 m_errorMonitor->VerifyFound();
1925 }
1926
1927 // Test compressed formats, if supported
sfricke-samsung6d97e562020-01-07 22:01:00 -08001928 // Support here requires both feature bit for compression and picked format supports transfer feature bits
unknown088160a2019-05-23 17:43:13 -06001929 VkPhysicalDeviceFeatures device_features = {};
1930 ASSERT_NO_FATAL_FAILURE(GetPhysicalDeviceFeatures(&device_features));
1931 if (!(device_features.textureCompressionBC || device_features.textureCompressionETC2 ||
1932 device_features.textureCompressionASTC_LDR)) {
1933 printf("%s No compressed formats supported - block compression tests skipped.\n", kSkipPrefix);
1934 } else {
sfricke-samsung6d97e562020-01-07 22:01:00 -08001935 // Verify transfer support for each compression format used blow
1936 bool missing_bc_support = false;
1937 bool missing_etc_support = false;
1938 bool missing_astc_support = false;
1939 bool missing_compression_support = false;
1940
1941 vk::GetPhysicalDeviceFormatProperties(m_device->phy().handle(), VK_FORMAT_BC3_SRGB_BLOCK, &props);
1942 missing_bc_support |= (props.bufferFeatures == 0 && props.linearTilingFeatures == 0 && props.optimalTilingFeatures == 0);
1943 missing_bc_support |= (props.optimalTilingFeatures & VK_FORMAT_FEATURE_TRANSFER_SRC_BIT) == 0;
1944 missing_bc_support |= (props.optimalTilingFeatures & VK_FORMAT_FEATURE_TRANSFER_DST_BIT) == 0;
1945
1946 vk::GetPhysicalDeviceFormatProperties(m_device->phy().handle(), VK_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK, &props);
1947 missing_etc_support |= (props.bufferFeatures == 0 && props.linearTilingFeatures == 0 && props.optimalTilingFeatures == 0);
1948 missing_etc_support |= (props.optimalTilingFeatures & VK_FORMAT_FEATURE_TRANSFER_SRC_BIT) == 0;
1949 missing_etc_support |= (props.optimalTilingFeatures & VK_FORMAT_FEATURE_TRANSFER_DST_BIT) == 0;
1950
1951 vk::GetPhysicalDeviceFormatProperties(m_device->phy().handle(), VK_FORMAT_ASTC_4x4_UNORM_BLOCK, &props);
1952 missing_astc_support |= (props.bufferFeatures == 0 && props.linearTilingFeatures == 0 && props.optimalTilingFeatures == 0);
1953 missing_astc_support |= (props.optimalTilingFeatures & VK_FORMAT_FEATURE_TRANSFER_SRC_BIT) == 0;
1954 missing_astc_support |= (props.optimalTilingFeatures & VK_FORMAT_FEATURE_TRANSFER_DST_BIT) == 0;
1955
1956 if (device_features.textureCompressionBC && (!missing_bc_support)) {
unknown088160a2019-05-23 17:43:13 -06001957 image_16k_4x4comp.Init(128, 128, 1, VK_FORMAT_BC3_SRGB_BLOCK, VK_IMAGE_USAGE_TRANSFER_SRC_BIT, VK_IMAGE_TILING_OPTIMAL,
1958 0);
1959 image_NPOT_4x4comp.Init(130, 130, 1, VK_FORMAT_BC3_SRGB_BLOCK, VK_IMAGE_USAGE_TRANSFER_SRC_BIT, VK_IMAGE_TILING_OPTIMAL,
1960 0);
sfricke-samsung6d97e562020-01-07 22:01:00 -08001961 } else if (device_features.textureCompressionETC2 && (!missing_etc_support)) {
unknown088160a2019-05-23 17:43:13 -06001962 image_16k_4x4comp.Init(128, 128, 1, VK_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK, VK_IMAGE_USAGE_TRANSFER_SRC_BIT,
1963 VK_IMAGE_TILING_OPTIMAL, 0);
1964 image_NPOT_4x4comp.Init(130, 130, 1, VK_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK, VK_IMAGE_USAGE_TRANSFER_SRC_BIT,
1965 VK_IMAGE_TILING_OPTIMAL, 0);
sfricke-samsung6d97e562020-01-07 22:01:00 -08001966 } else if (device_features.textureCompressionASTC_LDR && (!missing_astc_support)) {
unknown088160a2019-05-23 17:43:13 -06001967 image_16k_4x4comp.Init(128, 128, 1, VK_FORMAT_ASTC_4x4_UNORM_BLOCK, VK_IMAGE_USAGE_TRANSFER_SRC_BIT,
1968 VK_IMAGE_TILING_OPTIMAL, 0);
1969 image_NPOT_4x4comp.Init(130, 130, 1, VK_FORMAT_ASTC_4x4_UNORM_BLOCK, VK_IMAGE_USAGE_TRANSFER_SRC_BIT,
1970 VK_IMAGE_TILING_OPTIMAL, 0);
sfricke-samsung6d97e562020-01-07 22:01:00 -08001971 } else {
1972 missing_compression_support = true;
unknown088160a2019-05-23 17:43:13 -06001973 }
unknown088160a2019-05-23 17:43:13 -06001974
sfricke-samsung6d97e562020-01-07 22:01:00 -08001975 if (missing_compression_support) {
1976 printf("%s No compressed formats transfers bits are supported - block compression tests skipped.\n", kSkipPrefix);
1977 } else {
1978 ASSERT_TRUE(image_16k_4x4comp.initialized());
sfricke-samsung3a10b922020-05-13 23:23:16 -07001979 std::string vuid;
sfricke-samsung6d97e562020-01-07 22:01:00 -08001980 // Just fits
1981 m_errorMonitor->ExpectSuccess();
1982 region.imageExtent = {128, 128, 1};
1983 vk::CmdCopyImageToBuffer(m_commandBuffer->handle(), image_16k_4x4comp.handle(), VK_IMAGE_LAYOUT_GENERAL,
1984 buffer_16k.handle(), 1, &region);
1985 m_errorMonitor->VerifyNotFound();
unknown088160a2019-05-23 17:43:13 -06001986
sfricke-samsung6d97e562020-01-07 22:01:00 -08001987 // with offset, too big for buffer
Mark Lobodzinski20310782020-02-28 14:25:17 -07001988 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdCopyImageToBuffer-pRegions-00183");
sfricke-samsung6d97e562020-01-07 22:01:00 -08001989 region.bufferOffset = 16;
1990 vk::CmdCopyImageToBuffer(m_commandBuffer->handle(), image_16k_4x4comp.handle(), VK_IMAGE_LAYOUT_GENERAL,
1991 buffer_16k.handle(), 1, &region);
1992 m_errorMonitor->VerifyFound();
1993 region.bufferOffset = 0;
unknown088160a2019-05-23 17:43:13 -06001994
sfricke-samsung6d97e562020-01-07 22:01:00 -08001995 // extents that are not a multiple of compressed block size
sfricke-samsung3a10b922020-05-13 23:23:16 -07001996 vuid = mp_extensions ? "VUID-VkBufferImageCopy-None-01739" : "VUID-VkBufferImageCopy-imageExtent-00207";
1997 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, vuid); // extent width not a multiple of block size
Mark Lobodzinski20310782020-02-28 14:25:17 -07001998 m_errorMonitor->SetDesiredFailureMsg(kErrorBit,
sfricke-samsung6d97e562020-01-07 22:01:00 -08001999 "VUID-vkCmdCopyImageToBuffer-imageOffset-01794"); // image transfer granularity
2000 region.imageExtent.width = 66;
2001 vk::CmdCopyImageToBuffer(m_commandBuffer->handle(), image_NPOT_4x4comp.handle(), VK_IMAGE_LAYOUT_GENERAL,
2002 buffer_16k.handle(), 1, &region);
2003 m_errorMonitor->VerifyFound();
2004 region.imageExtent.width = 128;
unknown088160a2019-05-23 17:43:13 -06002005
sfricke-samsung3a10b922020-05-13 23:23:16 -07002006 vuid = mp_extensions ? "VUID-VkBufferImageCopy-None-01740" : "VUID-VkBufferImageCopy-imageExtent-00208";
2007 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, vuid); // extent height not a multiple of block size
Mark Lobodzinski20310782020-02-28 14:25:17 -07002008 m_errorMonitor->SetDesiredFailureMsg(kErrorBit,
sfricke-samsung6d97e562020-01-07 22:01:00 -08002009 "VUID-vkCmdCopyImageToBuffer-imageOffset-01794"); // image transfer granularity
2010 region.imageExtent.height = 2;
2011 vk::CmdCopyImageToBuffer(m_commandBuffer->handle(), image_NPOT_4x4comp.handle(), VK_IMAGE_LAYOUT_GENERAL,
2012 buffer_16k.handle(), 1, &region);
2013 m_errorMonitor->VerifyFound();
2014 region.imageExtent.height = 128;
unknown088160a2019-05-23 17:43:13 -06002015
sfricke-samsung6d97e562020-01-07 22:01:00 -08002016 // TODO: All available compressed formats are 2D, with block depth of 1. Unable to provoke VU_01277.
unknown088160a2019-05-23 17:43:13 -06002017
sfricke-samsung6d97e562020-01-07 22:01:00 -08002018 // non-multiple extents are allowed if at the far edge of a non-block-multiple image - these should pass
2019 m_errorMonitor->ExpectSuccess();
2020 region.imageExtent.width = 66;
2021 region.imageOffset.x = 64;
2022 vk::CmdCopyImageToBuffer(m_commandBuffer->handle(), image_NPOT_4x4comp.handle(), VK_IMAGE_LAYOUT_GENERAL,
2023 buffer_16k.handle(), 1, &region);
2024 region.imageExtent.width = 16;
2025 region.imageOffset.x = 0;
2026 region.imageExtent.height = 2;
2027 region.imageOffset.y = 128;
2028 vk::CmdCopyImageToBuffer(m_commandBuffer->handle(), image_NPOT_4x4comp.handle(), VK_IMAGE_LAYOUT_GENERAL,
2029 buffer_16k.handle(), 1, &region);
2030 m_errorMonitor->VerifyNotFound();
2031 region.imageOffset = {0, 0, 0};
unknown088160a2019-05-23 17:43:13 -06002032
sfricke-samsung6d97e562020-01-07 22:01:00 -08002033 // buffer offset must be a multiple of texel block size (16)
sfricke-samsung3a10b922020-05-13 23:23:16 -07002034 vuid = mp_extensions ? "VUID-VkBufferImageCopy-None-01738" : "VUID-VkBufferImageCopy-bufferOffset-00206";
2035 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, vuid);
Mark Lobodzinski20310782020-02-28 14:25:17 -07002036 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkBufferImageCopy-bufferOffset-00193");
sfricke-samsung6d97e562020-01-07 22:01:00 -08002037 region.imageExtent = {64, 64, 1};
2038 region.bufferOffset = 24;
2039 vk::CmdCopyImageToBuffer(m_commandBuffer->handle(), image_16k_4x4comp.handle(), VK_IMAGE_LAYOUT_GENERAL,
2040 buffer_16k.handle(), 1, &region);
2041 m_errorMonitor->VerifyFound();
unknown088160a2019-05-23 17:43:13 -06002042
sfricke-samsung6d97e562020-01-07 22:01:00 -08002043 // rowlength not a multiple of block width (4)
sfricke-samsung3a10b922020-05-13 23:23:16 -07002044 vuid = mp_extensions ? "VUID-VkBufferImageCopy-None-01735" : "VUID-VkBufferImageCopy-bufferRowLength-00203";
2045 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, vuid);
sfricke-samsung6d97e562020-01-07 22:01:00 -08002046 region.bufferOffset = 0;
2047 region.bufferRowLength = 130;
2048 region.bufferImageHeight = 0;
2049 vk::CmdCopyImageToBuffer(m_commandBuffer->handle(), image_16k_4x4comp.handle(), VK_IMAGE_LAYOUT_GENERAL,
2050 buffer_64k.handle(), 1, &region);
2051 m_errorMonitor->VerifyFound();
2052
2053 // imageheight not a multiple of block height (4)
sfricke-samsung3a10b922020-05-13 23:23:16 -07002054 vuid = mp_extensions ? "VUID-VkBufferImageCopy-None-01736" : "VUID-VkBufferImageCopy-bufferImageHeight-00204";
2055 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, vuid);
sfricke-samsung6d97e562020-01-07 22:01:00 -08002056 region.bufferRowLength = 0;
2057 region.bufferImageHeight = 130;
2058 vk::CmdCopyImageToBuffer(m_commandBuffer->handle(), image_16k_4x4comp.handle(), VK_IMAGE_LAYOUT_GENERAL,
2059 buffer_64k.handle(), 1, &region);
2060 m_errorMonitor->VerifyFound();
2061 }
2062 }
2063
2064 // Test multi-planar formats, if supported
2065 if (!mp_extensions) {
2066 printf("%s multi-planar extensions not supported; skipped.\n", kSkipPrefix);
2067 } else {
2068 // Try to use G8_B8R8_2PLANE_420_UNORM because need 2-plane format for some tests and likely supported due to copy support
2069 // being required with samplerYcbcrConversion feature
2070 bool missing_mp_support = false;
2071 vk::GetPhysicalDeviceFormatProperties(m_device->phy().handle(), VK_FORMAT_G8_B8R8_2PLANE_420_UNORM, &props);
2072 missing_mp_support |= (props.bufferFeatures == 0 && props.linearTilingFeatures == 0 && props.optimalTilingFeatures == 0);
2073 missing_mp_support |= (props.optimalTilingFeatures & VK_FORMAT_FEATURE_TRANSFER_SRC_BIT) == 0;
2074 missing_mp_support |= (props.optimalTilingFeatures & VK_FORMAT_FEATURE_TRANSFER_DST_BIT) == 0;
2075
2076 if (missing_mp_support) {
2077 printf("%s VK_FORMAT_G8_B8R8_2PLANE_420_UNORM transfer not supported; skipped.\n", kSkipPrefix);
2078 } else {
2079 VkBufferImageCopy mp_region = {};
2080 mp_region.bufferOffset = 0;
2081 mp_region.bufferRowLength = 0;
2082 mp_region.bufferImageHeight = 0;
2083 mp_region.imageSubresource.mipLevel = 0;
2084 mp_region.imageSubresource.baseArrayLayer = 0;
2085 mp_region.imageSubresource.layerCount = 1;
2086 mp_region.imageOffset = {0, 0, 0};
2087 mp_region.imageExtent = {128, 128, 1};
2088
2089 // YUV420 means 1/2 width and height so plane_0 is 128x128 and plane_1 is 64x64 here
2090 image_multi_planar.Init(128, 128, 1, VK_FORMAT_G8_B8R8_2PLANE_420_UNORM, VK_IMAGE_USAGE_TRANSFER_DST_BIT,
2091 VK_IMAGE_TILING_OPTIMAL, 0);
2092 ASSERT_TRUE(image_multi_planar.initialized());
2093
2094 // Copies into a mutli-planar image aspect properly
2095 m_errorMonitor->ExpectSuccess();
2096 mp_region.imageSubresource.aspectMask = VK_IMAGE_ASPECT_PLANE_0_BIT;
2097 vk::CmdCopyBufferToImage(m_commandBuffer->handle(), buffer_16k.handle(), image_multi_planar.handle(),
2098 VK_IMAGE_LAYOUT_GENERAL, 1, &mp_region);
2099 m_errorMonitor->VerifyNotFound();
2100
2101 // uses plane_2 without being 3 planar format
Mark Lobodzinski20310782020-02-28 14:25:17 -07002102 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkBufferImageCopy-aspectMask-01560");
sfricke-samsung6d97e562020-01-07 22:01:00 -08002103 mp_region.imageSubresource.aspectMask = VK_IMAGE_ASPECT_PLANE_2_BIT;
2104 vk::CmdCopyBufferToImage(m_commandBuffer->handle(), buffer_16k.handle(), image_multi_planar.handle(),
2105 VK_IMAGE_LAYOUT_GENERAL, 1, &mp_region);
2106 m_errorMonitor->VerifyFound();
2107
2108 // uses single-plane aspect mask
Mark Lobodzinski20310782020-02-28 14:25:17 -07002109 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkBufferImageCopy-aspectMask-01560");
sfricke-samsung6d97e562020-01-07 22:01:00 -08002110 mp_region.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
2111 vk::CmdCopyBufferToImage(m_commandBuffer->handle(), buffer_16k.handle(), image_multi_planar.handle(),
2112 VK_IMAGE_LAYOUT_GENERAL, 1, &mp_region);
2113 m_errorMonitor->VerifyFound();
2114 }
unknown088160a2019-05-23 17:43:13 -06002115 }
2116}
2117
2118TEST_F(VkLayerTest, MiscImageLayerTests) {
2119 TEST_DESCRIPTION("Image-related tests that don't belong elsewhere");
2120
2121 ASSERT_NO_FATAL_FAILURE(Init());
2122
2123 // TODO: Ideally we should check if a format is supported, before using it.
2124 VkImageObj image(m_device);
2125 image.Init(128, 128, 1, VK_FORMAT_R16G16B16A16_UINT, VK_IMAGE_USAGE_TRANSFER_DST_BIT, VK_IMAGE_TILING_OPTIMAL, 0); // 64bpp
2126 ASSERT_TRUE(image.initialized());
2127 VkBufferObj buffer;
2128 VkMemoryPropertyFlags reqs = 0;
2129 buffer.init_as_src(*m_device, 128 * 128 * 8, reqs);
2130 VkBufferImageCopy region = {};
2131 region.bufferRowLength = 128;
2132 region.bufferImageHeight = 128;
2133 region.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
2134 // layerCount can't be 0 - Expect MISMATCHED_IMAGE_ASPECT
2135 region.imageSubresource.layerCount = 1;
2136 region.imageExtent.height = 4;
2137 region.imageExtent.width = 4;
2138 region.imageExtent.depth = 1;
2139
2140 VkImageObj image2(m_device);
2141 image2.Init(128, 128, 1, VK_FORMAT_R8G8_UNORM, VK_IMAGE_USAGE_TRANSFER_DST_BIT, VK_IMAGE_TILING_OPTIMAL, 0); // 16bpp
2142 ASSERT_TRUE(image2.initialized());
2143 VkBufferObj buffer2;
2144 VkMemoryPropertyFlags reqs2 = 0;
2145 buffer2.init_as_src(*m_device, 128 * 128 * 2, reqs2);
2146 VkBufferImageCopy region2 = {};
2147 region2.bufferRowLength = 128;
2148 region2.bufferImageHeight = 128;
2149 region2.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
2150 // layerCount can't be 0 - Expect MISMATCHED_IMAGE_ASPECT
2151 region2.imageSubresource.layerCount = 1;
2152 region2.imageExtent.height = 4;
2153 region2.imageExtent.width = 4;
2154 region2.imageExtent.depth = 1;
2155 m_commandBuffer->begin();
2156
2157 // Image must have offset.z of 0 and extent.depth of 1
2158 // Introduce failure by setting imageExtent.depth to 0
2159 region.imageExtent.depth = 0;
Mark Lobodzinski20310782020-02-28 14:25:17 -07002160 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkBufferImageCopy-srcImage-00201");
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06002161 vk::CmdCopyBufferToImage(m_commandBuffer->handle(), buffer.handle(), image.handle(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1,
2162 &region);
unknown088160a2019-05-23 17:43:13 -06002163 m_errorMonitor->VerifyFound();
2164
2165 region.imageExtent.depth = 1;
2166
2167 // Image must have offset.z of 0 and extent.depth of 1
2168 // Introduce failure by setting imageOffset.z to 4
2169 // Note: Also (unavoidably) triggers 'region exceeds image' #1228
2170 region.imageOffset.z = 4;
Mark Lobodzinski20310782020-02-28 14:25:17 -07002171 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkBufferImageCopy-srcImage-00201");
2172 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkBufferImageCopy-imageOffset-00200");
2173 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdCopyBufferToImage-pRegions-00172");
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06002174 vk::CmdCopyBufferToImage(m_commandBuffer->handle(), buffer.handle(), image.handle(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1,
2175 &region);
unknown088160a2019-05-23 17:43:13 -06002176 m_errorMonitor->VerifyFound();
2177
2178 region.imageOffset.z = 0;
2179 // BufferOffset must be a multiple of the calling command's VkImage parameter's texel size
2180 // Introduce failure by setting bufferOffset to 1 and 1/2 texels
2181 region.bufferOffset = 4;
Mark Lobodzinski20310782020-02-28 14:25:17 -07002182 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkBufferImageCopy-bufferOffset-00193");
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06002183 vk::CmdCopyBufferToImage(m_commandBuffer->handle(), buffer.handle(), image.handle(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1,
2184 &region);
unknown088160a2019-05-23 17:43:13 -06002185 m_errorMonitor->VerifyFound();
2186
2187 // BufferOffset must be a multiple of 4
2188 // Introduce failure by setting bufferOffset to a value not divisible by 4
2189 region2.bufferOffset = 6;
Mark Lobodzinski20310782020-02-28 14:25:17 -07002190 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkBufferImageCopy-bufferOffset-00194");
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06002191 vk::CmdCopyBufferToImage(m_commandBuffer->handle(), buffer2.handle(), image2.handle(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1,
2192 &region2);
unknown088160a2019-05-23 17:43:13 -06002193 m_errorMonitor->VerifyFound();
2194
2195 // BufferRowLength must be 0, or greater than or equal to the width member of imageExtent
2196 region.bufferOffset = 0;
2197 region.imageExtent.height = 128;
2198 region.imageExtent.width = 128;
2199 // Introduce failure by setting bufferRowLength > 0 but less than width
2200 region.bufferRowLength = 64;
Mark Lobodzinski20310782020-02-28 14:25:17 -07002201 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkBufferImageCopy-bufferRowLength-00195");
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06002202 vk::CmdCopyBufferToImage(m_commandBuffer->handle(), buffer.handle(), image.handle(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1,
2203 &region);
unknown088160a2019-05-23 17:43:13 -06002204 m_errorMonitor->VerifyFound();
2205
2206 // BufferImageHeight must be 0, or greater than or equal to the height member of imageExtent
2207 region.bufferRowLength = 128;
2208 // Introduce failure by setting bufferRowHeight > 0 but less than height
2209 region.bufferImageHeight = 64;
Mark Lobodzinski20310782020-02-28 14:25:17 -07002210 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkBufferImageCopy-bufferImageHeight-00196");
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06002211 vk::CmdCopyBufferToImage(m_commandBuffer->handle(), buffer.handle(), image.handle(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1,
2212 &region);
unknown088160a2019-05-23 17:43:13 -06002213 m_errorMonitor->VerifyFound();
2214
2215 region.bufferImageHeight = 128;
2216 VkImageObj intImage1(m_device);
2217 intImage1.Init(128, 128, 1, VK_FORMAT_R8_UNORM, VK_IMAGE_USAGE_TRANSFER_SRC_BIT, VK_IMAGE_TILING_OPTIMAL, 0);
2218 intImage1.SetLayout(VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_GENERAL);
2219 VkImageObj intImage2(m_device);
2220 intImage2.Init(128, 128, 1, VK_FORMAT_R8_UNORM, VK_IMAGE_USAGE_TRANSFER_DST_BIT, VK_IMAGE_TILING_OPTIMAL, 0);
2221 intImage2.SetLayout(VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_GENERAL);
2222 VkImageBlit blitRegion = {};
2223 blitRegion.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
2224 blitRegion.srcSubresource.baseArrayLayer = 0;
2225 blitRegion.srcSubresource.layerCount = 1;
2226 blitRegion.srcSubresource.mipLevel = 0;
2227 blitRegion.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
2228 blitRegion.dstSubresource.baseArrayLayer = 0;
2229 blitRegion.dstSubresource.layerCount = 1;
2230 blitRegion.dstSubresource.mipLevel = 0;
2231 blitRegion.srcOffsets[0] = {128, 0, 0};
2232 blitRegion.srcOffsets[1] = {128, 128, 1};
2233 blitRegion.dstOffsets[0] = {0, 128, 0};
2234 blitRegion.dstOffsets[1] = {128, 128, 1};
2235
2236 // Look for NULL-blit warning
Mark Lobodzinski20310782020-02-28 14:25:17 -07002237 m_errorMonitor->SetDesiredFailureMsg(kWarningBit, "vkCmdBlitImage(): pRegions[0].srcOffsets specify a zero-volume area.");
2238 m_errorMonitor->SetDesiredFailureMsg(kWarningBit, "vkCmdBlitImage(): pRegions[0].dstOffsets specify a zero-volume area.");
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06002239 vk::CmdBlitImage(m_commandBuffer->handle(), intImage1.handle(), intImage1.Layout(), intImage2.handle(), intImage2.Layout(), 1,
2240 &blitRegion, VK_FILTER_LINEAR);
unknown088160a2019-05-23 17:43:13 -06002241 m_errorMonitor->VerifyFound();
2242}
2243
2244TEST_F(VkLayerTest, CopyImageTypeExtentMismatch) {
2245 // Image copy tests where format type and extents don't match
2246 ASSERT_NO_FATAL_FAILURE(Init());
2247
2248 VkImageCreateInfo ci;
2249 ci.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
2250 ci.pNext = NULL;
2251 ci.flags = 0;
2252 ci.imageType = VK_IMAGE_TYPE_1D;
2253 ci.format = VK_FORMAT_R8G8B8A8_UNORM;
2254 ci.extent = {32, 1, 1};
2255 ci.mipLevels = 1;
2256 ci.arrayLayers = 1;
2257 ci.samples = VK_SAMPLE_COUNT_1_BIT;
2258 ci.tiling = VK_IMAGE_TILING_OPTIMAL;
2259 ci.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
2260 ci.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
2261 ci.queueFamilyIndexCount = 0;
2262 ci.pQueueFamilyIndices = NULL;
2263 ci.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
2264
2265 // Create 1D image
2266 VkImageObj image_1D(m_device);
2267 image_1D.init(&ci);
2268 ASSERT_TRUE(image_1D.initialized());
2269
2270 // 2D image
2271 ci.imageType = VK_IMAGE_TYPE_2D;
2272 ci.extent = {32, 32, 1};
2273 VkImageObj image_2D(m_device);
2274 image_2D.init(&ci);
2275 ASSERT_TRUE(image_2D.initialized());
2276
2277 // 3D image
2278 ci.imageType = VK_IMAGE_TYPE_3D;
2279 ci.extent = {32, 32, 8};
2280 VkImageObj image_3D(m_device);
2281 image_3D.init(&ci);
2282 ASSERT_TRUE(image_3D.initialized());
2283
2284 // 2D image array
2285 ci.imageType = VK_IMAGE_TYPE_2D;
2286 ci.extent = {32, 32, 1};
2287 ci.arrayLayers = 8;
2288 VkImageObj image_2D_array(m_device);
2289 image_2D_array.init(&ci);
2290 ASSERT_TRUE(image_2D_array.initialized());
2291
2292 m_commandBuffer->begin();
2293
2294 VkImageCopy copy_region;
2295 copy_region.extent = {32, 1, 1};
2296 copy_region.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
2297 copy_region.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
2298 copy_region.srcSubresource.mipLevel = 0;
2299 copy_region.dstSubresource.mipLevel = 0;
2300 copy_region.srcSubresource.baseArrayLayer = 0;
2301 copy_region.dstSubresource.baseArrayLayer = 0;
2302 copy_region.srcSubresource.layerCount = 1;
2303 copy_region.dstSubresource.layerCount = 1;
2304 copy_region.srcOffset = {0, 0, 0};
2305 copy_region.dstOffset = {0, 0, 0};
2306
2307 // Sanity check
2308 m_errorMonitor->ExpectSuccess();
2309 m_commandBuffer->CopyImage(image_1D.image(), VK_IMAGE_LAYOUT_GENERAL, image_2D.image(), VK_IMAGE_LAYOUT_GENERAL, 1,
2310 &copy_region);
2311 m_errorMonitor->VerifyNotFound();
2312
2313 // 1D texture w/ offset.y > 0. Source = VU 09c00124, dest = 09c00130
2314 copy_region.srcOffset.y = 1;
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();
2320 copy_region.srcOffset.y = 0;
2321 copy_region.dstOffset.y = 1;
Mark Lobodzinski20310782020-02-28 14:25:17 -07002322 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkImageCopy-dstImage-00152");
2323 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkImageCopy-dstOffset-00151"); // also y-dim overrun
unknown088160a2019-05-23 17:43:13 -06002324 m_commandBuffer->CopyImage(image_2D.image(), VK_IMAGE_LAYOUT_GENERAL, image_1D.image(), VK_IMAGE_LAYOUT_GENERAL, 1,
2325 &copy_region);
2326 m_errorMonitor->VerifyFound();
2327 copy_region.dstOffset.y = 0;
2328
2329 // 1D texture w/ extent.height > 1. Source = VU 09c00124, dest = 09c00130
2330 copy_region.extent.height = 2;
Mark Lobodzinski20310782020-02-28 14:25:17 -07002331 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkImageCopy-srcImage-00146");
2332 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkImageCopy-srcOffset-00145"); // also y-dim overrun
unknown088160a2019-05-23 17:43:13 -06002333 m_commandBuffer->CopyImage(image_1D.image(), VK_IMAGE_LAYOUT_GENERAL, image_2D.image(), VK_IMAGE_LAYOUT_GENERAL, 1,
2334 &copy_region);
2335 m_errorMonitor->VerifyFound();
Mark Lobodzinski20310782020-02-28 14:25:17 -07002336 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkImageCopy-dstImage-00152");
2337 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkImageCopy-dstOffset-00151"); // also y-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.extent.height = 1;
2342
2343 // 1D texture w/ offset.z > 0. Source = VU 09c00df2, dest = 09c00df4
2344 copy_region.srcOffset.z = 1;
Mark Lobodzinski20310782020-02-28 14:25:17 -07002345 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkImageCopy-srcImage-01785");
2346 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkImageCopy-srcOffset-00147"); // also z-dim overrun
unknown088160a2019-05-23 17:43:13 -06002347 m_commandBuffer->CopyImage(image_1D.image(), VK_IMAGE_LAYOUT_GENERAL, image_2D.image(), VK_IMAGE_LAYOUT_GENERAL, 1,
2348 &copy_region);
2349 m_errorMonitor->VerifyFound();
2350 copy_region.srcOffset.z = 0;
2351 copy_region.dstOffset.z = 1;
Mark Lobodzinski20310782020-02-28 14:25:17 -07002352 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkImageCopy-dstImage-01786");
2353 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkImageCopy-dstOffset-00153"); // also z-dim overrun
unknown088160a2019-05-23 17:43:13 -06002354 m_commandBuffer->CopyImage(image_2D.image(), VK_IMAGE_LAYOUT_GENERAL, image_1D.image(), VK_IMAGE_LAYOUT_GENERAL, 1,
2355 &copy_region);
2356 m_errorMonitor->VerifyFound();
2357 copy_region.dstOffset.z = 0;
2358
2359 // 1D texture w/ extent.depth > 1. Source = VU 09c00df2, dest = 09c00df4
2360 copy_region.extent.depth = 2;
Mark Lobodzinski20310782020-02-28 14:25:17 -07002361 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkImageCopy-srcImage-01785");
2362 m_errorMonitor->SetDesiredFailureMsg(kErrorBit,
unknown088160a2019-05-23 17:43:13 -06002363 "VUID-VkImageCopy-srcOffset-00147"); // also z-dim overrun (src)
Mark Lobodzinski20310782020-02-28 14:25:17 -07002364 m_errorMonitor->SetDesiredFailureMsg(kErrorBit,
unknown088160a2019-05-23 17:43:13 -06002365 "VUID-VkImageCopy-dstOffset-00153"); // also z-dim overrun (dst)
Mark Lobodzinski20310782020-02-28 14:25:17 -07002366 m_errorMonitor->SetDesiredFailureMsg(kErrorBit,
sfricke-samsung211ee9c2020-02-13 23:38:39 -08002367 "VUID-VkImageCopy-srcImage-01789"); // 2D needs to be 1 pre-Vulkan 1.1
unknown088160a2019-05-23 17:43:13 -06002368 m_commandBuffer->CopyImage(image_1D.image(), VK_IMAGE_LAYOUT_GENERAL, image_2D.image(), VK_IMAGE_LAYOUT_GENERAL, 1,
2369 &copy_region);
2370 m_errorMonitor->VerifyFound();
Mark Lobodzinski20310782020-02-28 14:25:17 -07002371 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkImageCopy-dstImage-01786");
2372 m_errorMonitor->SetDesiredFailureMsg(kErrorBit,
unknown088160a2019-05-23 17:43:13 -06002373 "VUID-VkImageCopy-srcOffset-00147"); // also z-dim overrun (src)
Mark Lobodzinski20310782020-02-28 14:25:17 -07002374 m_errorMonitor->SetDesiredFailureMsg(kErrorBit,
unknown088160a2019-05-23 17:43:13 -06002375 "VUID-VkImageCopy-dstOffset-00153"); // also z-dim overrun (dst)
Mark Lobodzinski20310782020-02-28 14:25:17 -07002376 m_errorMonitor->SetDesiredFailureMsg(kErrorBit,
sfricke-samsung211ee9c2020-02-13 23:38:39 -08002377 "VUID-VkImageCopy-srcImage-01789"); // 2D needs to be 1 pre-Vulkan 1.1
unknown088160a2019-05-23 17:43:13 -06002378 m_commandBuffer->CopyImage(image_2D.image(), VK_IMAGE_LAYOUT_GENERAL, image_1D.image(), VK_IMAGE_LAYOUT_GENERAL, 1,
2379 &copy_region);
2380 m_errorMonitor->VerifyFound();
2381 copy_region.extent.depth = 1;
2382
2383 // 2D texture w/ offset.z > 0. Source = VU 09c00df6, dest = 09c00df8
2384 copy_region.extent = {16, 16, 1};
2385 copy_region.srcOffset.z = 4;
Mark Lobodzinski20310782020-02-28 14:25:17 -07002386 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkImageCopy-srcImage-01787");
2387 m_errorMonitor->SetDesiredFailureMsg(kErrorBit,
unknown088160a2019-05-23 17:43:13 -06002388 "VUID-VkImageCopy-srcOffset-00147"); // also z-dim overrun (src)
2389 m_commandBuffer->CopyImage(image_2D.image(), VK_IMAGE_LAYOUT_GENERAL, image_3D.image(), VK_IMAGE_LAYOUT_GENERAL, 1,
2390 &copy_region);
2391 m_errorMonitor->VerifyFound();
2392 copy_region.srcOffset.z = 0;
2393 copy_region.dstOffset.z = 1;
Mark Lobodzinski20310782020-02-28 14:25:17 -07002394 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkImageCopy-dstImage-01788");
2395 m_errorMonitor->SetDesiredFailureMsg(kErrorBit,
unknown088160a2019-05-23 17:43:13 -06002396 "VUID-VkImageCopy-dstOffset-00153"); // also z-dim overrun (dst)
2397 m_commandBuffer->CopyImage(image_3D.image(), VK_IMAGE_LAYOUT_GENERAL, image_2D.image(), VK_IMAGE_LAYOUT_GENERAL, 1,
2398 &copy_region);
2399 m_errorMonitor->VerifyFound();
2400 copy_region.dstOffset.z = 0;
2401
2402 // 3D texture accessing an array layer other than 0. VU 09c0011a
2403 copy_region.extent = {4, 4, 1};
2404 copy_region.srcSubresource.baseArrayLayer = 1;
Mark Lobodzinski20310782020-02-28 14:25:17 -07002405 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkImageCopy-srcImage-00141");
2406 m_errorMonitor->SetDesiredFailureMsg(kErrorBit,
unknown088160a2019-05-23 17:43:13 -06002407 "VUID-vkCmdCopyImage-srcSubresource-01698"); // also 'too many layers'
2408 m_commandBuffer->CopyImage(image_3D.image(), VK_IMAGE_LAYOUT_GENERAL, image_2D.image(), VK_IMAGE_LAYOUT_GENERAL, 1,
2409 &copy_region);
2410 m_errorMonitor->VerifyFound();
sfricke-samsung211ee9c2020-02-13 23:38:39 -08002411 copy_region.srcSubresource.baseArrayLayer = 0;
2412
unknown088160a2019-05-23 17:43:13 -06002413 m_commandBuffer->end();
2414}
2415
2416TEST_F(VkLayerTest, CopyImageTypeExtentMismatchMaintenance1) {
2417 // Image copy tests where format type and extents don't match and the Maintenance1 extension is enabled
Mark Lobodzinski09ce9c42020-03-06 10:02:44 -07002418 ASSERT_NO_FATAL_FAILURE(InitFramework(m_errorMonitor));
unknown088160a2019-05-23 17:43:13 -06002419 if (DeviceExtensionSupported(gpu(), nullptr, VK_KHR_MAINTENANCE1_EXTENSION_NAME)) {
2420 m_device_extension_names.push_back(VK_KHR_MAINTENANCE1_EXTENSION_NAME);
2421 } else {
2422 printf("%s Maintenance1 extension cannot be enabled, test skipped.\n", kSkipPrefix);
2423 return;
2424 }
2425 ASSERT_NO_FATAL_FAILURE(InitState());
2426
2427 VkFormat image_format = VK_FORMAT_R8G8B8A8_UNORM;
2428 VkFormatProperties format_props;
2429 // TODO: Remove this check if or when devsim handles extensions.
2430 // The chosen format has mandatory support the transfer src and dst format features when Maitenance1 is enabled. However, our
2431 // use of devsim and the mock ICD violate this guarantee.
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06002432 vk::GetPhysicalDeviceFormatProperties(m_device->phy().handle(), image_format, &format_props);
unknown088160a2019-05-23 17:43:13 -06002433 if (!(format_props.optimalTilingFeatures & VK_FORMAT_FEATURE_TRANSFER_SRC_BIT)) {
2434 printf("%s Maintenance1 extension is not supported.\n", kSkipPrefix);
2435 return;
2436 }
2437
2438 VkImageCreateInfo ci;
2439 ci.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
2440 ci.pNext = NULL;
2441 ci.flags = 0;
2442 ci.imageType = VK_IMAGE_TYPE_1D;
2443 ci.format = image_format;
2444 ci.extent = {32, 1, 1};
2445 ci.mipLevels = 1;
2446 ci.arrayLayers = 1;
2447 ci.samples = VK_SAMPLE_COUNT_1_BIT;
2448 ci.tiling = VK_IMAGE_TILING_OPTIMAL;
2449 ci.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
2450 ci.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
2451 ci.queueFamilyIndexCount = 0;
2452 ci.pQueueFamilyIndices = NULL;
2453 ci.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
2454
2455 // Create 1D image
2456 VkImageObj image_1D(m_device);
2457 image_1D.init(&ci);
2458 ASSERT_TRUE(image_1D.initialized());
2459
2460 // 2D image
2461 ci.imageType = VK_IMAGE_TYPE_2D;
2462 ci.extent = {32, 32, 1};
2463 VkImageObj image_2D(m_device);
2464 image_2D.init(&ci);
2465 ASSERT_TRUE(image_2D.initialized());
2466
2467 // 3D image
2468 ci.imageType = VK_IMAGE_TYPE_3D;
2469 ci.extent = {32, 32, 8};
2470 VkImageObj image_3D(m_device);
2471 image_3D.init(&ci);
2472 ASSERT_TRUE(image_3D.initialized());
2473
2474 // 2D image array
2475 ci.imageType = VK_IMAGE_TYPE_2D;
2476 ci.extent = {32, 32, 1};
2477 ci.arrayLayers = 8;
2478 VkImageObj image_2D_array(m_device);
2479 image_2D_array.init(&ci);
2480 ASSERT_TRUE(image_2D_array.initialized());
2481
sfricke-samsung211ee9c2020-02-13 23:38:39 -08002482 // second 2D image array
2483 ci.imageType = VK_IMAGE_TYPE_2D;
2484 ci.extent = {32, 32, 1};
2485 ci.arrayLayers = 8;
2486 VkImageObj image_2D_array_2(m_device);
2487 image_2D_array_2.init(&ci);
2488 ASSERT_TRUE(image_2D_array_2.initialized());
2489
unknown088160a2019-05-23 17:43:13 -06002490 m_commandBuffer->begin();
2491
2492 VkImageCopy copy_region;
2493 copy_region.extent = {32, 1, 1};
2494 copy_region.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
2495 copy_region.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
2496 copy_region.srcSubresource.mipLevel = 0;
2497 copy_region.dstSubresource.mipLevel = 0;
2498 copy_region.srcSubresource.baseArrayLayer = 0;
2499 copy_region.dstSubresource.baseArrayLayer = 0;
2500 copy_region.srcSubresource.layerCount = 1;
2501 copy_region.dstSubresource.layerCount = 1;
2502 copy_region.srcOffset = {0, 0, 0};
2503 copy_region.dstOffset = {0, 0, 0};
2504
2505 // Copy from layer not present
2506 copy_region.srcSubresource.baseArrayLayer = 4;
2507 copy_region.srcSubresource.layerCount = 6;
Mark Lobodzinski20310782020-02-28 14:25:17 -07002508 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdCopyImage-srcSubresource-01698");
unknown088160a2019-05-23 17:43:13 -06002509 m_commandBuffer->CopyImage(image_2D_array.image(), VK_IMAGE_LAYOUT_GENERAL, image_3D.image(), VK_IMAGE_LAYOUT_GENERAL, 1,
2510 &copy_region);
2511 m_errorMonitor->VerifyFound();
2512 copy_region.srcSubresource.baseArrayLayer = 0;
2513 copy_region.srcSubresource.layerCount = 1;
2514
2515 // Copy to layer not present
2516 copy_region.dstSubresource.baseArrayLayer = 1;
2517 copy_region.dstSubresource.layerCount = 8;
Mark Lobodzinski20310782020-02-28 14:25:17 -07002518 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdCopyImage-dstSubresource-01699");
unknown088160a2019-05-23 17:43:13 -06002519 m_commandBuffer->CopyImage(image_3D.image(), VK_IMAGE_LAYOUT_GENERAL, image_2D_array.image(), VK_IMAGE_LAYOUT_GENERAL, 1,
2520 &copy_region);
2521 m_errorMonitor->VerifyFound();
sfricke-samsung211ee9c2020-02-13 23:38:39 -08002522 copy_region.dstSubresource.baseArrayLayer = 0;
unknown088160a2019-05-23 17:43:13 -06002523 copy_region.dstSubresource.layerCount = 1;
2524
sfricke-samsung211ee9c2020-02-13 23:38:39 -08002525 // both 2D and extent.depth not 1
2526 // Need two 2D array images to prevent other errors
2527 copy_region.extent = {4, 1, 2};
Mark Lobodzinski20310782020-02-28 14:25:17 -07002528 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkImageCopy-srcImage-01790");
sfricke-samsung211ee9c2020-02-13 23:38:39 -08002529 m_commandBuffer->CopyImage(image_2D_array.image(), VK_IMAGE_LAYOUT_GENERAL, image_2D_array_2.image(), VK_IMAGE_LAYOUT_GENERAL,
2530 1, &copy_region);
2531 m_errorMonitor->VerifyFound();
2532 copy_region.extent = {32, 1, 1};
2533
2534 // 2D src / 3D dst and depth not equal to src layerCount
2535 copy_region.extent = {4, 1, 2};
Mark Lobodzinski20310782020-02-28 14:25:17 -07002536 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkImageCopy-srcImage-01791");
2537 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkImageCopy-extent-00140");
sfricke-samsung211ee9c2020-02-13 23:38:39 -08002538 m_commandBuffer->CopyImage(image_2D_array.image(), VK_IMAGE_LAYOUT_GENERAL, image_3D.image(), VK_IMAGE_LAYOUT_GENERAL, 1,
2539 &copy_region);
2540 m_errorMonitor->VerifyFound();
2541 copy_region.extent = {32, 1, 1};
2542
2543 // 3D src / 2D dst and depth not equal to dst layerCount
2544 copy_region.extent = {4, 1, 2};
Mark Lobodzinski20310782020-02-28 14:25:17 -07002545 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkImageCopy-dstImage-01792");
2546 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkImageCopy-extent-00140");
sfricke-samsung211ee9c2020-02-13 23:38:39 -08002547 m_commandBuffer->CopyImage(image_3D.image(), VK_IMAGE_LAYOUT_GENERAL, image_2D_array.image(), VK_IMAGE_LAYOUT_GENERAL, 1,
2548 &copy_region);
2549 m_errorMonitor->VerifyFound();
2550 copy_region.extent = {32, 1, 1};
2551
unknown088160a2019-05-23 17:43:13 -06002552 m_commandBuffer->end();
2553}
2554
2555TEST_F(VkLayerTest, CopyImageCompressedBlockAlignment) {
2556 // Image copy tests on compressed images with block alignment errors
2557 SetTargetApiVersion(VK_API_VERSION_1_1);
2558 ASSERT_NO_FATAL_FAILURE(Init());
2559
2560 // Select a compressed format and verify support
2561 VkPhysicalDeviceFeatures device_features = {};
2562 ASSERT_NO_FATAL_FAILURE(GetPhysicalDeviceFeatures(&device_features));
2563 VkFormat compressed_format = VK_FORMAT_UNDEFINED;
2564 if (device_features.textureCompressionBC) {
2565 compressed_format = VK_FORMAT_BC3_SRGB_BLOCK;
2566 } else if (device_features.textureCompressionETC2) {
2567 compressed_format = VK_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK;
2568 } else if (device_features.textureCompressionASTC_LDR) {
2569 compressed_format = VK_FORMAT_ASTC_4x4_UNORM_BLOCK;
2570 }
2571
2572 VkImageCreateInfo ci;
2573 ci.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
2574 ci.pNext = NULL;
2575 ci.flags = 0;
2576 ci.imageType = VK_IMAGE_TYPE_2D;
2577 ci.format = compressed_format;
2578 ci.extent = {64, 64, 1};
2579 ci.mipLevels = 1;
2580 ci.arrayLayers = 1;
2581 ci.samples = VK_SAMPLE_COUNT_1_BIT;
2582 ci.tiling = VK_IMAGE_TILING_OPTIMAL;
2583 ci.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
2584 ci.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
2585 ci.queueFamilyIndexCount = 0;
2586 ci.pQueueFamilyIndices = NULL;
2587 ci.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
2588
2589 VkImageFormatProperties img_prop = {};
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06002590 if (VK_SUCCESS != vk::GetPhysicalDeviceImageFormatProperties(m_device->phy().handle(), ci.format, ci.imageType, ci.tiling,
2591 ci.usage, ci.flags, &img_prop)) {
unknown088160a2019-05-23 17:43:13 -06002592 printf("%s No compressed formats supported - CopyImageCompressedBlockAlignment skipped.\n", kSkipPrefix);
2593 return;
2594 }
2595
2596 // Create images
2597 VkImageObj image_1(m_device);
2598 image_1.init(&ci);
2599 ASSERT_TRUE(image_1.initialized());
2600
2601 ci.extent = {62, 62, 1}; // slightly smaller and not divisible by block size
2602 VkImageObj image_2(m_device);
2603 image_2.init(&ci);
2604 ASSERT_TRUE(image_2.initialized());
2605
2606 m_commandBuffer->begin();
2607
2608 VkImageCopy copy_region;
2609 copy_region.extent = {48, 48, 1};
2610 copy_region.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
2611 copy_region.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
2612 copy_region.srcSubresource.mipLevel = 0;
2613 copy_region.dstSubresource.mipLevel = 0;
2614 copy_region.srcSubresource.baseArrayLayer = 0;
2615 copy_region.dstSubresource.baseArrayLayer = 0;
2616 copy_region.srcSubresource.layerCount = 1;
2617 copy_region.dstSubresource.layerCount = 1;
2618 copy_region.srcOffset = {0, 0, 0};
2619 copy_region.dstOffset = {0, 0, 0};
2620
2621 // Sanity check
2622 m_errorMonitor->ExpectSuccess();
2623 m_commandBuffer->CopyImage(image_1.image(), VK_IMAGE_LAYOUT_GENERAL, image_2.image(), VK_IMAGE_LAYOUT_GENERAL, 1, &copy_region);
2624 m_errorMonitor->VerifyNotFound();
2625
2626 std::string vuid;
2627 bool ycbcr = (DeviceExtensionEnabled(VK_KHR_SAMPLER_YCBCR_CONVERSION_EXTENSION_NAME) ||
2628 (DeviceValidationVersion() >= VK_API_VERSION_1_1));
2629
2630 // Src, Dest offsets must be multiples of compressed block sizes {4, 4, 1}
2631 // Image transfer granularity gets set to compressed block size, so an ITG error is also (unavoidably) triggered.
2632 vuid = ycbcr ? "VUID-VkImageCopy-srcImage-01727" : "VUID-VkImageCopy-srcOffset-00157";
2633 copy_region.srcOffset = {2, 4, 0}; // source width
Mark Lobodzinski20310782020-02-28 14:25:17 -07002634 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, vuid);
2635 m_errorMonitor->SetDesiredFailureMsg(kErrorBit,
unknown088160a2019-05-23 17:43:13 -06002636 "VUID-vkCmdCopyImage-srcOffset-01783"); // srcOffset image transfer granularity
2637 m_commandBuffer->CopyImage(image_1.image(), VK_IMAGE_LAYOUT_GENERAL, image_2.image(), VK_IMAGE_LAYOUT_GENERAL, 1, &copy_region);
2638 m_errorMonitor->VerifyFound();
2639 copy_region.srcOffset = {12, 1, 0}; // source height
Mark Lobodzinski20310782020-02-28 14:25:17 -07002640 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, vuid);
2641 m_errorMonitor->SetDesiredFailureMsg(kErrorBit,
unknown088160a2019-05-23 17:43:13 -06002642 "VUID-vkCmdCopyImage-srcOffset-01783"); // srcOffset image transfer granularity
2643 m_commandBuffer->CopyImage(image_1.image(), VK_IMAGE_LAYOUT_GENERAL, image_2.image(), VK_IMAGE_LAYOUT_GENERAL, 1, &copy_region);
2644 m_errorMonitor->VerifyFound();
2645 copy_region.srcOffset = {0, 0, 0};
2646
2647 vuid = ycbcr ? "VUID-VkImageCopy-dstImage-01731" : "VUID-VkImageCopy-dstOffset-00162";
2648 copy_region.dstOffset = {1, 0, 0}; // dest 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-dstOffset-01784"); // dstOffset 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 copy_region.dstOffset = {4, 1, 0}; // dest height
Mark Lobodzinski20310782020-02-28 14:25:17 -07002655 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, vuid);
2656 m_errorMonitor->SetDesiredFailureMsg(kErrorBit,
unknown088160a2019-05-23 17:43:13 -06002657 "VUID-vkCmdCopyImage-dstOffset-01784"); // dstOffset image transfer granularity
2658 m_commandBuffer->CopyImage(image_1.image(), VK_IMAGE_LAYOUT_GENERAL, image_2.image(), VK_IMAGE_LAYOUT_GENERAL, 1, &copy_region);
2659 m_errorMonitor->VerifyFound();
2660 copy_region.dstOffset = {0, 0, 0};
2661
2662 // Copy extent must be multiples of compressed block sizes {4, 4, 1} if not full width/height
2663 vuid = ycbcr ? "VUID-VkImageCopy-srcImage-01728" : "VUID-VkImageCopy-extent-00158";
2664 copy_region.extent = {62, 60, 1}; // source width
Mark Lobodzinski20310782020-02-28 14:25:17 -07002665 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, vuid);
2666 m_errorMonitor->SetDesiredFailureMsg(kErrorBit,
unknown088160a2019-05-23 17:43:13 -06002667 "VUID-vkCmdCopyImage-srcOffset-01783"); // src extent image transfer granularity
2668 m_commandBuffer->CopyImage(image_1.image(), VK_IMAGE_LAYOUT_GENERAL, image_2.image(), VK_IMAGE_LAYOUT_GENERAL, 1, &copy_region);
2669 m_errorMonitor->VerifyFound();
2670 vuid = ycbcr ? "VUID-VkImageCopy-srcImage-01729" : "VUID-VkImageCopy-extent-00159";
2671 copy_region.extent = {60, 62, 1}; // source height
Mark Lobodzinski20310782020-02-28 14:25:17 -07002672 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, vuid);
2673 m_errorMonitor->SetDesiredFailureMsg(kErrorBit,
unknown088160a2019-05-23 17:43:13 -06002674 "VUID-vkCmdCopyImage-srcOffset-01783"); // src extent image transfer granularity
2675 m_commandBuffer->CopyImage(image_1.image(), VK_IMAGE_LAYOUT_GENERAL, image_2.image(), VK_IMAGE_LAYOUT_GENERAL, 1, &copy_region);
2676 m_errorMonitor->VerifyFound();
2677
2678 vuid = ycbcr ? "VUID-VkImageCopy-dstImage-01732" : "VUID-VkImageCopy-extent-00163";
2679 copy_region.extent = {62, 60, 1}; // dest width
Mark Lobodzinski20310782020-02-28 14:25:17 -07002680 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, vuid);
2681 m_errorMonitor->SetDesiredFailureMsg(kErrorBit,
unknown088160a2019-05-23 17:43:13 -06002682 "VUID-vkCmdCopyImage-dstOffset-01784"); // dst extent image transfer granularity
2683 m_commandBuffer->CopyImage(image_2.image(), VK_IMAGE_LAYOUT_GENERAL, image_1.image(), VK_IMAGE_LAYOUT_GENERAL, 1, &copy_region);
2684 m_errorMonitor->VerifyFound();
2685 vuid = ycbcr ? "VUID-VkImageCopy-dstImage-01733" : "VUID-VkImageCopy-extent-00164";
2686 copy_region.extent = {60, 62, 1}; // dest height
Mark Lobodzinski20310782020-02-28 14:25:17 -07002687 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, vuid);
2688 m_errorMonitor->SetDesiredFailureMsg(kErrorBit,
unknown088160a2019-05-23 17:43:13 -06002689 "VUID-vkCmdCopyImage-dstOffset-01784"); // dst extent image transfer granularity
2690 m_commandBuffer->CopyImage(image_2.image(), VK_IMAGE_LAYOUT_GENERAL, image_1.image(), VK_IMAGE_LAYOUT_GENERAL, 1, &copy_region);
2691 m_errorMonitor->VerifyFound();
2692
2693 // Note: "VUID-VkImageCopy-extent-00160", "VUID-VkImageCopy-extent-00165", "VUID-VkImageCopy-srcImage-01730",
2694 // "VUID-VkImageCopy-dstImage-01734"
2695 // There are currently no supported compressed formats with a block depth other than 1,
2696 // so impossible to create a 'not a multiple' condition for depth.
2697 m_commandBuffer->end();
2698}
2699
2700TEST_F(VkLayerTest, CopyImageSinglePlane422Alignment) {
2701 // Image copy tests on single-plane _422 formats with block alignment errors
2702
2703 // Enable KHR multiplane req'd extensions
2704 bool mp_extensions = InstanceExtensionSupported(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME,
2705 VK_KHR_GET_MEMORY_REQUIREMENTS_2_SPEC_VERSION);
2706 if (mp_extensions) {
2707 m_instance_extension_names.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
2708 }
Mark Lobodzinski09ce9c42020-03-06 10:02:44 -07002709 ASSERT_NO_FATAL_FAILURE(InitFramework(m_errorMonitor));
unknown088160a2019-05-23 17:43:13 -06002710 mp_extensions = mp_extensions && DeviceExtensionSupported(gpu(), nullptr, VK_KHR_MAINTENANCE1_EXTENSION_NAME);
2711 mp_extensions = mp_extensions && DeviceExtensionSupported(gpu(), nullptr, VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME);
2712 mp_extensions = mp_extensions && DeviceExtensionSupported(gpu(), nullptr, VK_KHR_BIND_MEMORY_2_EXTENSION_NAME);
2713 mp_extensions = mp_extensions && DeviceExtensionSupported(gpu(), nullptr, VK_KHR_SAMPLER_YCBCR_CONVERSION_EXTENSION_NAME);
2714 if (mp_extensions) {
2715 m_device_extension_names.push_back(VK_KHR_MAINTENANCE1_EXTENSION_NAME);
2716 m_device_extension_names.push_back(VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME);
2717 m_device_extension_names.push_back(VK_KHR_BIND_MEMORY_2_EXTENSION_NAME);
2718 m_device_extension_names.push_back(VK_KHR_SAMPLER_YCBCR_CONVERSION_EXTENSION_NAME);
2719 } else {
2720 printf("%s test requires KHR multiplane extensions, not available. Skipping.\n", kSkipPrefix);
2721 return;
2722 }
2723 ASSERT_NO_FATAL_FAILURE(InitState());
2724
2725 // Select a _422 format and verify support
2726 VkImageCreateInfo ci = {};
2727 ci.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
2728 ci.pNext = NULL;
2729 ci.flags = 0;
2730 ci.imageType = VK_IMAGE_TYPE_2D;
2731 ci.format = VK_FORMAT_G8B8G8R8_422_UNORM_KHR;
2732 ci.tiling = VK_IMAGE_TILING_OPTIMAL;
2733 ci.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
2734 ci.mipLevels = 1;
2735 ci.arrayLayers = 1;
2736 ci.samples = VK_SAMPLE_COUNT_1_BIT;
2737 ci.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
2738 ci.queueFamilyIndexCount = 0;
2739 ci.pQueueFamilyIndices = NULL;
2740 ci.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
2741
2742 // Verify formats
2743 VkFormatFeatureFlags features = VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT;
2744 bool supported = ImageFormatAndFeaturesSupported(instance(), gpu(), ci, features);
2745 if (!supported) {
2746 printf("%s Single-plane _422 image format not supported. Skipping test.\n", kSkipPrefix);
2747 return; // Assume there's low ROI on searching for different mp formats
2748 }
2749
2750 // Create images
2751 ci.extent = {64, 64, 1};
2752 VkImageObj image_422(m_device);
2753 image_422.init(&ci);
2754 ASSERT_TRUE(image_422.initialized());
2755
2756 ci.extent = {64, 64, 1};
2757 ci.format = VK_FORMAT_R8G8B8A8_UNORM;
2758 VkImageObj image_ucmp(m_device);
2759 image_ucmp.init(&ci);
2760 ASSERT_TRUE(image_ucmp.initialized());
2761
2762 m_commandBuffer->begin();
2763
2764 VkImageCopy copy_region;
2765 copy_region.extent = {48, 48, 1};
2766 copy_region.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
2767 copy_region.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
2768 copy_region.srcSubresource.mipLevel = 0;
2769 copy_region.dstSubresource.mipLevel = 0;
2770 copy_region.srcSubresource.baseArrayLayer = 0;
2771 copy_region.dstSubresource.baseArrayLayer = 0;
2772 copy_region.srcSubresource.layerCount = 1;
2773 copy_region.dstSubresource.layerCount = 1;
2774 copy_region.srcOffset = {0, 0, 0};
2775 copy_region.dstOffset = {0, 0, 0};
2776
2777 // Src offsets must be multiples of compressed block sizes
2778 copy_region.srcOffset = {3, 4, 0}; // source offset x
Mark Lobodzinski20310782020-02-28 14:25:17 -07002779 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkImageCopy-srcImage-01727");
2780 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdCopyImage-srcOffset-01783");
unknown088160a2019-05-23 17:43:13 -06002781 m_commandBuffer->CopyImage(image_422.image(), VK_IMAGE_LAYOUT_GENERAL, image_ucmp.image(), VK_IMAGE_LAYOUT_GENERAL, 1,
2782 &copy_region);
2783 m_errorMonitor->VerifyFound();
2784 copy_region.srcOffset = {0, 0, 0};
2785
2786 // Dst offsets must be multiples of compressed block sizes
2787 copy_region.dstOffset = {1, 0, 0};
Mark Lobodzinski20310782020-02-28 14:25:17 -07002788 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkImageCopy-dstImage-01731");
2789 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdCopyImage-dstOffset-01784");
Mark Lobodzinski20310782020-02-28 14:25:17 -07002790 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkImageCopy-dstOffset-00150");
unknown088160a2019-05-23 17:43:13 -06002791 m_commandBuffer->CopyImage(image_ucmp.image(), VK_IMAGE_LAYOUT_GENERAL, image_422.image(), VK_IMAGE_LAYOUT_GENERAL, 1,
2792 &copy_region);
2793 m_errorMonitor->VerifyFound();
2794 copy_region.dstOffset = {0, 0, 0};
2795
2796 // Copy extent must be multiples of compressed block sizes if not full width/height
2797 copy_region.extent = {31, 60, 1}; // 422 source, extent.x
Mark Lobodzinski20310782020-02-28 14:25:17 -07002798 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkImageCopy-srcImage-01728");
2799 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdCopyImage-srcOffset-01783");
unknown088160a2019-05-23 17:43:13 -06002800 m_commandBuffer->CopyImage(image_422.image(), VK_IMAGE_LAYOUT_GENERAL, image_ucmp.image(), VK_IMAGE_LAYOUT_GENERAL, 1,
2801 &copy_region);
2802 m_errorMonitor->VerifyFound();
2803
unknown357e1782019-09-25 17:57:40 -06002804 // 422 dest
unknown088160a2019-05-23 17:43:13 -06002805 m_commandBuffer->CopyImage(image_ucmp.image(), VK_IMAGE_LAYOUT_GENERAL, image_422.image(), VK_IMAGE_LAYOUT_GENERAL, 1,
2806 &copy_region);
unknown357e1782019-09-25 17:57:40 -06002807 m_errorMonitor->VerifyNotFound();
unknown088160a2019-05-23 17:43:13 -06002808 copy_region.dstOffset = {0, 0, 0};
2809
2810 m_commandBuffer->end();
2811}
2812
2813TEST_F(VkLayerTest, CopyImageMultiplaneAspectBits) {
2814 // Image copy tests on multiplane images with aspect errors
2815
2816 // Enable KHR multiplane req'd extensions
2817 bool mp_extensions = InstanceExtensionSupported(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME,
2818 VK_KHR_GET_MEMORY_REQUIREMENTS_2_SPEC_VERSION);
2819 if (mp_extensions) {
2820 m_instance_extension_names.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
2821 }
Mark Lobodzinski09ce9c42020-03-06 10:02:44 -07002822 ASSERT_NO_FATAL_FAILURE(InitFramework(m_errorMonitor));
unknown088160a2019-05-23 17:43:13 -06002823 mp_extensions = mp_extensions && DeviceExtensionSupported(gpu(), nullptr, VK_KHR_MAINTENANCE1_EXTENSION_NAME);
2824 mp_extensions = mp_extensions && DeviceExtensionSupported(gpu(), nullptr, VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME);
2825 mp_extensions = mp_extensions && DeviceExtensionSupported(gpu(), nullptr, VK_KHR_BIND_MEMORY_2_EXTENSION_NAME);
2826 mp_extensions = mp_extensions && DeviceExtensionSupported(gpu(), nullptr, VK_KHR_SAMPLER_YCBCR_CONVERSION_EXTENSION_NAME);
2827 if (mp_extensions) {
2828 m_device_extension_names.push_back(VK_KHR_MAINTENANCE1_EXTENSION_NAME);
2829 m_device_extension_names.push_back(VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME);
2830 m_device_extension_names.push_back(VK_KHR_BIND_MEMORY_2_EXTENSION_NAME);
2831 m_device_extension_names.push_back(VK_KHR_SAMPLER_YCBCR_CONVERSION_EXTENSION_NAME);
2832 } else {
2833 printf("%s test requires KHR multiplane extensions, not available. Skipping.\n", kSkipPrefix);
2834 return;
2835 }
2836 ASSERT_NO_FATAL_FAILURE(InitState());
2837
2838 // Select multi-plane formats and verify support
2839 VkFormat mp3_format = VK_FORMAT_G8_B8_R8_3PLANE_422_UNORM_KHR;
2840 VkFormat mp2_format = VK_FORMAT_G8_B8R8_2PLANE_422_UNORM_KHR;
2841
2842 VkImageCreateInfo ci = {};
2843 ci.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
2844 ci.pNext = NULL;
2845 ci.flags = 0;
2846 ci.imageType = VK_IMAGE_TYPE_2D;
2847 ci.format = mp2_format;
2848 ci.extent = {256, 256, 1};
2849 ci.tiling = VK_IMAGE_TILING_OPTIMAL;
2850 ci.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
2851 ci.mipLevels = 1;
2852 ci.arrayLayers = 1;
2853 ci.samples = VK_SAMPLE_COUNT_1_BIT;
2854 ci.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
2855 ci.queueFamilyIndexCount = 0;
2856 ci.pQueueFamilyIndices = NULL;
2857 ci.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
2858
2859 // Verify formats
2860 VkFormatFeatureFlags features = VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT;
2861 bool supported = ImageFormatAndFeaturesSupported(instance(), gpu(), ci, features);
2862 ci.format = VK_FORMAT_D24_UNORM_S8_UINT;
2863 supported = supported && ImageFormatAndFeaturesSupported(instance(), gpu(), ci, features);
2864 ci.format = mp3_format;
2865 supported = supported && ImageFormatAndFeaturesSupported(instance(), gpu(), ci, features);
2866 if (!supported) {
2867 printf("%s Multiplane image formats or optimally tiled depth-stencil buffers not supported. Skipping test.\n",
2868 kSkipPrefix);
2869 return; // Assume there's low ROI on searching for different mp formats
2870 }
2871
2872 // Create images
2873 VkImageObj mp3_image(m_device);
2874 mp3_image.init(&ci);
2875 ASSERT_TRUE(mp3_image.initialized());
2876
2877 ci.format = mp2_format;
2878 VkImageObj mp2_image(m_device);
2879 mp2_image.init(&ci);
2880 ASSERT_TRUE(mp2_image.initialized());
2881
2882 ci.format = VK_FORMAT_D24_UNORM_S8_UINT;
2883 VkImageObj sp_image(m_device);
2884 sp_image.init(&ci);
2885 ASSERT_TRUE(sp_image.initialized());
2886
2887 m_commandBuffer->begin();
2888
2889 VkImageCopy copy_region;
2890 copy_region.extent = {128, 128, 1};
2891 copy_region.srcSubresource.aspectMask = VK_IMAGE_ASPECT_PLANE_2_BIT_KHR;
2892 copy_region.dstSubresource.aspectMask = VK_IMAGE_ASPECT_PLANE_2_BIT_KHR;
2893 copy_region.srcSubresource.mipLevel = 0;
2894 copy_region.dstSubresource.mipLevel = 0;
2895 copy_region.srcSubresource.baseArrayLayer = 0;
2896 copy_region.dstSubresource.baseArrayLayer = 0;
2897 copy_region.srcSubresource.layerCount = 1;
2898 copy_region.dstSubresource.layerCount = 1;
2899 copy_region.srcOffset = {0, 0, 0};
2900 copy_region.dstOffset = {0, 0, 0};
2901
Mark Lobodzinski20310782020-02-28 14:25:17 -07002902 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkImageCopy-srcImage-01552");
unknown088160a2019-05-23 17:43:13 -06002903 m_commandBuffer->CopyImage(mp2_image.image(), VK_IMAGE_LAYOUT_GENERAL, mp3_image.image(), VK_IMAGE_LAYOUT_GENERAL, 1,
2904 &copy_region);
2905 m_errorMonitor->VerifyFound();
2906
unknown088160a2019-05-23 17:43:13 -06002907 copy_region.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
2908 copy_region.dstSubresource.aspectMask = VK_IMAGE_ASPECT_PLANE_0_BIT_KHR;
Mark Lobodzinski20310782020-02-28 14:25:17 -07002909 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkImageCopy-srcImage-01553");
unknown088160a2019-05-23 17:43:13 -06002910 m_commandBuffer->CopyImage(mp3_image.image(), VK_IMAGE_LAYOUT_GENERAL, mp2_image.image(), VK_IMAGE_LAYOUT_GENERAL, 1,
2911 &copy_region);
2912 m_errorMonitor->VerifyFound();
2913
2914 copy_region.srcSubresource.aspectMask = VK_IMAGE_ASPECT_PLANE_1_BIT_KHR;
2915 copy_region.dstSubresource.aspectMask = VK_IMAGE_ASPECT_PLANE_2_BIT_KHR;
Mark Lobodzinski20310782020-02-28 14:25:17 -07002916 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkImageCopy-dstImage-01554");
unknown088160a2019-05-23 17:43:13 -06002917 m_commandBuffer->CopyImage(mp3_image.image(), VK_IMAGE_LAYOUT_GENERAL, mp2_image.image(), VK_IMAGE_LAYOUT_GENERAL, 1,
2918 &copy_region);
2919 m_errorMonitor->VerifyFound();
2920
2921 copy_region.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
Mark Lobodzinski20310782020-02-28 14:25:17 -07002922 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkImageCopy-dstImage-01555");
unknown088160a2019-05-23 17:43:13 -06002923 m_commandBuffer->CopyImage(mp2_image.image(), VK_IMAGE_LAYOUT_GENERAL, mp3_image.image(), VK_IMAGE_LAYOUT_GENERAL, 1,
2924 &copy_region);
2925 m_errorMonitor->VerifyFound();
2926
2927 copy_region.dstSubresource.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT;
Mark Lobodzinski20310782020-02-28 14:25:17 -07002928 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkImageCopy-srcImage-01556");
sfricke-samsung99dc12c2020-04-23 01:52:01 -07002929 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdCopyImage-None-01549"); // since also non-compatiable
unknown088160a2019-05-23 17:43:13 -06002930 m_commandBuffer->CopyImage(mp2_image.image(), VK_IMAGE_LAYOUT_GENERAL, sp_image.image(), VK_IMAGE_LAYOUT_GENERAL, 1,
2931 &copy_region);
2932 m_errorMonitor->VerifyFound();
2933
2934 copy_region.srcSubresource.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT;
2935 copy_region.dstSubresource.aspectMask = VK_IMAGE_ASPECT_PLANE_2_BIT_KHR;
Mark Lobodzinski20310782020-02-28 14:25:17 -07002936 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkImageCopy-dstImage-01557");
sfricke-samsung99dc12c2020-04-23 01:52:01 -07002937 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdCopyImage-None-01549"); // since also non-compatiable
unknown088160a2019-05-23 17:43:13 -06002938 m_commandBuffer->CopyImage(sp_image.image(), VK_IMAGE_LAYOUT_GENERAL, mp3_image.image(), VK_IMAGE_LAYOUT_GENERAL, 1,
2939 &copy_region);
2940 m_errorMonitor->VerifyFound();
2941
2942 m_commandBuffer->end();
2943}
2944
2945TEST_F(VkLayerTest, CopyImageSrcSizeExceeded) {
2946 // Image copy with source region specified greater than src image size
2947 ASSERT_NO_FATAL_FAILURE(Init());
2948
2949 // Create images with full mip chain
2950 VkImageCreateInfo ci;
2951 ci.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
2952 ci.pNext = NULL;
2953 ci.flags = 0;
2954 ci.imageType = VK_IMAGE_TYPE_3D;
2955 ci.format = VK_FORMAT_R8G8B8A8_UNORM;
2956 ci.extent = {32, 32, 8};
2957 ci.mipLevels = 6;
2958 ci.arrayLayers = 1;
2959 ci.samples = VK_SAMPLE_COUNT_1_BIT;
2960 ci.tiling = VK_IMAGE_TILING_OPTIMAL;
2961 ci.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
2962 ci.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
2963 ci.queueFamilyIndexCount = 0;
2964 ci.pQueueFamilyIndices = NULL;
2965 ci.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
2966
2967 VkImageObj src_image(m_device);
2968 src_image.init(&ci);
2969 ASSERT_TRUE(src_image.initialized());
2970
2971 // Dest image with one more mip level
2972 ci.extent = {64, 64, 16};
2973 ci.mipLevels = 7;
2974 ci.usage = VK_IMAGE_USAGE_TRANSFER_DST_BIT;
2975 VkImageObj dst_image(m_device);
2976 dst_image.init(&ci);
2977 ASSERT_TRUE(dst_image.initialized());
2978
2979 m_commandBuffer->begin();
2980
2981 VkImageCopy copy_region;
2982 copy_region.extent = {32, 32, 8};
2983 copy_region.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
2984 copy_region.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
2985 copy_region.srcSubresource.mipLevel = 0;
2986 copy_region.dstSubresource.mipLevel = 0;
2987 copy_region.srcSubresource.baseArrayLayer = 0;
2988 copy_region.dstSubresource.baseArrayLayer = 0;
2989 copy_region.srcSubresource.layerCount = 1;
2990 copy_region.dstSubresource.layerCount = 1;
2991 copy_region.srcOffset = {0, 0, 0};
2992 copy_region.dstOffset = {0, 0, 0};
2993
2994 m_errorMonitor->ExpectSuccess();
2995 m_commandBuffer->CopyImage(src_image.image(), VK_IMAGE_LAYOUT_GENERAL, dst_image.image(), VK_IMAGE_LAYOUT_GENERAL, 1,
2996 &copy_region);
2997 m_errorMonitor->VerifyNotFound();
2998
2999 // Source exceeded in x-dim, VU 01202
3000 copy_region.srcOffset.x = 4;
Mark Lobodzinski20310782020-02-28 14:25:17 -07003001 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkImageCopy-srcOffset-00144");
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 // Source exceeded in y-dim, VU 01203
3007 copy_region.srcOffset.x = 0;
3008 copy_region.extent.height = 48;
Mark Lobodzinski20310782020-02-28 14:25:17 -07003009 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkImageCopy-srcOffset-00145");
unknown088160a2019-05-23 17:43:13 -06003010 m_commandBuffer->CopyImage(src_image.image(), VK_IMAGE_LAYOUT_GENERAL, dst_image.image(), VK_IMAGE_LAYOUT_GENERAL, 1,
3011 &copy_region);
3012 m_errorMonitor->VerifyFound();
3013
3014 // Source exceeded in z-dim, VU 01204
3015 copy_region.extent = {4, 4, 4};
3016 copy_region.srcSubresource.mipLevel = 2;
Mark Lobodzinski20310782020-02-28 14:25:17 -07003017 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkImageCopy-srcOffset-00147");
unknown088160a2019-05-23 17:43:13 -06003018 m_commandBuffer->CopyImage(src_image.image(), VK_IMAGE_LAYOUT_GENERAL, dst_image.image(), VK_IMAGE_LAYOUT_GENERAL, 1,
3019 &copy_region);
3020 m_errorMonitor->VerifyFound();
3021
3022 m_commandBuffer->end();
3023}
3024
3025TEST_F(VkLayerTest, CopyImageDstSizeExceeded) {
3026 // Image copy with dest region specified greater than dest image size
3027 ASSERT_NO_FATAL_FAILURE(Init());
3028
3029 // Create images with full mip chain
3030 VkImageCreateInfo ci;
3031 ci.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
3032 ci.pNext = NULL;
3033 ci.flags = 0;
3034 ci.imageType = VK_IMAGE_TYPE_3D;
3035 ci.format = VK_FORMAT_R8G8B8A8_UNORM;
3036 ci.extent = {32, 32, 8};
3037 ci.mipLevels = 6;
3038 ci.arrayLayers = 1;
3039 ci.samples = VK_SAMPLE_COUNT_1_BIT;
3040 ci.tiling = VK_IMAGE_TILING_OPTIMAL;
3041 ci.usage = VK_IMAGE_USAGE_TRANSFER_DST_BIT;
3042 ci.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
3043 ci.queueFamilyIndexCount = 0;
3044 ci.pQueueFamilyIndices = NULL;
3045 ci.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
3046
3047 VkImageObj dst_image(m_device);
3048 dst_image.init(&ci);
3049 ASSERT_TRUE(dst_image.initialized());
3050
3051 // Src image with one more mip level
3052 ci.extent = {64, 64, 16};
3053 ci.mipLevels = 7;
3054 ci.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
3055 VkImageObj src_image(m_device);
3056 src_image.init(&ci);
3057 ASSERT_TRUE(src_image.initialized());
3058
3059 m_commandBuffer->begin();
3060
3061 VkImageCopy copy_region;
3062 copy_region.extent = {32, 32, 8};
3063 copy_region.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
3064 copy_region.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
3065 copy_region.srcSubresource.mipLevel = 0;
3066 copy_region.dstSubresource.mipLevel = 0;
3067 copy_region.srcSubresource.baseArrayLayer = 0;
3068 copy_region.dstSubresource.baseArrayLayer = 0;
3069 copy_region.srcSubresource.layerCount = 1;
3070 copy_region.dstSubresource.layerCount = 1;
3071 copy_region.srcOffset = {0, 0, 0};
3072 copy_region.dstOffset = {0, 0, 0};
3073
3074 m_errorMonitor->ExpectSuccess();
3075 m_commandBuffer->CopyImage(src_image.image(), VK_IMAGE_LAYOUT_GENERAL, dst_image.image(), VK_IMAGE_LAYOUT_GENERAL, 1,
3076 &copy_region);
3077 m_errorMonitor->VerifyNotFound();
3078
3079 // Dest exceeded in x-dim, VU 01205
3080 copy_region.dstOffset.x = 4;
Mark Lobodzinski20310782020-02-28 14:25:17 -07003081 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkImageCopy-dstOffset-00150");
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 // Dest exceeded in y-dim, VU 01206
3087 copy_region.dstOffset.x = 0;
3088 copy_region.extent.height = 48;
Mark Lobodzinski20310782020-02-28 14:25:17 -07003089 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkImageCopy-dstOffset-00151");
unknown088160a2019-05-23 17:43:13 -06003090 m_commandBuffer->CopyImage(src_image.image(), VK_IMAGE_LAYOUT_GENERAL, dst_image.image(), VK_IMAGE_LAYOUT_GENERAL, 1,
3091 &copy_region);
3092 m_errorMonitor->VerifyFound();
3093
3094 // Dest exceeded in z-dim, VU 01207
3095 copy_region.extent = {4, 4, 4};
3096 copy_region.dstSubresource.mipLevel = 2;
Mark Lobodzinski20310782020-02-28 14:25:17 -07003097 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkImageCopy-dstOffset-00153");
unknown088160a2019-05-23 17:43:13 -06003098 m_commandBuffer->CopyImage(src_image.image(), VK_IMAGE_LAYOUT_GENERAL, dst_image.image(), VK_IMAGE_LAYOUT_GENERAL, 1,
3099 &copy_region);
3100 m_errorMonitor->VerifyFound();
3101
3102 m_commandBuffer->end();
3103}
3104
sfricke-samsung8ceaaea2020-03-07 14:08:08 -08003105TEST_F(VkLayerTest, CopyImageMultiPlaneSizeExceeded) {
3106 TEST_DESCRIPTION("Image Copy for multi-planar format that exceed size of plane for both src and dst");
3107
3108 // Enable KHR multiplane req'd extensions
3109 bool mp_extensions = InstanceExtensionSupported(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME,
3110 VK_KHR_GET_MEMORY_REQUIREMENTS_2_SPEC_VERSION);
3111 if (mp_extensions == true) {
3112 m_instance_extension_names.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
3113 }
3114 ASSERT_NO_FATAL_FAILURE(InitFramework(m_errorMonitor));
3115 mp_extensions = mp_extensions && DeviceExtensionSupported(gpu(), nullptr, VK_KHR_MAINTENANCE1_EXTENSION_NAME);
3116 mp_extensions = mp_extensions && DeviceExtensionSupported(gpu(), nullptr, VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME);
3117 mp_extensions = mp_extensions && DeviceExtensionSupported(gpu(), nullptr, VK_KHR_BIND_MEMORY_2_EXTENSION_NAME);
3118 mp_extensions = mp_extensions && DeviceExtensionSupported(gpu(), nullptr, VK_KHR_SAMPLER_YCBCR_CONVERSION_EXTENSION_NAME);
3119 if (mp_extensions == true) {
3120 m_device_extension_names.push_back(VK_KHR_MAINTENANCE1_EXTENSION_NAME);
3121 m_device_extension_names.push_back(VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME);
3122 m_device_extension_names.push_back(VK_KHR_BIND_MEMORY_2_EXTENSION_NAME);
3123 m_device_extension_names.push_back(VK_KHR_SAMPLER_YCBCR_CONVERSION_EXTENSION_NAME);
3124 } else {
3125 printf("%s test requires KHR multiplane extensions, not available. Skipping.\n", kSkipPrefix);
3126 return;
3127 }
3128 ASSERT_NO_FATAL_FAILURE(InitState());
3129
sfricke-samsung99dc12c2020-04-23 01:52:01 -07003130 // Try to use VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM because need multi-plane format for some tests and likely supported due to
3131 // copy support being required with samplerYcbcrConversion feature
sfricke-samsung8ceaaea2020-03-07 14:08:08 -08003132 VkFormatProperties props = {0, 0, 0};
3133 bool missing_format_support = false;
sfricke-samsung99dc12c2020-04-23 01:52:01 -07003134 vk::GetPhysicalDeviceFormatProperties(m_device->phy().handle(), VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM, &props);
sfricke-samsung8ceaaea2020-03-07 14:08:08 -08003135 missing_format_support |= (props.bufferFeatures == 0 && props.linearTilingFeatures == 0 && props.optimalTilingFeatures == 0);
3136 missing_format_support |= (props.optimalTilingFeatures & VK_FORMAT_FEATURE_TRANSFER_SRC_BIT) == 0;
3137 missing_format_support |= (props.optimalTilingFeatures & VK_FORMAT_FEATURE_TRANSFER_DST_BIT) == 0;
3138
3139 if (missing_format_support == true) {
sfricke-samsung99dc12c2020-04-23 01:52:01 -07003140 printf("%s VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM transfer not supported; skipped.\n", kSkipPrefix);
sfricke-samsung8ceaaea2020-03-07 14:08:08 -08003141 return;
3142 }
3143
3144 // 128^2 texels in plane_0 and 64^2 texels in plane_1
3145 VkImageObj src_image(m_device);
3146 VkImageObj dst_image(m_device);
sfricke-samsung99dc12c2020-04-23 01:52:01 -07003147 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 -08003148 ASSERT_TRUE(src_image.initialized());
sfricke-samsung99dc12c2020-04-23 01:52:01 -07003149 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 -08003150 ASSERT_TRUE(dst_image.initialized());
3151
3152 VkImageCopy copy_region = {};
3153 copy_region.extent = {64, 64, 1}; // Size of plane 1
3154 copy_region.srcSubresource.aspectMask = VK_IMAGE_ASPECT_PLANE_1_BIT;
3155 copy_region.dstSubresource.aspectMask = VK_IMAGE_ASPECT_PLANE_1_BIT;
3156 copy_region.srcSubresource.mipLevel = 0;
3157 copy_region.dstSubresource.mipLevel = 0;
3158 copy_region.srcSubresource.baseArrayLayer = 0;
3159 copy_region.dstSubresource.baseArrayLayer = 0;
3160 copy_region.srcSubresource.layerCount = 1;
3161 copy_region.dstSubresource.layerCount = 1;
3162 copy_region.srcOffset = {0, 0, 0};
3163 copy_region.dstOffset = {0, 0, 0};
3164 VkImageCopy original_region = copy_region;
3165
3166 m_commandBuffer->begin();
3167
3168 // Should be able to do a 64x64 copy from plane 1 -> Plane 1
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 0
3175 copy_region.srcSubresource.aspectMask = VK_IMAGE_ASPECT_PLANE_0_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 64x64 copy from plane 0 -> Plane 1
3183 copy_region.srcSubresource.aspectMask = VK_IMAGE_ASPECT_PLANE_0_BIT;
3184 copy_region.dstSubresource.aspectMask = VK_IMAGE_ASPECT_PLANE_1_BIT;
3185 m_errorMonitor->ExpectSuccess();
3186 m_commandBuffer->CopyImage(src_image.image(), VK_IMAGE_LAYOUT_GENERAL, dst_image.image(), VK_IMAGE_LAYOUT_GENERAL, 1,
3187 &copy_region);
3188 m_errorMonitor->VerifyNotFound();
3189
3190 // Should be able to do a 64x64 copy from plane 0 -> Plane 1
3191 copy_region.srcSubresource.aspectMask = VK_IMAGE_ASPECT_PLANE_1_BIT;
3192 copy_region.dstSubresource.aspectMask = VK_IMAGE_ASPECT_PLANE_0_BIT;
3193 m_errorMonitor->ExpectSuccess();
3194 m_commandBuffer->CopyImage(src_image.image(), VK_IMAGE_LAYOUT_GENERAL, dst_image.image(), VK_IMAGE_LAYOUT_GENERAL, 1,
3195 &copy_region);
3196 m_errorMonitor->VerifyNotFound();
3197
3198 // Should be able to do a 128x64 copy from plane 0 -> Plane 0
3199 copy_region.extent = {128, 64, 1};
3200 copy_region.srcSubresource.aspectMask = VK_IMAGE_ASPECT_PLANE_0_BIT;
3201 copy_region.dstSubresource.aspectMask = VK_IMAGE_ASPECT_PLANE_0_BIT;
3202 m_errorMonitor->ExpectSuccess();
3203 m_commandBuffer->CopyImage(src_image.image(), VK_IMAGE_LAYOUT_GENERAL, dst_image.image(), VK_IMAGE_LAYOUT_GENERAL, 1,
3204 &copy_region);
3205 m_errorMonitor->VerifyNotFound();
3206
3207 // 128x64 copy from plane 0 -> Plane 1
3208 copy_region.extent = {128, 64, 1};
3209 copy_region.srcSubresource.aspectMask = VK_IMAGE_ASPECT_PLANE_0_BIT;
3210 copy_region.dstSubresource.aspectMask = VK_IMAGE_ASPECT_PLANE_1_BIT;
sfricke-samsung8ceaaea2020-03-07 14:08:08 -08003211 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkImageCopy-dstOffset-00150");
3212 m_commandBuffer->CopyImage(src_image.image(), VK_IMAGE_LAYOUT_GENERAL, dst_image.image(), VK_IMAGE_LAYOUT_GENERAL, 1,
3213 &copy_region);
3214 m_errorMonitor->VerifyFound();
3215
3216 // 128x64 copy from plane 1 -> Plane 0
3217 copy_region.extent = {128, 64, 1};
3218 copy_region.srcSubresource.aspectMask = VK_IMAGE_ASPECT_PLANE_1_BIT;
3219 copy_region.dstSubresource.aspectMask = VK_IMAGE_ASPECT_PLANE_0_BIT;
sfricke-samsung8ceaaea2020-03-07 14:08:08 -08003220 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkImageCopy-srcOffset-00144");
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 // src exceeded in y-dim from offset
3226 copy_region = original_region;
3227 copy_region.srcOffset.y = 4;
sfricke-samsung8ceaaea2020-03-07 14:08:08 -08003228 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkImageCopy-srcOffset-00145");
3229 m_commandBuffer->CopyImage(src_image.image(), VK_IMAGE_LAYOUT_GENERAL, dst_image.image(), VK_IMAGE_LAYOUT_GENERAL, 1,
3230 &copy_region);
3231 m_errorMonitor->VerifyFound();
3232
3233 // dst exceeded in y-dim from offset
3234 copy_region = original_region;
3235 copy_region.dstOffset.y = 4;
sfricke-samsung8ceaaea2020-03-07 14:08:08 -08003236 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkImageCopy-dstOffset-00151");
3237 m_commandBuffer->CopyImage(src_image.image(), VK_IMAGE_LAYOUT_GENERAL, dst_image.image(), VK_IMAGE_LAYOUT_GENERAL, 1,
3238 &copy_region);
3239 m_errorMonitor->VerifyFound();
3240
3241 m_commandBuffer->end();
3242}
3243
unknown088160a2019-05-23 17:43:13 -06003244TEST_F(VkLayerTest, CopyImageFormatSizeMismatch) {
sfricke-samsung51067b22020-04-30 21:41:17 -07003245 if (!EnableDeviceProfileLayer()) {
3246 printf("%s Failed to enable device profile layer.\n", kSkipPrefix);
3247 return;
3248 }
unknown088160a2019-05-23 17:43:13 -06003249
sfricke-samsung8ceaaea2020-03-07 14:08:08 -08003250 // Enable KHR multiplane req'd extensions
3251 bool mp_extensions = InstanceExtensionSupported(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME,
3252 VK_KHR_GET_MEMORY_REQUIREMENTS_2_SPEC_VERSION);
3253 if (mp_extensions == true) {
3254 m_instance_extension_names.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
3255 }
3256 ASSERT_NO_FATAL_FAILURE(InitFramework(m_errorMonitor));
3257 mp_extensions = mp_extensions && DeviceExtensionSupported(gpu(), nullptr, VK_KHR_MAINTENANCE1_EXTENSION_NAME);
3258 mp_extensions = mp_extensions && DeviceExtensionSupported(gpu(), nullptr, VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME);
3259 mp_extensions = mp_extensions && DeviceExtensionSupported(gpu(), nullptr, VK_KHR_BIND_MEMORY_2_EXTENSION_NAME);
3260 mp_extensions = mp_extensions && DeviceExtensionSupported(gpu(), nullptr, VK_KHR_SAMPLER_YCBCR_CONVERSION_EXTENSION_NAME);
3261 if (mp_extensions == true) {
3262 m_device_extension_names.push_back(VK_KHR_MAINTENANCE1_EXTENSION_NAME);
3263 m_device_extension_names.push_back(VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME);
3264 m_device_extension_names.push_back(VK_KHR_BIND_MEMORY_2_EXTENSION_NAME);
3265 m_device_extension_names.push_back(VK_KHR_SAMPLER_YCBCR_CONVERSION_EXTENSION_NAME);
3266 }
3267 ASSERT_NO_FATAL_FAILURE(InitState());
unknown088160a2019-05-23 17:43:13 -06003268
sfricke-samsung51067b22020-04-30 21:41:17 -07003269 PFN_vkSetPhysicalDeviceFormatPropertiesEXT fpvkSetPhysicalDeviceFormatPropertiesEXT = nullptr;
3270 PFN_vkGetOriginalPhysicalDeviceFormatPropertiesEXT fpvkGetOriginalPhysicalDeviceFormatPropertiesEXT = nullptr;
sfricke-samsungdce5f692020-03-07 13:59:31 -08003271
sfricke-samsung51067b22020-04-30 21:41:17 -07003272 // Load required functions
3273 if (!LoadDeviceProfileLayer(fpvkSetPhysicalDeviceFormatPropertiesEXT, fpvkGetOriginalPhysicalDeviceFormatPropertiesEXT)) {
3274 printf("%s Failed to device profile layer.\n", kSkipPrefix);
3275 return;
3276 }
3277
3278 // Set transfer for all potential used formats
3279 VkFormatProperties format_props;
3280 fpvkGetOriginalPhysicalDeviceFormatPropertiesEXT(gpu(), VK_FORMAT_R8_UNORM, &format_props);
3281 format_props.optimalTilingFeatures |= (VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT);
3282 fpvkSetPhysicalDeviceFormatPropertiesEXT(gpu(), VK_FORMAT_R8_UNORM, format_props);
3283
3284 fpvkGetOriginalPhysicalDeviceFormatPropertiesEXT(gpu(), VK_FORMAT_R8_UINT, &format_props);
3285 format_props.optimalTilingFeatures |= (VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT);
3286 fpvkSetPhysicalDeviceFormatPropertiesEXT(gpu(), VK_FORMAT_R8_UINT, format_props);
unknown088160a2019-05-23 17:43:13 -06003287
3288 VkImageCreateInfo image_create_info = {};
3289 image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
3290 image_create_info.pNext = NULL;
3291 image_create_info.imageType = VK_IMAGE_TYPE_2D;
unknown088160a2019-05-23 17:43:13 -06003292 image_create_info.extent.width = 32;
3293 image_create_info.extent.height = 32;
3294 image_create_info.extent.depth = 1;
3295 image_create_info.mipLevels = 1;
3296 image_create_info.arrayLayers = 1;
3297 image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
sfricke-samsung51067b22020-04-30 21:41:17 -07003298 image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL;
3299 image_create_info.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
unknown088160a2019-05-23 17:43:13 -06003300 image_create_info.flags = 0;
3301
sfricke-samsung51067b22020-04-30 21:41:17 -07003302 image_create_info.format = VK_FORMAT_R8_UNORM;
3303 VkImageObj image_8b_unorm(m_device);
3304 image_8b_unorm.init(&image_create_info);
unknown088160a2019-05-23 17:43:13 -06003305
sfricke-samsung51067b22020-04-30 21:41:17 -07003306 image_create_info.format = VK_FORMAT_R8_UINT;
3307 VkImageObj image_8b_uint(m_device);
3308 image_8b_uint.init(&image_create_info);
3309
3310 // First try to test two single plane mismatch
3311 {
3312 fpvkGetOriginalPhysicalDeviceFormatPropertiesEXT(gpu(), VK_FORMAT_R8G8B8A8_UNORM, &format_props);
3313 format_props.optimalTilingFeatures |= (VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT);
3314 fpvkSetPhysicalDeviceFormatPropertiesEXT(gpu(), VK_FORMAT_R8G8B8A8_UNORM, format_props);
3315
3316 image_create_info.format = VK_FORMAT_R8G8B8A8_UNORM;
3317 VkImageObj image_32b_unorm(m_device);
3318 image_32b_unorm.init(&image_create_info);
3319
3320 m_commandBuffer->begin();
3321 VkImageCopy copyRegion;
3322 copyRegion.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
3323 copyRegion.srcSubresource.mipLevel = 0;
3324 copyRegion.srcSubresource.baseArrayLayer = 0;
3325 copyRegion.srcSubresource.layerCount = 1;
3326 copyRegion.srcOffset.x = 0;
3327 copyRegion.srcOffset.y = 0;
3328 copyRegion.srcOffset.z = 0;
3329 copyRegion.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
3330 copyRegion.dstSubresource.mipLevel = 0;
3331 copyRegion.dstSubresource.baseArrayLayer = 0;
3332 copyRegion.dstSubresource.layerCount = 1;
3333 copyRegion.dstOffset.x = 0;
3334 copyRegion.dstOffset.y = 0;
3335 copyRegion.dstOffset.z = 0;
3336 copyRegion.extent.width = 1;
3337 copyRegion.extent.height = 1;
3338 copyRegion.extent.depth = 1;
3339
3340 // Sanity check between two 8bit formats
3341 m_errorMonitor->ExpectSuccess();
3342 m_commandBuffer->CopyImage(image_8b_unorm.handle(), VK_IMAGE_LAYOUT_GENERAL, image_8b_uint.handle(),
3343 VK_IMAGE_LAYOUT_GENERAL, 1, &copyRegion);
3344 m_errorMonitor->VerifyNotFound();
3345
3346 const char *vuid = (mp_extensions) ? "VUID-vkCmdCopyImage-srcImage-01548" : "VUID-vkCmdCopyImage-srcImage-00135";
3347 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, vuid);
3348 m_commandBuffer->CopyImage(image_8b_unorm.handle(), VK_IMAGE_LAYOUT_GENERAL, image_32b_unorm.handle(),
3349 VK_IMAGE_LAYOUT_GENERAL, 1, &copyRegion);
3350 m_errorMonitor->VerifyFound();
3351
3352 // Swap src and dst
3353 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, vuid);
3354 m_commandBuffer->CopyImage(image_32b_unorm.handle(), VK_IMAGE_LAYOUT_GENERAL, image_8b_unorm.handle(),
3355 VK_IMAGE_LAYOUT_GENERAL, 1, &copyRegion);
3356 m_errorMonitor->VerifyFound();
3357
3358 m_commandBuffer->end();
unknown088160a2019-05-23 17:43:13 -06003359 }
3360
sfricke-samsung51067b22020-04-30 21:41:17 -07003361 // DstImage is a mismatched plane of a multi-planar format
3362 if (mp_extensions == false) {
3363 printf("%s No multi-planar support; section of tests skipped.\n", kSkipPrefix);
3364 } else {
3365 fpvkGetOriginalPhysicalDeviceFormatPropertiesEXT(gpu(), VK_FORMAT_G8_B8R8_2PLANE_420_UNORM, &format_props);
3366 format_props.optimalTilingFeatures |= (VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT);
3367 fpvkSetPhysicalDeviceFormatPropertiesEXT(gpu(), VK_FORMAT_G8_B8R8_2PLANE_420_UNORM, format_props);
unknown088160a2019-05-23 17:43:13 -06003368
sfricke-samsung51067b22020-04-30 21:41:17 -07003369 image_create_info.format = VK_FORMAT_G8_B8R8_2PLANE_420_UNORM;
3370 VkImageObj image_8b_16b_420_unorm(m_device);
3371 image_8b_16b_420_unorm.init(&image_create_info);
unknown088160a2019-05-23 17:43:13 -06003372
sfricke-samsung51067b22020-04-30 21:41:17 -07003373 m_commandBuffer->begin();
3374 VkImageCopy copyRegion;
3375 copyRegion.srcSubresource.mipLevel = 0;
3376 copyRegion.srcSubresource.baseArrayLayer = 0;
3377 copyRegion.srcSubresource.layerCount = 1;
3378 copyRegion.srcOffset.x = 0;
3379 copyRegion.srcOffset.y = 0;
3380 copyRegion.srcOffset.z = 0;
3381 copyRegion.dstSubresource.mipLevel = 0;
3382 copyRegion.dstSubresource.baseArrayLayer = 0;
3383 copyRegion.dstSubresource.layerCount = 1;
3384 copyRegion.dstOffset.x = 0;
3385 copyRegion.dstOffset.y = 0;
3386 copyRegion.dstOffset.z = 0;
3387 copyRegion.extent.width = 1;
3388 copyRegion.extent.height = 1;
3389 copyRegion.extent.depth = 1;
unknown088160a2019-05-23 17:43:13 -06003390
sfricke-samsung51067b22020-04-30 21:41:17 -07003391 // First test single-plane -> multi-plan
3392 copyRegion.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
3393 copyRegion.dstSubresource.aspectMask = VK_IMAGE_ASPECT_PLANE_0_BIT;
unknown088160a2019-05-23 17:43:13 -06003394
sfricke-samsung51067b22020-04-30 21:41:17 -07003395 // Plane 0 is VK_FORMAT_R8_UNORM so this should succeed
3396 m_errorMonitor->ExpectSuccess();
3397 m_commandBuffer->CopyImage(image_8b_unorm.handle(), VK_IMAGE_LAYOUT_GENERAL, image_8b_16b_420_unorm.handle(),
3398 VK_IMAGE_LAYOUT_GENERAL, 1, &copyRegion);
3399 m_errorMonitor->VerifyNotFound();
unknown088160a2019-05-23 17:43:13 -06003400
sfricke-samsung51067b22020-04-30 21:41:17 -07003401 // Make sure no false postiives if Compatible format
3402 m_errorMonitor->ExpectSuccess();
3403 m_commandBuffer->CopyImage(image_8b_uint.handle(), VK_IMAGE_LAYOUT_GENERAL, image_8b_16b_420_unorm.handle(),
3404 VK_IMAGE_LAYOUT_GENERAL, 1, &copyRegion);
3405 m_errorMonitor->VerifyNotFound();
unknown088160a2019-05-23 17:43:13 -06003406
sfricke-samsung51067b22020-04-30 21:41:17 -07003407 // Plane 1 is VK_FORMAT_R8G8_UNORM so this should fail
3408 copyRegion.dstSubresource.aspectMask = VK_IMAGE_ASPECT_PLANE_1_BIT;
3409 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdCopyImage-None-01549");
3410 m_commandBuffer->CopyImage(image_8b_unorm.handle(), VK_IMAGE_LAYOUT_GENERAL, image_8b_16b_420_unorm.handle(),
3411 VK_IMAGE_LAYOUT_GENERAL, 1, &copyRegion);
3412 m_errorMonitor->VerifyFound();
unknown088160a2019-05-23 17:43:13 -06003413
sfricke-samsung51067b22020-04-30 21:41:17 -07003414 // Same tests but swap src and dst
3415 copyRegion.srcSubresource.aspectMask = VK_IMAGE_ASPECT_PLANE_0_BIT;
3416 copyRegion.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
sfricke-samsungdce5f692020-03-07 13:59:31 -08003417
sfricke-samsung51067b22020-04-30 21:41:17 -07003418 m_errorMonitor->ExpectSuccess();
3419 m_commandBuffer->CopyImage(image_8b_16b_420_unorm.handle(), VK_IMAGE_LAYOUT_GENERAL, image_8b_unorm.handle(),
3420 VK_IMAGE_LAYOUT_GENERAL, 1, &copyRegion);
3421 m_errorMonitor->VerifyNotFound();
3422
3423 m_errorMonitor->ExpectSuccess();
3424 m_commandBuffer->CopyImage(image_8b_16b_420_unorm.handle(), VK_IMAGE_LAYOUT_GENERAL, image_8b_uint.handle(),
3425 VK_IMAGE_LAYOUT_GENERAL, 1, &copyRegion);
3426 m_errorMonitor->VerifyNotFound();
3427
3428 copyRegion.srcSubresource.aspectMask = VK_IMAGE_ASPECT_PLANE_1_BIT;
3429 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdCopyImage-None-01549");
3430 m_commandBuffer->CopyImage(image_8b_16b_420_unorm.handle(), VK_IMAGE_LAYOUT_GENERAL, image_8b_unorm.handle(),
3431 VK_IMAGE_LAYOUT_GENERAL, 1, &copyRegion);
3432 m_errorMonitor->VerifyFound();
3433
3434 m_commandBuffer->end();
3435 }
unknown088160a2019-05-23 17:43:13 -06003436}
3437
3438TEST_F(VkLayerTest, CopyImageDepthStencilFormatMismatch) {
3439 ASSERT_NO_FATAL_FAILURE(Init());
3440 auto depth_format = FindSupportedDepthStencilFormat(gpu());
3441 if (!depth_format) {
3442 printf("%s Couldn't depth stencil image format.\n", kSkipPrefix);
3443 return;
3444 }
3445
3446 VkFormatProperties properties;
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06003447 vk::GetPhysicalDeviceFormatProperties(m_device->phy().handle(), VK_FORMAT_D32_SFLOAT, &properties);
unknown088160a2019-05-23 17:43:13 -06003448 if (properties.optimalTilingFeatures == 0) {
3449 printf("%s Image format not supported; skipped.\n", kSkipPrefix);
3450 return;
3451 }
3452
3453 VkImageObj srcImage(m_device);
3454 srcImage.Init(32, 32, 1, VK_FORMAT_D32_SFLOAT, VK_IMAGE_USAGE_TRANSFER_SRC_BIT, VK_IMAGE_TILING_OPTIMAL);
3455 ASSERT_TRUE(srcImage.initialized());
3456 VkImageObj dstImage(m_device);
3457 dstImage.Init(32, 32, 1, depth_format, VK_IMAGE_USAGE_TRANSFER_DST_BIT, VK_IMAGE_TILING_OPTIMAL);
3458 ASSERT_TRUE(dstImage.initialized());
3459
3460 // Create two images of different types and try to copy between them
3461
3462 m_commandBuffer->begin();
3463 VkImageCopy copyRegion;
3464 copyRegion.srcSubresource.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT;
3465 copyRegion.srcSubresource.mipLevel = 0;
3466 copyRegion.srcSubresource.baseArrayLayer = 0;
3467 copyRegion.srcSubresource.layerCount = 1;
3468 copyRegion.srcOffset.x = 0;
3469 copyRegion.srcOffset.y = 0;
3470 copyRegion.srcOffset.z = 0;
3471 copyRegion.dstSubresource.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT;
3472 copyRegion.dstSubresource.mipLevel = 0;
3473 copyRegion.dstSubresource.baseArrayLayer = 0;
3474 copyRegion.dstSubresource.layerCount = 1;
3475 copyRegion.dstOffset.x = 0;
3476 copyRegion.dstOffset.y = 0;
3477 copyRegion.dstOffset.z = 0;
3478 copyRegion.extent.width = 1;
3479 copyRegion.extent.height = 1;
3480 copyRegion.extent.depth = 1;
3481
sfricke-samsung99dc12c2020-04-23 01:52:01 -07003482 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdCopyImage-srcImage-00135");
unknown088160a2019-05-23 17:43:13 -06003483 m_commandBuffer->CopyImage(srcImage.handle(), VK_IMAGE_LAYOUT_GENERAL, dstImage.handle(), VK_IMAGE_LAYOUT_GENERAL, 1,
3484 &copyRegion);
3485 m_commandBuffer->end();
3486
3487 m_errorMonitor->VerifyFound();
3488}
3489
3490TEST_F(VkLayerTest, CopyImageSampleCountMismatch) {
3491 TEST_DESCRIPTION("Image copies with sample count mis-matches");
3492
3493 ASSERT_NO_FATAL_FAILURE(Init());
3494
3495 VkImageFormatProperties image_format_properties;
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06003496 vk::GetPhysicalDeviceImageFormatProperties(gpu(), VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_TYPE_2D, VK_IMAGE_TILING_OPTIMAL,
3497 VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT, 0,
3498 &image_format_properties);
unknown088160a2019-05-23 17:43:13 -06003499
3500 if ((0 == (VK_SAMPLE_COUNT_2_BIT & image_format_properties.sampleCounts)) ||
3501 (0 == (VK_SAMPLE_COUNT_4_BIT & image_format_properties.sampleCounts))) {
3502 printf("%s Image multi-sample support not found; skipped.\n", kSkipPrefix);
3503 return;
3504 }
3505
3506 VkImageCreateInfo ci;
3507 ci.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
3508 ci.pNext = NULL;
3509 ci.flags = 0;
3510 ci.imageType = VK_IMAGE_TYPE_2D;
3511 ci.format = VK_FORMAT_R8G8B8A8_UNORM;
3512 ci.extent = {128, 128, 1};
3513 ci.mipLevels = 1;
3514 ci.arrayLayers = 1;
3515 ci.samples = VK_SAMPLE_COUNT_1_BIT;
3516 ci.tiling = VK_IMAGE_TILING_OPTIMAL;
3517 ci.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
3518 ci.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
3519 ci.queueFamilyIndexCount = 0;
3520 ci.pQueueFamilyIndices = NULL;
3521 ci.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
3522
3523 VkImageObj image1(m_device);
3524 image1.init(&ci);
3525 ASSERT_TRUE(image1.initialized());
3526
3527 ci.samples = VK_SAMPLE_COUNT_2_BIT;
3528 VkImageObj image2(m_device);
3529 image2.init(&ci);
3530 ASSERT_TRUE(image2.initialized());
3531
3532 ci.samples = VK_SAMPLE_COUNT_4_BIT;
3533 VkImageObj image4(m_device);
3534 image4.init(&ci);
3535 ASSERT_TRUE(image4.initialized());
3536
3537 m_commandBuffer->begin();
3538
3539 VkImageCopy copyRegion;
3540 copyRegion.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
3541 copyRegion.srcSubresource.mipLevel = 0;
3542 copyRegion.srcSubresource.baseArrayLayer = 0;
3543 copyRegion.srcSubresource.layerCount = 1;
3544 copyRegion.srcOffset = {0, 0, 0};
3545 copyRegion.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
3546 copyRegion.dstSubresource.mipLevel = 0;
3547 copyRegion.dstSubresource.baseArrayLayer = 0;
3548 copyRegion.dstSubresource.layerCount = 1;
3549 copyRegion.dstOffset = {0, 0, 0};
3550 copyRegion.extent = {128, 128, 1};
3551
3552 // Copy a single sample image to/from a multi-sample image
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(), image1.handle(), VK_IMAGE_LAYOUT_GENERAL, image4.handle(), VK_IMAGE_LAYOUT_GENERAL,
3555 1, &copyRegion);
unknown088160a2019-05-23 17:43:13 -06003556 m_errorMonitor->VerifyFound();
3557
Mark Lobodzinski20310782020-02-28 14:25:17 -07003558 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdCopyImage-srcImage-00136");
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06003559 vk::CmdCopyImage(m_commandBuffer->handle(), image2.handle(), VK_IMAGE_LAYOUT_GENERAL, image1.handle(), VK_IMAGE_LAYOUT_GENERAL,
3560 1, &copyRegion);
unknown088160a2019-05-23 17:43:13 -06003561 m_errorMonitor->VerifyFound();
3562
3563 // Copy between multi-sample images with different sample counts
Mark Lobodzinski20310782020-02-28 14:25:17 -07003564 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdCopyImage-srcImage-00136");
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06003565 vk::CmdCopyImage(m_commandBuffer->handle(), image2.handle(), VK_IMAGE_LAYOUT_GENERAL, image4.handle(), VK_IMAGE_LAYOUT_GENERAL,
3566 1, &copyRegion);
unknown088160a2019-05-23 17:43:13 -06003567 m_errorMonitor->VerifyFound();
3568
Mark Lobodzinski20310782020-02-28 14:25:17 -07003569 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdCopyImage-srcImage-00136");
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06003570 vk::CmdCopyImage(m_commandBuffer->handle(), image4.handle(), VK_IMAGE_LAYOUT_GENERAL, image2.handle(), VK_IMAGE_LAYOUT_GENERAL,
3571 1, &copyRegion);
unknown088160a2019-05-23 17:43:13 -06003572 m_errorMonitor->VerifyFound();
3573
3574 m_commandBuffer->end();
3575}
3576
3577TEST_F(VkLayerTest, CopyImageAspectMismatch) {
3578 TEST_DESCRIPTION("Image copies with aspect mask errors");
sfricke-samsung99dc12c2020-04-23 01:52:01 -07003579
3580 if (!EnableDeviceProfileLayer()) {
3581 printf("%s Failed to enable device profile layer.\n", kSkipPrefix);
3582 return;
3583 }
3584
3585 bool mp_extensions = InstanceExtensionSupported(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME, 1);
3586 if (mp_extensions) {
3587 m_instance_extension_names.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
3588 }
3589
3590 ASSERT_NO_FATAL_FAILURE(InitFramework(m_errorMonitor));
3591 mp_extensions = mp_extensions && DeviceExtensionSupported(gpu(), nullptr, VK_KHR_MAINTENANCE1_EXTENSION_NAME);
3592 mp_extensions = mp_extensions && DeviceExtensionSupported(gpu(), nullptr, VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME);
3593 mp_extensions = mp_extensions && DeviceExtensionSupported(gpu(), nullptr, VK_KHR_BIND_MEMORY_2_EXTENSION_NAME);
3594 mp_extensions = mp_extensions && DeviceExtensionSupported(gpu(), nullptr, VK_KHR_SAMPLER_YCBCR_CONVERSION_EXTENSION_NAME);
3595 if (mp_extensions) {
3596 m_device_extension_names.push_back(VK_KHR_MAINTENANCE1_EXTENSION_NAME);
3597 m_device_extension_names.push_back(VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME);
3598 m_device_extension_names.push_back(VK_KHR_BIND_MEMORY_2_EXTENSION_NAME);
3599 m_device_extension_names.push_back(VK_KHR_SAMPLER_YCBCR_CONVERSION_EXTENSION_NAME);
3600 }
3601 ASSERT_NO_FATAL_FAILURE(InitState());
3602
3603 PFN_vkSetPhysicalDeviceFormatPropertiesEXT fpvkSetPhysicalDeviceFormatPropertiesEXT = nullptr;
3604 PFN_vkGetOriginalPhysicalDeviceFormatPropertiesEXT fpvkGetOriginalPhysicalDeviceFormatPropertiesEXT = nullptr;
3605
3606 if (!LoadDeviceProfileLayer(fpvkSetPhysicalDeviceFormatPropertiesEXT, fpvkGetOriginalPhysicalDeviceFormatPropertiesEXT)) {
3607 printf("%s Required extensions are not avaiable.\n", kSkipPrefix);
3608 return;
3609 }
3610
unknown088160a2019-05-23 17:43:13 -06003611 auto ds_format = FindSupportedDepthStencilFormat(gpu());
3612 if (!ds_format) {
3613 printf("%s Couldn't find depth stencil format.\n", kSkipPrefix);
3614 return;
3615 }
3616
sfricke-samsung99dc12c2020-04-23 01:52:01 -07003617 // Add Transfer support for all used formats
3618 VkFormatProperties formatProps;
3619 fpvkGetOriginalPhysicalDeviceFormatPropertiesEXT(gpu(), VK_FORMAT_R32_SFLOAT, &formatProps);
3620 formatProps.optimalTilingFeatures |= (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT);
3621 fpvkSetPhysicalDeviceFormatPropertiesEXT(gpu(), VK_FORMAT_R32_SFLOAT, formatProps);
3622 fpvkGetOriginalPhysicalDeviceFormatPropertiesEXT(gpu(), VK_FORMAT_D32_SFLOAT, &formatProps);
3623 formatProps.optimalTilingFeatures |= (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT);
3624 fpvkSetPhysicalDeviceFormatPropertiesEXT(gpu(), VK_FORMAT_R32_SFLOAT, formatProps);
3625 fpvkGetOriginalPhysicalDeviceFormatPropertiesEXT(gpu(), ds_format, &formatProps);
3626 formatProps.optimalTilingFeatures |= (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT);
3627 fpvkSetPhysicalDeviceFormatPropertiesEXT(gpu(), ds_format, formatProps);
3628
unknown088160a2019-05-23 17:43:13 -06003629 VkImageObj color_image(m_device), ds_image(m_device), depth_image(m_device);
3630 color_image.Init(128, 128, 1, VK_FORMAT_R32_SFLOAT, VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT);
3631 depth_image.Init(128, 128, 1, VK_FORMAT_D32_SFLOAT, VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT,
3632 VK_IMAGE_TILING_OPTIMAL, 0);
3633 ds_image.Init(128, 128, 1, ds_format, VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT,
3634 VK_IMAGE_TILING_OPTIMAL, 0);
3635 ASSERT_TRUE(color_image.initialized());
3636 ASSERT_TRUE(depth_image.initialized());
3637 ASSERT_TRUE(ds_image.initialized());
3638
3639 VkImageCopy copyRegion;
3640 copyRegion.srcSubresource.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT;
3641 copyRegion.srcSubresource.mipLevel = 0;
3642 copyRegion.srcSubresource.baseArrayLayer = 0;
3643 copyRegion.srcSubresource.layerCount = 1;
3644 copyRegion.srcOffset = {0, 0, 0};
3645 copyRegion.dstSubresource.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT;
3646 copyRegion.dstSubresource.mipLevel = 0;
3647 copyRegion.dstSubresource.baseArrayLayer = 0;
3648 copyRegion.dstSubresource.layerCount = 1;
3649 copyRegion.dstOffset = {64, 0, 0};
3650 copyRegion.extent = {64, 128, 1};
3651
3652 // Submitting command before command buffer is in recording state
Mark Lobodzinski20310782020-02-28 14:25:17 -07003653 m_errorMonitor->SetDesiredFailureMsg(kErrorBit,
unknown088160a2019-05-23 17:43:13 -06003654 "You must call vkBeginCommandBuffer"); // "VUID-vkCmdCopyImage-commandBuffer-recording");
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06003655 vk::CmdCopyImage(m_commandBuffer->handle(), depth_image.handle(), VK_IMAGE_LAYOUT_GENERAL, depth_image.handle(),
3656 VK_IMAGE_LAYOUT_GENERAL, 1, &copyRegion);
unknown088160a2019-05-23 17:43:13 -06003657 m_errorMonitor->VerifyFound();
3658
3659 m_commandBuffer->begin();
3660
3661 // Src and dest aspect masks don't match
3662 copyRegion.dstSubresource.aspectMask = VK_IMAGE_ASPECT_STENCIL_BIT;
sfricke-samsung99dc12c2020-04-23 01:52:01 -07003663 const char *vuid = mp_extensions ? "VUID-VkImageCopy-srcImage-01551" : "VUID-VkImageCopy-aspectMask-00137";
Mark Lobodzinski20310782020-02-28 14:25:17 -07003664 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, vuid);
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06003665 vk::CmdCopyImage(m_commandBuffer->handle(), ds_image.handle(), VK_IMAGE_LAYOUT_GENERAL, ds_image.handle(),
3666 VK_IMAGE_LAYOUT_GENERAL, 1, &copyRegion);
unknown088160a2019-05-23 17:43:13 -06003667 m_errorMonitor->VerifyFound();
3668 copyRegion.dstSubresource.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT;
3669
3670 // Illegal combinations of aspect bits
3671 copyRegion.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT | VK_IMAGE_ASPECT_DEPTH_BIT; // color must be alone
3672 copyRegion.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
Mark Lobodzinski20310782020-02-28 14:25:17 -07003673 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkImageSubresourceLayers-aspectMask-00167");
unknown088160a2019-05-23 17:43:13 -06003674 // These aspect/format mismatches are redundant but unavoidable here
Mark Lobodzinski20310782020-02-28 14:25:17 -07003675 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkImageCopy-aspectMask-00142");
3676 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, vuid);
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06003677 vk::CmdCopyImage(m_commandBuffer->handle(), color_image.handle(), VK_IMAGE_LAYOUT_GENERAL, color_image.handle(),
3678 VK_IMAGE_LAYOUT_GENERAL, 1, &copyRegion);
unknown088160a2019-05-23 17:43:13 -06003679 m_errorMonitor->VerifyFound();
3680 // same test for dstSubresource
3681 copyRegion.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
3682 copyRegion.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT | VK_IMAGE_ASPECT_DEPTH_BIT; // color must be alone
Mark Lobodzinski20310782020-02-28 14:25:17 -07003683 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkImageSubresourceLayers-aspectMask-00167");
unknown088160a2019-05-23 17:43:13 -06003684 // These aspect/format mismatches are redundant but unavoidable here
Mark Lobodzinski20310782020-02-28 14:25:17 -07003685 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkImageCopy-aspectMask-00143");
3686 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, vuid);
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06003687 vk::CmdCopyImage(m_commandBuffer->handle(), color_image.handle(), VK_IMAGE_LAYOUT_GENERAL, color_image.handle(),
3688 VK_IMAGE_LAYOUT_GENERAL, 1, &copyRegion);
unknown088160a2019-05-23 17:43:13 -06003689 m_errorMonitor->VerifyFound();
3690
3691 // Metadata aspect is illegal
3692 copyRegion.srcSubresource.aspectMask = VK_IMAGE_ASPECT_METADATA_BIT;
3693 copyRegion.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
Mark Lobodzinski20310782020-02-28 14:25:17 -07003694 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkImageSubresourceLayers-aspectMask-00168");
unknown088160a2019-05-23 17:43:13 -06003695 // These aspect/format mismatches are redundant but unavoidable here
Mark Lobodzinski20310782020-02-28 14:25:17 -07003696 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, vuid);
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06003697 vk::CmdCopyImage(m_commandBuffer->handle(), color_image.handle(), VK_IMAGE_LAYOUT_GENERAL, color_image.handle(),
3698 VK_IMAGE_LAYOUT_GENERAL, 1, &copyRegion);
unknown088160a2019-05-23 17:43:13 -06003699 m_errorMonitor->VerifyFound();
3700 // same test for dstSubresource
3701 copyRegion.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
3702 copyRegion.dstSubresource.aspectMask = VK_IMAGE_ASPECT_METADATA_BIT;
Mark Lobodzinski20310782020-02-28 14:25:17 -07003703 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkImageSubresourceLayers-aspectMask-00168");
unknown088160a2019-05-23 17:43:13 -06003704 // These aspect/format mismatches are redundant but unavoidable here
Mark Lobodzinski20310782020-02-28 14:25:17 -07003705 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, vuid);
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06003706 vk::CmdCopyImage(m_commandBuffer->handle(), color_image.handle(), VK_IMAGE_LAYOUT_GENERAL, color_image.handle(),
3707 VK_IMAGE_LAYOUT_GENERAL, 1, &copyRegion);
unknown088160a2019-05-23 17:43:13 -06003708 m_errorMonitor->VerifyFound();
3709
3710 copyRegion.srcSubresource.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT;
3711 copyRegion.dstSubresource.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT;
sfricke-samsung99dc12c2020-04-23 01:52:01 -07003712 const char *compatible_vuid = mp_extensions ? "VUID-vkCmdCopyImage-srcImage-01548" : "VUID-vkCmdCopyImage-srcImage-00135";
unknown088160a2019-05-23 17:43:13 -06003713
3714 // Aspect mask doesn't match source image format
Mark Lobodzinski20310782020-02-28 14:25:17 -07003715 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkImageCopy-aspectMask-00142");
unknown088160a2019-05-23 17:43:13 -06003716 // Again redundant but unavoidable
sfricke-samsung99dc12c2020-04-23 01:52:01 -07003717 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, compatible_vuid);
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06003718 vk::CmdCopyImage(m_commandBuffer->handle(), color_image.handle(), VK_IMAGE_LAYOUT_GENERAL, depth_image.handle(),
3719 VK_IMAGE_LAYOUT_GENERAL, 1, &copyRegion);
unknown088160a2019-05-23 17:43:13 -06003720 m_errorMonitor->VerifyFound();
3721
3722 // Aspect mask doesn't match dest image format
3723 copyRegion.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
3724 copyRegion.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
Mark Lobodzinski20310782020-02-28 14:25:17 -07003725 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkImageCopy-aspectMask-00143");
unknown088160a2019-05-23 17:43:13 -06003726 // Again redundant but unavoidable
sfricke-samsung99dc12c2020-04-23 01:52:01 -07003727 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, compatible_vuid);
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06003728 vk::CmdCopyImage(m_commandBuffer->handle(), color_image.handle(), VK_IMAGE_LAYOUT_GENERAL, depth_image.handle(),
3729 VK_IMAGE_LAYOUT_GENERAL, 1, &copyRegion);
unknown088160a2019-05-23 17:43:13 -06003730 m_errorMonitor->VerifyFound();
3731
3732 m_commandBuffer->end();
3733}
3734
3735TEST_F(VkLayerTest, ResolveImageLowSampleCount) {
Mark Lobodzinski20310782020-02-28 14:25:17 -07003736 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "vkCmdResolveImage called with source sample count less than 2.");
unknown088160a2019-05-23 17:43:13 -06003737
3738 ASSERT_NO_FATAL_FAILURE(Init());
3739
3740 // Create two images of sample count 1 and try to Resolve between them
3741
3742 VkImageCreateInfo image_create_info = {};
3743 image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
3744 image_create_info.pNext = NULL;
3745 image_create_info.imageType = VK_IMAGE_TYPE_2D;
3746 image_create_info.format = VK_FORMAT_B8G8R8A8_UNORM;
3747 image_create_info.extent.width = 32;
3748 image_create_info.extent.height = 1;
3749 image_create_info.extent.depth = 1;
3750 image_create_info.mipLevels = 1;
3751 image_create_info.arrayLayers = 1;
3752 image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
3753 image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL;
3754 image_create_info.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
3755 image_create_info.flags = 0;
3756
3757 VkImageObj srcImage(m_device);
3758 srcImage.init(&image_create_info);
3759 ASSERT_TRUE(srcImage.initialized());
3760
3761 VkImageObj dstImage(m_device);
3762 dstImage.init(&image_create_info);
3763 ASSERT_TRUE(dstImage.initialized());
3764
3765 m_commandBuffer->begin();
3766 VkImageResolve resolveRegion;
3767 resolveRegion.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
3768 resolveRegion.srcSubresource.mipLevel = 0;
3769 resolveRegion.srcSubresource.baseArrayLayer = 0;
3770 resolveRegion.srcSubresource.layerCount = 1;
3771 resolveRegion.srcOffset.x = 0;
3772 resolveRegion.srcOffset.y = 0;
3773 resolveRegion.srcOffset.z = 0;
3774 resolveRegion.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
3775 resolveRegion.dstSubresource.mipLevel = 0;
3776 resolveRegion.dstSubresource.baseArrayLayer = 0;
3777 resolveRegion.dstSubresource.layerCount = 1;
3778 resolveRegion.dstOffset.x = 0;
3779 resolveRegion.dstOffset.y = 0;
3780 resolveRegion.dstOffset.z = 0;
3781 resolveRegion.extent.width = 1;
3782 resolveRegion.extent.height = 1;
3783 resolveRegion.extent.depth = 1;
3784 m_commandBuffer->ResolveImage(srcImage.handle(), VK_IMAGE_LAYOUT_GENERAL, dstImage.handle(), VK_IMAGE_LAYOUT_GENERAL, 1,
3785 &resolveRegion);
3786 m_commandBuffer->end();
3787
3788 m_errorMonitor->VerifyFound();
3789}
3790
3791TEST_F(VkLayerTest, ResolveImageHighSampleCount) {
Mark Lobodzinski20310782020-02-28 14:25:17 -07003792 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "vkCmdResolveImage called with dest sample count greater than 1.");
unknown088160a2019-05-23 17:43:13 -06003793
3794 ASSERT_NO_FATAL_FAILURE(Init());
3795
3796 // Create two images of sample count 4 and try to Resolve between them
3797
3798 VkImageCreateInfo image_create_info = {};
3799 image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
3800 image_create_info.pNext = NULL;
3801 image_create_info.imageType = VK_IMAGE_TYPE_2D;
3802 image_create_info.format = VK_FORMAT_B8G8R8A8_UNORM;
3803 image_create_info.extent.width = 32;
3804 image_create_info.extent.height = 1;
3805 image_create_info.extent.depth = 1;
3806 image_create_info.mipLevels = 1;
3807 image_create_info.arrayLayers = 1;
3808 image_create_info.samples = VK_SAMPLE_COUNT_4_BIT;
3809 image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL;
3810 // Note: Some implementations expect color attachment usage for any
3811 // multisample surface
3812 image_create_info.usage =
3813 VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
3814 image_create_info.flags = 0;
3815
3816 VkImageObj srcImage(m_device);
3817 srcImage.init(&image_create_info);
3818 ASSERT_TRUE(srcImage.initialized());
3819
3820 VkImageObj dstImage(m_device);
3821 dstImage.init(&image_create_info);
3822 ASSERT_TRUE(dstImage.initialized());
3823
3824 m_commandBuffer->begin();
3825 // Need memory barrier to VK_IMAGE_LAYOUT_GENERAL for source and dest?
3826 // VK_IMAGE_LAYOUT_UNDEFINED = 0,
3827 // VK_IMAGE_LAYOUT_GENERAL = 1,
3828 VkImageResolve resolveRegion;
3829 resolveRegion.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
3830 resolveRegion.srcSubresource.mipLevel = 0;
3831 resolveRegion.srcSubresource.baseArrayLayer = 0;
3832 resolveRegion.srcSubresource.layerCount = 1;
3833 resolveRegion.srcOffset.x = 0;
3834 resolveRegion.srcOffset.y = 0;
3835 resolveRegion.srcOffset.z = 0;
3836 resolveRegion.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
3837 resolveRegion.dstSubresource.mipLevel = 0;
3838 resolveRegion.dstSubresource.baseArrayLayer = 0;
3839 resolveRegion.dstSubresource.layerCount = 1;
3840 resolveRegion.dstOffset.x = 0;
3841 resolveRegion.dstOffset.y = 0;
3842 resolveRegion.dstOffset.z = 0;
3843 resolveRegion.extent.width = 1;
3844 resolveRegion.extent.height = 1;
3845 resolveRegion.extent.depth = 1;
3846 m_commandBuffer->ResolveImage(srcImage.handle(), VK_IMAGE_LAYOUT_GENERAL, dstImage.handle(), VK_IMAGE_LAYOUT_GENERAL, 1,
3847 &resolveRegion);
3848 m_commandBuffer->end();
3849
3850 m_errorMonitor->VerifyFound();
3851}
3852
3853TEST_F(VkLayerTest, ResolveImageFormatMismatch) {
Mark Lobodzinski20310782020-02-28 14:25:17 -07003854 m_errorMonitor->SetDesiredFailureMsg(kWarningBit, "vkCmdResolveImage called with unmatched source and dest formats.");
unknown088160a2019-05-23 17:43:13 -06003855
3856 ASSERT_NO_FATAL_FAILURE(Init());
3857
3858 // Create two images of different types and try to copy between them
locke-lunarg8e2c91b2019-06-11 17:53:26 -06003859 VkImageObj srcImage(m_device);
3860 VkImageObj dstImage(m_device);
unknown088160a2019-05-23 17:43:13 -06003861
3862 VkImageCreateInfo image_create_info = {};
3863 image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
3864 image_create_info.pNext = NULL;
3865 image_create_info.imageType = VK_IMAGE_TYPE_2D;
3866 image_create_info.format = VK_FORMAT_B8G8R8A8_UNORM;
3867 image_create_info.extent.width = 32;
3868 image_create_info.extent.height = 1;
3869 image_create_info.extent.depth = 1;
3870 image_create_info.mipLevels = 1;
3871 image_create_info.arrayLayers = 1;
3872 image_create_info.samples = VK_SAMPLE_COUNT_2_BIT;
3873 image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL;
3874 // Note: Some implementations expect color attachment usage for any
3875 // multisample surface
3876 image_create_info.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
3877 image_create_info.flags = 0;
locke-lunarg8e2c91b2019-06-11 17:53:26 -06003878 srcImage.init(&image_create_info);
unknown088160a2019-05-23 17:43:13 -06003879
3880 // Set format to something other than source image
3881 image_create_info.format = VK_FORMAT_R32_SFLOAT;
3882 // Note: Some implementations expect color attachment usage for any
3883 // multisample surface
3884 image_create_info.usage = VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
3885 image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
locke-lunarg8e2c91b2019-06-11 17:53:26 -06003886 dstImage.init(&image_create_info);
unknown088160a2019-05-23 17:43:13 -06003887
3888 m_commandBuffer->begin();
3889 // Need memory barrier to VK_IMAGE_LAYOUT_GENERAL for source and dest?
3890 // VK_IMAGE_LAYOUT_UNDEFINED = 0,
3891 // VK_IMAGE_LAYOUT_GENERAL = 1,
3892 VkImageResolve resolveRegion;
3893 resolveRegion.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
3894 resolveRegion.srcSubresource.mipLevel = 0;
3895 resolveRegion.srcSubresource.baseArrayLayer = 0;
3896 resolveRegion.srcSubresource.layerCount = 1;
3897 resolveRegion.srcOffset.x = 0;
3898 resolveRegion.srcOffset.y = 0;
3899 resolveRegion.srcOffset.z = 0;
3900 resolveRegion.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
3901 resolveRegion.dstSubresource.mipLevel = 0;
3902 resolveRegion.dstSubresource.baseArrayLayer = 0;
3903 resolveRegion.dstSubresource.layerCount = 1;
3904 resolveRegion.dstOffset.x = 0;
3905 resolveRegion.dstOffset.y = 0;
3906 resolveRegion.dstOffset.z = 0;
3907 resolveRegion.extent.width = 1;
3908 resolveRegion.extent.height = 1;
3909 resolveRegion.extent.depth = 1;
locke-lunarg8e2c91b2019-06-11 17:53:26 -06003910 m_commandBuffer->ResolveImage(srcImage.handle(), VK_IMAGE_LAYOUT_GENERAL, dstImage.handle(), VK_IMAGE_LAYOUT_GENERAL, 1,
3911 &resolveRegion);
unknown088160a2019-05-23 17:43:13 -06003912 m_commandBuffer->end();
3913
3914 m_errorMonitor->VerifyFound();
unknown088160a2019-05-23 17:43:13 -06003915}
3916
3917TEST_F(VkLayerTest, ResolveImageTypeMismatch) {
Mark Lobodzinski20310782020-02-28 14:25:17 -07003918 m_errorMonitor->SetDesiredFailureMsg(kWarningBit, "vkCmdResolveImage called with unmatched source and dest image types.");
unknown088160a2019-05-23 17:43:13 -06003919
3920 ASSERT_NO_FATAL_FAILURE(Init());
3921
3922 // Create two images of different types and try to copy between them
locke-lunarg8e2c91b2019-06-11 17:53:26 -06003923 VkImageObj srcImage(m_device);
3924 VkImageObj dstImage(m_device);
unknown088160a2019-05-23 17:43:13 -06003925
3926 VkImageCreateInfo image_create_info = {};
3927 image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
3928 image_create_info.pNext = NULL;
3929 image_create_info.imageType = VK_IMAGE_TYPE_2D;
3930 image_create_info.format = VK_FORMAT_B8G8R8A8_UNORM;
3931 image_create_info.extent.width = 32;
3932 image_create_info.extent.height = 1;
3933 image_create_info.extent.depth = 1;
3934 image_create_info.mipLevels = 1;
3935 image_create_info.arrayLayers = 1;
3936 image_create_info.samples = VK_SAMPLE_COUNT_2_BIT;
3937 image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL;
3938 // Note: Some implementations expect color attachment usage for any
3939 // multisample surface
3940 image_create_info.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
3941 image_create_info.flags = 0;
locke-lunarg8e2c91b2019-06-11 17:53:26 -06003942 srcImage.init(&image_create_info);
unknown088160a2019-05-23 17:43:13 -06003943
3944 image_create_info.imageType = VK_IMAGE_TYPE_1D;
3945 // Note: Some implementations expect color attachment usage for any
3946 // multisample surface
3947 image_create_info.usage = VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
3948 image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
locke-lunarg8e2c91b2019-06-11 17:53:26 -06003949 dstImage.init(&image_create_info);
unknown088160a2019-05-23 17:43:13 -06003950
3951 m_commandBuffer->begin();
3952 // Need memory barrier to VK_IMAGE_LAYOUT_GENERAL for source and dest?
3953 // VK_IMAGE_LAYOUT_UNDEFINED = 0,
3954 // VK_IMAGE_LAYOUT_GENERAL = 1,
3955 VkImageResolve resolveRegion;
3956 resolveRegion.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
3957 resolveRegion.srcSubresource.mipLevel = 0;
3958 resolveRegion.srcSubresource.baseArrayLayer = 0;
3959 resolveRegion.srcSubresource.layerCount = 1;
3960 resolveRegion.srcOffset.x = 0;
3961 resolveRegion.srcOffset.y = 0;
3962 resolveRegion.srcOffset.z = 0;
3963 resolveRegion.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
3964 resolveRegion.dstSubresource.mipLevel = 0;
3965 resolveRegion.dstSubresource.baseArrayLayer = 0;
3966 resolveRegion.dstSubresource.layerCount = 1;
3967 resolveRegion.dstOffset.x = 0;
3968 resolveRegion.dstOffset.y = 0;
3969 resolveRegion.dstOffset.z = 0;
3970 resolveRegion.extent.width = 1;
3971 resolveRegion.extent.height = 1;
3972 resolveRegion.extent.depth = 1;
locke-lunarg8e2c91b2019-06-11 17:53:26 -06003973 m_commandBuffer->ResolveImage(srcImage.handle(), VK_IMAGE_LAYOUT_GENERAL, dstImage.handle(), VK_IMAGE_LAYOUT_GENERAL, 1,
3974 &resolveRegion);
unknown088160a2019-05-23 17:43:13 -06003975 m_commandBuffer->end();
3976
3977 m_errorMonitor->VerifyFound();
unknown088160a2019-05-23 17:43:13 -06003978}
3979
3980TEST_F(VkLayerTest, ResolveImageLayoutMismatch) {
3981 ASSERT_NO_FATAL_FAILURE(Init());
3982
3983 // Create two images of different types and try to copy between them
3984 VkImageObj srcImage(m_device);
3985 VkImageObj dstImage(m_device);
3986
3987 VkImageCreateInfo image_create_info = {};
3988 image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
3989 image_create_info.pNext = NULL;
3990 image_create_info.imageType = VK_IMAGE_TYPE_2D;
3991 image_create_info.format = VK_FORMAT_B8G8R8A8_UNORM;
3992 image_create_info.extent.width = 32;
3993 image_create_info.extent.height = 32;
3994 image_create_info.extent.depth = 1;
3995 image_create_info.mipLevels = 1;
3996 image_create_info.arrayLayers = 1;
3997 image_create_info.samples = VK_SAMPLE_COUNT_2_BIT;
3998 image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL;
3999 image_create_info.usage =
4000 VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
4001 // Note: Some implementations expect color attachment usage for any
4002 // multisample surface
4003 image_create_info.flags = 0;
4004 srcImage.init(&image_create_info);
4005 ASSERT_TRUE(srcImage.initialized());
4006
4007 // Note: Some implementations expect color attachment usage for any
4008 // multisample surface
4009 image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
4010 dstImage.init(&image_create_info);
4011 ASSERT_TRUE(dstImage.initialized());
4012
4013 m_commandBuffer->begin();
4014 // source image must have valid contents before resolve
4015 VkClearColorValue clear_color = {{0, 0, 0, 0}};
4016 VkImageSubresourceRange subresource = {};
4017 subresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
4018 subresource.layerCount = 1;
4019 subresource.levelCount = 1;
4020 srcImage.SetLayout(m_commandBuffer, VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
4021 m_commandBuffer->ClearColorImage(srcImage.image(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &clear_color, 1, &subresource);
4022 srcImage.SetLayout(m_commandBuffer, VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL);
4023 dstImage.SetLayout(m_commandBuffer, VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
4024
4025 VkImageResolve resolveRegion;
4026 resolveRegion.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
4027 resolveRegion.srcSubresource.mipLevel = 0;
4028 resolveRegion.srcSubresource.baseArrayLayer = 0;
4029 resolveRegion.srcSubresource.layerCount = 1;
4030 resolveRegion.srcOffset.x = 0;
4031 resolveRegion.srcOffset.y = 0;
4032 resolveRegion.srcOffset.z = 0;
4033 resolveRegion.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
4034 resolveRegion.dstSubresource.mipLevel = 0;
4035 resolveRegion.dstSubresource.baseArrayLayer = 0;
4036 resolveRegion.dstSubresource.layerCount = 1;
4037 resolveRegion.dstOffset.x = 0;
4038 resolveRegion.dstOffset.y = 0;
4039 resolveRegion.dstOffset.z = 0;
4040 resolveRegion.extent.width = 1;
4041 resolveRegion.extent.height = 1;
4042 resolveRegion.extent.depth = 1;
4043 // source image layout mismatch
Mark Lobodzinski20310782020-02-28 14:25:17 -07004044 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdResolveImage-srcImageLayout-00260");
unknown088160a2019-05-23 17:43:13 -06004045 m_commandBuffer->ResolveImage(srcImage.image(), VK_IMAGE_LAYOUT_GENERAL, dstImage.image(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
4046 1, &resolveRegion);
4047 m_errorMonitor->VerifyFound();
4048 // dst image layout mismatch
Mark Lobodzinski20310782020-02-28 14:25:17 -07004049 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdResolveImage-dstImageLayout-00262");
unknown088160a2019-05-23 17:43:13 -06004050 m_commandBuffer->ResolveImage(srcImage.image(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, dstImage.image(), VK_IMAGE_LAYOUT_GENERAL,
4051 1, &resolveRegion);
4052 m_errorMonitor->VerifyFound();
4053 m_commandBuffer->end();
4054}
4055
4056TEST_F(VkLayerTest, ResolveInvalidSubresource) {
4057 ASSERT_NO_FATAL_FAILURE(Init());
4058
4059 // Create two images of different types and try to copy between them
4060 VkImageObj srcImage(m_device);
4061 VkImageObj dstImage(m_device);
4062
4063 VkImageCreateInfo image_create_info = {};
4064 image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
4065 image_create_info.pNext = NULL;
4066 image_create_info.imageType = VK_IMAGE_TYPE_2D;
4067 image_create_info.format = VK_FORMAT_B8G8R8A8_UNORM;
4068 image_create_info.extent.width = 32;
4069 image_create_info.extent.height = 32;
4070 image_create_info.extent.depth = 1;
4071 image_create_info.mipLevels = 1;
4072 image_create_info.arrayLayers = 1;
4073 image_create_info.samples = VK_SAMPLE_COUNT_2_BIT;
4074 image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL;
4075 image_create_info.usage =
4076 VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
4077 // Note: Some implementations expect color attachment usage for any
4078 // multisample surface
4079 image_create_info.flags = 0;
4080 srcImage.init(&image_create_info);
4081 ASSERT_TRUE(srcImage.initialized());
4082
4083 // Note: Some implementations expect color attachment usage for any
4084 // multisample surface
4085 image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
4086 dstImage.init(&image_create_info);
4087 ASSERT_TRUE(dstImage.initialized());
4088
4089 m_commandBuffer->begin();
4090 // source image must have valid contents before resolve
4091 VkClearColorValue clear_color = {{0, 0, 0, 0}};
4092 VkImageSubresourceRange subresource = {};
4093 subresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
4094 subresource.layerCount = 1;
4095 subresource.levelCount = 1;
4096 srcImage.SetLayout(m_commandBuffer, VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
4097 m_commandBuffer->ClearColorImage(srcImage.image(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &clear_color, 1, &subresource);
4098 srcImage.SetLayout(m_commandBuffer, VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL);
4099 dstImage.SetLayout(m_commandBuffer, VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
4100
4101 VkImageResolve resolveRegion;
4102 resolveRegion.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
4103 resolveRegion.srcSubresource.mipLevel = 0;
4104 resolveRegion.srcSubresource.baseArrayLayer = 0;
4105 resolveRegion.srcSubresource.layerCount = 1;
4106 resolveRegion.srcOffset.x = 0;
4107 resolveRegion.srcOffset.y = 0;
4108 resolveRegion.srcOffset.z = 0;
4109 resolveRegion.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
4110 resolveRegion.dstSubresource.mipLevel = 0;
4111 resolveRegion.dstSubresource.baseArrayLayer = 0;
4112 resolveRegion.dstSubresource.layerCount = 1;
4113 resolveRegion.dstOffset.x = 0;
4114 resolveRegion.dstOffset.y = 0;
4115 resolveRegion.dstOffset.z = 0;
4116 resolveRegion.extent.width = 1;
4117 resolveRegion.extent.height = 1;
4118 resolveRegion.extent.depth = 1;
4119 // invalid source mip level
4120 resolveRegion.srcSubresource.mipLevel = image_create_info.mipLevels;
Mark Lobodzinski20310782020-02-28 14:25:17 -07004121 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdResolveImage-srcSubresource-01709");
unknown088160a2019-05-23 17:43:13 -06004122 m_commandBuffer->ResolveImage(srcImage.image(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, dstImage.image(),
4123 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &resolveRegion);
4124 m_errorMonitor->VerifyFound();
4125 resolveRegion.srcSubresource.mipLevel = 0;
4126 // invalid dest mip level
4127 resolveRegion.dstSubresource.mipLevel = image_create_info.mipLevels;
Mark Lobodzinski20310782020-02-28 14:25:17 -07004128 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdResolveImage-dstSubresource-01710");
unknown088160a2019-05-23 17:43:13 -06004129 m_commandBuffer->ResolveImage(srcImage.image(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, dstImage.image(),
4130 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &resolveRegion);
4131 m_errorMonitor->VerifyFound();
4132 resolveRegion.dstSubresource.mipLevel = 0;
4133 // invalid source array layer range
4134 resolveRegion.srcSubresource.baseArrayLayer = image_create_info.arrayLayers;
Mark Lobodzinski20310782020-02-28 14:25:17 -07004135 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdResolveImage-srcSubresource-01711");
unknown088160a2019-05-23 17:43:13 -06004136 m_commandBuffer->ResolveImage(srcImage.image(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, dstImage.image(),
4137 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &resolveRegion);
4138 m_errorMonitor->VerifyFound();
4139 resolveRegion.srcSubresource.baseArrayLayer = 0;
4140 // invalid dest array layer range
4141 resolveRegion.dstSubresource.baseArrayLayer = image_create_info.arrayLayers;
Mark Lobodzinski20310782020-02-28 14:25:17 -07004142 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdResolveImage-dstSubresource-01712");
unknown088160a2019-05-23 17:43:13 -06004143 m_commandBuffer->ResolveImage(srcImage.image(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, dstImage.image(),
4144 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &resolveRegion);
4145 m_errorMonitor->VerifyFound();
4146 resolveRegion.dstSubresource.baseArrayLayer = 0;
4147
4148 m_commandBuffer->end();
4149}
4150
4151TEST_F(VkLayerTest, ClearImageErrors) {
4152 TEST_DESCRIPTION("Call ClearColorImage w/ a depth|stencil image and ClearDepthStencilImage with a color image.");
4153
4154 ASSERT_NO_FATAL_FAILURE(Init());
4155 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
4156
4157 m_commandBuffer->begin();
4158
4159 // Color image
4160 VkClearColorValue clear_color;
4161 memset(clear_color.uint32, 0, sizeof(uint32_t) * 4);
4162 const VkFormat color_format = VK_FORMAT_B8G8R8A8_UNORM;
4163 const int32_t img_width = 32;
4164 const int32_t img_height = 32;
4165 VkImageCreateInfo image_create_info = {};
4166 image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
4167 image_create_info.pNext = NULL;
4168 image_create_info.imageType = VK_IMAGE_TYPE_2D;
4169 image_create_info.format = color_format;
4170 image_create_info.extent.width = img_width;
4171 image_create_info.extent.height = img_height;
4172 image_create_info.extent.depth = 1;
4173 image_create_info.mipLevels = 1;
4174 image_create_info.arrayLayers = 1;
4175 image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
4176 image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL;
4177
4178 image_create_info.usage = VK_IMAGE_USAGE_SAMPLED_BIT;
4179 vk_testing::Image color_image_no_transfer;
4180 color_image_no_transfer.init(*m_device, image_create_info);
4181
4182 image_create_info.usage = VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
4183 vk_testing::Image color_image;
4184 color_image.init(*m_device, image_create_info);
4185
4186 const VkImageSubresourceRange color_range = vk_testing::Image::subresource_range(image_create_info, VK_IMAGE_ASPECT_COLOR_BIT);
4187
4188 // Depth/Stencil image
4189 VkClearDepthStencilValue clear_value = {0};
4190 VkImageCreateInfo ds_image_create_info = vk_testing::Image::create_info();
4191 ds_image_create_info.imageType = VK_IMAGE_TYPE_2D;
4192 ds_image_create_info.format = VK_FORMAT_D16_UNORM;
4193 ds_image_create_info.extent.width = 64;
4194 ds_image_create_info.extent.height = 64;
4195 ds_image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL;
4196 ds_image_create_info.usage = VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
4197
4198 vk_testing::Image ds_image;
4199 ds_image.init(*m_device, ds_image_create_info);
4200
4201 const VkImageSubresourceRange ds_range = vk_testing::Image::subresource_range(ds_image_create_info, VK_IMAGE_ASPECT_DEPTH_BIT);
4202
sfricke-samsungcd924d92020-05-20 23:51:17 -07004203 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdClearColorImage-image-00007");
unknown088160a2019-05-23 17:43:13 -06004204
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06004205 vk::CmdClearColorImage(m_commandBuffer->handle(), ds_image.handle(), VK_IMAGE_LAYOUT_GENERAL, &clear_color, 1, &color_range);
unknown088160a2019-05-23 17:43:13 -06004206
4207 m_errorMonitor->VerifyFound();
4208
sfricke-samsungcd924d92020-05-20 23:51:17 -07004209 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdClearColorImage-image-00002");
unknown088160a2019-05-23 17:43:13 -06004210
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06004211 vk::CmdClearColorImage(m_commandBuffer->handle(), color_image_no_transfer.handle(), VK_IMAGE_LAYOUT_GENERAL, &clear_color, 1,
4212 &color_range);
unknown088160a2019-05-23 17:43:13 -06004213
4214 m_errorMonitor->VerifyFound();
4215
4216 // Call CmdClearDepthStencilImage with color image
sfricke-samsungcd924d92020-05-20 23:51:17 -07004217 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdClearDepthStencilImage-image-00014");
unknown088160a2019-05-23 17:43:13 -06004218
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06004219 vk::CmdClearDepthStencilImage(m_commandBuffer->handle(), color_image.handle(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
4220 &clear_value, 1, &ds_range);
unknown088160a2019-05-23 17:43:13 -06004221
4222 m_errorMonitor->VerifyFound();
4223}
4224
4225TEST_F(VkLayerTest, CommandQueueFlags) {
4226 TEST_DESCRIPTION(
4227 "Allocate a command buffer on a queue that does not support graphics and try to issue a graphics-only command");
4228
4229 ASSERT_NO_FATAL_FAILURE(Init());
4230
4231 uint32_t queueFamilyIndex = m_device->QueueFamilyWithoutCapabilities(VK_QUEUE_GRAPHICS_BIT);
4232 if (queueFamilyIndex == UINT32_MAX) {
4233 printf("%s Non-graphics queue family not found; skipped.\n", kSkipPrefix);
4234 return;
4235 } else {
4236 // Create command pool on a non-graphics queue
4237 VkCommandPoolObj command_pool(m_device, queueFamilyIndex);
4238
4239 // Setup command buffer on pool
4240 VkCommandBufferObj command_buffer(m_device, &command_pool);
4241 command_buffer.begin();
4242
4243 // Issue a graphics only command
Mark Lobodzinski20310782020-02-28 14:25:17 -07004244 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdSetViewport-commandBuffer-cmdpool");
unknown088160a2019-05-23 17:43:13 -06004245 VkViewport viewport = {0, 0, 16, 16, 0, 1};
4246 command_buffer.SetViewport(0, 1, &viewport);
4247 m_errorMonitor->VerifyFound();
4248 }
4249}
4250
4251TEST_F(VkLayerTest, ExecuteUnrecordedSecondaryCB) {
4252 TEST_DESCRIPTION("Attempt vkCmdExecuteCommands with a CB in the initial state");
4253 ASSERT_NO_FATAL_FAILURE(Init());
4254 VkCommandBufferObj secondary(m_device, m_commandPool, VK_COMMAND_BUFFER_LEVEL_SECONDARY);
4255 // never record secondary
4256
Mark Lobodzinski20310782020-02-28 14:25:17 -07004257 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdExecuteCommands-pCommandBuffers-00089");
unknown088160a2019-05-23 17:43:13 -06004258 m_commandBuffer->begin();
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06004259 vk::CmdExecuteCommands(m_commandBuffer->handle(), 1, &secondary.handle());
unknown088160a2019-05-23 17:43:13 -06004260 m_errorMonitor->VerifyFound();
4261 m_commandBuffer->end();
4262}
4263
4264TEST_F(VkLayerTest, ExecuteSecondaryCBWithLayoutMismatch) {
4265 TEST_DESCRIPTION("Attempt vkCmdExecuteCommands with a CB with incorrect initial layout.");
4266
Mark Lobodzinski09ce9c42020-03-06 10:02:44 -07004267 ASSERT_NO_FATAL_FAILURE(InitFramework(m_errorMonitor));
unknown088160a2019-05-23 17:43:13 -06004268 ASSERT_NO_FATAL_FAILURE(InitState(nullptr, nullptr, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT));
4269
4270 VkImageCreateInfo image_create_info = {};
4271 image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
4272 image_create_info.pNext = NULL;
4273 image_create_info.imageType = VK_IMAGE_TYPE_2D;
4274 image_create_info.format = VK_FORMAT_B8G8R8A8_UNORM;
4275 image_create_info.extent.width = 32;
4276 image_create_info.extent.height = 1;
4277 image_create_info.extent.depth = 1;
4278 image_create_info.mipLevels = 1;
4279 image_create_info.arrayLayers = 1;
4280 image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
4281 image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL;
4282 image_create_info.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
4283 image_create_info.flags = 0;
4284
4285 VkImageSubresource image_sub = VkImageObj::subresource(VK_IMAGE_ASPECT_COLOR_BIT, 0, 0);
4286 VkImageSubresourceRange image_sub_range = VkImageObj::subresource_range(image_sub);
4287
4288 VkImageObj image(m_device);
4289 image.init(&image_create_info);
4290 ASSERT_TRUE(image.initialized());
4291 VkImageMemoryBarrier image_barrier =
4292 image.image_memory_barrier(0, 0, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_GENERAL, image_sub_range);
4293
4294 auto pipeline = [&image_barrier](const VkCommandBufferObj &cb, VkImageLayout old_layout, VkImageLayout new_layout) {
4295 image_barrier.oldLayout = old_layout;
4296 image_barrier.newLayout = new_layout;
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06004297 vk::CmdPipelineBarrier(cb.handle(), VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, 0, nullptr,
4298 0, nullptr, 1, &image_barrier);
unknown088160a2019-05-23 17:43:13 -06004299 };
4300
4301 // Validate that mismatched use of image layout in secondary command buffer is caught at record time
4302 VkCommandBufferObj secondary(m_device, m_commandPool, VK_COMMAND_BUFFER_LEVEL_SECONDARY);
4303 secondary.begin();
4304 pipeline(secondary, VK_IMAGE_LAYOUT_GENERAL, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
4305 secondary.end();
4306
Mark Lobodzinski20310782020-02-28 14:25:17 -07004307 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "UNASSIGNED-vkCmdExecuteCommands-commandBuffer-00001");
unknown088160a2019-05-23 17:43:13 -06004308 m_commandBuffer->begin();
4309 pipeline(*m_commandBuffer, VK_IMAGE_LAYOUT_GENERAL, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL);
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06004310 vk::CmdExecuteCommands(m_commandBuffer->handle(), 1, &secondary.handle());
unknown088160a2019-05-23 17:43:13 -06004311 m_errorMonitor->VerifyFound();
4312
unknown088160a2019-05-23 17:43:13 -06004313 m_commandBuffer->reset();
4314 secondary.reset();
4315
4316 // Validate that UNDEFINED doesn't false positive on us
4317 secondary.begin();
4318 pipeline(secondary, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
4319 secondary.end();
4320 m_commandBuffer->begin();
4321 pipeline(*m_commandBuffer, VK_IMAGE_LAYOUT_GENERAL, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
4322 m_errorMonitor->ExpectSuccess();
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06004323 vk::CmdExecuteCommands(m_commandBuffer->handle(), 1, &secondary.handle());
unknown088160a2019-05-23 17:43:13 -06004324 m_errorMonitor->VerifyNotFound();
4325 m_commandBuffer->end();
4326}
4327
4328TEST_F(VkLayerTest, SetDynViewportParamTests) {
4329 TEST_DESCRIPTION("Test parameters of vkCmdSetViewport without multiViewport feature");
4330
4331 SetTargetApiVersion(VK_API_VERSION_1_1);
4332 VkPhysicalDeviceFeatures features{};
4333 ASSERT_NO_FATAL_FAILURE(Init(&features));
4334
4335 const VkViewport vp = {0.0, 0.0, 64.0, 64.0, 0.0, 1.0};
4336 const VkViewport viewports[] = {vp, vp};
4337
4338 m_commandBuffer->begin();
4339
4340 // array tests
Mark Lobodzinski20310782020-02-28 14:25:17 -07004341 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdSetViewport-firstViewport-01224");
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06004342 vk::CmdSetViewport(m_commandBuffer->handle(), 1, 1, viewports);
unknown088160a2019-05-23 17:43:13 -06004343 m_errorMonitor->VerifyFound();
4344
Mark Lobodzinski20310782020-02-28 14:25:17 -07004345 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdSetViewport-viewportCount-arraylength");
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06004346 vk::CmdSetViewport(m_commandBuffer->handle(), 0, 0, nullptr);
unknown088160a2019-05-23 17:43:13 -06004347 m_errorMonitor->VerifyFound();
4348
Mark Lobodzinski20310782020-02-28 14:25:17 -07004349 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdSetViewport-viewportCount-01225");
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06004350 vk::CmdSetViewport(m_commandBuffer->handle(), 0, 2, viewports);
unknown088160a2019-05-23 17:43:13 -06004351 m_errorMonitor->VerifyFound();
4352
Mark Lobodzinski20310782020-02-28 14:25:17 -07004353 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdSetViewport-firstViewport-01224");
4354 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdSetViewport-viewportCount-01225");
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06004355 vk::CmdSetViewport(m_commandBuffer->handle(), 1, 2, viewports);
unknown088160a2019-05-23 17:43:13 -06004356 m_errorMonitor->VerifyFound();
4357
Mark Lobodzinski20310782020-02-28 14:25:17 -07004358 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdSetViewport-pViewports-parameter");
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06004359 vk::CmdSetViewport(m_commandBuffer->handle(), 0, 1, nullptr);
unknown088160a2019-05-23 17:43:13 -06004360 m_errorMonitor->VerifyFound();
4361
4362 // core viewport tests
4363 using std::vector;
4364 struct TestCase {
4365 VkViewport vp;
4366 std::string veid;
4367 };
4368
4369 // not necessarily boundary values (unspecified cast rounding), but guaranteed to be over limit
4370 const auto one_past_max_w = NearestGreater(static_cast<float>(m_device->props.limits.maxViewportDimensions[0]));
4371 const auto one_past_max_h = NearestGreater(static_cast<float>(m_device->props.limits.maxViewportDimensions[1]));
4372
4373 const auto min_bound = m_device->props.limits.viewportBoundsRange[0];
4374 const auto max_bound = m_device->props.limits.viewportBoundsRange[1];
4375 const auto one_before_min_bounds = NearestSmaller(min_bound);
4376 const auto one_past_max_bounds = NearestGreater(max_bound);
4377
4378 const auto below_zero = NearestSmaller(0.0f);
4379 const auto past_one = NearestGreater(1.0f);
4380
4381 vector<TestCase> test_cases = {
4382 {{0.0, 0.0, 0.0, 64.0, 0.0, 1.0}, "VUID-VkViewport-width-01770"},
4383 {{0.0, 0.0, one_past_max_w, 64.0, 0.0, 1.0}, "VUID-VkViewport-width-01771"},
4384 {{0.0, 0.0, NAN, 64.0, 0.0, 1.0}, "VUID-VkViewport-width-01770"},
4385 {{0.0, 0.0, 64.0, one_past_max_h, 0.0, 1.0}, "VUID-VkViewport-height-01773"},
4386 {{one_before_min_bounds, 0.0, 64.0, 64.0, 0.0, 1.0}, "VUID-VkViewport-x-01774"},
4387 {{one_past_max_bounds, 0.0, 64.0, 64.0, 0.0, 1.0}, "VUID-VkViewport-x-01232"},
4388 {{NAN, 0.0, 64.0, 64.0, 0.0, 1.0}, "VUID-VkViewport-x-01774"},
4389 {{0.0, one_before_min_bounds, 64.0, 64.0, 0.0, 1.0}, "VUID-VkViewport-y-01775"},
4390 {{0.0, NAN, 64.0, 64.0, 0.0, 1.0}, "VUID-VkViewport-y-01775"},
4391 {{max_bound, 0.0, 1.0, 64.0, 0.0, 1.0}, "VUID-VkViewport-x-01232"},
4392 {{0.0, max_bound, 64.0, 1.0, 0.0, 1.0}, "VUID-VkViewport-y-01233"},
4393 {{0.0, 0.0, 64.0, 64.0, below_zero, 1.0}, "VUID-VkViewport-minDepth-01234"},
4394 {{0.0, 0.0, 64.0, 64.0, past_one, 1.0}, "VUID-VkViewport-minDepth-01234"},
4395 {{0.0, 0.0, 64.0, 64.0, NAN, 1.0}, "VUID-VkViewport-minDepth-01234"},
4396 {{0.0, 0.0, 64.0, 64.0, 0.0, below_zero}, "VUID-VkViewport-maxDepth-01235"},
4397 {{0.0, 0.0, 64.0, 64.0, 0.0, past_one}, "VUID-VkViewport-maxDepth-01235"},
4398 {{0.0, 0.0, 64.0, 64.0, 0.0, NAN}, "VUID-VkViewport-maxDepth-01235"},
4399 };
4400
4401 if (DeviceValidationVersion() < VK_API_VERSION_1_1) {
4402 test_cases.push_back({{0.0, 0.0, 64.0, 0.0, 0.0, 1.0}, "VUID-VkViewport-height-01772"});
4403 test_cases.push_back({{0.0, 0.0, 64.0, NAN, 0.0, 1.0}, "VUID-VkViewport-height-01772"});
4404 } else {
4405 test_cases.push_back({{0.0, 0.0, 64.0, NAN, 0.0, 1.0}, "VUID-VkViewport-height-01773"});
4406 }
4407
4408 for (const auto &test_case : test_cases) {
Mark Lobodzinski20310782020-02-28 14:25:17 -07004409 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, test_case.veid);
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06004410 vk::CmdSetViewport(m_commandBuffer->handle(), 0, 1, &test_case.vp);
unknown088160a2019-05-23 17:43:13 -06004411 m_errorMonitor->VerifyFound();
4412 }
4413}
4414
4415TEST_F(VkLayerTest, SetDynViewportParamMaintenance1Tests) {
4416 TEST_DESCRIPTION("Verify errors are detected on misuse of SetViewport with a negative viewport extension enabled.");
4417
Mark Lobodzinski09ce9c42020-03-06 10:02:44 -07004418 ASSERT_NO_FATAL_FAILURE(InitFramework(m_errorMonitor));
unknown088160a2019-05-23 17:43:13 -06004419
4420 if (DeviceExtensionSupported(gpu(), nullptr, VK_KHR_MAINTENANCE1_EXTENSION_NAME)) {
4421 m_device_extension_names.push_back(VK_KHR_MAINTENANCE1_EXTENSION_NAME);
4422 } else {
4423 printf("%s VK_KHR_maintenance1 extension not supported -- skipping test\n", kSkipPrefix);
4424 return;
4425 }
4426 ASSERT_NO_FATAL_FAILURE(InitState());
4427
4428 NegHeightViewportTests(m_device, m_commandBuffer, m_errorMonitor);
4429}
4430
4431TEST_F(VkLayerTest, SetDynViewportParamMultiviewportTests) {
4432 TEST_DESCRIPTION("Test parameters of vkCmdSetViewport with multiViewport feature enabled");
4433
4434 ASSERT_NO_FATAL_FAILURE(Init());
4435
4436 if (!m_device->phy().features().multiViewport) {
4437 printf("%s VkPhysicalDeviceFeatures::multiViewport is not supported -- skipping test.\n", kSkipPrefix);
4438 return;
4439 }
4440
unknown088160a2019-05-23 17:43:13 -06004441 m_commandBuffer->begin();
4442
Mark Lobodzinski20310782020-02-28 14:25:17 -07004443 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdSetViewport-viewportCount-arraylength");
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06004444 vk::CmdSetViewport(m_commandBuffer->handle(), 0, 0, nullptr);
unknown088160a2019-05-23 17:43:13 -06004445 m_errorMonitor->VerifyFound();
4446
Petr Kraus14e49492019-09-09 20:13:29 +02004447 const auto max_viewports = m_device->props.limits.maxViewports;
4448
Mark Lobodzinski20310782020-02-28 14:25:17 -07004449 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdSetViewport-pViewports-parameter");
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06004450 vk::CmdSetViewport(m_commandBuffer->handle(), 0, max_viewports, nullptr);
unknown088160a2019-05-23 17:43:13 -06004451 m_errorMonitor->VerifyFound();
4452
Petr Kraus14e49492019-09-09 20:13:29 +02004453 const uint32_t too_big_max_viewports = 65536 + 1; // let's say this is too much to allocate
4454 if (max_viewports >= too_big_max_viewports) {
4455 printf("%s VkPhysicalDeviceLimits::maxViewports is too large to practically test against -- skipping part of test.\n",
4456 kSkipPrefix);
4457 } else {
4458 const VkViewport vp = {0.0, 0.0, 64.0, 64.0, 0.0, 1.0};
4459 const std::vector<VkViewport> viewports(max_viewports + 1, vp);
4460
Mark Lobodzinski20310782020-02-28 14:25:17 -07004461 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdSetViewport-firstViewport-01223");
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06004462 vk::CmdSetViewport(m_commandBuffer->handle(), 0, max_viewports + 1, viewports.data());
Petr Kraus14e49492019-09-09 20:13:29 +02004463 m_errorMonitor->VerifyFound();
4464
Mark Lobodzinski20310782020-02-28 14:25:17 -07004465 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdSetViewport-firstViewport-01223");
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06004466 vk::CmdSetViewport(m_commandBuffer->handle(), max_viewports, 1, viewports.data());
Petr Kraus14e49492019-09-09 20:13:29 +02004467 m_errorMonitor->VerifyFound();
4468
Mark Lobodzinski20310782020-02-28 14:25:17 -07004469 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdSetViewport-firstViewport-01223");
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06004470 vk::CmdSetViewport(m_commandBuffer->handle(), 1, max_viewports, viewports.data());
Petr Kraus14e49492019-09-09 20:13:29 +02004471 m_errorMonitor->VerifyFound();
4472
Mark Lobodzinski20310782020-02-28 14:25:17 -07004473 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdSetViewport-viewportCount-arraylength");
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06004474 vk::CmdSetViewport(m_commandBuffer->handle(), 1, 0, viewports.data());
Petr Kraus14e49492019-09-09 20:13:29 +02004475 m_errorMonitor->VerifyFound();
unknown088160a2019-05-23 17:43:13 -06004476 }
unknown088160a2019-05-23 17:43:13 -06004477}
4478
4479TEST_F(VkLayerTest, BadRenderPassScopeSecondaryCmdBuffer) {
4480 TEST_DESCRIPTION(
4481 "Test secondary buffers executed in wrong render pass scope wrt VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT");
4482
4483 ASSERT_NO_FATAL_FAILURE(Init());
4484 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
4485
4486 VkCommandBufferObj sec_cmdbuff_inside_rp(m_device, m_commandPool, VK_COMMAND_BUFFER_LEVEL_SECONDARY);
4487 VkCommandBufferObj sec_cmdbuff_outside_rp(m_device, m_commandPool, VK_COMMAND_BUFFER_LEVEL_SECONDARY);
4488
4489 const VkCommandBufferInheritanceInfo cmdbuff_ii = {
4490 VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO,
4491 nullptr, // pNext
4492 m_renderPass,
4493 0, // subpass
4494 m_framebuffer,
4495 };
4496 const VkCommandBufferBeginInfo cmdbuff_bi_tmpl = {VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,
4497 nullptr, // pNext
4498 VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT, &cmdbuff_ii};
4499
4500 VkCommandBufferBeginInfo cmdbuff_inside_rp_bi = cmdbuff_bi_tmpl;
4501 cmdbuff_inside_rp_bi.flags |= VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT;
4502 sec_cmdbuff_inside_rp.begin(&cmdbuff_inside_rp_bi);
4503 sec_cmdbuff_inside_rp.end();
4504
4505 VkCommandBufferBeginInfo cmdbuff_outside_rp_bi = cmdbuff_bi_tmpl;
4506 cmdbuff_outside_rp_bi.flags &= ~VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT;
4507 sec_cmdbuff_outside_rp.begin(&cmdbuff_outside_rp_bi);
4508 sec_cmdbuff_outside_rp.end();
4509
4510 m_commandBuffer->begin();
4511
Mark Lobodzinski20310782020-02-28 14:25:17 -07004512 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdExecuteCommands-pCommandBuffers-00100");
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06004513 vk::CmdExecuteCommands(m_commandBuffer->handle(), 1, &sec_cmdbuff_inside_rp.handle());
unknown088160a2019-05-23 17:43:13 -06004514 m_errorMonitor->VerifyFound();
4515
4516 const VkRenderPassBeginInfo rp_bi{VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,
4517 nullptr, // pNext
4518 m_renderPass,
4519 m_framebuffer,
4520 {{0, 0}, {32, 32}},
4521 static_cast<uint32_t>(m_renderPassClearValues.size()),
4522 m_renderPassClearValues.data()};
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06004523 vk::CmdBeginRenderPass(m_commandBuffer->handle(), &rp_bi, VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS);
unknown088160a2019-05-23 17:43:13 -06004524
Mark Lobodzinski20310782020-02-28 14:25:17 -07004525 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdExecuteCommands-pCommandBuffers-00096");
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06004526 vk::CmdExecuteCommands(m_commandBuffer->handle(), 1, &sec_cmdbuff_outside_rp.handle());
unknown088160a2019-05-23 17:43:13 -06004527 m_errorMonitor->VerifyFound();
4528}
4529
4530TEST_F(VkLayerTest, SecondaryCommandBufferClearColorAttachmentsRenderArea) {
4531 TEST_DESCRIPTION(
4532 "Create a secondary command buffer with CmdClearAttachments call that has a rect outside of renderPass renderArea");
4533 ASSERT_NO_FATAL_FAILURE(Init());
4534 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
4535
4536 VkCommandBufferAllocateInfo command_buffer_allocate_info = {};
4537 command_buffer_allocate_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
4538 command_buffer_allocate_info.commandPool = m_commandPool->handle();
4539 command_buffer_allocate_info.level = VK_COMMAND_BUFFER_LEVEL_SECONDARY;
4540 command_buffer_allocate_info.commandBufferCount = 1;
4541
4542 VkCommandBuffer secondary_command_buffer;
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06004543 ASSERT_VK_SUCCESS(vk::AllocateCommandBuffers(m_device->device(), &command_buffer_allocate_info, &secondary_command_buffer));
unknown088160a2019-05-23 17:43:13 -06004544 VkCommandBufferBeginInfo command_buffer_begin_info = {};
4545 VkCommandBufferInheritanceInfo command_buffer_inheritance_info = {};
4546 command_buffer_inheritance_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO;
4547 command_buffer_inheritance_info.renderPass = m_renderPass;
4548 command_buffer_inheritance_info.framebuffer = m_framebuffer;
4549
4550 command_buffer_begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
4551 command_buffer_begin_info.flags =
4552 VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT | VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT;
4553 command_buffer_begin_info.pInheritanceInfo = &command_buffer_inheritance_info;
4554
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06004555 vk::BeginCommandBuffer(secondary_command_buffer, &command_buffer_begin_info);
unknown088160a2019-05-23 17:43:13 -06004556 VkClearAttachment color_attachment;
4557 color_attachment.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
4558 color_attachment.clearValue.color.float32[0] = 0;
4559 color_attachment.clearValue.color.float32[1] = 0;
4560 color_attachment.clearValue.color.float32[2] = 0;
4561 color_attachment.clearValue.color.float32[3] = 0;
4562 color_attachment.colorAttachment = 0;
4563 // x extent of 257 exceeds render area of 256
Mark Lobodzinski62490892019-06-28 09:58:27 -06004564 VkClearRect clear_rect = {{{0, 0}, {257, 32}}, 0, 1};
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06004565 vk::CmdClearAttachments(secondary_command_buffer, 1, &color_attachment, 1, &clear_rect);
4566 vk::EndCommandBuffer(secondary_command_buffer);
unknown088160a2019-05-23 17:43:13 -06004567 m_commandBuffer->begin();
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06004568 vk::CmdBeginRenderPass(m_commandBuffer->handle(), &m_renderPassBeginInfo, VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS);
unknown088160a2019-05-23 17:43:13 -06004569
Mark Lobodzinski20310782020-02-28 14:25:17 -07004570 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdClearAttachments-pRects-00016");
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06004571 vk::CmdExecuteCommands(m_commandBuffer->handle(), 1, &secondary_command_buffer);
unknown088160a2019-05-23 17:43:13 -06004572 m_errorMonitor->VerifyFound();
4573
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06004574 vk::CmdEndRenderPass(m_commandBuffer->handle());
unknown088160a2019-05-23 17:43:13 -06004575 m_commandBuffer->end();
4576}
4577
4578TEST_F(VkLayerTest, PushDescriptorSetCmdPushBadArgs) {
4579 TEST_DESCRIPTION("Attempt to push a push descriptor set with incorrect arguments.");
4580 if (InstanceExtensionSupported(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME)) {
4581 m_instance_extension_names.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
4582 } else {
4583 printf("%s %s Extension not supported, skipping tests\n", kSkipPrefix,
4584 VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
4585 return;
4586 }
4587
Mark Lobodzinski09ce9c42020-03-06 10:02:44 -07004588 ASSERT_NO_FATAL_FAILURE(InitFramework(m_errorMonitor));
unknown088160a2019-05-23 17:43:13 -06004589 if (DeviceExtensionSupported(gpu(), nullptr, VK_KHR_PUSH_DESCRIPTOR_EXTENSION_NAME)) {
4590 m_device_extension_names.push_back(VK_KHR_PUSH_DESCRIPTOR_EXTENSION_NAME);
4591 } else {
4592 printf("%s %s Extension not supported, skipping tests\n", kSkipPrefix, VK_KHR_PUSH_DESCRIPTOR_EXTENSION_NAME);
4593 return;
4594 }
4595 ASSERT_NO_FATAL_FAILURE(InitState());
4596
4597 auto push_descriptor_prop = GetPushDescriptorProperties(instance(), gpu());
4598 if (push_descriptor_prop.maxPushDescriptors < 1) {
4599 // Some implementations report an invalid maxPushDescriptors of 0
4600 printf("%s maxPushDescriptors is zero, skipping tests\n", kSkipPrefix);
4601 return;
4602 }
4603
4604 // Create ordinary and push descriptor set layout
4605 VkDescriptorSetLayoutBinding binding = {0, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1, VK_SHADER_STAGE_FRAGMENT_BIT, nullptr};
4606 const VkDescriptorSetLayoutObj ds_layout(m_device, {binding});
4607 ASSERT_TRUE(ds_layout.initialized());
4608 const VkDescriptorSetLayoutObj push_ds_layout(m_device, {binding}, VK_DESCRIPTOR_SET_LAYOUT_CREATE_PUSH_DESCRIPTOR_BIT_KHR);
4609 ASSERT_TRUE(push_ds_layout.initialized());
4610
4611 // Now use the descriptor set layouts to create a pipeline layout
4612 const VkPipelineLayoutObj pipeline_layout(m_device, {&push_ds_layout, &ds_layout});
4613 ASSERT_TRUE(pipeline_layout.initialized());
4614
4615 // Create a descriptor to push
4616 const uint32_t buffer_data[4] = {4, 5, 6, 7};
4617 VkConstantBufferObj buffer_obj(m_device, sizeof(buffer_data), &buffer_data);
4618 ASSERT_TRUE(buffer_obj.initialized());
4619
4620 // Create a "write" struct, noting that the buffer_info cannot be a temporary arg (the return from write_descriptor_set
4621 // references its data), and the DescriptorSet() can be temporary, because the value is ignored
4622 VkDescriptorBufferInfo buffer_info = {buffer_obj.handle(), 0, VK_WHOLE_SIZE};
4623
4624 VkWriteDescriptorSet descriptor_write = vk_testing::Device::write_descriptor_set(
4625 vk_testing::DescriptorSet(), 0, 0, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1, &buffer_info);
4626
4627 // Find address of extension call and make the call
4628 PFN_vkCmdPushDescriptorSetKHR vkCmdPushDescriptorSetKHR =
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06004629 (PFN_vkCmdPushDescriptorSetKHR)vk::GetDeviceProcAddr(m_device->device(), "vkCmdPushDescriptorSetKHR");
unknown088160a2019-05-23 17:43:13 -06004630 ASSERT_TRUE(vkCmdPushDescriptorSetKHR != nullptr);
4631
4632 // Section 1: Queue family matching/capabilities.
4633 // Create command pool on a non-graphics queue
4634 const uint32_t no_gfx_qfi = m_device->QueueFamilyMatching(VK_QUEUE_COMPUTE_BIT, VK_QUEUE_GRAPHICS_BIT);
4635 const uint32_t transfer_only_qfi =
4636 m_device->QueueFamilyMatching(VK_QUEUE_TRANSFER_BIT, (VK_QUEUE_COMPUTE_BIT | VK_QUEUE_GRAPHICS_BIT));
4637 if ((UINT32_MAX == transfer_only_qfi) && (UINT32_MAX == no_gfx_qfi)) {
unknownc3033e52019-06-21 16:56:20 -06004638 printf("%s No compute or transfer only queue family, skipping bindpoint and queue tests.\n", kSkipPrefix);
unknown088160a2019-05-23 17:43:13 -06004639 } else {
4640 const uint32_t err_qfi = (UINT32_MAX == no_gfx_qfi) ? transfer_only_qfi : no_gfx_qfi;
4641
4642 VkCommandPoolObj command_pool(m_device, err_qfi);
4643 ASSERT_TRUE(command_pool.initialized());
4644 VkCommandBufferObj command_buffer(m_device, &command_pool);
4645 ASSERT_TRUE(command_buffer.initialized());
4646 command_buffer.begin();
4647
Mark Lobodzinski20310782020-02-28 14:25:17 -07004648 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdPushDescriptorSetKHR-pipelineBindPoint-00363");
4649 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkWriteDescriptorSet-descriptorType-00330");
unknown088160a2019-05-23 17:43:13 -06004650 if (err_qfi == transfer_only_qfi) {
4651 // This as this queue neither supports the gfx or compute bindpoints, we'll get two errors
Mark Lobodzinski20310782020-02-28 14:25:17 -07004652 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdPushDescriptorSetKHR-commandBuffer-cmdpool");
unknown088160a2019-05-23 17:43:13 -06004653 }
4654 vkCmdPushDescriptorSetKHR(command_buffer.handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_layout.handle(), 0, 1,
4655 &descriptor_write);
4656 m_errorMonitor->VerifyFound();
4657 command_buffer.end();
4658
4659 // If we succeed in testing only one condition above, we need to test the other below.
4660 if ((UINT32_MAX != transfer_only_qfi) && (err_qfi != transfer_only_qfi)) {
4661 // Need to test the neither compute/gfx supported case separately.
4662 VkCommandPoolObj tran_command_pool(m_device, transfer_only_qfi);
4663 ASSERT_TRUE(tran_command_pool.initialized());
4664 VkCommandBufferObj tran_command_buffer(m_device, &tran_command_pool);
4665 ASSERT_TRUE(tran_command_buffer.initialized());
4666 tran_command_buffer.begin();
4667
4668 // We can't avoid getting *both* errors in this case
Mark Lobodzinski20310782020-02-28 14:25:17 -07004669 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdPushDescriptorSetKHR-pipelineBindPoint-00363");
4670 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkWriteDescriptorSet-descriptorType-00330");
4671 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdPushDescriptorSetKHR-commandBuffer-cmdpool");
unknown088160a2019-05-23 17:43:13 -06004672 vkCmdPushDescriptorSetKHR(tran_command_buffer.handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_layout.handle(), 0, 1,
4673 &descriptor_write);
4674 m_errorMonitor->VerifyFound();
4675 tran_command_buffer.end();
4676 }
4677 }
4678
4679 // Push to the non-push binding
4680 m_commandBuffer->begin();
Mark Lobodzinski20310782020-02-28 14:25:17 -07004681 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdPushDescriptorSetKHR-set-00365");
unknown088160a2019-05-23 17:43:13 -06004682 vkCmdPushDescriptorSetKHR(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_layout.handle(), 1, 1,
4683 &descriptor_write);
4684 m_errorMonitor->VerifyFound();
4685
4686 // Specify set out of bounds
Mark Lobodzinski20310782020-02-28 14:25:17 -07004687 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdPushDescriptorSetKHR-set-00364");
unknown088160a2019-05-23 17:43:13 -06004688 vkCmdPushDescriptorSetKHR(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_layout.handle(), 2, 1,
4689 &descriptor_write);
4690 m_errorMonitor->VerifyFound();
4691 m_commandBuffer->end();
4692
4693 // This is a test for VUID-vkCmdPushDescriptorSetKHR-commandBuffer-recording
4694 // TODO: Add VALIDATION_ERROR_ code support to core_validation::ValidateCmd
Mark Lobodzinski20310782020-02-28 14:25:17 -07004695 m_errorMonitor->SetDesiredFailureMsg(kErrorBit,
unknown088160a2019-05-23 17:43:13 -06004696 "You must call vkBeginCommandBuffer() before this call to vkCmdPushDescriptorSetKHR()");
Mark Lobodzinski20310782020-02-28 14:25:17 -07004697 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkWriteDescriptorSet-descriptorType-00330");
unknown088160a2019-05-23 17:43:13 -06004698 vkCmdPushDescriptorSetKHR(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_layout.handle(), 0, 1,
4699 &descriptor_write);
4700 m_errorMonitor->VerifyFound();
4701}
4702
Jeremy Hayesf96a5162020-02-10 13:49:31 -07004703TEST_F(VkLayerTest, PushDescriptorSetCmdBufferOffsetUnaligned) {
4704 TEST_DESCRIPTION("Attempt to push a push descriptor set buffer with unaligned offset.");
4705 if (InstanceExtensionSupported(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME)) {
4706 m_instance_extension_names.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
4707 } else {
4708 printf("%s %s Extension not supported, skipping tests\n", kSkipPrefix,
4709 VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
4710 return;
4711 }
4712
Mark Lobodzinski09ce9c42020-03-06 10:02:44 -07004713 ASSERT_NO_FATAL_FAILURE(InitFramework(m_errorMonitor));
Jeremy Hayesf96a5162020-02-10 13:49:31 -07004714 if (DeviceExtensionSupported(gpu(), nullptr, VK_KHR_PUSH_DESCRIPTOR_EXTENSION_NAME)) {
4715 m_device_extension_names.push_back(VK_KHR_PUSH_DESCRIPTOR_EXTENSION_NAME);
4716 } else {
4717 printf("%s %s Extension not supported, skipping tests\n", kSkipPrefix, VK_KHR_PUSH_DESCRIPTOR_EXTENSION_NAME);
4718 return;
4719 }
4720 ASSERT_NO_FATAL_FAILURE(InitState());
4721
4722 auto const push_descriptor_prop = GetPushDescriptorProperties(instance(), gpu());
4723 if (push_descriptor_prop.maxPushDescriptors < 1) {
4724 // Some implementations report an invalid maxPushDescriptors of 0.
4725 printf("%s maxPushDescriptors is zero, skipping test\n", kSkipPrefix);
4726 return;
4727 }
4728
4729 auto const min_alignment = m_device->props.limits.minUniformBufferOffsetAlignment;
4730 if (min_alignment == 0) {
4731 printf("%s minUniformBufferOffsetAlignment is zero, skipping test\n", kSkipPrefix);
4732 return;
4733 }
4734
4735 VkDescriptorSetLayoutBinding binding = {0, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1, VK_SHADER_STAGE_FRAGMENT_BIT, nullptr};
4736 const VkDescriptorSetLayoutObj push_ds_layout(m_device, {binding}, VK_DESCRIPTOR_SET_LAYOUT_CREATE_PUSH_DESCRIPTOR_BIT_KHR);
4737 ASSERT_TRUE(push_ds_layout.initialized());
4738
4739 const VkPipelineLayoutObj pipeline_layout(m_device, {&push_ds_layout});
4740 ASSERT_TRUE(pipeline_layout.initialized());
4741
4742 const uint32_t buffer_data[4] = {4, 5, 6, 7};
4743 VkConstantBufferObj buffer_obj(m_device, sizeof(buffer_data), &buffer_data, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT);
4744 ASSERT_TRUE(buffer_obj.initialized());
4745
4746 // Use an invalid alignment.
4747 VkDescriptorBufferInfo buffer_info = {buffer_obj.handle(), min_alignment - 1, VK_WHOLE_SIZE};
4748 VkWriteDescriptorSet descriptor_write = vk_testing::Device::write_descriptor_set(
4749 vk_testing::DescriptorSet(), 0, 0, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1, &buffer_info);
4750
4751 PFN_vkCmdPushDescriptorSetKHR vkCmdPushDescriptorSetKHR =
4752 (PFN_vkCmdPushDescriptorSetKHR)vk::GetDeviceProcAddr(m_device->device(), "vkCmdPushDescriptorSetKHR");
4753 ASSERT_TRUE(vkCmdPushDescriptorSetKHR != nullptr);
4754
4755 m_commandBuffer->begin();
Mark Lobodzinski20310782020-02-28 14:25:17 -07004756 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkWriteDescriptorSet-descriptorType-00327");
Jeremy Hayesf96a5162020-02-10 13:49:31 -07004757 vkCmdPushDescriptorSetKHR(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_layout.handle(), 0, 1,
4758 &descriptor_write);
4759 m_errorMonitor->VerifyFound();
4760
4761 m_commandBuffer->end();
4762}
4763
unknown088160a2019-05-23 17:43:13 -06004764TEST_F(VkLayerTest, SetDynScissorParamTests) {
4765 TEST_DESCRIPTION("Test parameters of vkCmdSetScissor without multiViewport feature");
4766
4767 VkPhysicalDeviceFeatures features{};
4768 ASSERT_NO_FATAL_FAILURE(Init(&features));
4769
4770 const VkRect2D scissor = {{0, 0}, {16, 16}};
4771 const VkRect2D scissors[] = {scissor, scissor};
4772
4773 m_commandBuffer->begin();
4774
4775 // array tests
Mark Lobodzinski20310782020-02-28 14:25:17 -07004776 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdSetScissor-firstScissor-00593");
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06004777 vk::CmdSetScissor(m_commandBuffer->handle(), 1, 1, scissors);
unknown088160a2019-05-23 17:43:13 -06004778 m_errorMonitor->VerifyFound();
4779
Mark Lobodzinski20310782020-02-28 14:25:17 -07004780 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdSetScissor-scissorCount-arraylength");
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06004781 vk::CmdSetScissor(m_commandBuffer->handle(), 0, 0, nullptr);
unknown088160a2019-05-23 17:43:13 -06004782 m_errorMonitor->VerifyFound();
4783
Mark Lobodzinski20310782020-02-28 14:25:17 -07004784 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdSetScissor-scissorCount-00594");
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06004785 vk::CmdSetScissor(m_commandBuffer->handle(), 0, 2, scissors);
unknown088160a2019-05-23 17:43:13 -06004786 m_errorMonitor->VerifyFound();
4787
Mark Lobodzinski20310782020-02-28 14:25:17 -07004788 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdSetScissor-firstScissor-00593");
4789 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdSetScissor-scissorCount-00594");
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06004790 vk::CmdSetScissor(m_commandBuffer->handle(), 1, 2, scissors);
unknown088160a2019-05-23 17:43:13 -06004791 m_errorMonitor->VerifyFound();
4792
Mark Lobodzinski20310782020-02-28 14:25:17 -07004793 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdSetScissor-pScissors-parameter");
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06004794 vk::CmdSetScissor(m_commandBuffer->handle(), 0, 1, nullptr);
unknown088160a2019-05-23 17:43:13 -06004795 m_errorMonitor->VerifyFound();
4796
4797 struct TestCase {
4798 VkRect2D scissor;
4799 std::string vuid;
4800 };
4801
4802 std::vector<TestCase> test_cases = {{{{-1, 0}, {16, 16}}, "VUID-vkCmdSetScissor-x-00595"},
4803 {{{0, -1}, {16, 16}}, "VUID-vkCmdSetScissor-x-00595"},
4804 {{{1, 0}, {INT32_MAX, 16}}, "VUID-vkCmdSetScissor-offset-00596"},
4805 {{{INT32_MAX, 0}, {1, 16}}, "VUID-vkCmdSetScissor-offset-00596"},
4806 {{{0, 0}, {uint32_t{INT32_MAX} + 1, 16}}, "VUID-vkCmdSetScissor-offset-00596"},
4807 {{{0, 1}, {16, INT32_MAX}}, "VUID-vkCmdSetScissor-offset-00597"},
4808 {{{0, INT32_MAX}, {16, 1}}, "VUID-vkCmdSetScissor-offset-00597"},
4809 {{{0, 0}, {16, uint32_t{INT32_MAX} + 1}}, "VUID-vkCmdSetScissor-offset-00597"}};
4810
4811 for (const auto &test_case : test_cases) {
Mark Lobodzinski20310782020-02-28 14:25:17 -07004812 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, test_case.vuid);
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06004813 vk::CmdSetScissor(m_commandBuffer->handle(), 0, 1, &test_case.scissor);
unknown088160a2019-05-23 17:43:13 -06004814 m_errorMonitor->VerifyFound();
4815 }
4816
4817 m_commandBuffer->end();
4818}
4819
4820TEST_F(VkLayerTest, SetDynScissorParamMultiviewportTests) {
4821 TEST_DESCRIPTION("Test parameters of vkCmdSetScissor with multiViewport feature enabled");
4822
4823 ASSERT_NO_FATAL_FAILURE(Init());
4824
4825 if (!m_device->phy().features().multiViewport) {
4826 printf("%s VkPhysicalDeviceFeatures::multiViewport is not supported -- skipping test.\n", kSkipPrefix);
4827 return;
4828 }
4829
unknown088160a2019-05-23 17:43:13 -06004830 m_commandBuffer->begin();
4831
Mark Lobodzinski20310782020-02-28 14:25:17 -07004832 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdSetScissor-scissorCount-arraylength");
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06004833 vk::CmdSetScissor(m_commandBuffer->handle(), 0, 0, nullptr);
unknown088160a2019-05-23 17:43:13 -06004834 m_errorMonitor->VerifyFound();
4835
Petr Kraus14e49492019-09-09 20:13:29 +02004836 const auto max_scissors = m_device->props.limits.maxViewports;
4837
Mark Lobodzinski20310782020-02-28 14:25:17 -07004838 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdSetScissor-pScissors-parameter");
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06004839 vk::CmdSetScissor(m_commandBuffer->handle(), 0, max_scissors, nullptr);
unknown088160a2019-05-23 17:43:13 -06004840 m_errorMonitor->VerifyFound();
4841
Petr Kraus14e49492019-09-09 20:13:29 +02004842 const uint32_t too_big_max_scissors = 65536 + 1; // let's say this is too much to allocate
4843 if (max_scissors >= too_big_max_scissors) {
4844 printf("%s VkPhysicalDeviceLimits::maxViewports is too large to practically test against -- skipping part of test.\n",
4845 kSkipPrefix);
4846 } else {
4847 const VkRect2D scissor = {{0, 0}, {16, 16}};
4848 const std::vector<VkRect2D> scissors(max_scissors + 1, scissor);
4849
Mark Lobodzinski20310782020-02-28 14:25:17 -07004850 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdSetScissor-firstScissor-00592");
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06004851 vk::CmdSetScissor(m_commandBuffer->handle(), 0, max_scissors + 1, scissors.data());
Petr Kraus14e49492019-09-09 20:13:29 +02004852 m_errorMonitor->VerifyFound();
4853
Mark Lobodzinski20310782020-02-28 14:25:17 -07004854 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdSetScissor-firstScissor-00592");
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06004855 vk::CmdSetScissor(m_commandBuffer->handle(), max_scissors, 1, scissors.data());
Petr Kraus14e49492019-09-09 20:13:29 +02004856 m_errorMonitor->VerifyFound();
4857
Mark Lobodzinski20310782020-02-28 14:25:17 -07004858 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdSetScissor-firstScissor-00592");
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06004859 vk::CmdSetScissor(m_commandBuffer->handle(), 1, max_scissors, scissors.data());
Petr Kraus14e49492019-09-09 20:13:29 +02004860 m_errorMonitor->VerifyFound();
4861
Mark Lobodzinski20310782020-02-28 14:25:17 -07004862 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdSetScissor-scissorCount-arraylength");
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06004863 vk::CmdSetScissor(m_commandBuffer->handle(), 1, 0, scissors.data());
Petr Kraus14e49492019-09-09 20:13:29 +02004864 m_errorMonitor->VerifyFound();
unknown088160a2019-05-23 17:43:13 -06004865 }
unknown088160a2019-05-23 17:43:13 -06004866}
4867
4868TEST_F(VkLayerTest, DrawIndirect) {
4869 TEST_DESCRIPTION("Test covered valid usage for vkCmdDrawIndirect");
4870
4871 ASSERT_NO_FATAL_FAILURE(Init());
4872 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
4873
locke-lunarg8e2c91b2019-06-11 17:53:26 -06004874 CreatePipelineHelper pipe(*this);
4875 pipe.InitInfo();
4876 const VkDynamicState dyn_states[] = {VK_DYNAMIC_STATE_VIEWPORT, VK_DYNAMIC_STATE_SCISSOR};
4877 VkPipelineDynamicStateCreateInfo dyn_state_ci = {};
4878 dyn_state_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO;
4879 dyn_state_ci.dynamicStateCount = size(dyn_states);
4880 dyn_state_ci.pDynamicStates = dyn_states;
4881 pipe.dyn_state_ci_ = dyn_state_ci;
4882 pipe.InitState();
4883 pipe.CreateGraphicsPipeline();
unknown088160a2019-05-23 17:43:13 -06004884
4885 m_commandBuffer->begin();
4886 m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
4887
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06004888 vk::CmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.pipeline_);
4889 vk::CmdBindDescriptorSets(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.pipeline_layout_.handle(), 0, 1,
4890 &pipe.descriptor_set_->set_, 0, NULL);
unknown088160a2019-05-23 17:43:13 -06004891
4892 VkViewport viewport = {0, 0, 16, 16, 0, 1};
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06004893 vk::CmdSetViewport(m_commandBuffer->handle(), 0, 1, &viewport);
unknown088160a2019-05-23 17:43:13 -06004894 VkRect2D scissor = {{0, 0}, {16, 16}};
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06004895 vk::CmdSetScissor(m_commandBuffer->handle(), 0, 1, &scissor);
unknown088160a2019-05-23 17:43:13 -06004896
4897 VkBufferCreateInfo buffer_create_info = {VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO};
4898 buffer_create_info.usage = VK_BUFFER_USAGE_VERTEX_BUFFER_BIT;
4899 buffer_create_info.size = sizeof(VkDrawIndirectCommand);
locke-lunarg8e2c91b2019-06-11 17:53:26 -06004900 VkBufferObj draw_buffer;
4901 draw_buffer.init(*m_device, buffer_create_info);
unknown088160a2019-05-23 17:43:13 -06004902
4903 // VUID-vkCmdDrawIndirect-buffer-02709
Mark Lobodzinski20310782020-02-28 14:25:17 -07004904 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdDrawIndirect-buffer-02709");
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06004905 vk::CmdDrawIndirect(m_commandBuffer->handle(), draw_buffer.handle(), 0, 1, sizeof(VkDrawIndirectCommand));
unknown088160a2019-05-23 17:43:13 -06004906 m_errorMonitor->VerifyFound();
4907
4908 m_commandBuffer->EndRenderPass();
4909 m_commandBuffer->end();
unknown088160a2019-05-23 17:43:13 -06004910}
4911
Mark Lobodzinski977f0342019-12-19 14:24:09 -07004912TEST_F(VkLayerTest, DrawIndirectByteCountEXT) {
4913 TEST_DESCRIPTION("Test covered valid usage for vkCmdDrawIndirectByteCountEXT");
4914
4915 if (InstanceExtensionSupported(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME)) {
4916 m_instance_extension_names.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
4917 } else {
4918 printf("%s Did not find required instance extension %s; skipped.\n", kSkipPrefix,
4919 VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
4920 return;
4921 }
Mark Lobodzinski09ce9c42020-03-06 10:02:44 -07004922 ASSERT_NO_FATAL_FAILURE(InitFramework(m_errorMonitor));
Mark Lobodzinski977f0342019-12-19 14:24:09 -07004923
4924 if (DeviceExtensionSupported(gpu(), nullptr, VK_EXT_TRANSFORM_FEEDBACK_EXTENSION_NAME)) {
4925 m_device_extension_names.push_back(VK_EXT_TRANSFORM_FEEDBACK_EXTENSION_NAME);
4926 } else {
4927 printf("%s VK_EXT_transform_feedback extension not supported, skipping test\n", kSkipPrefix);
Mark Lobodzinskid01b2bc2019-12-20 10:19:36 -07004928 return;
Mark Lobodzinski977f0342019-12-19 14:24:09 -07004929 }
4930
4931 ASSERT_NO_FATAL_FAILURE(InitState());
4932 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
4933
4934 PFN_vkCmdDrawIndirectByteCountEXT fpvkCmdDrawIndirectByteCountEXT =
4935 (PFN_vkCmdDrawIndirectByteCountEXT)vk::GetDeviceProcAddr(device(), "vkCmdDrawIndirectByteCountEXT");
4936
4937 m_commandBuffer->begin();
4938 m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
4939 VkBufferCreateInfo buffer_create_info = {VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO};
4940 buffer_create_info.usage = VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT;
4941 buffer_create_info.size = 1024;
4942 VkBufferObj counter_buffer;
4943 counter_buffer.init(*m_device, buffer_create_info);
4944
4945 // VUID-vkCmdDrawIndirectByteCountEXT-vertexStride-02289
Mark Lobodzinski20310782020-02-28 14:25:17 -07004946 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdDrawIndirectByteCountEXT-vertexStride-02289");
Mark Lobodzinski977f0342019-12-19 14:24:09 -07004947 fpvkCmdDrawIndirectByteCountEXT(m_commandBuffer->handle(), 1, 0, counter_buffer.handle(), 0, 1, 0xCADECADE);
4948 m_errorMonitor->VerifyFound();
4949
4950 m_commandBuffer->EndRenderPass();
4951 m_commandBuffer->end();
4952}
4953
unknown088160a2019-05-23 17:43:13 -06004954TEST_F(VkLayerTest, DrawIndirectCountKHR) {
4955 TEST_DESCRIPTION("Test covered valid usage for vkCmdDrawIndirectCountKHR");
4956
Mark Lobodzinski09ce9c42020-03-06 10:02:44 -07004957 ASSERT_NO_FATAL_FAILURE(InitFramework(m_errorMonitor));
unknown088160a2019-05-23 17:43:13 -06004958 if (DeviceExtensionSupported(gpu(), nullptr, VK_KHR_DRAW_INDIRECT_COUNT_EXTENSION_NAME)) {
4959 m_device_extension_names.push_back(VK_KHR_DRAW_INDIRECT_COUNT_EXTENSION_NAME);
4960 } else {
4961 printf(" VK_KHR_draw_indirect_count Extension not supported, skipping test\n");
4962 return;
4963 }
4964 ASSERT_NO_FATAL_FAILURE(InitState());
4965 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
4966
4967 VkMemoryRequirements memory_requirements;
4968 VkMemoryAllocateInfo memory_allocate_info = {VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO};
4969
4970 auto vkCmdDrawIndirectCountKHR =
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06004971 (PFN_vkCmdDrawIndirectCountKHR)vk::GetDeviceProcAddr(m_device->device(), "vkCmdDrawIndirectCountKHR");
unknown088160a2019-05-23 17:43:13 -06004972
locke-lunarg8e2c91b2019-06-11 17:53:26 -06004973 CreatePipelineHelper pipe(*this);
4974 pipe.InitInfo();
4975 const VkDynamicState dyn_states[] = {VK_DYNAMIC_STATE_VIEWPORT, VK_DYNAMIC_STATE_SCISSOR};
4976 VkPipelineDynamicStateCreateInfo dyn_state_ci = {};
4977 dyn_state_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO;
4978 dyn_state_ci.dynamicStateCount = size(dyn_states);
4979 dyn_state_ci.pDynamicStates = dyn_states;
4980 pipe.dyn_state_ci_ = dyn_state_ci;
4981 pipe.InitState();
4982 pipe.CreateGraphicsPipeline();
unknown088160a2019-05-23 17:43:13 -06004983
4984 m_commandBuffer->begin();
4985 m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
4986
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06004987 vk::CmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.pipeline_);
4988 vk::CmdBindDescriptorSets(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.pipeline_layout_.handle(), 0, 1,
4989 &pipe.descriptor_set_->set_, 0, NULL);
unknown088160a2019-05-23 17:43:13 -06004990
4991 VkViewport viewport = {0, 0, 16, 16, 0, 1};
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06004992 vk::CmdSetViewport(m_commandBuffer->handle(), 0, 1, &viewport);
unknown088160a2019-05-23 17:43:13 -06004993 VkRect2D scissor = {{0, 0}, {16, 16}};
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06004994 vk::CmdSetScissor(m_commandBuffer->handle(), 0, 1, &scissor);
unknown088160a2019-05-23 17:43:13 -06004995
4996 VkBufferCreateInfo buffer_create_info = {VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO};
4997 buffer_create_info.size = sizeof(VkDrawIndirectCommand);
4998 buffer_create_info.usage = VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT;
4999 VkBuffer draw_buffer;
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06005000 vk::CreateBuffer(m_device->device(), &buffer_create_info, nullptr, &draw_buffer);
unknown088160a2019-05-23 17:43:13 -06005001
5002 VkBufferCreateInfo count_buffer_create_info = {VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO};
5003 count_buffer_create_info.size = sizeof(uint32_t);
5004 count_buffer_create_info.usage = VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT;
locke-lunarg8e2c91b2019-06-11 17:53:26 -06005005 VkBufferObj count_buffer;
5006 count_buffer.init(*m_device, count_buffer_create_info);
unknown088160a2019-05-23 17:43:13 -06005007
Mike Schuchardt65847d92019-12-20 13:50:47 -08005008 // VUID-vkCmdDrawIndirectCount-buffer-02708
Mark Lobodzinski20310782020-02-28 14:25:17 -07005009 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdDrawIndirectCount-buffer-02708");
locke-lunarg8e2c91b2019-06-11 17:53:26 -06005010 vkCmdDrawIndirectCountKHR(m_commandBuffer->handle(), draw_buffer, 0, count_buffer.handle(), 0, 1,
5011 sizeof(VkDrawIndirectCommand));
unknown088160a2019-05-23 17:43:13 -06005012 m_errorMonitor->VerifyFound();
5013
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06005014 vk::GetBufferMemoryRequirements(m_device->device(), draw_buffer, &memory_requirements);
unknown088160a2019-05-23 17:43:13 -06005015 memory_allocate_info.allocationSize = memory_requirements.size;
5016 m_device->phy().set_memory_type(memory_requirements.memoryTypeBits, &memory_allocate_info, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT);
5017 VkDeviceMemory draw_buffer_memory;
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06005018 vk::AllocateMemory(m_device->device(), &memory_allocate_info, NULL, &draw_buffer_memory);
5019 vk::BindBufferMemory(m_device->device(), draw_buffer, draw_buffer_memory, 0);
unknown088160a2019-05-23 17:43:13 -06005020
5021 VkBuffer count_buffer_unbound;
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06005022 vk::CreateBuffer(m_device->device(), &count_buffer_create_info, nullptr, &count_buffer_unbound);
unknown088160a2019-05-23 17:43:13 -06005023
Mike Schuchardt65847d92019-12-20 13:50:47 -08005024 // VUID-vkCmdDrawIndirectCount-countBuffer-02714
Mark Lobodzinski20310782020-02-28 14:25:17 -07005025 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdDrawIndirectCount-countBuffer-02714");
unknown088160a2019-05-23 17:43:13 -06005026 vkCmdDrawIndirectCountKHR(m_commandBuffer->handle(), draw_buffer, 0, count_buffer_unbound, 0, 1, sizeof(VkDrawIndirectCommand));
5027 m_errorMonitor->VerifyFound();
5028
Mike Schuchardt65847d92019-12-20 13:50:47 -08005029 // VUID-vkCmdDrawIndirectCount-offset-02710
Mark Lobodzinski20310782020-02-28 14:25:17 -07005030 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdDrawIndirectCount-offset-02710");
locke-lunarg8e2c91b2019-06-11 17:53:26 -06005031 vkCmdDrawIndirectCountKHR(m_commandBuffer->handle(), draw_buffer, 1, count_buffer.handle(), 0, 1,
5032 sizeof(VkDrawIndirectCommand));
unknown088160a2019-05-23 17:43:13 -06005033 m_errorMonitor->VerifyFound();
5034
Mike Schuchardt65847d92019-12-20 13:50:47 -08005035 // VUID-vkCmdDrawIndirectCount-countBufferOffset-02716
Mark Lobodzinski20310782020-02-28 14:25:17 -07005036 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdDrawIndirectCount-countBufferOffset-02716");
locke-lunarg8e2c91b2019-06-11 17:53:26 -06005037 vkCmdDrawIndirectCountKHR(m_commandBuffer->handle(), draw_buffer, 0, count_buffer.handle(), 1, 1,
5038 sizeof(VkDrawIndirectCommand));
unknown088160a2019-05-23 17:43:13 -06005039 m_errorMonitor->VerifyFound();
5040
Mike Schuchardt65847d92019-12-20 13:50:47 -08005041 // VUID-vkCmdDrawIndirectCount-stride-03110
Mark Lobodzinski20310782020-02-28 14:25:17 -07005042 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdDrawIndirectCount-stride-03110");
locke-lunarg8e2c91b2019-06-11 17:53:26 -06005043 vkCmdDrawIndirectCountKHR(m_commandBuffer->handle(), draw_buffer, 0, count_buffer.handle(), 0, 1, 1);
unknown088160a2019-05-23 17:43:13 -06005044 m_errorMonitor->VerifyFound();
5045
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06005046 // 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 -06005047 // these:
Mike Schuchardt65847d92019-12-20 13:50:47 -08005048 // VUID-vkCmdDrawIndirectCount-renderPass-02684
5049 // VUID-vkCmdDrawIndirectCount-subpass-02685
5050 // VUID-vkCmdDrawIndirectCount-commandBuffer-02701
unknown088160a2019-05-23 17:43:13 -06005051
5052 m_commandBuffer->EndRenderPass();
5053 m_commandBuffer->end();
5054
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06005055 vk::DestroyBuffer(m_device->device(), draw_buffer, 0);
5056 vk::DestroyBuffer(m_device->device(), count_buffer_unbound, 0);
unknown088160a2019-05-23 17:43:13 -06005057
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06005058 vk::FreeMemory(m_device->device(), draw_buffer_memory, 0);
unknown088160a2019-05-23 17:43:13 -06005059}
5060
5061TEST_F(VkLayerTest, DrawIndexedIndirectCountKHR) {
5062 TEST_DESCRIPTION("Test covered valid usage for vkCmdDrawIndexedIndirectCountKHR");
5063
Mark Lobodzinski09ce9c42020-03-06 10:02:44 -07005064 ASSERT_NO_FATAL_FAILURE(InitFramework(m_errorMonitor));
unknown088160a2019-05-23 17:43:13 -06005065 if (DeviceExtensionSupported(gpu(), nullptr, VK_KHR_DRAW_INDIRECT_COUNT_EXTENSION_NAME)) {
5066 m_device_extension_names.push_back(VK_KHR_DRAW_INDIRECT_COUNT_EXTENSION_NAME);
5067 } else {
5068 printf(" VK_KHR_draw_indirect_count Extension not supported, skipping test\n");
5069 return;
5070 }
5071 ASSERT_NO_FATAL_FAILURE(InitState());
5072 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
5073
unknown088160a2019-05-23 17:43:13 -06005074 auto vkCmdDrawIndexedIndirectCountKHR =
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06005075 (PFN_vkCmdDrawIndexedIndirectCountKHR)vk::GetDeviceProcAddr(m_device->device(), "vkCmdDrawIndexedIndirectCountKHR");
unknown088160a2019-05-23 17:43:13 -06005076
locke-lunarg8e2c91b2019-06-11 17:53:26 -06005077 CreatePipelineHelper pipe(*this);
5078 pipe.InitInfo();
5079 const VkDynamicState dyn_states[] = {VK_DYNAMIC_STATE_VIEWPORT, VK_DYNAMIC_STATE_SCISSOR};
5080 VkPipelineDynamicStateCreateInfo dyn_state_ci = {};
5081 dyn_state_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO;
5082 dyn_state_ci.dynamicStateCount = size(dyn_states);
5083 dyn_state_ci.pDynamicStates = dyn_states;
5084 pipe.dyn_state_ci_ = dyn_state_ci;
5085 pipe.InitState();
5086 pipe.CreateGraphicsPipeline();
unknown088160a2019-05-23 17:43:13 -06005087
5088 m_commandBuffer->begin();
5089 m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
5090
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06005091 vk::CmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.pipeline_);
5092 vk::CmdBindDescriptorSets(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.pipeline_layout_.handle(), 0, 1,
5093 &pipe.descriptor_set_->set_, 0, NULL);
unknown088160a2019-05-23 17:43:13 -06005094
5095 VkViewport viewport = {0, 0, 16, 16, 0, 1};
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06005096 vk::CmdSetViewport(m_commandBuffer->handle(), 0, 1, &viewport);
unknown088160a2019-05-23 17:43:13 -06005097 VkRect2D scissor = {{0, 0}, {16, 16}};
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06005098 vk::CmdSetScissor(m_commandBuffer->handle(), 0, 1, &scissor);
unknown088160a2019-05-23 17:43:13 -06005099
5100 VkBufferCreateInfo buffer_create_info = {VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO};
5101 buffer_create_info.size = sizeof(VkDrawIndexedIndirectCommand);
5102 buffer_create_info.usage = VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT;
locke-lunarg8e2c91b2019-06-11 17:53:26 -06005103 VkBufferObj draw_buffer;
5104 draw_buffer.init(*m_device, buffer_create_info);
unknown088160a2019-05-23 17:43:13 -06005105
5106 VkBufferCreateInfo count_buffer_create_info = {VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO};
5107 count_buffer_create_info.size = sizeof(uint32_t);
5108 count_buffer_create_info.usage = VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT;
locke-lunarg8e2c91b2019-06-11 17:53:26 -06005109 VkBufferObj count_buffer;
5110 count_buffer.init(*m_device, count_buffer_create_info);
unknown088160a2019-05-23 17:43:13 -06005111
5112 VkBufferCreateInfo index_buffer_create_info = {VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO};
5113 index_buffer_create_info.size = sizeof(uint32_t);
5114 index_buffer_create_info.usage = VK_BUFFER_USAGE_INDEX_BUFFER_BIT;
locke-lunarg8e2c91b2019-06-11 17:53:26 -06005115 VkBufferObj index_buffer;
5116 index_buffer.init(*m_device, index_buffer_create_info);
unknown088160a2019-05-23 17:43:13 -06005117
Mike Schuchardt65847d92019-12-20 13:50:47 -08005118 // VUID-vkCmdDrawIndexedIndirectCount-commandBuffer-02701 (partial - only tests whether the index buffer is bound)
Mark Lobodzinski20310782020-02-28 14:25:17 -07005119 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdDrawIndexedIndirectCount-commandBuffer-02701");
locke-lunarg8e2c91b2019-06-11 17:53:26 -06005120 vkCmdDrawIndexedIndirectCountKHR(m_commandBuffer->handle(), draw_buffer.handle(), 0, count_buffer.handle(), 0, 1,
unknown088160a2019-05-23 17:43:13 -06005121 sizeof(VkDrawIndexedIndirectCommand));
5122 m_errorMonitor->VerifyFound();
5123
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06005124 vk::CmdBindIndexBuffer(m_commandBuffer->handle(), index_buffer.handle(), 0, VK_INDEX_TYPE_UINT32);
unknown088160a2019-05-23 17:43:13 -06005125
5126 VkBuffer draw_buffer_unbound;
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06005127 vk::CreateBuffer(m_device->device(), &count_buffer_create_info, nullptr, &draw_buffer_unbound);
unknown088160a2019-05-23 17:43:13 -06005128
Mike Schuchardt65847d92019-12-20 13:50:47 -08005129 // VUID-vkCmdDrawIndexedIndirectCount-buffer-02708
Mark Lobodzinski20310782020-02-28 14:25:17 -07005130 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdDrawIndexedIndirectCount-buffer-02708");
locke-lunarg8e2c91b2019-06-11 17:53:26 -06005131 vkCmdDrawIndexedIndirectCountKHR(m_commandBuffer->handle(), draw_buffer_unbound, 0, count_buffer.handle(), 0, 1,
unknown088160a2019-05-23 17:43:13 -06005132 sizeof(VkDrawIndexedIndirectCommand));
5133 m_errorMonitor->VerifyFound();
5134
5135 VkBuffer count_buffer_unbound;
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06005136 vk::CreateBuffer(m_device->device(), &count_buffer_create_info, nullptr, &count_buffer_unbound);
unknown088160a2019-05-23 17:43:13 -06005137
Mike Schuchardt65847d92019-12-20 13:50:47 -08005138 // VUID-vkCmdDrawIndexedIndirectCount-countBuffer-02714
Mark Lobodzinski20310782020-02-28 14:25:17 -07005139 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdDrawIndexedIndirectCount-countBuffer-02714");
locke-lunarg8e2c91b2019-06-11 17:53:26 -06005140 vkCmdDrawIndexedIndirectCountKHR(m_commandBuffer->handle(), draw_buffer.handle(), 0, count_buffer_unbound, 0, 1,
unknown088160a2019-05-23 17:43:13 -06005141 sizeof(VkDrawIndexedIndirectCommand));
5142 m_errorMonitor->VerifyFound();
5143
Mike Schuchardt65847d92019-12-20 13:50:47 -08005144 // VUID-vkCmdDrawIndexedIndirectCount-offset-02710
Mark Lobodzinski20310782020-02-28 14:25:17 -07005145 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdDrawIndexedIndirectCount-offset-02710");
locke-lunarg8e2c91b2019-06-11 17:53:26 -06005146 vkCmdDrawIndexedIndirectCountKHR(m_commandBuffer->handle(), draw_buffer.handle(), 1, count_buffer.handle(), 0, 1,
unknown088160a2019-05-23 17:43:13 -06005147 sizeof(VkDrawIndexedIndirectCommand));
5148 m_errorMonitor->VerifyFound();
5149
Mike Schuchardt65847d92019-12-20 13:50:47 -08005150 // VUID-vkCmdDrawIndexedIndirectCount-countBufferOffset-02716
Mark Lobodzinski20310782020-02-28 14:25:17 -07005151 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdDrawIndexedIndirectCount-countBufferOffset-02716");
locke-lunarg8e2c91b2019-06-11 17:53:26 -06005152 vkCmdDrawIndexedIndirectCountKHR(m_commandBuffer->handle(), draw_buffer.handle(), 0, count_buffer.handle(), 1, 1,
unknown088160a2019-05-23 17:43:13 -06005153 sizeof(VkDrawIndexedIndirectCommand));
5154 m_errorMonitor->VerifyFound();
5155
Mike Schuchardt65847d92019-12-20 13:50:47 -08005156 // VUID-vkCmdDrawIndexedIndirectCount-stride-03142
Mark Lobodzinski20310782020-02-28 14:25:17 -07005157 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdDrawIndexedIndirectCount-stride-03142");
locke-lunarg8e2c91b2019-06-11 17:53:26 -06005158 vkCmdDrawIndexedIndirectCountKHR(m_commandBuffer->handle(), draw_buffer.handle(), 0, count_buffer.handle(), 0, 1, 1);
unknown088160a2019-05-23 17:43:13 -06005159 m_errorMonitor->VerifyFound();
5160
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06005161 // 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 -06005162 // these:
Mike Schuchardt65847d92019-12-20 13:50:47 -08005163 // VUID-vkCmdDrawIndexedIndirectCount-renderPass-02684
5164 // VUID-vkCmdDrawIndexedIndirectCount-subpass-02685
5165 // VUID-vkCmdDrawIndexedIndirectCount-commandBuffer-02701 (partial)
unknown088160a2019-05-23 17:43:13 -06005166
5167 m_commandBuffer->EndRenderPass();
5168 m_commandBuffer->end();
5169
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06005170 vk::DestroyBuffer(m_device->device(), draw_buffer_unbound, 0);
5171 vk::DestroyBuffer(m_device->device(), count_buffer_unbound, 0);
unknown088160a2019-05-23 17:43:13 -06005172}
5173
sfricke-samsung860d3b22020-05-04 21:08:29 -07005174TEST_F(VkLayerTest, DrawIndirectCountFeature) {
5175 TEST_DESCRIPTION("Test covered valid usage for the 1.2 drawIndirectCount feature");
5176
5177 SetTargetApiVersion(VK_API_VERSION_1_2);
5178 ASSERT_NO_FATAL_FAILURE(Init());
5179 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
5180 if (DeviceValidationVersion() < VK_API_VERSION_1_2) {
5181 printf("%s Tests requires Vulkan 1.2+, skipping test\n", kSkipPrefix);
5182 return;
5183 }
5184
5185 VkBufferObj indirect_buffer;
5186 indirect_buffer.init(*m_device, sizeof(VkDrawIndirectCommand), VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT,
5187 VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT);
5188
5189 VkBufferObj indexed_indirect_buffer;
5190 indexed_indirect_buffer.init(*m_device, sizeof(VkDrawIndexedIndirectCommand), VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT,
5191 VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT);
5192
5193 VkBufferObj count_buffer;
5194 count_buffer.init(*m_device, sizeof(uint32_t), VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT);
5195
5196 VkBufferObj index_buffer;
5197 index_buffer.init(*m_device, sizeof(uint32_t), VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, VK_BUFFER_USAGE_INDEX_BUFFER_BIT);
5198
5199 CreatePipelineHelper pipe(*this);
5200 pipe.InitInfo();
5201 pipe.InitState();
5202 pipe.CreateGraphicsPipeline();
5203
5204 // Make calls to valid commands but without the drawIndirectCount feature set
5205 m_commandBuffer->begin();
5206 m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
5207
5208 vk::CmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.pipeline_);
5209
5210 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdDrawIndirectCount-None-02836");
5211 vk::CmdDrawIndirectCount(m_commandBuffer->handle(), indirect_buffer.handle(), 0, count_buffer.handle(), 0, 1,
5212 sizeof(VkDrawIndirectCommand));
5213 m_errorMonitor->VerifyFound();
5214
5215 vk::CmdBindIndexBuffer(m_commandBuffer->handle(), index_buffer.handle(), 0, VK_INDEX_TYPE_UINT32);
5216
5217 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdDrawIndexedIndirect-None-02837");
5218 vk::CmdDrawIndexedIndirectCount(m_commandBuffer->handle(), indexed_indirect_buffer.handle(), 0, count_buffer.handle(), 0, 1,
5219 sizeof(VkDrawIndexedIndirectCommand));
5220 m_errorMonitor->VerifyFound();
5221
5222 m_commandBuffer->EndRenderPass();
5223 m_commandBuffer->end();
5224}
5225
unknown088160a2019-05-23 17:43:13 -06005226TEST_F(VkLayerTest, ExclusiveScissorNV) {
5227 TEST_DESCRIPTION("Test VK_NV_scissor_exclusive with multiViewport disabled.");
5228
5229 if (InstanceExtensionSupported(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME)) {
5230 m_instance_extension_names.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
5231 } else {
5232 printf("%s Did not find required instance extension %s; skipped.\n", kSkipPrefix,
5233 VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
5234 return;
5235 }
Mark Lobodzinski09ce9c42020-03-06 10:02:44 -07005236 ASSERT_NO_FATAL_FAILURE(InitFramework(m_errorMonitor));
unknown088160a2019-05-23 17:43:13 -06005237 std::array<const char *, 1> required_device_extensions = {{VK_NV_SCISSOR_EXCLUSIVE_EXTENSION_NAME}};
5238 for (auto device_extension : required_device_extensions) {
5239 if (DeviceExtensionSupported(gpu(), nullptr, device_extension)) {
5240 m_device_extension_names.push_back(device_extension);
5241 } else {
5242 printf("%s %s Extension not supported, skipping tests\n", kSkipPrefix, device_extension);
5243 return;
5244 }
5245 }
5246
5247 PFN_vkGetPhysicalDeviceFeatures2KHR vkGetPhysicalDeviceFeatures2KHR =
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06005248 (PFN_vkGetPhysicalDeviceFeatures2KHR)vk::GetInstanceProcAddr(instance(), "vkGetPhysicalDeviceFeatures2KHR");
unknown088160a2019-05-23 17:43:13 -06005249 ASSERT_TRUE(vkGetPhysicalDeviceFeatures2KHR != nullptr);
5250
5251 // Create a device that enables exclusive scissor but disables multiViewport
5252 auto exclusive_scissor_features = lvl_init_struct<VkPhysicalDeviceExclusiveScissorFeaturesNV>();
5253 auto features2 = lvl_init_struct<VkPhysicalDeviceFeatures2KHR>(&exclusive_scissor_features);
5254 vkGetPhysicalDeviceFeatures2KHR(gpu(), &features2);
5255
5256 features2.features.multiViewport = VK_FALSE;
5257
5258 ASSERT_NO_FATAL_FAILURE(InitState(nullptr, &features2));
5259 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
5260
5261 if (m_device->phy().properties().limits.maxViewports) {
5262 printf("%s Device doesn't support the necessary number of viewports, skipping test.\n", kSkipPrefix);
5263 return;
5264 }
5265
5266 // Based on PSOViewportStateTests
5267 {
5268 VkViewport viewport = {0.0f, 0.0f, 64.0f, 64.0f, 0.0f, 1.0f};
5269 VkViewport viewports[] = {viewport, viewport};
5270 VkRect2D scissor = {{0, 0}, {64, 64}};
5271 VkRect2D scissors[100] = {scissor, scissor};
5272
5273 using std::vector;
5274 struct TestCase {
5275 uint32_t viewport_count;
5276 VkViewport *viewports;
5277 uint32_t scissor_count;
5278 VkRect2D *scissors;
5279 uint32_t exclusive_scissor_count;
5280 VkRect2D *exclusive_scissors;
5281
5282 vector<std::string> vuids;
5283 };
5284
5285 vector<TestCase> test_cases = {
5286 {1,
5287 viewports,
5288 1,
5289 scissors,
5290 2,
5291 scissors,
5292 {"VUID-VkPipelineViewportExclusiveScissorStateCreateInfoNV-exclusiveScissorCount-02027",
5293 "VUID-VkPipelineViewportExclusiveScissorStateCreateInfoNV-exclusiveScissorCount-02029"}},
5294 {1,
5295 viewports,
5296 1,
5297 scissors,
5298 100,
5299 scissors,
5300 {"VUID-VkPipelineViewportExclusiveScissorStateCreateInfoNV-exclusiveScissorCount-02027",
5301 "VUID-VkPipelineViewportExclusiveScissorStateCreateInfoNV-exclusiveScissorCount-02028",
5302 "VUID-VkPipelineViewportExclusiveScissorStateCreateInfoNV-exclusiveScissorCount-02029"}},
5303 {1,
5304 viewports,
5305 1,
5306 scissors,
5307 1,
5308 nullptr,
5309 {"VUID-VkPipelineViewportExclusiveScissorStateCreateInfoNV-pDynamicStates-02030"}},
5310 };
5311
5312 for (const auto &test_case : test_cases) {
5313 VkPipelineViewportExclusiveScissorStateCreateInfoNV exc = {
5314 VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_EXCLUSIVE_SCISSOR_STATE_CREATE_INFO_NV};
5315
5316 const auto break_vp = [&test_case, &exc](CreatePipelineHelper &helper) {
5317 helper.vp_state_ci_.viewportCount = test_case.viewport_count;
5318 helper.vp_state_ci_.pViewports = test_case.viewports;
5319 helper.vp_state_ci_.scissorCount = test_case.scissor_count;
5320 helper.vp_state_ci_.pScissors = test_case.scissors;
5321 helper.vp_state_ci_.pNext = &exc;
5322
5323 exc.exclusiveScissorCount = test_case.exclusive_scissor_count;
5324 exc.pExclusiveScissors = test_case.exclusive_scissors;
5325 };
Mark Lobodzinski20310782020-02-28 14:25:17 -07005326 CreatePipelineHelper::OneshotTest(*this, break_vp, kErrorBit, test_case.vuids);
unknown088160a2019-05-23 17:43:13 -06005327 }
5328 }
5329
5330 // Based on SetDynScissorParamTests
5331 {
5332 auto vkCmdSetExclusiveScissorNV =
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06005333 (PFN_vkCmdSetExclusiveScissorNV)vk::GetDeviceProcAddr(m_device->device(), "vkCmdSetExclusiveScissorNV");
unknown088160a2019-05-23 17:43:13 -06005334
5335 const VkRect2D scissor = {{0, 0}, {16, 16}};
5336 const VkRect2D scissors[] = {scissor, scissor};
5337
5338 m_commandBuffer->begin();
5339
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, 1, scissors);
5342 m_errorMonitor->VerifyFound();
5343
Mark Lobodzinski20310782020-02-28 14:25:17 -07005344 m_errorMonitor->SetDesiredFailureMsg(kErrorBit,
unknown088160a2019-05-23 17:43:13 -06005345 "vkCmdSetExclusiveScissorNV: parameter exclusiveScissorCount must be greater than 0");
5346 vkCmdSetExclusiveScissorNV(m_commandBuffer->handle(), 0, 0, nullptr);
5347 m_errorMonitor->VerifyFound();
5348
Mark Lobodzinski20310782020-02-28 14:25:17 -07005349 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdSetExclusiveScissorNV-exclusiveScissorCount-02036");
unknown088160a2019-05-23 17:43:13 -06005350 vkCmdSetExclusiveScissorNV(m_commandBuffer->handle(), 0, 2, scissors);
5351 m_errorMonitor->VerifyFound();
5352
Mark Lobodzinski20310782020-02-28 14:25:17 -07005353 m_errorMonitor->SetDesiredFailureMsg(kErrorBit,
unknown088160a2019-05-23 17:43:13 -06005354 "vkCmdSetExclusiveScissorNV: parameter exclusiveScissorCount must be greater than 0");
Mark Lobodzinski20310782020-02-28 14:25:17 -07005355 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdSetExclusiveScissorNV-firstExclusiveScissor-02035");
unknown088160a2019-05-23 17:43:13 -06005356 vkCmdSetExclusiveScissorNV(m_commandBuffer->handle(), 1, 0, scissors);
5357 m_errorMonitor->VerifyFound();
5358
Mark Lobodzinski20310782020-02-28 14:25:17 -07005359 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdSetExclusiveScissorNV-firstExclusiveScissor-02035");
5360 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdSetExclusiveScissorNV-exclusiveScissorCount-02036");
unknown088160a2019-05-23 17:43:13 -06005361 vkCmdSetExclusiveScissorNV(m_commandBuffer->handle(), 1, 2, scissors);
5362 m_errorMonitor->VerifyFound();
5363
Mark Lobodzinski20310782020-02-28 14:25:17 -07005364 m_errorMonitor->SetDesiredFailureMsg(kErrorBit,
unknown088160a2019-05-23 17:43:13 -06005365 "vkCmdSetExclusiveScissorNV: required parameter pExclusiveScissors specified as NULL");
5366 vkCmdSetExclusiveScissorNV(m_commandBuffer->handle(), 0, 1, nullptr);
5367 m_errorMonitor->VerifyFound();
5368
5369 struct TestCase {
5370 VkRect2D scissor;
5371 std::string vuid;
5372 };
5373
5374 std::vector<TestCase> test_cases = {
5375 {{{-1, 0}, {16, 16}}, "VUID-vkCmdSetExclusiveScissorNV-x-02037"},
5376 {{{0, -1}, {16, 16}}, "VUID-vkCmdSetExclusiveScissorNV-x-02037"},
5377 {{{1, 0}, {INT32_MAX, 16}}, "VUID-vkCmdSetExclusiveScissorNV-offset-02038"},
5378 {{{INT32_MAX, 0}, {1, 16}}, "VUID-vkCmdSetExclusiveScissorNV-offset-02038"},
5379 {{{0, 0}, {uint32_t{INT32_MAX} + 1, 16}}, "VUID-vkCmdSetExclusiveScissorNV-offset-02038"},
5380 {{{0, 1}, {16, INT32_MAX}}, "VUID-vkCmdSetExclusiveScissorNV-offset-02039"},
5381 {{{0, INT32_MAX}, {16, 1}}, "VUID-vkCmdSetExclusiveScissorNV-offset-02039"},
5382 {{{0, 0}, {16, uint32_t{INT32_MAX} + 1}}, "VUID-vkCmdSetExclusiveScissorNV-offset-02039"}};
5383
5384 for (const auto &test_case : test_cases) {
Mark Lobodzinski20310782020-02-28 14:25:17 -07005385 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, test_case.vuid);
unknown088160a2019-05-23 17:43:13 -06005386 vkCmdSetExclusiveScissorNV(m_commandBuffer->handle(), 0, 1, &test_case.scissor);
5387 m_errorMonitor->VerifyFound();
5388 }
5389
5390 m_commandBuffer->end();
5391 }
5392}
5393
5394TEST_F(VkLayerTest, MeshShaderNV) {
5395 TEST_DESCRIPTION("Test VK_NV_mesh_shader.");
5396
5397 if (InstanceExtensionSupported(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME)) {
5398 m_instance_extension_names.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
5399 } else {
5400 printf("%s Did not find required instance extension %s; skipped.\n", kSkipPrefix,
5401 VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
5402 return;
5403 }
Mark Lobodzinski09ce9c42020-03-06 10:02:44 -07005404 ASSERT_NO_FATAL_FAILURE(InitFramework(m_errorMonitor));
unknown088160a2019-05-23 17:43:13 -06005405 std::array<const char *, 1> required_device_extensions = {{VK_NV_MESH_SHADER_EXTENSION_NAME}};
5406 for (auto device_extension : required_device_extensions) {
5407 if (DeviceExtensionSupported(gpu(), nullptr, device_extension)) {
5408 m_device_extension_names.push_back(device_extension);
5409 } else {
5410 printf("%s %s Extension not supported, skipping tests\n", kSkipPrefix, device_extension);
5411 return;
5412 }
5413 }
5414
Tony-LunarG048f5012020-04-29 16:55:11 -06005415 if (IsPlatform(kMockICD) || DeviceSimulation()) {
unknown088160a2019-05-23 17:43:13 -06005416 printf("%sNot suppored by MockICD, skipping tests\n", kSkipPrefix);
5417 return;
5418 }
5419
5420 PFN_vkGetPhysicalDeviceFeatures2KHR vkGetPhysicalDeviceFeatures2KHR =
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06005421 (PFN_vkGetPhysicalDeviceFeatures2KHR)vk::GetInstanceProcAddr(instance(), "vkGetPhysicalDeviceFeatures2KHR");
unknown088160a2019-05-23 17:43:13 -06005422 ASSERT_TRUE(vkGetPhysicalDeviceFeatures2KHR != nullptr);
5423
5424 // Create a device that enables mesh_shader
5425 auto mesh_shader_features = lvl_init_struct<VkPhysicalDeviceMeshShaderFeaturesNV>();
5426 auto features2 = lvl_init_struct<VkPhysicalDeviceFeatures2KHR>(&mesh_shader_features);
5427 vkGetPhysicalDeviceFeatures2KHR(gpu(), &features2);
5428 features2.features.multiDrawIndirect = VK_FALSE;
5429
5430 ASSERT_NO_FATAL_FAILURE(InitState(nullptr, &features2));
5431 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
5432
5433 static const char vertShaderText[] =
5434 "#version 450\n"
5435 "vec2 vertices[3];\n"
5436 "void main() {\n"
5437 " vertices[0] = vec2(-1.0, -1.0);\n"
5438 " vertices[1] = vec2( 1.0, -1.0);\n"
5439 " vertices[2] = vec2( 0.0, 1.0);\n"
5440 " gl_Position = vec4(vertices[gl_VertexIndex % 3], 0.0, 1.0);\n"
5441 " gl_PointSize = 1.0f;\n"
5442 "}\n";
5443
5444 static const char meshShaderText[] =
5445 "#version 450\n"
5446 "#extension GL_NV_mesh_shader : require\n"
5447 "layout(local_size_x = 1) in;\n"
5448 "layout(max_vertices = 3) out;\n"
5449 "layout(max_primitives = 1) out;\n"
5450 "layout(triangles) out;\n"
5451 "void main() {\n"
5452 " gl_MeshVerticesNV[0].gl_Position = vec4(-1.0, -1.0, 0, 1);\n"
5453 " gl_MeshVerticesNV[1].gl_Position = vec4( 1.0, -1.0, 0, 1);\n"
5454 " gl_MeshVerticesNV[2].gl_Position = vec4( 0.0, 1.0, 0, 1);\n"
5455 " gl_PrimitiveIndicesNV[0] = 0;\n"
5456 " gl_PrimitiveIndicesNV[1] = 1;\n"
5457 " gl_PrimitiveIndicesNV[2] = 2;\n"
5458 " gl_PrimitiveCountNV = 1;\n"
5459 "}\n";
5460
5461 VkShaderObj vs(m_device, vertShaderText, VK_SHADER_STAGE_VERTEX_BIT, this);
5462 VkShaderObj ms(m_device, meshShaderText, VK_SHADER_STAGE_MESH_BIT_NV, this);
5463 VkShaderObj fs(m_device, bindStateFragShaderText, VK_SHADER_STAGE_FRAGMENT_BIT, this);
5464
5465 // Test pipeline creation
5466 {
5467 // can't mix mesh with vertex
5468 const auto break_vp = [&](CreatePipelineHelper &helper) {
5469 helper.shader_stages_ = {vs.GetStageCreateInfo(), fs.GetStageCreateInfo(), ms.GetStageCreateInfo()};
5470 };
Mark Lobodzinski20310782020-02-28 14:25:17 -07005471 CreatePipelineHelper::OneshotTest(*this, break_vp, kErrorBit,
unknown088160a2019-05-23 17:43:13 -06005472 vector<std::string>({"VUID-VkGraphicsPipelineCreateInfo-pStages-02095"}));
5473
5474 // vertex or mesh must be present
5475 const auto break_vp2 = [&](CreatePipelineHelper &helper) { helper.shader_stages_ = {fs.GetStageCreateInfo()}; };
Mark Lobodzinski20310782020-02-28 14:25:17 -07005476 CreatePipelineHelper::OneshotTest(*this, break_vp2, kErrorBit,
unknown088160a2019-05-23 17:43:13 -06005477 vector<std::string>({"VUID-VkGraphicsPipelineCreateInfo-stage-02096"}));
5478
5479 // vertexinput and inputassembly must be valid when vertex stage is present
5480 const auto break_vp3 = [&](CreatePipelineHelper &helper) {
5481 helper.shader_stages_ = {vs.GetStageCreateInfo(), fs.GetStageCreateInfo()};
5482 helper.gp_ci_.pVertexInputState = nullptr;
5483 helper.gp_ci_.pInputAssemblyState = nullptr;
5484 };
Mark Lobodzinski20310782020-02-28 14:25:17 -07005485 CreatePipelineHelper::OneshotTest(*this, break_vp3, kErrorBit,
unknown088160a2019-05-23 17:43:13 -06005486 vector<std::string>({"VUID-VkGraphicsPipelineCreateInfo-pStages-02097",
5487 "VUID-VkGraphicsPipelineCreateInfo-pStages-02098"}));
5488 }
5489
5490 PFN_vkCmdDrawMeshTasksIndirectNV vkCmdDrawMeshTasksIndirectNV =
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06005491 (PFN_vkCmdDrawMeshTasksIndirectNV)vk::GetInstanceProcAddr(instance(), "vkCmdDrawMeshTasksIndirectNV");
unknown088160a2019-05-23 17:43:13 -06005492
5493 VkBufferCreateInfo buffer_create_info = {VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO};
5494 buffer_create_info.size = sizeof(uint32_t);
5495 buffer_create_info.usage = VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT;
5496 VkBuffer buffer;
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06005497 VkResult result = vk::CreateBuffer(m_device->device(), &buffer_create_info, nullptr, &buffer);
unknown088160a2019-05-23 17:43:13 -06005498 ASSERT_VK_SUCCESS(result);
5499
5500 m_commandBuffer->begin();
5501
Mark Lobodzinski20310782020-02-28 14:25:17 -07005502 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdDrawMeshTasksIndirectNV-drawCount-02146");
5503 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdDrawMeshTasksIndirectNV-drawCount-02718");
unknown088160a2019-05-23 17:43:13 -06005504 vkCmdDrawMeshTasksIndirectNV(m_commandBuffer->handle(), buffer, 0, 2, 0);
5505 m_errorMonitor->VerifyFound();
5506
5507 m_commandBuffer->end();
5508
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06005509 vk::DestroyBuffer(m_device->device(), buffer, 0);
unknown088160a2019-05-23 17:43:13 -06005510}
5511
5512TEST_F(VkLayerTest, MeshShaderDisabledNV) {
5513 TEST_DESCRIPTION("Test VK_NV_mesh_shader VUs with NV_mesh_shader disabled.");
5514 ASSERT_NO_FATAL_FAILURE(Init());
5515 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
5516
5517 VkEvent event;
5518 VkEventCreateInfo event_create_info{};
5519 event_create_info.sType = VK_STRUCTURE_TYPE_EVENT_CREATE_INFO;
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06005520 vk::CreateEvent(m_device->device(), &event_create_info, nullptr, &event);
unknown088160a2019-05-23 17:43:13 -06005521
5522 m_commandBuffer->begin();
5523
Mark Lobodzinski20310782020-02-28 14:25:17 -07005524 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdSetEvent-stageMask-02107");
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06005525 vk::CmdSetEvent(m_commandBuffer->handle(), event, VK_PIPELINE_STAGE_MESH_SHADER_BIT_NV);
unknown088160a2019-05-23 17:43:13 -06005526 m_errorMonitor->VerifyFound();
5527
Mark Lobodzinski20310782020-02-28 14:25:17 -07005528 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdSetEvent-stageMask-02108");
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06005529 vk::CmdSetEvent(m_commandBuffer->handle(), event, VK_PIPELINE_STAGE_TASK_SHADER_BIT_NV);
unknown088160a2019-05-23 17:43:13 -06005530 m_errorMonitor->VerifyFound();
5531
Mark Lobodzinski20310782020-02-28 14:25:17 -07005532 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdResetEvent-stageMask-02109");
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06005533 vk::CmdResetEvent(m_commandBuffer->handle(), event, VK_PIPELINE_STAGE_MESH_SHADER_BIT_NV);
unknown088160a2019-05-23 17:43:13 -06005534 m_errorMonitor->VerifyFound();
5535
Mark Lobodzinski20310782020-02-28 14:25:17 -07005536 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdResetEvent-stageMask-02110");
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06005537 vk::CmdResetEvent(m_commandBuffer->handle(), event, VK_PIPELINE_STAGE_TASK_SHADER_BIT_NV);
unknown088160a2019-05-23 17:43:13 -06005538 m_errorMonitor->VerifyFound();
5539
Mark Lobodzinski20310782020-02-28 14:25:17 -07005540 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdWaitEvents-srcStageMask-02111");
5541 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdWaitEvents-dstStageMask-02113");
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06005542 vk::CmdWaitEvents(m_commandBuffer->handle(), 1, &event, VK_PIPELINE_STAGE_MESH_SHADER_BIT_NV,
5543 VK_PIPELINE_STAGE_MESH_SHADER_BIT_NV, 0, nullptr, 0, nullptr, 0, nullptr);
unknown088160a2019-05-23 17:43:13 -06005544 m_errorMonitor->VerifyFound();
5545
Mark Lobodzinski20310782020-02-28 14:25:17 -07005546 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdWaitEvents-srcStageMask-02112");
5547 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdWaitEvents-dstStageMask-02114");
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06005548 vk::CmdWaitEvents(m_commandBuffer->handle(), 1, &event, VK_PIPELINE_STAGE_TASK_SHADER_BIT_NV,
5549 VK_PIPELINE_STAGE_TASK_SHADER_BIT_NV, 0, nullptr, 0, nullptr, 0, nullptr);
unknown088160a2019-05-23 17:43:13 -06005550 m_errorMonitor->VerifyFound();
5551
Mark Lobodzinski20310782020-02-28 14:25:17 -07005552 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdPipelineBarrier-srcStageMask-02115");
5553 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdPipelineBarrier-dstStageMask-02117");
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06005554 vk::CmdPipelineBarrier(m_commandBuffer->handle(), VK_PIPELINE_STAGE_MESH_SHADER_BIT_NV, VK_PIPELINE_STAGE_MESH_SHADER_BIT_NV, 0,
5555 0, nullptr, 0, nullptr, 0, nullptr);
unknown088160a2019-05-23 17:43:13 -06005556 m_errorMonitor->VerifyFound();
5557
Mark Lobodzinski20310782020-02-28 14:25:17 -07005558 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdPipelineBarrier-srcStageMask-02116");
5559 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdPipelineBarrier-dstStageMask-02118");
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06005560 vk::CmdPipelineBarrier(m_commandBuffer->handle(), VK_PIPELINE_STAGE_TASK_SHADER_BIT_NV, VK_PIPELINE_STAGE_TASK_SHADER_BIT_NV, 0,
5561 0, nullptr, 0, nullptr, 0, nullptr);
unknown088160a2019-05-23 17:43:13 -06005562 m_errorMonitor->VerifyFound();
5563
5564 m_commandBuffer->end();
5565
5566 VkSemaphoreCreateInfo semaphore_create_info = {};
5567 semaphore_create_info.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO;
5568 VkSemaphore semaphore;
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06005569 ASSERT_VK_SUCCESS(vk::CreateSemaphore(m_device->device(), &semaphore_create_info, nullptr, &semaphore));
unknown088160a2019-05-23 17:43:13 -06005570
5571 VkPipelineStageFlags stage_flags = VK_PIPELINE_STAGE_MESH_SHADER_BIT_NV | VK_PIPELINE_STAGE_TASK_SHADER_BIT_NV;
5572 VkSubmitInfo submit_info = {};
5573
5574 // Signal the semaphore so the next test can wait on it.
5575 submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
5576 submit_info.signalSemaphoreCount = 1;
5577 submit_info.pSignalSemaphores = &semaphore;
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06005578 vk::QueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
unknown088160a2019-05-23 17:43:13 -06005579 m_errorMonitor->VerifyNotFound();
5580
5581 submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
5582 submit_info.signalSemaphoreCount = 0;
5583 submit_info.pSignalSemaphores = nullptr;
5584 submit_info.waitSemaphoreCount = 1;
5585 submit_info.pWaitSemaphores = &semaphore;
5586 submit_info.pWaitDstStageMask = &stage_flags;
5587
Mark Lobodzinski20310782020-02-28 14:25:17 -07005588 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkSubmitInfo-pWaitDstStageMask-02089");
5589 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkSubmitInfo-pWaitDstStageMask-02090");
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06005590 vk::QueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
unknown088160a2019-05-23 17:43:13 -06005591 m_errorMonitor->VerifyFound();
5592
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06005593 vk::QueueWaitIdle(m_device->m_queue);
unknown088160a2019-05-23 17:43:13 -06005594
5595 VkShaderObj vs(m_device, bindStateVertShaderText, VK_SHADER_STAGE_VERTEX_BIT, this);
5596 VkPipelineShaderStageCreateInfo meshStage = {VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO};
5597 meshStage = vs.GetStageCreateInfo();
5598 meshStage.stage = VK_SHADER_STAGE_MESH_BIT_NV;
5599 VkPipelineShaderStageCreateInfo taskStage = {VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO};
5600 taskStage = vs.GetStageCreateInfo();
5601 taskStage.stage = VK_SHADER_STAGE_TASK_BIT_NV;
5602
5603 // mesh and task shaders not supported
5604 const auto break_vp = [&](CreatePipelineHelper &helper) {
5605 helper.shader_stages_ = {meshStage, taskStage, vs.GetStageCreateInfo()};
5606 };
5607 CreatePipelineHelper::OneshotTest(
Mark Lobodzinski20310782020-02-28 14:25:17 -07005608 *this, break_vp, kErrorBit,
unknown088160a2019-05-23 17:43:13 -06005609 vector<std::string>({"VUID-VkPipelineShaderStageCreateInfo-pName-00707", "VUID-VkPipelineShaderStageCreateInfo-pName-00707",
5610 "VUID-VkPipelineShaderStageCreateInfo-stage-02091",
5611 "VUID-VkPipelineShaderStageCreateInfo-stage-02092"}));
5612
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06005613 vk::DestroyEvent(m_device->device(), event, nullptr);
5614 vk::DestroySemaphore(m_device->device(), semaphore, nullptr);
unknown088160a2019-05-23 17:43:13 -06005615}
Chris Mayerc93536f2019-09-19 16:34:49 +02005616
5617TEST_F(VkLayerTest, ViewportWScalingNV) {
5618 TEST_DESCRIPTION("Verify VK_NV_clip_space_w_scaling");
5619
Mark Lobodzinski09ce9c42020-03-06 10:02:44 -07005620 ASSERT_NO_FATAL_FAILURE(InitFramework(m_errorMonitor));
Chris Mayerc93536f2019-09-19 16:34:49 +02005621
5622 VkPhysicalDeviceFeatures device_features = {};
5623 ASSERT_NO_FATAL_FAILURE(GetPhysicalDeviceFeatures(&device_features));
5624
5625 if (!device_features.multiViewport) {
5626 printf("%s VkPhysicalDeviceFeatures::multiViewport is not supported, skipping tests\n", kSkipPrefix);
5627 return;
5628 }
5629
5630 if (DeviceExtensionSupported(gpu(), nullptr, VK_NV_CLIP_SPACE_W_SCALING_EXTENSION_NAME)) {
5631 m_device_extension_names.push_back(VK_NV_CLIP_SPACE_W_SCALING_EXTENSION_NAME);
5632 } else {
5633 printf("%s %s Extension not supported, skipping tests\n", kSkipPrefix, VK_NV_CLIP_SPACE_W_SCALING_EXTENSION_NAME);
5634 return;
5635 }
5636
5637 ASSERT_NO_FATAL_FAILURE(InitState(&device_features));
5638 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
5639
5640 auto vkCmdSetViewportWScalingNV =
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06005641 reinterpret_cast<PFN_vkCmdSetViewportWScalingNV>(vk::GetDeviceProcAddr(m_device->device(), "vkCmdSetViewportWScalingNV"));
Chris Mayerc93536f2019-09-19 16:34:49 +02005642
5643 const char vs_src[] = R"(
5644 #version 450
5645 const vec2 positions[] = { vec2(-1.0f, 1.0f),
5646 vec2( 1.0f, 1.0f),
5647 vec2(-1.0f, -1.0f),
5648 vec2( 1.0f, -1.0f) };
5649 out gl_PerVertex {
5650 vec4 gl_Position;
5651 };
5652
5653 void main() {
5654 gl_Position = vec4(positions[gl_VertexIndex % 4], 0.0f, 1.0f);
5655 })";
5656
5657 const char fs_src[] = R"(
5658 #version 450
5659 layout(location = 0) out vec4 outColor;
5660
5661 void main() {
5662 outColor = vec4(0.0f, 1.0f, 0.0f, 1.0f);
5663 })";
5664
5665 const std::vector<VkViewport> vp = {
5666 {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}};
5667 const std::vector<VkRect2D> sc = {{{0, 0}, {32, 32}}, {{32, 0}, {32, 32}}, {{0, 32}, {32, 32}}, {{32, 32}, {32, 32}}};
5668 const std::vector<VkViewportWScalingNV> scale = {{-0.2f, -0.2f}, {0.2f, -0.2f}, {-0.2f, 0.2f}, {0.2f, 0.2f}};
5669
5670 const uint32_t vp_count = static_cast<uint32_t>(vp.size());
5671
5672 VkPipelineViewportWScalingStateCreateInfoNV vpsi = {VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_W_SCALING_STATE_CREATE_INFO_NV};
5673 vpsi.viewportWScalingEnable = VK_TRUE;
5674 vpsi.viewportCount = vp_count;
5675 vpsi.pViewportWScalings = scale.data();
5676
5677 VkPipelineViewportStateCreateInfo vpci = {VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO};
5678 vpci.viewportCount = vp_count;
5679 vpci.pViewports = vp.data();
5680 vpci.scissorCount = vp_count;
5681 vpci.pScissors = sc.data();
5682 vpci.pNext = &vpsi;
5683
5684 const auto set_vpci = [&vpci](CreatePipelineHelper &helper) { helper.vp_state_ci_ = vpci; };
5685
5686 // Make sure no errors show up when creating the pipeline with w-scaling enabled
Mark Lobodzinski20310782020-02-28 14:25:17 -07005687 CreatePipelineHelper::OneshotTest(*this, set_vpci, kErrorBit, vector<std::string>(), true);
Chris Mayerc93536f2019-09-19 16:34:49 +02005688
5689 // Create pipeline with w-scaling enabled but without a valid scaling array
5690 vpsi.pViewportWScalings = nullptr;
Mark Lobodzinski20310782020-02-28 14:25:17 -07005691 CreatePipelineHelper::OneshotTest(*this, set_vpci, kErrorBit,
Chris Mayerc93536f2019-09-19 16:34:49 +02005692 vector<std::string>({"VUID-VkGraphicsPipelineCreateInfo-pDynamicStates-01715"}));
5693
5694 vpsi.pViewportWScalings = scale.data();
5695
5696 // Create pipeline with w-scaling enabled but without matching viewport counts
5697 vpsi.viewportCount = 1;
Mark Lobodzinski20310782020-02-28 14:25:17 -07005698 CreatePipelineHelper::OneshotTest(*this, set_vpci, kErrorBit,
Chris Mayerc93536f2019-09-19 16:34:49 +02005699 vector<std::string>({"VUID-VkPipelineViewportStateCreateInfo-viewportWScalingEnable-01726"}));
5700
5701 const VkPipelineLayoutObj pl(m_device);
5702
5703 VkShaderObj vs(m_device, vs_src, VK_SHADER_STAGE_VERTEX_BIT, this);
5704 VkShaderObj fs(m_device, fs_src, VK_SHADER_STAGE_FRAGMENT_BIT, this);
5705
5706 VkPipelineObj pipe(m_device);
5707 pipe.AddDefaultColorAttachment();
5708 pipe.AddShader(&vs);
5709 pipe.AddShader(&fs);
5710 pipe.SetViewport(vp);
5711 pipe.SetScissor(sc);
5712 pipe.CreateVKPipeline(pl.handle(), renderPass());
5713
5714 VkPipelineObj pipeDynWScale(m_device);
5715 pipeDynWScale.AddDefaultColorAttachment();
5716 pipeDynWScale.AddShader(&vs);
5717 pipeDynWScale.AddShader(&fs);
5718 pipeDynWScale.SetViewport(vp);
5719 pipeDynWScale.SetScissor(sc);
5720 pipeDynWScale.MakeDynamic(VK_DYNAMIC_STATE_VIEWPORT_W_SCALING_NV);
5721 pipeDynWScale.CreateVKPipeline(pl.handle(), renderPass());
5722
5723 m_commandBuffer->begin();
5724
5725 // Bind pipeline without dynamic w scaling enabled
5726 m_errorMonitor->ExpectSuccess();
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06005727 vk::CmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.handle());
Chris Mayerc93536f2019-09-19 16:34:49 +02005728 m_errorMonitor->VerifyNotFound();
5729
Chris Mayerc93536f2019-09-19 16:34:49 +02005730 // Bind pipeline that has dynamic w-scaling enabled
5731 m_errorMonitor->ExpectSuccess();
Mark Lobodzinski902cb0f2019-09-27 14:45:36 -06005732 vk::CmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeDynWScale.handle());
Chris Mayerc93536f2019-09-19 16:34:49 +02005733 m_errorMonitor->VerifyNotFound();
5734
5735 const auto max_vps = m_device->props.limits.maxViewports;
5736
Mark Lobodzinski20310782020-02-28 14:25:17 -07005737 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdSetViewportWScalingNV-firstViewport-01323");
Chris Mayerc93536f2019-09-19 16:34:49 +02005738 vkCmdSetViewportWScalingNV(m_commandBuffer->handle(), max_vps, vp_count, scale.data());
5739 m_errorMonitor->VerifyFound();
5740
Mark Lobodzinski20310782020-02-28 14:25:17 -07005741 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdSetViewportWScalingNV-firstViewport-01324");
Chris Mayerc93536f2019-09-19 16:34:49 +02005742 vkCmdSetViewportWScalingNV(m_commandBuffer->handle(), 1, max_vps, scale.data());
5743 m_errorMonitor->VerifyFound();
5744
5745 m_errorMonitor->ExpectSuccess();
5746 vkCmdSetViewportWScalingNV(m_commandBuffer->handle(), 0, vp_count, scale.data());
5747 m_errorMonitor->VerifyNotFound();
5748
5749 m_commandBuffer->end();
5750}
sfricke-samsung914e8002020-01-07 22:26:18 -08005751
5752TEST_F(VkLayerTest, CreateSamplerYcbcrConversionEnable) {
5753 TEST_DESCRIPTION("Checks samplerYcbcrConversion is enabled before calling vkCreateSamplerYcbcrConversion");
5754
5755 // Enable Sampler YCbCr Conversion req'd extensions
5756 // Only need revision 1 of vkGetPhysicalDeviceProperties2 and this allows more device capable for testing
5757 bool mp_extensions = InstanceExtensionSupported(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME, 1);
5758 if (mp_extensions) {
5759 m_instance_extension_names.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
5760 }
5761 SetTargetApiVersion(VK_API_VERSION_1_1);
Mark Lobodzinski09ce9c42020-03-06 10:02:44 -07005762 ASSERT_NO_FATAL_FAILURE(InitFramework(m_errorMonitor));
sfricke-samsung914e8002020-01-07 22:26:18 -08005763 mp_extensions = mp_extensions && DeviceExtensionSupported(gpu(), nullptr, VK_KHR_MAINTENANCE1_EXTENSION_NAME);
5764 mp_extensions = mp_extensions && DeviceExtensionSupported(gpu(), nullptr, VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME);
5765 mp_extensions = mp_extensions && DeviceExtensionSupported(gpu(), nullptr, VK_KHR_BIND_MEMORY_2_EXTENSION_NAME);
5766 mp_extensions = mp_extensions && DeviceExtensionSupported(gpu(), nullptr, VK_KHR_SAMPLER_YCBCR_CONVERSION_EXTENSION_NAME);
5767 if (mp_extensions) {
5768 m_device_extension_names.push_back(VK_KHR_MAINTENANCE1_EXTENSION_NAME);
5769 m_device_extension_names.push_back(VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME);
5770 m_device_extension_names.push_back(VK_KHR_BIND_MEMORY_2_EXTENSION_NAME);
5771 m_device_extension_names.push_back(VK_KHR_SAMPLER_YCBCR_CONVERSION_EXTENSION_NAME);
5772 } else {
5773 printf("%s test requires Sampler YCbCr Conversion extensions, not available. Skipping.\n", kSkipPrefix);
5774 return;
5775 }
5776
5777 // Explictly not enable Ycbcr Conversion Features
5778 VkPhysicalDeviceSamplerYcbcrConversionFeatures ycbcr_features = {};
5779 ycbcr_features.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SAMPLER_YCBCR_CONVERSION_FEATURES;
5780 ycbcr_features.samplerYcbcrConversion = VK_FALSE;
5781 ASSERT_NO_FATAL_FAILURE(InitState(nullptr, &ycbcr_features));
5782
5783 PFN_vkCreateSamplerYcbcrConversionKHR vkCreateSamplerYcbcrConversionFunction =
5784 (PFN_vkCreateSamplerYcbcrConversionKHR)vk::GetDeviceProcAddr(m_device->handle(), "vkCreateSamplerYcbcrConversionKHR");
5785 if (vkCreateSamplerYcbcrConversionFunction == nullptr) {
5786 printf("%s did not find vkCreateSamplerYcbcrConversionKHR function pointer; Skipping.\n", kSkipPrefix);
5787 return;
5788 }
5789
5790 // Create Ycbcr conversion
5791 VkSamplerYcbcrConversion conversions;
5792 VkSamplerYcbcrConversionCreateInfo ycbcr_create_info = {VK_STRUCTURE_TYPE_SAMPLER_YCBCR_CONVERSION_CREATE_INFO,
5793 NULL,
5794 VK_FORMAT_G8_B8R8_2PLANE_420_UNORM_KHR,
5795 VK_SAMPLER_YCBCR_MODEL_CONVERSION_RGB_IDENTITY,
5796 VK_SAMPLER_YCBCR_RANGE_ITU_FULL,
5797 {VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY,
5798 VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY},
5799 VK_CHROMA_LOCATION_COSITED_EVEN,
5800 VK_CHROMA_LOCATION_COSITED_EVEN,
5801 VK_FILTER_NEAREST,
5802 false};
5803
Mark Lobodzinski20310782020-02-28 14:25:17 -07005804 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCreateSamplerYcbcrConversion-None-01648");
sfricke-samsung914e8002020-01-07 22:26:18 -08005805 vkCreateSamplerYcbcrConversionFunction(m_device->handle(), &ycbcr_create_info, nullptr, &conversions);
5806 m_errorMonitor->VerifyFound();
Shannon McPherson50421602020-01-28 15:18:46 -07005807}
Jeremy Hayescd7df2c2020-05-21 16:36:47 -06005808
5809TEST_F(VkLayerTest, TransformFeedbackFeatureEnabled) {
5810 TEST_DESCRIPTION("VkPhysicalDeviceTransformFeedbackFeaturesEXT::transformFeedback must be enabled");
5811
5812 if (!InstanceExtensionSupported(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME)) {
5813 printf("%s Did not find required instance extension %s; skipped.\n", kSkipPrefix,
5814 VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
5815 return;
5816 }
5817 m_instance_extension_names.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
5818
5819 ASSERT_NO_FATAL_FAILURE(InitFramework(m_errorMonitor));
5820
5821 if (!DeviceExtensionSupported(gpu(), nullptr, VK_EXT_TRANSFORM_FEEDBACK_EXTENSION_NAME)) {
5822 printf("%s %s Extension not supported, skipping tests\n", kSkipPrefix, VK_EXT_TRANSFORM_FEEDBACK_EXTENSION_NAME);
5823 return;
5824 }
5825 m_device_extension_names.push_back(VK_EXT_TRANSFORM_FEEDBACK_EXTENSION_NAME);
5826
5827 {
5828 PFN_vkGetPhysicalDeviceFeatures2KHR vkGetPhysicalDeviceFeatures2KHR =
5829 (PFN_vkGetPhysicalDeviceFeatures2KHR)vk::GetInstanceProcAddr(instance(), "vkGetPhysicalDeviceFeatures2KHR");
5830 ASSERT_TRUE(vkGetPhysicalDeviceFeatures2KHR != nullptr);
5831
5832 auto tf_features = lvl_init_struct<VkPhysicalDeviceTransformFeedbackFeaturesEXT>();
5833 auto pd_features = lvl_init_struct<VkPhysicalDeviceFeatures2>(&tf_features);
5834 vkGetPhysicalDeviceFeatures2KHR(gpu(), &pd_features);
5835
5836 if (!tf_features.transformFeedback) {
5837 printf("%s transformFeedback not supported; skipped.\n", kSkipPrefix);
5838 return;
5839 }
5840 }
5841
5842 ASSERT_NO_FATAL_FAILURE(InitState());
5843 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
5844
5845 {
5846 auto vkCmdBindTransformFeedbackBuffersEXT = (PFN_vkCmdBindTransformFeedbackBuffersEXT)vk::GetDeviceProcAddr(
5847 m_device->device(), "vkCmdBindTransformFeedbackBuffersEXT");
5848 ASSERT_TRUE(vkCmdBindTransformFeedbackBuffersEXT != nullptr);
5849
5850 auto info = lvl_init_struct<VkBufferCreateInfo>();
5851 info.usage = VK_BUFFER_USAGE_TRANSFORM_FEEDBACK_BUFFER_BIT_EXT;
5852 info.size = 4;
5853 VkBufferObj buffer;
5854 buffer.init(*m_device, info);
5855 VkDeviceSize offsets[1]{};
5856
5857 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdBindTransformFeedbackBuffersEXT-transformFeedback-02355");
5858 vkCmdBindTransformFeedbackBuffersEXT(m_commandBuffer->handle(), 0, 1, &buffer.handle(), offsets, nullptr);
5859 m_errorMonitor->VerifyFound();
5860 }
5861
5862 {
5863 auto vkCmdBeginTransformFeedbackEXT =
5864 (PFN_vkCmdBeginTransformFeedbackEXT)vk::GetDeviceProcAddr(m_device->device(), "vkCmdBeginTransformFeedbackEXT");
5865 ASSERT_TRUE(vkCmdBeginTransformFeedbackEXT != nullptr);
5866
5867 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdBeginTransformFeedbackEXT-transformFeedback-02366");
5868 vkCmdBeginTransformFeedbackEXT(m_commandBuffer->handle(), 0, 1, nullptr, nullptr);
5869 m_errorMonitor->VerifyFound();
5870 }
5871
5872 {
5873 auto vkCmdEndTransformFeedbackEXT =
5874 (PFN_vkCmdEndTransformFeedbackEXT)vk::GetDeviceProcAddr(m_device->device(), "vkCmdEndTransformFeedbackEXT");
5875 ASSERT_TRUE(vkCmdEndTransformFeedbackEXT != nullptr);
5876
5877 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdEndTransformFeedbackEXT-transformFeedback-02374");
5878 m_errorMonitor->SetUnexpectedError("VUID-vkCmdEndTransformFeedbackEXT-None-02375");
5879 vkCmdEndTransformFeedbackEXT(m_commandBuffer->handle(), 0, 1, nullptr, nullptr);
5880 m_errorMonitor->VerifyFound();
5881 }
5882}
5883
5884TEST_F(VkLayerTest, TransformFeedbackCmdBindTransformFeedbackBuffersEXT) {
5885 TEST_DESCRIPTION("Submit invalid arguments to vkCmdBindTransformFeedbackBuffersEXT");
5886
5887 if (!InstanceExtensionSupported(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME)) {
5888 printf("%s Did not find required instance extension %s; skipped.\n", kSkipPrefix,
5889 VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
5890 return;
5891 }
5892 m_instance_extension_names.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
5893
5894 ASSERT_NO_FATAL_FAILURE(InitFramework(m_errorMonitor));
5895
5896 if (!DeviceExtensionSupported(gpu(), nullptr, VK_EXT_TRANSFORM_FEEDBACK_EXTENSION_NAME)) {
5897 printf("%s %s Extension not supported, skipping tests\n", kSkipPrefix, VK_EXT_TRANSFORM_FEEDBACK_EXTENSION_NAME);
5898 return;
5899 }
5900 m_device_extension_names.push_back(VK_EXT_TRANSFORM_FEEDBACK_EXTENSION_NAME);
5901
5902 {
5903 PFN_vkGetPhysicalDeviceFeatures2KHR vkGetPhysicalDeviceFeatures2KHR =
5904 (PFN_vkGetPhysicalDeviceFeatures2KHR)vk::GetInstanceProcAddr(instance(), "vkGetPhysicalDeviceFeatures2KHR");
5905 ASSERT_TRUE(vkGetPhysicalDeviceFeatures2KHR != nullptr);
5906
5907 auto tf_features = lvl_init_struct<VkPhysicalDeviceTransformFeedbackFeaturesEXT>();
5908 auto pd_features = lvl_init_struct<VkPhysicalDeviceFeatures2>(&tf_features);
5909 vkGetPhysicalDeviceFeatures2KHR(gpu(), &pd_features);
5910
5911 if (!tf_features.transformFeedback) {
5912 printf("%s transformFeedback not supported; skipped.\n", kSkipPrefix);
5913 return;
5914 }
5915
5916 ASSERT_NO_FATAL_FAILURE(InitState(nullptr, &pd_features));
5917 }
5918
5919 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
5920
5921 auto vkCmdBindTransformFeedbackBuffersEXT =
5922 (PFN_vkCmdBindTransformFeedbackBuffersEXT)vk::GetDeviceProcAddr(m_device->device(), "vkCmdBindTransformFeedbackBuffersEXT");
5923 ASSERT_TRUE(vkCmdBindTransformFeedbackBuffersEXT != nullptr);
5924
5925 {
5926 auto tf_properties = lvl_init_struct<VkPhysicalDeviceTransformFeedbackPropertiesEXT>();
5927 auto pd_properties = lvl_init_struct<VkPhysicalDeviceProperties2>(&tf_properties);
5928 vk::GetPhysicalDeviceProperties2(gpu(), &pd_properties);
5929
5930 auto info = lvl_init_struct<VkBufferCreateInfo>();
5931 info.usage = VK_BUFFER_USAGE_TRANSFORM_FEEDBACK_BUFFER_BIT_EXT;
5932 info.size = 8;
5933 VkBufferObj const buffer_obj(*m_device, info);
5934
5935 // Request a firstBinding that is too large.
5936 {
5937 auto const firstBinding = tf_properties.maxTransformFeedbackBuffers;
5938 VkDeviceSize const offsets[1]{};
5939
5940 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdBindTransformFeedbackBuffersEXT-firstBinding-02356");
5941 m_errorMonitor->SetUnexpectedError("VUID-vkCmdBindTransformFeedbackBuffersEXT-firstBinding-02357");
5942 vkCmdBindTransformFeedbackBuffersEXT(m_commandBuffer->handle(), firstBinding, 1, &buffer_obj.handle(), offsets,
5943 nullptr);
5944 m_errorMonitor->VerifyFound();
5945 }
5946
5947 // Request too many bindings.
5948 if (tf_properties.maxTransformFeedbackBuffers < std::numeric_limits<uint32_t>::max()) {
5949 auto const bindingCount = tf_properties.maxTransformFeedbackBuffers + 1;
5950 std::vector<VkBuffer> buffers(bindingCount, buffer_obj.handle());
5951
5952 std::vector<VkDeviceSize> offsets(bindingCount);
5953
5954 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdBindTransformFeedbackBuffersEXT-firstBinding-02357");
5955 vkCmdBindTransformFeedbackBuffersEXT(m_commandBuffer->handle(), 0, bindingCount, buffers.data(), offsets.data(),
5956 nullptr);
5957 m_errorMonitor->VerifyFound();
5958 }
5959
5960 // Request a size that is larger than the maximum size.
5961 if (tf_properties.maxTransformFeedbackBufferSize < std::numeric_limits<VkDeviceSize>::max()) {
5962 VkDeviceSize const offsets[1]{};
5963 VkDeviceSize const sizes[1]{tf_properties.maxTransformFeedbackBufferSize + 1};
5964
5965 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdBindTransformFeedbackBuffersEXT-pSize-02361");
5966 vkCmdBindTransformFeedbackBuffersEXT(m_commandBuffer->handle(), 0, 1, &buffer_obj.handle(), offsets, sizes);
5967 m_errorMonitor->VerifyFound();
5968 }
5969 }
5970
5971 {
5972 auto info = lvl_init_struct<VkBufferCreateInfo>();
5973 info.usage = VK_BUFFER_USAGE_TRANSFORM_FEEDBACK_BUFFER_BIT_EXT;
5974 info.size = 8;
5975 VkBufferObj const buffer_obj(*m_device, info);
5976
5977 // Request an offset that is too large.
5978 {
5979 VkDeviceSize const offsets[1]{info.size + 4};
5980
5981 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdBindTransformFeedbackBuffersEXT-pOffsets-02358");
5982 vkCmdBindTransformFeedbackBuffersEXT(m_commandBuffer->handle(), 0, 1, &buffer_obj.handle(), offsets, nullptr);
5983 m_errorMonitor->VerifyFound();
5984 }
5985
5986 // Request an offset that is not a multiple of 4.
5987 {
5988 VkDeviceSize const offsets[1]{1};
5989
5990 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdBindTransformFeedbackBuffersEXT-pOffsets-02359");
5991 vkCmdBindTransformFeedbackBuffersEXT(m_commandBuffer->handle(), 0, 1, &buffer_obj.handle(), offsets, nullptr);
5992 m_errorMonitor->VerifyFound();
5993 }
5994
5995 // Request a size that is larger than the buffer's size.
5996 {
5997 VkDeviceSize const offsets[1]{};
5998 VkDeviceSize const sizes[1]{info.size + 1};
5999
6000 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdBindTransformFeedbackBuffersEXT-pSizes-02362");
6001 m_errorMonitor->SetUnexpectedError("VUID-vkCmdBindTransformFeedbackBuffersEXT-pOffsets-02363");
6002 vkCmdBindTransformFeedbackBuffersEXT(m_commandBuffer->handle(), 0, 1, &buffer_obj.handle(), offsets, sizes);
6003 m_errorMonitor->VerifyFound();
6004 }
6005
6006 // Request an offset and size whose sum is larger than the buffer's size.
6007 {
6008 VkDeviceSize const offsets[1]{4};
6009 VkDeviceSize const sizes[1]{info.size - 3};
6010
6011 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdBindTransformFeedbackBuffersEXT-pOffsets-02363");
6012 vkCmdBindTransformFeedbackBuffersEXT(m_commandBuffer->handle(), 0, 1, &buffer_obj.handle(), offsets, sizes);
6013 m_errorMonitor->VerifyFound();
6014 }
6015
6016 // Bind while transform feedback is active.
6017 {
6018 auto vkCmdBeginTransformFeedbackEXT =
6019 (PFN_vkCmdBeginTransformFeedbackEXT)vk::GetDeviceProcAddr(m_device->device(), "vkCmdBeginTransformFeedbackEXT");
6020 ASSERT_TRUE(vkCmdBeginTransformFeedbackEXT != nullptr);
6021 vkCmdBeginTransformFeedbackEXT(m_commandBuffer->handle(), 0, 1, nullptr, nullptr);
6022
6023 VkDeviceSize const offsets[1]{};
6024
6025 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdBindTransformFeedbackBuffersEXT-None-02365");
6026 vkCmdBindTransformFeedbackBuffersEXT(m_commandBuffer->handle(), 0, 1, &buffer_obj.handle(), offsets, nullptr);
6027 m_errorMonitor->VerifyFound();
6028
6029 auto vkCmdEndTransformFeedbackEXT =
6030 (PFN_vkCmdEndTransformFeedbackEXT)vk::GetDeviceProcAddr(m_device->device(), "vkCmdEndTransformFeedbackEXT");
6031 ASSERT_TRUE(vkCmdEndTransformFeedbackEXT != nullptr);
6032 vkCmdEndTransformFeedbackEXT(m_commandBuffer->handle(), 0, 1, nullptr, nullptr);
6033 }
6034 }
6035
6036 // Don't set VK_BUFFER_USAGE_TRANSFORM_FEEDBACK_BUFFER_BIT_EXT.
6037 {
6038 auto info = lvl_init_struct<VkBufferCreateInfo>();
6039 // info.usage = VK_BUFFER_USAGE_TRANSFORM_FEEDBACK_BUFFER_BIT_EXT;
6040 info.size = 4;
6041 VkBufferObj const buffer_obj(*m_device, info);
6042
6043 VkDeviceSize const offsets[1]{};
6044
6045 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdBindTransformFeedbackBuffersEXT-pBuffers-02360");
6046 vkCmdBindTransformFeedbackBuffersEXT(m_commandBuffer->handle(), 0, 1, &buffer_obj.handle(), offsets, nullptr);
6047 m_errorMonitor->VerifyFound();
6048 }
6049
6050 // Don't bind memory.
6051 {
6052 VkBuffer buffer{};
6053 {
6054 auto vkCreateBuffer = (PFN_vkCreateBuffer)vk::GetDeviceProcAddr(m_device->device(), "vkCreateBuffer");
6055 ASSERT_TRUE(vkCreateBuffer != nullptr);
6056
6057 auto info = lvl_init_struct<VkBufferCreateInfo>();
6058 info.usage = VK_BUFFER_USAGE_TRANSFORM_FEEDBACK_BUFFER_BIT_EXT;
6059 info.size = 4;
6060 vkCreateBuffer(m_device->device(), &info, nullptr, &buffer);
6061 }
6062
6063 VkDeviceSize const offsets[1]{};
6064
6065 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdBindTransformFeedbackBuffersEXT-pBuffers-02364");
6066 vkCmdBindTransformFeedbackBuffersEXT(m_commandBuffer->handle(), 0, 1, &buffer, offsets, nullptr);
6067 m_errorMonitor->VerifyFound();
6068 }
6069}
6070
6071TEST_F(VkLayerTest, TransformFeedbackCmdBeginTransformFeedbackEXT) {
6072 TEST_DESCRIPTION("Submit invalid arguments to vkCmdBeginTransformFeedbackEXT");
6073
6074 if (!InstanceExtensionSupported(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME)) {
6075 printf("%s Did not find required instance extension %s; skipped.\n", kSkipPrefix,
6076 VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
6077 return;
6078 }
6079 m_instance_extension_names.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
6080
6081 ASSERT_NO_FATAL_FAILURE(InitFramework(m_errorMonitor));
6082
6083 if (!DeviceExtensionSupported(gpu(), nullptr, VK_EXT_TRANSFORM_FEEDBACK_EXTENSION_NAME)) {
6084 printf("%s %s Extension not supported, skipping tests\n", kSkipPrefix, VK_EXT_TRANSFORM_FEEDBACK_EXTENSION_NAME);
6085 return;
6086 }
6087 m_device_extension_names.push_back(VK_EXT_TRANSFORM_FEEDBACK_EXTENSION_NAME);
6088
6089 {
6090 PFN_vkGetPhysicalDeviceFeatures2KHR vkGetPhysicalDeviceFeatures2KHR =
6091 (PFN_vkGetPhysicalDeviceFeatures2KHR)vk::GetInstanceProcAddr(instance(), "vkGetPhysicalDeviceFeatures2KHR");
6092 ASSERT_TRUE(vkGetPhysicalDeviceFeatures2KHR != nullptr);
6093
6094 auto tf_features = lvl_init_struct<VkPhysicalDeviceTransformFeedbackFeaturesEXT>();
6095 auto pd_features = lvl_init_struct<VkPhysicalDeviceFeatures2>(&tf_features);
6096 vkGetPhysicalDeviceFeatures2KHR(gpu(), &pd_features);
6097
6098 if (!tf_features.transformFeedback) {
6099 printf("%s transformFeedback not supported; skipped.\n", kSkipPrefix);
6100 return;
6101 }
6102
6103 ASSERT_NO_FATAL_FAILURE(InitState(nullptr, &pd_features));
6104 }
6105
6106 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
6107
6108 auto vkCmdBeginTransformFeedbackEXT =
6109 (PFN_vkCmdBeginTransformFeedbackEXT)vk::GetDeviceProcAddr(m_device->device(), "vkCmdBeginTransformFeedbackEXT");
6110 ASSERT_TRUE(vkCmdBeginTransformFeedbackEXT != nullptr);
6111
6112 {
6113 auto tf_properties = lvl_init_struct<VkPhysicalDeviceTransformFeedbackPropertiesEXT>();
6114 auto pd_properties = lvl_init_struct<VkPhysicalDeviceProperties2>(&tf_properties);
6115 vk::GetPhysicalDeviceProperties2(gpu(), &pd_properties);
6116
6117 // Request a firstCounterBuffer that is too large.
6118 {
6119 auto const firstCounterBuffer = tf_properties.maxTransformFeedbackBuffers;
6120
6121 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdBeginTransformFeedbackEXT-firstCounterBuffer-02368");
6122 m_errorMonitor->SetUnexpectedError("VUID-vkCmdBeginTransformFeedbackEXT-firstCounterBuffer-02369");
6123 vkCmdBeginTransformFeedbackEXT(m_commandBuffer->handle(), firstCounterBuffer, 1, nullptr, nullptr);
6124 m_errorMonitor->VerifyFound();
6125 }
6126
6127 // Request too many buffers.
6128 if (tf_properties.maxTransformFeedbackBuffers < std::numeric_limits<uint32_t>::max()) {
6129 auto const counterBufferCount = tf_properties.maxTransformFeedbackBuffers + 1;
6130
6131 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdBeginTransformFeedbackEXT-firstCounterBuffer-02369");
6132 vkCmdBeginTransformFeedbackEXT(m_commandBuffer->handle(), 0, counterBufferCount, nullptr, nullptr);
6133 m_errorMonitor->VerifyFound();
6134 }
6135 }
6136
6137 // Request an out-of-bounds location.
6138 {
6139 auto info = lvl_init_struct<VkBufferCreateInfo>();
6140 info.usage = VK_BUFFER_USAGE_TRANSFORM_FEEDBACK_COUNTER_BUFFER_BIT_EXT;
6141 info.size = 4;
6142 VkBufferObj const buffer_obj(*m_device, info);
6143
6144 VkDeviceSize const offsets[1]{1};
6145
6146 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdBeginTransformFeedbackEXT-pCounterBufferOffsets-02370");
6147 vkCmdBeginTransformFeedbackEXT(m_commandBuffer->handle(), 0, 1, &buffer_obj.handle(), offsets);
6148 m_errorMonitor->VerifyFound();
6149 }
6150
6151 // Request specific offsets without specifying buffers.
6152 {
6153 VkDeviceSize const offsets[1]{};
6154
6155 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdBeginTransformFeedbackEXT-pCounterBuffer-02371");
6156 vkCmdBeginTransformFeedbackEXT(m_commandBuffer->handle(), 0, 1, nullptr, offsets);
6157 m_errorMonitor->VerifyFound();
6158 }
6159
6160 // Don't set VK_BUFFER_USAGE_TRANSFORM_FEEDBACK_COUNTER_BUFFER_BIT_EXT.
6161 {
6162 auto info = lvl_init_struct<VkBufferCreateInfo>();
6163 // info.usage = VK_BUFFER_USAGE_TRANSFORM_FEEDBACK_COUNTER_BUFFER_BIT_EXT;
6164 info.size = 4;
6165 VkBufferObj const buffer_obj(*m_device, info);
6166
6167 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdBeginTransformFeedbackEXT-pCounterBuffers-02372");
6168 vkCmdBeginTransformFeedbackEXT(m_commandBuffer->handle(), 0, 1, &buffer_obj.handle(), nullptr);
6169 m_errorMonitor->VerifyFound();
6170 }
6171
6172 // Begin while transform feedback is active.
6173 {
6174 vkCmdBeginTransformFeedbackEXT(m_commandBuffer->handle(), 0, 1, nullptr, nullptr);
6175
6176 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdBeginTransformFeedbackEXT-None-02367");
6177 vkCmdBeginTransformFeedbackEXT(m_commandBuffer->handle(), 0, 1, nullptr, nullptr);
6178 m_errorMonitor->VerifyFound();
6179
6180 auto vkCmdEndTransformFeedbackEXT =
6181 (PFN_vkCmdEndTransformFeedbackEXT)vk::GetDeviceProcAddr(m_device->device(), "vkCmdEndTransformFeedbackEXT");
6182 ASSERT_TRUE(vkCmdEndTransformFeedbackEXT != nullptr);
6183
6184 vkCmdEndTransformFeedbackEXT(m_commandBuffer->handle(), 0, 1, nullptr, nullptr);
6185 }
6186}
6187
6188TEST_F(VkLayerTest, TransformFeedbackCmdEndTransformFeedbackEXT) {
6189 TEST_DESCRIPTION("Submit invalid arguments to vkCmdEndTransformFeedbackEXT");
6190
6191 if (!InstanceExtensionSupported(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME)) {
6192 printf("%s Did not find required instance extension %s; skipped.\n", kSkipPrefix,
6193 VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
6194 return;
6195 }
6196 m_instance_extension_names.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
6197
6198 ASSERT_NO_FATAL_FAILURE(InitFramework(m_errorMonitor));
6199
6200 if (!DeviceExtensionSupported(gpu(), nullptr, VK_EXT_TRANSFORM_FEEDBACK_EXTENSION_NAME)) {
6201 printf("%s %s Extension not supported, skipping tests\n", kSkipPrefix, VK_EXT_TRANSFORM_FEEDBACK_EXTENSION_NAME);
6202 return;
6203 }
6204 m_device_extension_names.push_back(VK_EXT_TRANSFORM_FEEDBACK_EXTENSION_NAME);
6205
6206 {
6207 PFN_vkGetPhysicalDeviceFeatures2KHR vkGetPhysicalDeviceFeatures2KHR =
6208 (PFN_vkGetPhysicalDeviceFeatures2KHR)vk::GetInstanceProcAddr(instance(), "vkGetPhysicalDeviceFeatures2KHR");
6209 ASSERT_TRUE(vkGetPhysicalDeviceFeatures2KHR != nullptr);
6210
6211 auto tf_features = lvl_init_struct<VkPhysicalDeviceTransformFeedbackFeaturesEXT>();
6212 auto pd_features = lvl_init_struct<VkPhysicalDeviceFeatures2>(&tf_features);
6213 vkGetPhysicalDeviceFeatures2KHR(gpu(), &pd_features);
6214
6215 if (!tf_features.transformFeedback) {
6216 printf("%s transformFeedback not supported; skipped.\n", kSkipPrefix);
6217 return;
6218 }
6219
6220 ASSERT_NO_FATAL_FAILURE(InitState(nullptr, &pd_features));
6221 }
6222
6223 ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
6224
6225 auto vkCmdEndTransformFeedbackEXT =
6226 (PFN_vkCmdEndTransformFeedbackEXT)vk::GetDeviceProcAddr(m_device->device(), "vkCmdEndTransformFeedbackEXT");
6227 ASSERT_TRUE(vkCmdEndTransformFeedbackEXT != nullptr);
6228
6229 {
6230 // Activate transform feedback.
6231 auto vkCmdBeginTransformFeedbackEXT =
6232 (PFN_vkCmdBeginTransformFeedbackEXT)vk::GetDeviceProcAddr(m_device->device(), "vkCmdBeginTransformFeedbackEXT");
6233 ASSERT_TRUE(vkCmdBeginTransformFeedbackEXT != nullptr);
6234 vkCmdBeginTransformFeedbackEXT(m_commandBuffer->handle(), 0, 1, nullptr, nullptr);
6235
6236 {
6237 auto tf_properties = lvl_init_struct<VkPhysicalDeviceTransformFeedbackPropertiesEXT>();
6238 auto pd_properties = lvl_init_struct<VkPhysicalDeviceProperties2>(&tf_properties);
6239 vk::GetPhysicalDeviceProperties2(gpu(), &pd_properties);
6240
6241 // Request a firstCounterBuffer that is too large.
6242 {
6243 auto const firstCounterBuffer = tf_properties.maxTransformFeedbackBuffers;
6244
6245 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdEndTransformFeedbackEXT-firstCounterBuffer-02376");
6246 m_errorMonitor->SetUnexpectedError("VUID-vkCmdEndTransformFeedbackEXT-firstCounterBuffer-02377");
6247 vkCmdEndTransformFeedbackEXT(m_commandBuffer->handle(), firstCounterBuffer, 1, nullptr, nullptr);
6248 m_errorMonitor->VerifyFound();
6249 }
6250
6251 // Request too many buffers.
6252 if (tf_properties.maxTransformFeedbackBuffers < std::numeric_limits<uint32_t>::max()) {
6253 auto const counterBufferCount = tf_properties.maxTransformFeedbackBuffers + 1;
6254
6255 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdEndTransformFeedbackEXT-firstCounterBuffer-02377");
6256 vkCmdEndTransformFeedbackEXT(m_commandBuffer->handle(), 0, counterBufferCount, nullptr, nullptr);
6257 m_errorMonitor->VerifyFound();
6258 }
6259 }
6260
6261 // Request an out-of-bounds location.
6262 {
6263 auto info = lvl_init_struct<VkBufferCreateInfo>();
6264 info.usage = VK_BUFFER_USAGE_TRANSFORM_FEEDBACK_COUNTER_BUFFER_BIT_EXT;
6265 info.size = 4;
6266 VkBufferObj const buffer_obj(*m_device, info);
6267
6268 VkDeviceSize const offsets[1]{1};
6269
6270 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdEndTransformFeedbackEXT-pCounterBufferOffsets-02378");
6271 vkCmdEndTransformFeedbackEXT(m_commandBuffer->handle(), 0, 1, &buffer_obj.handle(), offsets);
6272 m_errorMonitor->VerifyFound();
6273 }
6274
6275 // Request specific offsets without specifying buffers.
6276 {
6277 VkDeviceSize const offsets[1]{};
6278
6279 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdEndTransformFeedbackEXT-pCounterBuffer-02379");
6280 vkCmdEndTransformFeedbackEXT(m_commandBuffer->handle(), 0, 1, nullptr, offsets);
6281 m_errorMonitor->VerifyFound();
6282 }
6283
6284 // Don't set VK_BUFFER_USAGE_TRANSFORM_FEEDBACK_COUNTER_BUFFER_BIT_EXT.
6285 {
6286 auto info = lvl_init_struct<VkBufferCreateInfo>();
6287 // info.usage = VK_BUFFER_USAGE_TRANSFORM_FEEDBACK_COUNTER_BUFFER_BIT_EXT;
6288 info.size = 4;
6289 VkBufferObj const buffer_obj(*m_device, info);
6290
6291 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdEndTransformFeedbackEXT-pCounterBuffers-02380");
6292 vkCmdEndTransformFeedbackEXT(m_commandBuffer->handle(), 0, 1, &buffer_obj.handle(), nullptr);
6293 m_errorMonitor->VerifyFound();
6294 }
6295 }
6296
6297 // End while transform feedback is inactive.
6298 {
6299 vkCmdEndTransformFeedbackEXT(m_commandBuffer->handle(), 0, 1, nullptr, nullptr);
6300
6301 m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-vkCmdEndTransformFeedbackEXT-None-02375");
6302 vkCmdEndTransformFeedbackEXT(m_commandBuffer->handle(), 0, 1, nullptr, nullptr);
6303 m_errorMonitor->VerifyFound();
6304 }
6305}