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