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