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